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 失效(其实也有办法可以绕过,只是条件苛刻)