Skip to content
KitploitKITPLOIT
工具博客
提交
工具博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

··订阅源·联系·隐私·© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
CVE-2019-25485 — R 3.4.4 中存在基于栈的缓冲区溢出。在 x86 上可完整利用,但由于程序约束,在 x64 上仅能通过 gadget 分析实现 RIP 控制。同一漏洞横跨两种架构,导致了不同的利用路径。 | Kitploit
工具/GitHubGitHub/themalwareguardian/cve-2019-25485
漏洞分析漏洞利用逆向工程Shellcode调试器学习与教育Payload 开发二进制利用
GitHubthemalwareguardian/cve-2019-25485

CVE-2019-25485

R 3.4.4 中存在基于栈的缓冲区溢出。在 x86 上可完整利用,但由于程序约束,在 x64 上仅能通过 gadget 分析实现 RIP 控制。同一漏洞横跨两种架构,导致了不同的利用路径。

查看仓库
35个月前尚未审核

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享

🐞 CVE-2019-25485: R 3.4.4 - 基于栈的缓冲区溢出(x86 与 x64)

R 3.4.4 中的基于栈的缓冲区溢出。在 x86 上实现完全利用,但在 x64 上由于程序约束,仅实现 RIP 控制并进行 gadget 分析。同一个漏洞存在于两种架构中,却导致不同的利用路径。




📑 目录

  • 为什么存在这个仓库
  • 为什么这个漏洞有趣
  • 背景与受影响软件
  • 关于漏洞
  • 触发崩溃
  • 漏洞利用



🎓 为什么存在这个仓库

本仓库是我在讲授内存破坏利用时所使用材料的一部分(除了日常工作外,我还在多个网络安全课程中授课,帮助培训下一代逆向工程师)。

CVE-2019-25485 是我想让学生针对同一个漏洞在两种不同架构上分别进行完整研究,并亲眼看到其间差异时所用的案例。R 3.4.4 同时提供 x86 和 x64 版本,二者中存在完全相同的溢出:同一个 GUI 字段、同一个输入处理程序、同一个崩溃。这里将两者作为两个独立练习分别记录并完成利用:

  • x86 版本遵循经典的普通 EIP 覆盖方法。溢出到达 EIP,在未启用 ASLR 的模块中找到 JMP ESP gadget,在 EIP 覆盖之后放置 shellcode,并成功获得可用的反向 shell。这是一个干净直接的利用程序,展示了基于栈的缓冲区溢出的基本原理。
  • x64 版本实现了 RIP 控制并确认了偏移量,但未实现完整的 RCE。这是刻意为之,也正是本练习的意义所在。x64 利用尝试完整记录了 gadget 搜索过程,分析了每个 gadget 类别为何在此特定上下文中失败,解释输入处理程序带来的空字节约束,并描述了绕过 DEP 所需的 ROP 链结构,以及为什么在该输入向量的约束下无法构建这条链。仅凭此单一漏洞实现完整利用,剩下的唯一理论路径是 JOP(Jump-Oriented Programming,跳转导向编程),它串联以 JMP 而非 RET 结尾的 gadget,并且不依赖栈来控制执行流。在 RIP 覆盖之后没有任何可写的受控区域的情况下,手工构造 JOP 链是一项超出本练习范围的高阶开放性挑战。失败不是方法论上的缺口,而正是这堂课的内容。



  • 💡 为什么这个漏洞有趣

    R 3.4.4 是一个统计计算应用程序,不是网络服务或浏览器。该溢出通过桌面 GUI 字段触发,这意味着其攻击面与我讲授的其他所有案例都完全不同。这个案例的教学价值在于:

    • 没有网络组件。 payload 被粘贴到 GUI 字段中,这带来了一类不同的约束,尤其是 GUI 输入处理程序在字节到达易受攻击的复制操作之前如何处理它们。
    • RIP 控制已确认。 溢出到达 RIP 并找到偏移量。这并非一个无法触达漏洞的案例。对指令指针的控制已被完整演示。
    • 规范地址强制检查打破了经典方法。 在 x86 上,你可以覆盖 EIP 并附加 shellcode。在 x64 上,RIP 的高位字节必须是 \x00\x00,地址才是规范地址,而这些空字节会在 gadget 地址之后立即终止输入。覆盖之后没有空间再放置 shellcode 或 ROP 链值。
    • 空字节转换阻断了 ROP。 GUI 字段在将数据复制到缓冲区之前,会把空字节转换为空格。每个 x64 地址的高半部分都包含空字节。没有任何 gadget 地址能作为 ROP 链值被放到栈上,它们到达时都已被破坏。
    • DEP 阻止直接执行。 即使找到了通往 shellcode 缓冲区的方法,DEP 也会强制执行并阻止在栈上执行代码。
    • Gadget 搜索被完整记录。 从每个已加载模块中导出 gadget、按类型筛选、再分析每个 gadget 为何失败,这一过程被逐步记录。这是每个漏洞利用开发者所需的核心技能。
    • 解释了 VirtualProtect 的 ROP 链骨架。 学生可以清楚看到绕过 DEP 需要什么、为什么调用约定很重要,以及为什么在输入约束下无法构建这条特定的链。



    🔍 背景与受影响软件

    R 是一个可用于 Windows、macOS 和 Linux 的统计计算与图形环境。该漏洞位于 GUI 首选项对话框中,具体是“菜单和消息语言”字段,该字段会将用户输入复制到固定大小的栈缓冲区,而不验证其长度。

    关键技术细节:

    • 漏洞类型:基于栈的缓冲区溢出
    • 受影响版本:R 3.4.4 x86_x64
    • 受影响入口:编辑 -> GUI 首选项 -> 菜单和消息语言
    • 易受攻击组件:GUI 首选项输入处理程序
    • 是否需要认证:否(本地应用程序)
    • 影响:x86 - 远程代码执行 | x64 - 控制流已确认



    ⚠️ 关于漏洞

    R 3.4.4 在处理“菜单和消息语言”字段时,会将所提供字符串复制到固定大小的栈缓冲区中,而不检查其长度。易受攻击逻辑的简化版本如下:

    root@kitploit:~
    char language_buffer[256];
    
    strcpy(language_buffer, user_input);
    

    发送足够长的字符串会导致复制操作写入越过缓冲区末尾,破坏栈,直到保存的返回地址被覆盖。当函数返回时,CPU 会从栈中将攻击者控制的值加载到 RIP,并尝试跳转到该地址。

    在 x64 上,Windows 会在任何跳转发生前强制执行规范地址验证。像 0x4141414141414141 这样的非规范地址会在 RIP 被加载前立即触发访问冲突,这意味着崩溃现象与 x86 不同,不会出现干净的 RIP = 4141414141414141。必须通过崩溃后从栈中读取循环模式来寻找偏移量,而不是直接从 RIP 读取。




    💥 触发崩溃

    可以通过向语言字段中粘贴长字符串来复现崩溃。无需认证。下面是用 Python 生成 payload 的示例:

    root@kitploit:~
    import struct
    
    payload = b'A' * 400
    
    with open('payload.txt', 'wb') as f:
    	f.write(payload)
    
    root@kitploit:~
    Open R 3.4.4 x64
    Edit -> GUI Preferences
    Paste contents of payload.txt into Language for menus and messages
    Click OK
    



    💣 漏洞利用

    本仓库的目标不仅是演示崩溃,而是完整走一遍两种架构上的利用过程,记录 x86 上哪些方法有效、x64 上哪些方法失效,以及更重要的是,为什么。

    为了让主 README 保持简洁,详细的利用笔记、脚本和调试器步骤都放在本仓库的 Vulnerability 📂 文件夹中,并分别组织在 x86 和 x64 子文件夹里。

    在那里你可以找到针对两种架构的完整工作流程:

    x86 - 完整利用:

    • 对语言字段进行模糊测试以定位崩溃。
    • 发现偏移量,以定位 EIP 在栈上的精确位置。
    • 坏字符分析,以识别会破坏 payload 的字节。
    • 在 stats.dll 中定位 JMP ESP gadget,该模块在编译时未启用 ASLR 或 SafeSEH。
    • 放置并执行 shellcode,成功获得完整反向 shell。

    x64 - RIP 控制与利用分析:

    • 配置 x64dbg,避免 DLL 加载事件持续中断调试。
    • 分三个阶段对语言字段进行模糊测试,以找到精确的崩溃大小。
    • 通过从栈中读取循环模式而非从 RIP 读取,来找到 RIP 偏移量。
    • 使用带有自动空字节填充的 6 字节覆盖来确认 RIP 控制。
    • 确认空字节到空格的转换是根本性的输入约束。
    • 使用 rp++ 从所有已加载的 R 模块中导出 gadget,并通过 PowerShell 进行筛选。
    • 分析每个 gadget 类别:CALL RBX、CALL RSP、POP RSP、SUB RSP、PUSH RSP,并记录为什么每个类别在此特定上下文中都会失败。
    • 解释调用 VirtualProtect 并绕过 DEP 所需的 ROP 链结构,以及为什么在空字节约束下无法构建它。
    下载工具
  • 记录 JOP 是仅存的理论路径,以及为什么它仍然是一个开放性挑战。