exit_hook攻击利用
字数 1460 2025-08-20 18:17:41
exit_hook攻击利用技术详解
概述
exit_hook攻击是一种针对glibc动态链接器机制的利用技术,通过劫持程序退出时的处理流程来实现代码执行。本文将详细分析该技术的原理、利用条件、实现方法以及实际案例。
适用版本
- 适用于glibc-2.34之前的版本
- glibc-2.34及以后版本已失效
利用条件
-
内存写入能力:
- 至少需要一次任意地址写入能力
- 理想情况下需要两次任意地址写入能力
-
程序退出条件:
- 程序可以显式触发exit函数
- 或者主函数由libc_start_main启动且可正常退出,从而调用到_dl_fini函数
技术原理分析
退出流程分析
当程序退出时,会调用exit函数,其执行流程如下:
- exit函数调用
__run_exit_handlers __run_exit_handlers进一步调用_dl_fini函数_dl_fini函数会访问_rtld_global结构体中的两个关键函数指针:rtld_lock_default_lock_recursivertld_lock_default_unlock_recursive
关键数据结构
_rtld_global结构体(位于ld.so中)包含以下关键字段:
rtld_lock_default_lock_recursive(偏移0xf08)rtld_lock_default_unlock_recursive(偏移0xf10)_dl_load_lock(偏移0x908) - 可作为参数存储区
攻击方式
-
一次任意写:
- 直接将
rtld_lock_default_lock_recursive修改为one_gadget地址 - 成功率取决于one_gadget的约束条件
- 直接将
-
两次任意写(更可靠):
- 第一次写:修改
rtld_lock_default_lock_recursive为system函数地址 - 第二次写:修改
_dl_load_lock为"/bin/sh\x00"字符串 - 程序退出时会执行
system("/bin/sh")
- 第一次写:修改
实际案例分析
案例1:The fastest man
利用步骤:
-
绕过密码验证(发现base64编码中有key)
-
获取libc基地址
-
计算关键地址:
ld_base = libc_base + 0x213000 _rtld_global = ld_base + ld.sym['_rtld_global'] _dl_rtld_lock_recursive = _rtld_global + 0xf08 -
将one_gadget写入
_dl_rtld_lock_recursive
EXP关键代码:
ru('give me a address:')
sl(str(_dl_rtld_lock_recursive))
sla('give me a value:',str(ogg)) # ogg为one_gadget地址
案例2:2023蓝帽杯半决赛-uaf
利用特点:
- 通过UAF漏洞结合程序提供的任意写机会
- 直接修改exit_hook实现利用
EXP关键代码:
adm('shu',2) # 触发任意写
_rtld_global = libc_base+0x226060
_dl_rtld_lock_recursive = _rtld_global + 0xf08
ru('WRITE MODE: ')
s(p64(_dl_rtld_lock_recursive))
og = libc_base + 0xe6c7e # one_gadget
s(p64(og))
案例3:WMCTF2023-blindless
特殊场景:
- 无信息泄露,需要爆破3位地址(1/4096概率)
- 通过mmap分配大内存实现越界写
利用步骤:
- 申请超大内存触发mmap
- 计算
_rtld_global相关地址 - 构造payload写入system和"/bin/sh"
EXP关键代码:
payload = b'@' + p32(argv0 - 0x10) + write(b'/bin/sh\x00')
payload += b'@' + p32(rtld_lock - argv0 - 8) + write(b'\x90\x02\x46') #system
防御措施
- 升级到glibc-2.34或更高版本
- 加强内存写保护机制
- 监控关键函数指针的修改行为
参考链接
总结
exit_hook攻击是一种在特定glibc版本下有效的利用技术,特别适合在有任意写能力但缺乏信息泄露的场景。通过深入理解动态链接器的内部机制,攻击者可以绕过多种保护措施实现代码执行。防御方面应及时升级系统库,并加强对关键内存区域的保护。