1. 栈溢出漏洞原理深度解析
栈溢出是二进制安全领域最基础也最经典的漏洞类型,理解其原理是Pwn入门的必经之路。让我们从计算机底层机制开始,彻底拆解栈溢出的技术本质。
1.1 函数调用栈的运行时结构
当程序执行函数调用时,系统会在内存的栈区为这次调用分配一个栈帧(Stack Frame),其典型布局如下(以x86-64架构为例):
code复制高地址
+-------------------+
| 参数区域 | ← 调用者传入的参数(x86-64前6个参数用寄存器传递)
+-------------------+
| 返回地址 | ← 函数执行完毕后应返回的指令位置(8字节)
+-------------------+
| 保存的rbp | ← 调用者的栈基址(8字节)
+-------------------+
| 局部变量 | ← 当前函数的局部变量空间
+-------------------+
| 临时空间 | ← 编译器可能使用的临时存储区
低地址
关键点在于:返回地址决定了函数执行后的程序流向,而局部变量区域与返回地址在内存中是相邻的。
1.2 溢出发生的必要条件
栈溢出漏洞需要同时满足三个条件:
- 存在危险函数:使用不检查输入长度的函数(如gets、strcpy等)
- 缓冲区在栈上:目标缓冲区必须是栈上的局部变量
- 无保护机制:编译时关闭了栈保护(-fno-stack-protector)
以示例程序中的gets(buf)为例:
- buf是16字节的栈上数组
- gets()会持续读取输入直到遇到换行符,完全不检查长度
- 编译时禁用了栈保护
当输入超过16字节时,多余的数据就会覆盖栈帧中的其他数据,包括关键的返回地址。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. ret2text攻击技术详解
ret2text(Return to Text)是栈溢出最直接的利用方式,其核心思想是将返回地址覆盖为程序代码段(.text)中已存在的后门函数地址。
2.1 攻击流程四步法
2.1.1 定位漏洞点
使用IDA Pro反编译目标程序:
- 识别危险函数调用(如gets、scanf等)
- 确认缓冲区在栈上的大小
