House of Lore

House of Lore主要是在有UAF漏洞的情况下,通过修改smallbins的bk实现在任意位置申请smallbins的利用方法。

不过类似的思想同样也可以用在unsortedbin以及largebin上

 

实践

直接来看一下目标程序

程序运行起来输出了libc和堆的地址,输入一个username之后进入常规的堆菜单

<img src=”https://static.hack1s.fun/images/2021/11/18/image-20211118164315417.png” alt=”image-20211118164315417″ style=”zoom:50%;” />

可以申请的chunk大小要在0x400以内,但是实际上最大可以申请0x428的空间

存在的问题主要是malloc的内容在free掉之后仍然可以使用edit来写

也就是存在UAF的问题

那么接下来就根据我们想要edit的bins类型进行分类,实现将伪造的chunk加入到对应的bins链表中,并申请到对应的空间实现任意地址写的效果。

Unsortedbin

根据我们已经学过的知识,在我们申请一个大小处于unsortedbin的chunk,并将其free掉之后

利用UAF的漏洞修改unsortedbin的bk,就可以利用unsortebin attack实现任意地址写

但是这里我们和unsortedbin attack不同的地方在于

unsortedbin attack中,我们关注的是unsortedbin ulink下来时执行的操作,并不关注这个chunk是否会被申请

但是这里我们确确实实是想要将这个chunk申请下来的

在内存中,想要修改的target在输入的username附近

和前面类似的技巧,通过修改username,将其伪造为一个合适的大小

username = p64(0) + p64(0xb1)
chunk_A = malloc(0x98)
chunk_B = malloc(0x88)
free(chunk_A)
edit(chunk_A, p64(0)+p64(elf.sym.user))

这部分代码运行可以看到unsortedbin的bk被修改为了user结构体的地址

这之后继续malloc一个0xa0的chunk

这时malloc首先会检查大小为0xa0的smallbin,发现里面为空之后会检查unsortedbin

(从main_arena倒着搜索)

正好发现unsortedbin里面的chunk大小为0xa0,所以分配成功,同时写值

分配成功后可以看到main_arena中的unsortedbin bk指向了user结构体

这时如果再申请一个chunk,就会尝试从user结构体位置申请

我们之前写了一个大小为0xb0,那么就申请一个大小为0xb0的chunk

但是在运行是出现了报错,这是因为我们伪造的这个unsortedbin chunk的bk是0

在unsortedbin unlink下来的时候p->bk->fd=fd会发生这样的写操作,也就是unsortedbin attack中的副作用

而在这里我们伪造的unsortedbin chunk的bk是一个不可写的值,因此在尝试向0x0这附近的地址写内容时会出错;

需要改进的地方是将这个地方填上一个合理的地址,还是直接改为user结构体的地址

username = p64(0) + p64(0xb1) + p64(0) + p64(elf.sym.user)
chunk_A = malloc(0x98)
chunk_B = malloc(0x88)
free(chunk_A)
edit(chunk_A, p64(0)+p64(elf.sym.user))
malloc(0x98)
chunk_C = malloc(0xa8)

正常执行,这样我们就申请到了target前方的chunk

最后执行一句edit(chunk_C, p64(0)*4+b"Much Win")

就可以将目标字符串修改了

总结一下,unsortedbin的house of lore有点类似之前fastbin dup中从任意位置申请来一个伪造的chunk,这里面还有几个特点

  • 可以利用内存中的flag位,并且unused位被置1的情况下也可以成功;
  • 因为fake chunk的unsortedbin可以修改为一个可写的地址,可以进一步利用这个地址继续申请大小合适的unsortedbin
  • 在glibc 2.29及更新的版本中无法使用,因为unsortedbin attack被修复了

发表回复

您的电子邮箱地址不会被公开。