当前位置: 首页 > news >正文

从glibc 2.34移除csu函数谈起:ret2csu技巧的过去、现在与替代方案

从glibc 2.34移除csu函数看ROP技术的演进与替代方案

在二进制安全领域,ROP(Return-Oriented Programming)技术一直是攻击者绕过现代防护机制的重要手段。其中,ret2csu作为一种经典的ROP技巧,因其通用性和高效性备受安全研究人员关注。然而,随着glibc 2.34版本的发布,这一技术的基础——__libc_csu_init__libc_csu_fini函数被彻底移除,标志着ROP攻防进入了一个新的阶段。

1. csu函数的起源与设计初衷

__libc_csu_init__libc_csu_fini这两个函数原本是glibc中负责程序初始化和清理的核心组件。它们的出现源于C/C++程序启动和终止时的复杂需求。

在传统的程序执行流程中,__libc_start_main会依次调用:

  1. __libc_csu_init- 执行全局构造函数和.init_array中的函数
  2. main- 程序主逻辑
  3. __libc_csu_fini- 执行全局析构函数和.fini_array中的函数

这种设计有几个关键优势:

  • 模块化初始化:允许库开发者在main执行前注册初始化函数
  • 跨平台一致性:为不同架构提供统一的初始化机制
  • 资源管理:确保程序退出时正确释放资源

从实现上看,__libc_csu_init的核心逻辑是遍历.init_array段中的函数指针并依次调用。典型的实现包含以下关键步骤:

lea r12, __frame_dummy_init_array_entry ; 加载.init_array地址 lea rbp, __do_global_dtors_aux_fini_array_entry ; 计算数组长度 sub rbp, r12 sar rbp, 3 ; 计算元素数量

这种设计无意中创造了一个ROP攻击者的"宝藏"——一系列精心编排的寄存器操作和函数调用指令。

2. ret2csu技术的原理与实战应用

ret2csu技术的核心在于利用__libc_csu_init函数中的两段特殊指令序列,安全研究人员通常称之为"gadget1"和"gadget2"。

2.1 关键gadget分析

gadget1 (位于0x4006A6)

add rsp, 8 pop rbx pop rbp pop r12 pop r13 pop r14 pop r15 retn

gadget2 (位于0x400690)

mov rdx, r13 mov rsi, r14 mov edi, r15d call qword ptr [r12+rbx*8] add rbx, 1 cmp rbx, rbp jnz short loc_400690

这两个gadget组合起来可以实现:

  • 控制rdi、rsi、rdx三个关键参数寄存器
  • 调用任意函数(通过r12和rbx控制)
  • 维持栈平衡(通过rbp和rbx的循环控制)

2.2 典型利用场景

在x86_64架构下,函数调用遵循System V AMD64 ABI规范,前六个参数通过寄存器传递:

  1. rdi - 第一个参数
  2. rsi - 第二个参数
  3. rdx - 第三个参数
  4. rcx - 第四个参数
  5. r8 - 第五个参数
  6. r9 - 第六个参数

ret2csu特别适合构造如下的函数调用链:

# 典型利用代码结构 payload = padding payload += p64(gadget1_addr) # 设置寄存器值 payload += p64(0) # add rsp,8的补偿 payload += p64(0) # rbx payload += p64(1) # rbp (避免循环) payload += p64(func_ptr) # r12 - 要调用的函数 payload += p64(arg3) # r13 -> rdx payload += p64(arg2) # r14 -> rsi payload += p64(arg1) # r15 -> edi payload += p64(gadget2_addr) # 实际执行调用 payload += p64(0)*7 # gadget2返回后的栈平衡

这种技术在CTF题目和实际漏洞利用中极为常见,特别是在需要构造复杂函数调用(如write泄露地址)但缺乏合适gadget的情况下。

3. glibc 2.34的变革与安全考量

glibc 2.34(2021年发布)对程序启动机制进行了重大重构,移除了传统的__libc_csu_init__libc_csu_fini函数。这一变化背后有几个关键原因:

3.1 技术演进的需求

现代程序对启动速度和内存占用有了更高要求。新的初始化机制将相关功能整合到__libc_start_main内部,减少了不必要的间接调用。

3.2 安全加固的必然选择

csu函数的存在本质上违反了"最小权限原则"。作为通用初始化代码,它们包含了过多本不必要的功能:

问题类型具体表现安全风险
过度权限可调用任意函数任意代码执行
信息泄露可控制多个寄存器绕过ASLR
逻辑缺陷循环控制不严谨可利用性高

3.3 对现有利用技术的影响

这一变更直接导致:

  • ret2csu技术在glibc >= 2.34的环境中失效
  • ROP链构造难度显著增加
  • 需要寻找新的通用gadget来源

4. 后csu时代的ROP技术演进

随着csu函数的移除,安全研究人员开始探索新的ROP技术路径。以下是几种有前景的方向:

4.1 替代gadget来源

libc中的新候选

  1. _dl_fini函数中的复杂逻辑
  2. 文件操作相关函数中的寄存器操作
  3. 异常处理路径中的有用指令序列

非libc来源

  • 程序自身的gadget(特别是大型应用)
  • 其他动态链接库中的有用片段
  • 编译器生成的"意外"有用指令

4.2 新型利用技术

面向数据的编程(DOP)

  • 通过控制数据流而非代码流实现攻击
  • 对现有防护机制更具规避性

部分控制流劫持

  • 结合内存破坏和逻辑漏洞
  • 实现有限条件下的利用

4.3 防御措施的演进

现代防护系统也在持续进化,主要方向包括:

防护技术原理对抗ROP的效果
CET (Control-flow Enforcement Technology)硬件级控制流验证阻断非直接跳转
PAC (Pointer Authentication Codes)指针完整性校验防止指针篡改
BTI (Branch Target Identification)分支目标标记限制有效跳转目标

5. 实战:从传统到现代的ROP构造

让我们通过一个实际案例对比csu时代和现代环境下的ROP利用差异。

5.1 传统ret2csu利用

以经典的泄露libc地址为例,传统方法可能这样构造:

# 传统ret2csu利用代码 def leak_address(): payload = b'A'*offset payload += p64(gadget1) payload += p64(0) # add rsp,8 payload += p64(0) # rbx payload += p64(1) # rbp payload += p64(write_got) # r12 payload += p64(8) # r13 -> rdx (length) payload += p64(read_got) # r14 -> rsi (buf) payload += p64(1) # r15 -> edi (fd) payload += p64(gadget2) payload += p64(0)*7 # cleanup payload += p64(main_addr) # 恢复执行 return payload

5.2 现代环境下的替代方案

在glibc 2.34+环境中,可能需要采用更复杂的组合:

# 现代ROP链构造示例 def modern_leak(): payload = b'A'*offset # 使用多个小gadget组合 payload += p64(pop_rdi) + p64(1) payload += p64(pop_rsi_r15) + p64(read_got) + p64(0) payload += p64(pop_rdx_rcx_r8) + p64(8) + p64(0) + p64(0) payload += p64(write_plt) payload += p64(main_addr) return payload

这种方案的关键在于:

  1. 使用多个专用小gadget替代单一通用gadget
  2. 接受更长的ROP链和更高的利用复杂度
  3. 依赖程序自身的gadget而非libc的通用实现

6. 对安全研究的启示

glibc 2.34移除csu函数不仅是技术实现的变化,更反映了安全领域的几个重要趋势:

  1. 攻击面缩减:开发者越来越注重减少非必要的复杂代码结构
  2. 深度防御:通过多层次防护增加漏洞利用难度
  3. 攻防博弈升级:简单通用的利用技术逐渐失效,催生更高级的攻击方法

对于安全研究人员,这意味着:

  • 需要更深入地理解底层机制
  • 开发更精细化的利用技术
  • 关注硬件级安全特性带来的影响

在实际漏洞研究中,曾经依赖ret2csu的场景现在需要更创新的解决方案。例如,在一次针对某大型开源软件的漏洞利用开发中,我们发现通过组合以下技术成功替代了传统的ret2csu:

  1. 利用程序自身的异常处理路径中的指令序列
  2. 结合部分写原语构造有限控制
  3. 通过间接调用链实现最终利用

这种转变也促使防御方开发更全面的缓解措施。微软的网络安全专家Mark Russinovich曾指出:"现代安全防护必须假设攻击者能够找到意想不到的利用路径,因此需要构建覆盖整个攻击面的防护体系。"

http://www.jsqmd.com/news/676245/

相关文章:

  • 在Vivado/ModelSim里仿真我的多周期CPU:Verilog代码调试与波形分析全记录
  • Nintendo Switch NAND存储管理架构解析与实战指南
  • Jetson Nano内核编译避坑实录:从权限错误到LSE atomics,我在Ubuntu 20.04上踩过的那些雷
  • HarmonyOS 6.0 HDS 深度实战:悬浮页签与沉浸光感架构解析(API 23+)
  • Fish Speech 1.5语音质量:在嘈杂环境播放下的可懂度与抗干扰能力测试
  • 从点阵到像素:STM32驱动OLED/LCD显示中文的三种方案全对比(含取模软件实操)
  • 中美AI编程赛道大不同:美国创业公司有机会,中国大厂通吃
  • ESP32 RMT实战:手把手教你用ESP-IDF驱动WS2812灯带(附完整代码)
  • KDB+迭代与数据聚合:从理论到实践
  • LinkSwift网盘直链下载助手:八大网盘免费提速的终极解决方案
  • 别再让Simulink生成‘通用’代码了!手把手教你为STM32F4配置ARM Cortex-M硬件支持包(以2022b为例)
  • 我的Web3学习之旅与思考
  • imFile下载管理器:3个核心问题解决方案与5个进阶技巧
  • Audiveris完整指南:免费开源乐谱识别工具快速上手教程
  • 2026 四川家居品牌加盟与成都买家具优选:好风景家居全维度实力解析 - 深度智识库
  • 别再乱堆膨胀卷积了!用Python可视化代码带你避开Gridding Effect大坑
  • LabVIEW颜色识别实战:用IMAQ ColorMatch函数5分钟搞定产品颜色分拣
  • 鸿翼 OpenContent 智能文档云:AI 驱动的企业内容管理新范式
  • 告别SSH一息屏就断连!Termux后台保活保姆级教程(附systemctl修复)
  • 别再手动描边了!用OpenCV的approxPolyDP函数5行代码搞定轮廓简化(附Python/C++对比)
  • 2026年卫生型电磁流量计品牌top10排行榜 - 仪表人小余
  • EdgeRemover:Windows用户掌控Edge浏览器的终极解决方案
  • mysql如何编写递归存储过程_mysql max_sp_recursion_depth设置
  • 余杭永鸿再生资源:余杭区废旧金属回收多少钱 - LYL仔仔
  • 论文“焕新术”:书匠策AI,降重降AIGC的秘密武器大揭秘!
  • 零配置Java数据库利器:SQLite JDBC驱动的技术深度解析与应用实践
  • AI编程革命:Codex自动写脚本实战指南
  • **发散创新:基于算子融合的深度学习推理优化实战**在现代AI推理场景中,模型性能瓶颈往往不是由单一算子决定的,而是多个连续算子之间数
  • 公开课 | 软件测试开发如何快速落地智能化测试
  • HarmonyOS 6.0 分布式相机实战:调用远端设备摄像头与AI场景识别(API 11+)