ctfshow pwn047
1. 简介
本篇分享对pwn047的解题思路,以及对pwntools 内部计算符号地址的研究
参考文章:https://blog.csdn.net/2402_84408069/article/details/158155516?spm=1001.2014.3001.5501
2. 题目信息
1. 文件基本信息

32位程序、动态链接、无canary、无PIE、NX打开
2. 函数执行逻辑
(1) 静态分析
丢进IDA中看一眼:


根据这些我们可以得到:
libc中puts()等函数的真实地址"\bin\sh"的地址
(2) 漏洞函数

由gets()函数引起的栈溢出漏洞。
3. 攻击思路
整体思路为:
利用gets(),通过构造ROP链,构造并执行 system(“\bin\sh”) 来 get shell。
细节:
由于 ASLR (地址空间布局随机化) 的存在,Libc 库在内存中的加载基址每次都是随机的。但是,程序直接打印出了puts()函数在当前内存中的真实地址,这就相当于直接告诉了我们 ASLR 的随机偏移量。
4. 编写exp
1. payload构造
(1) 偏移量(offset)
通过cyclic能比较方便地获得offset

所以,offset = 156 + 4 = 160
(2) ROP构造

注意 :
我们要利用Libc里面的system()函数来达到我们的目的,因而我们需要用到
1 | system_addr = libc.sym['system'] |
但是 pwntools 中的 ELF 对象是带有动态基址状态的(libc.address)。
pwntools 内部计算符号地址的公式是:
1 | libc.sym['函数名'] = libc.address (基址) + 偏移 (Offset) |
当我们不告诉 pwntools 此时 libc 在内存里的真实加载地址时, libc.address 默认为 0
这样就会导致libc.sym['函数名']返回一个错误的值,引发段错误。
所以我们要先用程序给我们的puts()函数泄露基址,然后再进行后续操作。
脚本:
1 | from pwn import * |
宇宙级免责声明
重要声明:本文仅供合法授权下的安全研究与教育目的!
- 合法授权:本文所述技术仅适用于已获得明确书面授权的目标或自己的靶场内系统。未经授权的渗透测试、漏洞扫描或暴力破解行为均属违法,可能导致法律后果(包括但不限于刑事指控、民事诉讼及巨额赔偿)。
- 道德约束:黑客精神的核心是建设而非破坏。请确保你的行为符合道德规范,仅用于提升系统安全性,而非恶意入侵、数据窃取或服务干扰。
- 风险自担:使用本文所述工具和技术时,你需自行承担所有风险。作者及发布平台不对任何滥用、误用或由此引发的法律问题负责。
- 合规性:确保你的测试符合当地及国际法律法规(如《计算机欺诈与滥用法案》(CFAA)、《通用数据保护条例》(GDPR)等)。必要时,咨询法律顾问。
- 最小影响原则:测试过程中应避免对目标系统造成破坏或服务中断。建议在非生产环境或沙箱环境中进行演练。
- 数据保护:不得访问、存储或泄露任何未授权的用户数据。如意外获取敏感信息,应立即报告相关方并删除。
- 免责范围:作者、平台及关联方明确拒绝承担因读者行为导致的任何直接、间接、附带或惩罚性损害责任。
安全研究的正确姿势:
- 先授权,再测试
- 只针对自己拥有或有权测试的系统
- 发现漏洞后,及时报告并协助修复
- 尊重隐私,不越界
警告:技术无善恶,人心有黑白。请明智选择你的道路。
评论
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 0x0off!







