You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何构造输入触发缓冲区溢出将num从-200改为400并绕过栈保护?

栈溢出修改变量并绕过Stack Smashing保护的方法

一、当前输入无效的原因

你的测试代码里,letters[20]是20字节数组,后续跟着long num变量。当前输入的"aaaabbbbccccdddd600"长度不足20字节,连letters数组都没填满,更不可能覆盖到栈上的num。另外,GCC默认启用Stack Smashing Protector(SSP/栈金丝雀),一旦栈上的金丝雀值被非法覆盖,程序就会触发栈溢出检测并终止。

二、测试环境下关闭栈保护(最直接方案)

如果仅用于测试栈溢出修改变量的逻辑,编译时可以关闭SSP保护,同时关闭位置无关执行(PIE)方便调试:

gcc -fno-stack-protector -no-pie -O0 your_code.c -o test_overflow
  • -fno-stack-protector:禁用栈金丝雀保护
  • -no-pie:关闭位置无关执行,固定栈变量地址
  • -O0:禁用编译器优化,确保num变量存储在栈上而非寄存器

三、构造正确的溢出输入

1. 确定栈填充长度

栈上letters数组占20字节,假设无额外对齐填充(可通过GDB调试确认),需要先输入20个任意字符填满letters,再覆盖后续的num变量。

2. 转换目标值为字节序

目标值400的十六进制是0x00000190,x86架构默认是小端字节序,所以需要将字节按0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00的顺序写入(long类型占8字节)。

3. 生成输入并测试

用Python生成符合要求的输入,通过管道传递给程序:

python3 -c "print('a'*20 + b'\x90\x01\x00\x00\x00\x00\x00\x00'.decode('latin-1'), end='')" | ./test_overflow

执行后就能看到num的值被修改为400。

四、不关闭栈保护的绕过思路(进阶)

如果必须保留SSP保护,绕过难度会大幅提升:

  • 栈金丝雀是随机生成的,且最后一个字节固定为0x00(用于截断gets的读取),无法通过gets直接泄漏完整金丝雀值
  • 若要覆盖num,必须先精准覆盖金丝雀值,但金丝雀的随机性导致每次运行都需要重新获取,而常规手段无法在这个场景下实现泄漏

因此,测试栈溢出修改变量的场景,关闭SSP是最实用的方案。

内容的提问来源于stack exchange,提问作者Bryan Mak

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 10:50:37