Mac环境模拟Buffer Overflow遇Segmentation Fault问题求助
缓冲区溢出模拟失败的原因及修复方案
核心问题分析
你的代码和操作存在几个关键问题,导致段错误:
- Payload无有效跳转地址:构造的
packet全是0x41(即字符'A'),没有填充malicious_function的实际地址,导致返回地址被覆盖为无效的0x41414141...,触发段错误。 - 栈布局计算错误:64位系统下,缓冲区到返回地址之间存在栈基址寄存器(RBP)的存储区域(8字节),你直接覆盖缓冲区末尾的位置并未命中返回地址。
- 未关闭地址随机化(ASLR)与位置无关执行(PIE):Mac/Windows默认开启ASLR和PIE,导致函数地址每次运行都随机变化,即使硬编码地址也无法稳定跳转。
- 代码逻辑顺序错误:
memcpy在sprintf之后执行,而sprintf已经将缓冲区填满了'A',覆盖了memcpy要写入的目标位置,导致跳转地址并未被正确写入栈中。
修复步骤
1. 调整编译选项
需要关闭栈保护、Fortify保护、PIE,确保代码地址固定:
# Mac环境编译命令 gcc -o sql_slammer slammer.c -fno-stack-protector -D_FORTIFY_SOURCE=0 -no-pie -O0 && ./sql_slammer
2. 关闭系统级ASLR
- Intel架构Mac:
sudo sysctl -w kern.randomize_vmspace=0 - ARM64架构Mac:
sudo sysctl -w kern.arm64.aslr_enabled=0 - Windows环境:编译时添加
/GS- /dynamicbase:no /fixed:yes选项,或在PE文件属性中关闭地址随机化。
3. 修正代码逻辑
重新构造Payload,正确覆盖返回地址:
#include <stdio.h> #include <string.h> #define BUFFER_SIZE 27 #define RBP_SIZE 8 // 64位系统下RBP占8字节,32位系统改为4 void malicious_function() { printf("Malicious code executed!\n"); } void vulnerable_function(char *data) { char buffer[BUFFER_SIZE]; printf("Vulnerable function executed!\n"); sprintf(buffer, "%s", data); } int main() { // 构造完整Payload:缓冲区填充 + RBP覆盖 + 跳转地址 char packet[BUFFER_SIZE + RBP_SIZE + sizeof(void*)]; // 填充缓冲区为'A' memset(packet, 'A', BUFFER_SIZE); // 覆盖RBP为'A' memset(packet + BUFFER_SIZE, 'A', RBP_SIZE); // 将恶意函数地址以小端序写入Payload末尾(对应返回地址位置) void (*func_ptr)() = malicious_function; memcpy(packet + BUFFER_SIZE + RBP_SIZE, &func_ptr, sizeof(void*)); vulnerable_function(packet); return 0; }
关键说明
- 64位系统采用小端序存储地址,代码中直接通过
memcpy写入函数指针即可自动适配小端序。 - 若使用32位编译,需将
RBP_SIZE改为4,编译时添加-m32选项。 - 测试完成后建议恢复ASLR,避免降低系统安全性:
# Intel Mac sudo sysctl -w kern.randomize_vmspace=1 # ARM64 Mac sudo sysctl -w kern.arm64.aslr_enabled=1
内容的提问来源于stack exchange,提问作者Ryu Hyunsun
相关产品推荐
相关产品推荐

