House Of Emma
House Of Emma 的利用背景:
学习 House Of Kiwi 大概是一个月之前了,中间由于学校的一些活动确实是有一段时间没怎么学习,回过神来还需要把前面的知识再重新复习一遍,感觉也不算是很扎实。
House Of Kiwi 可以说是和 Emma 一脉相承的一个利用手法吧,我们通常在 _IO_file_jumps 可以写的情况下的利用 Kiwi ,那如果不可写呢,house of emma 就是对其的补充,也可以说是进阶。
如果 vtable 指向的 _IO_file_jumps 不可写,那么 House of Kiwi 这种攻击手法就会失效。这时候就需要考虑劫持 vtable 。但在新版 glibc ,之前的劫持 vtable 的方法已经失效。
- 由于自 libc-2.24 起对 vtable 指向的地址范围有检查,因此不能随便将 vtable 劫持到某块伪造了 _IO_jump_t 的内存上。
- 自 glibc-2.28 起,_IO_str_jumps 上的 _IO_str_finish 不再调用 _IO_strfile(IO_FILE 结构体) 上的函数指针。
因此需要寻找其他的危险函数来劫持程序流。
House Of Emma 的利用手法:
_IO_cookie_jumps
vtable 的合法范围内,还有另一个 _IO_jump_t 类型的函数表叫做 _IO_cookie_jumps ,其中有如下危险函数可供我们利用:
1 | static ssize_t |
其中 _IO_cookie_file 有如下定义:
1 | /* Special file type for fopencookie function. */ |
因此攻击手法与前面的 _IO_str_jumps 相似,不过需要绕过指针保护 PTR_DEMANGLE 。
分析汇编可知,这段宏定义的操作是将函数指针循环右移 11 位然后与 fs:[0x30] 异或得到真正的函数地址。

我们知道, fs:[0x28] 是 tls 上存储的 canary,根据 tcbhead_t 结构体的定义,fs[0x30] 是 pointer_guard ,用于对指针进行加密。
1 | //sysdeps/x86_64/nptl/tls.h |
因此我们可以先泄露堆地址和 libc 基地址,然后利用 large bin attack 在 tls 对应 pointer_guard 上写一个 chunk 地址,从而绕过指针保护。
在实际调试时可以利用 canary 等方法查找 pointer_guard 地址,然后在攻击时根据 libc 基地址定位 pointer_guard 。

与 house of kiwi 一样,house of emma 也是通过 __malloc_assert 触发漏洞,但是由于 pointer_guard 已被修改,原来受保护的函数指针都已经无法调用,因此要选择最早调用的 vtable 中的函数进行触发,因此这里选择下面这个调用链:
1 | static void |
具体利用流程:在利用 UAF 泄露 libc 和堆地址后,利用 2 次 large bin attack 分别覆盖 pointer_guard 和 stderr 指针为某 chunk 地址,然后作如下图所示构造。最后通过 __malloc_asserrt 触发漏洞。

需要注意的是,由于伪造的 IO_FILE 的 flag 的 _IO_USER_LOCK(0x8000)没有置位,因此在 __vfxprintf 函数中会执行如下代码:

因此伪造的 IO_FILE 的 _lock 应该指向可读写的内存。
glibc-2.36 的 __malloc_assert 发生重大改变,直接通过系统调用不走 IO,该方法失效。不过只要能够调用 vtable 中的函数我们就能够完成 House Of Emma 利用。
1 | _Noreturn static void |
参考资料:https://xz.aliyun.com/news/15458
更新: 2026-05-19 17:29:42
原文: https://www.yuque.com/idcm/wnemg9/qbrsyfxe1dilrnd9