2026/1/29 3:35:46
网站建设
项目流程
个人网站建设大全,购买空间安装wordpress,wordpress多个标签,上海帝程网站建设公司CTF Pwn模块系列分享#xff08;三#xff09;#xff1a;溢出基础与ret2text漏洞利用
今天咱们就如约进入Pwn实战的核心第一站——栈溢出基础与ret2text漏洞利用。
这是新手第一次真正意义上构造payload攻击程序#xff0c;也是Pwn入门的里程碑。今天的内容全程围绕实战…CTF Pwn模块系列分享三溢出基础与ret2text漏洞利用今天咱们就如约进入Pwn实战的核心第一站——栈溢出基础与ret2text漏洞利用。这是新手第一次真正意义上构造payload攻击程序也是Pwn入门的里程碑。今天的内容全程围绕实战展开从什么是栈溢出到亲手构造payload拿到shell每一步都写得明明白白跟着操作就能成功记住栈溢出是Pwn最基础、最常考的漏洞搞定它你就跨进了Pwn的大门。一、先回顾拆解什么是栈溢出结合上一期讲的栈帧结构我们用通俗例子核心原理再拆一遍栈溢出确保所有人都懂1. 通俗例子栈溢出就像“杯子装太多水”程序给局部变量分配的栈空间就像一个固定容量的杯子用户输入的数据就像往杯子里倒水。正常情况下水数据不会超过杯子容量栈空间但如果程序没检查输入长度你倒了太多水水就会溢出来流到杯子外面覆盖栈里的其他数据——这就是“栈溢出”。2. 核心原理覆盖“返回地址”控制程序执行流结合栈帧结构栈溢出的核心逻辑是今天我们学的“ret2text”就是“return to text返回文本段”——把返回地址改成程序自带的、位于代码段.text的“后门函数地址”比如执行/bin/sh的函数让程序执行后门拿到shell。小提醒ret2text是最基础的栈溢出利用方式程序通常是“无保护”的关闭栈保护、关闭PIE等适合新手入门。二、实战准备环境工具测试程序我们用“自定义简单漏洞程序”实战和CTF比赛中的入门栈溢题逻辑完全一致先准备好这些环境延续上一期的Ubuntu 20.04GDBpwntoolsIDA如果之前装了pwndbgGDB插件用它调试更友好没装也没关系用原生GDB也能完成。编写漏洞程序保存为pwn1.c#include stdio.h #include string.h // 后门函数执行/bin/sh拿到shell void backdoor() { system(/bin/sh); } void vulnerable_function() { char buf[16]; // 分配16字节局部变量空间 gets(buf); // 危险函数gets不限制输入长度导致栈溢出 printf(Input: %s\n, buf); } int main() { vulnerable_function(); return 0; }关键说明gets(buf)是“危险函数”不检查输入长度这是栈溢出漏洞的根源backdoor()是后门函数执行system(“/bin/sh”)调用后就能拿到shell我们的目标通过栈溢出让程序执行backdoor()而不是正常返回main。编译程序关闭所有保护方便新手调试终端执行命令复制直接用gcc -g -fno-stack-protector -z execstack -no-pie -o pwn1 pwn1.c参数解释-fno-stack-protector关闭栈保护避免canary检测新手先避开-z execstack允许栈执行后续进阶会讲现在关闭减少干扰-no-pie关闭PIE程序地址随机化关闭后函数地址固定方便我们找-g添加调试信息方便GDB调试。三、实战步骤手把手教你构造payload拿到shell整个解题流程分4步找漏洞函数→找后门地址→算溢出偏移→构造payload攻击一步都不能少第一步用IDA分析程序找漏洞函数和后门地址IDA是反汇编工具帮我们快速定位漏洞和关键函数地址打开IDA把编译好的pwn1拖进去选择“64-bit”x86_64架构点击“OK”。等待IDA分析完成点击左侧“Functions”窗口找到三个函数main、vulnerable_function、backdoor。确认漏洞双击vulnerable_function查看反汇编代码能看到调用了gets函数红色标注危险函数确认存在栈溢出。找backdoor地址双击backdoor函数顶部会显示函数的虚拟地址比如0x401146每个人的地址可能一样以自己IDA显示的为准记下来这是我们要跳转的目标地址。小技巧在IDA中按“F5”可以查看伪代码更直观确认backdoor函数调用了system(“/bin/sh”)。第二步用GDB找“溢出偏移”核心确定要填多少垃圾数据“偏移”就是从buf的起始地址到“返回地址”的字节数——我们需要先填这么多“垃圾数据”比如A才能覆盖到返回地址。找偏移用“cyclic模式”最方便启动GDB调试程序gdb ./pwn1在vulnerable_function的gets函数处下断点确保输入后程序暂停① 先找gets的调用地址输入b vulnerable_function然后r程序停在vulnerable_function开头。② 输入ni单步执行直到看到“call getsplt”调用gets函数再输入b *$rip在当前指令下断点。③ 输入c继续执行程序等待输入。生成cyclic pattern特殊的重复字符串用来定位溢出位置 在GDB中输入cyclic 100会生成100个字符的pattern比如aaaaabaaaaac…复制这个字符串。粘贴pattern作为输入程序会崩溃因为栈溢出。查看rsp寄存器的值栈顶此时栈顶是被覆盖的返回地址 输入x/wx $rsp会显示一个值比如0x62616167这是pattern对应的十六进制。计算偏移输入cyclic -l 0x62616167把刚才的十六进制值填进去GDB会输出一个数字比如24——这就是偏移意味着我们需要先填24个垃圾数据才能覆盖到返回地址。小提醒如果用pwndbg步骤更简单直接cyclic 100生成pattern输入后程序崩溃pwndbg会自动显示“cyclic shift: 24”直接拿到偏移。第三步构造payloadpayload的结构很简单x86_64架构每个地址占8字节payload 垃圾数据偏移字节数 后门函数地址8字节结合我们的实战数据假设偏移24backdoor地址0x401146用Python构造关键说明b’A’把字符串转成字节流pwntools要求p64()把十六进制地址转成64位的小端字节序x86_64架构默认小端必须用p64不能直接写地址字符串。第四步发送payload拿到shell有两种方式发送payload新手先学第一种简单直观方式1GDB中测试确认漏洞利用成功重新启动GDBgdb ./pwn1输入r payload把payload文件作为输入发送给程序程序执行后会出现“$”提示符——这就是shell成功了输入ls查看文件输入cat flag如果有flag文件就能拿到Flag。方式2pwntools脚本自动化攻击比赛常用编写完整脚本保存为exp.py终端执行脚本python3 exp.py执行后直接拿到shell输入cat flag即可获取Flag——这就是CTF比赛中Pwn题的标准解题流程四、新手避坑这5个问题最容易卡壳偏移算错如果发送payload后程序没拿到shell大概率是偏移错了——重新用cyclic找确保断点下在gets调用后输入pattern后程序崩溃。地址用错一定要用IDA里看到的backdoor地址不能抄我的虽然大概率一样但要确认。没加p64直接把地址写成字符串比如’0x401146’程序肯定执行失败——必须用p64转成64位字节流。程序有保护如果编译时没加“-fno-stack-protector -no-pie”程序会有保护导致溢出失败——新手先关闭所有保护练手。GDB调试卡壳如果不会下断点直接用pwndbg的b gets在gets函数处下断点然后r输入pattern即可。五、下期预告今天我们完成了第一次Pwn实战亲手用栈溢出ret2text拿到了shell——这是Pwn入门的关键一步下期我们将进阶栈溢出进阶之ROP链构造解决“程序没有后门函数”的问题学习如何拼接代码段中的指令构造ROP链执行system(“/bin/sh”)。如果今天的内容对你有帮助别忘了点赞、在看转发给一起学CTF的小伙伴CTF学习资源网上虽然也有很多的学习资源但基本上都残缺不全的这是我们和网安大厂360共同研发的的网安视频教程内容涵盖了入门必备的操作系统、计算机网络和编程语言等初级知识而且包含了中级的各种渗透技术并且还有后期的CTF对抗、区块链安全等高阶技术。总共200多节视频100多本网安电子书最新学习路线图和工具安装包都有不用担心学不全。这些东西我都可以免费分享给大家需要的可以点这里自取:网安入门到进阶资源