House Of Roman
House of Roman 的一个核心思路就是利用 局部写 减少随机化的程度,从而给出爆破的可能
这种利用手法的主要特点是不需要 leak libc的地址,用于 bypass ALSR,利用 12-bit 的爆破来达到获取 shell 的目的,且仅仅只需要一个 UAF 漏洞以及能创建任意大小的 chunk 的情况下,就能完成利用(当然也可以来绕 PIE)
- 利用 off-by-one 把原本不可能进入 fastbin 的 unsorted chunk 进行修改(修改 size 到 fastbin 的范围),使遗留有“main_arena+xx”的chunk进入 fastbin
- 利用 UAF 修改遗留在 fast chunk 中的“main_arena+xx”,使其指向目标地址
House Of Roman 利用姿势
外国老哥给了一个 demo:
1 | switch ( v4 ) |
- malloc_chunk:用户输入
size, 然后malloc(size), 大小不限 - write_chunk:往指定
heap_ptr写入size+1字节数据,off-by-one(Write时只是校验指针是否为0) - free_chunk:调用
free释放掉heap_ptr,不过没有清零,double free和uaf
1 | void free_chunk() |
保护如下:
1 | 04:44 haclh@ubuntu:house_of_roman $ checksec ./new_chall |
分析外国老哥的exp:
一,分配 3 个 chunk ,在 chunk2 + 0x78 处设置 p64(0x61) , 作用是 fake size ,用于后面 的 fastbin attack
1 | create(0x18,0) # chunk1 |
二,释放掉 chunk2 , 然后分配同样大小再次分配到 chunk2 , 此时 chunk2+0x10 和 chunk2+0x18 中有 main_arean 的地址,分配 3 个 fastbin ,利用 off-by-one 修改 chunk2->size = 0x71
1 | free(1) # chunk2 to unsortedbin |
这里的 off-by-one 保证了 chunk2 可以进入大小为“0x70~0x80”的 fastbin
这样“main_arena+88”就会进入 fastbin 了(方便后续的 UAF 进行修改)
三,生成两个 fastbin ,然后利用 uaf ,部分地址写,把 chunk1 链入到 fastbin
1 | free(2) |
1 | 0x70: 0x555555757160 —▸ 0x555555757020 —▸ 0x7ffff7dd1b78 (main_arena+88) ◂— 0x7ffff7dd1b78 |
- 0x555555757160 就是 chunk4
- 0x555555757020 就是 chunk1(原本该是chunk3,但是末尾字节被覆盖了)
四,通过修改 chunk1->fd 的低 2 字节, 使得 chunk1->fd= malloc_hook - 0x23
1 | malloc_hook_nearly = "\xed\x1a" # 该地址为 malloc_hook 上方 |
即把“main_arena+88”覆盖为“malloc_hook - 0x23”
五,然后分配 3 个 0x70 的 chunk ,就可以拿到 malloc_hook 所在的那个 chunk
1 | create(0x65,0) |
注意:这里设置的是“malloc_hook - 0x23”,存在“\x7f”来通过检查
六,释放掉 chunk16 ,进入 fastbin ,利用 uaf 设置 chunk16->fd = 0 , 修复了 fastbin
1 | free(15) |
现在 fastbin 中只留有 chunk16 的地址(这个“修复”是什么意思,没有搞明白)
七,unsortedbin attack,使得 malloc_hook 被写入 main_arena+88
1 | create(0xc8,1) # chunk2 |
根据 unsortedbin 的特性,它会向 第一个chunk 和 最后一个chunk 中写入 main_arena+xx ,修改其FD指向 malloc_hook ,最后一个chunk 就变为了 malloc_hook ,当然会被写入 main_arena+88
八,修改 malloc_hook 的低三个字节 ,使得 malloc_hook 为 one_gadget 的地址
1 | over = "R"*0x13 # padding for malloc_hook |
九,然后 free 两次同一个 chunk ,触发 malloc_printerr , getshell
1 | free(18) |
上面的偏移均为调试所得,开启 aslr 后,需要爆破程序
利用条件:
- UAF(对 fastbin 中的“main_arena+xx”进行修改,使其指向目标地址)
- off-by-one(覆写“size”的大小,为了使保留有“main_arena+xx”进入fastbin)
版本对 House Of Roman 的影响
House Of Roman 并不依赖于 libc 源码,它的思想完全可以独立使用(覆盖main_arena)
但是实现 House Of Roman 需要 fastbin attack,unsortedbin attack 等技术的配合,而它们会受 libc 版本影响:
libc-2.27
- fastbin attack 需要绕 tache(对chunk的数量有要求)
- unsortedbin attack 可以直接打(只检查了“victim->size”,形同虚设)
libc-2.29
- fastbin attack 需要绕 tache(对chunk的数量有要求)
- unsortedbin attack 失效(其实也有办法可以绕过,只是条件苛刻)