任意写入到 RCE
将以下提示词粘贴到你的 AI 对话框中:
请根据 https://skillhub.cn/install/skillhub.md,安装 @user_3c6cb52e/arbitrary-write-to-rce-y5gy
技能介绍
问题:拿到任意写之后,最后一公里卡在哪
在堆利用、格式化字符串或栈溢出拿到任意地址写入原语后,pwn 的最终目标是把这份写能力兑换成代码执行。难点不在"能写哪",而在"写哪里会被执行"。glibc 的多个经典劫持点(__malloc_hook、__free_hook)在 glibc 2.34 之后已被移除,基础模型仍会按旧教程推荐这些失效目标;__exit_funcs、__atexit 等路径上的函数指针带有 TLS 指针混淆(pointer mangling)保护,直接写入会被反混淆逻辑打回,必须同步覆写 fs:[0x30] 处的指针 guard 并预先做 ROL/ROR 变换。版本错配与指针混淆,是这条路上最常见的两个翻车点。
技能如何工作:按 glibc 版本组织的目标选择
技能将覆写目标按 glibc 版本兼容性分组,形成一张决策地图:
- House of Cat / FSOP 路径:针对 glibc ≥ 2.35,利用
_IO_wfile_seekoff→_IO_switch_to_wget_mode链伪造 wide vtable 触发 FSOP。 TLS_dtor_list:glibc ≥ 2.34 之后的主力目标,替代被移除的 hook。__exit_funcs/__atexit:在能同时覆写函数指针与 TLS 指针 guard 的前提下,按ROL(target, 0x11)且 guard 置 0 的流程绕过 mangling。_dl_fini/ linkmap 破坏:exit 时_dl_fini遍历 linkmap 并调用DT_FINI_ARRAY条目,破坏l_addr或l_info[DT_FINI_ARRAY]指向伪造数组;优点是 FINI_ARRAY 中的函数指针不做混淆。modprobe_path(内核):覆写内核路径以 root 执行任意命令,需配合内核写原语。.fini_array:覆写程序正常退出时调用的析构指针,但 Full RELRO 下可能只读。setcontextgadget:glibc < 2.29 与 ≥ 2.29 分别适配,作为寄存器 pivot gadget。
适用边界与注意点
- 技能只覆盖"写原语 → 执行"这一层,前置的任意写获取需配合
heap-exploitation、format-string-exploitation等技能。 .fini_array在 Full RELRO 二进制中通常不可写,选择前需确认保护配置。- 内核侧
modprobe_path覆写要求已具备内核级写能力,不可单独使用。 setcontext与__exit_funcs流程均有严格的版本与寄存器条件,落地前按目标 glibc 版本核对。
使用场景
- 你已通过堆利用拿到任意写原语,需要判断当前 glibc 版本下应覆写 GOT、TLS_dtor_list 还是 _dl_fini 来触发执行
- 二进制 pwn 题中 Full RELRO 开启,__free_hook 已失效,需要按技能的 glibc 版本对照表选择仍可写的劫持目标
- 实战中覆写 __exit_funcs 的函数指针被 TLS 指针混淆拦截,需要按技能步骤同步覆写 fs:[0x30] 的 guard 并做 ROL 变换
- 目标环境 glibc ≥ 2.34,旧的 hook 链不可用,需要转向 TLS_dtor_list 或 _dl_fini / link_map 破坏路径
适合人员
- CTF pwn 选手,在比赛解题中需要快速确定任意写原语到代码执行的覆写目标
- 二进制安全研究员,分析真实漏洞时要把堆或格式化字符串写能力兑换成执行流
- 逆向工程师,确认目标二进制的 glibc 版本与保护配置后筛选可用的劫持点
- 漏洞利用开发者,在编写 poc 时需要处理 TLS 指针混淆与版本兼容细节