三亩地.
  • 首页
  • 学习日记
  • 项目实战
  • 学习方法
  • 代码技巧
  • 避坑指南
  • 调试经验
  • 实战教程
  • 编程思维
  • 资讯中心
  • 关于我们

资讯详情

深入了解每一个知识点

  • 首页
  • /
  • 资讯中心
  • /
  • 文章详情

2026-08-03-gitlab-rce漏洞链深度分析-从oj解析器内存损坏到远程代码执行

📅 2026/8/4 9:20:01 👁️ 阅读次数 📝 编程学习
2026-08-03-gitlab-rce漏洞链深度分析-从oj解析器内存损坏到远程代码执行

2026-08-03-gitlab-rce漏洞链深度分析-从oj解析器内存损坏到远程代码执行

一条被低估的链

2026 年 7 月 24 日,Depthfirst 公开了一条 GitLab 远程代码执行链。两个在 Oj(GitLab 依赖的高性能 JSON 解析器)里潜伏了近五年的内存损坏缺陷,被串起来打穿了整个 Rails 进程。

这条链最值得聊的点不是技术难度本身,而是它击穿了"Ruby 是内存安全语言"这个直觉。Oj 的核心是 C 扩展,里面有指针、定长缓冲区、手动生命周期管理。GitLab 通过 Oj::Parser.usual.parse 把用户提交的 notebook 文件喂进这个 C 解析器——然后攻击者只需要一个能推送代码的普通账户,就能触发内存损坏。

受影响版本:GitLab CE/EE 15.2.0–18.10.7、18.11.0–18.11.4、19.0.0–19.0.1。修复版本 18.10.8 / 18.11.5 / 19.0.2。GitLab 把这次 Oj 升级归类为"Bug 修复"而非安全补丁——这意味着运维人员没有理由把它当紧急事件处理,这是该漏洞长期暴露的关键运营因素。

Oj 里的两个 bug

漏洞一是个越界写入。Oj 解析器用定长 1024 字节数组跟踪 JSON 嵌套深度:

typedef struct _ojParser {int depth;unsigned char stack[1024];   // 定长嵌套栈void (*start)(struct _ojParser *p);   // 回调指针// ...
} *ojParser;

打开数组时的处理没有深度检查:

case OPEN_ARRAY:p->depth++;p->stack[p->depth] = ARRAY_FUN;   // 超过 1024 层直接溢出

攻击者构造超过 1024 层嵌套数组,stack 之后的字段被持续写入 0x01。配合 Oj 的"自延续"特性——每次写入的 0x01 在下一层被当作 Array 回调选择器读回——这个扫掠可以越过 padding 一路推进到 buf.head 指针,把它的低字节从 0x80 改为 0x01,向后回退 127 字节。

漏洞二是堆指针泄露。一个超长对象键(65565 字节)的长度从 size_t 被截断为有符号 16 位整数,回绕为 29。Oj 为完整键分配了堆内存,但截断后的长度让返回路径从内联缓冲区读 29 字节,其中恰好包含活跃的堆指针。GitLab 渲染 diff 时把它作为输出的一部分返回给攻击者。

堆风水 + ASLR 探测 = RCE

两个单独的 bug 看起来都不严重——一个只能写 0x01,另一个只泄露少量内存。链化才是关键。整个利用分三步:

ASLR 绕过。 攻击者拿到堆指针后,不直接读内存,而是构造一个基于"执行反馈"的侧信道:把自循环指令地址写入 p->start 回调指针,观察解析器是挂起还是存活。挂起说明地址落在可执行映射内。在新实例上 5-10 分钟、成熟实例上 1-2 小时就能恢复 libc 基址。

堆风水。 写原语只能写 0x01,怎么把任意地址写进 p->start?利用链把被篡改的 buf.head 喂给 realloc,迫使其缓存一个伪造的内部指针。随后 Ruby Array 分配恰好回收同一块内存,Array 的元素内容覆盖了解析器的 p->start 指针。这是对 jemalloc 的 size class(3584 字节区域)和 slab 缓存语义的精确利用——没写 shellcode,靠分配器自己的行为完成了指针替换。

命令执行。 NX/DEP 禁止堆上直接执行,所以攻击者不投 shellcode。p->start 被覆盖后,跳转到 libruby 内的两个跳板 gadget,最终落入 system(),命令字符串作为参数投递。整个利用在单个 diffs_stream 请求内完成,两个 notebook 按字典序排列,分别负责泄漏和触发。

一句话总结这条链:普通认证用户推送含恶意 notebook 的提交 → 打开 diff → notebook 渲染器调用 Oj::Parser.usual.parse → 内存损坏改写回调指针 → 经 libruby 跳板进 system() → 以 git 用户执行命令。

缓解与修复

缓解机制 效果 绕过方式
ASLR 关键防线 堆指针泄露 + 侧信道探测恢复基址
Stack Canary 完全无效 不覆盖栈返回地址,攻击目标在堆上
NX/DEP 阻止直接 shellcode 不投 shellcode,ROP 式跳转进 system()
PIE 与 ASLR 协同 同 ASLR 绕过路径

Stack Canary 彻底失效这件事值得多想一层——它针对的是栈返回地址覆盖,而这个漏洞的写入目标在堆上的结构体内。对"结构体内部越界写 + 函数指针劫持"类缺陷,CFI(控制流完整性)才是对症的缓解。如果 libruby 启用 CFI,p->start(p) 的间接调用和跳板路径都可能被阻断。

上游修复(Oj 3.17.2/3.17.3,ec368db)做了四件事:在 open_array/open_object 的 depth++ 后加边界检查(超限直接 parse_error);冻结输入字符串防止解析期间缓冲区被外部改写;把多处 int len 收窄统一改为 size_t 消除大长度回绕;加缩进上限 16 字符。

怎么防

WAF 侧: 传统 WAF 很难拦截——恶意载荷藏在仓库文件内容里,走的是正常的 diff 流式接口。能做的是限制单文件大小,对 .ipynb 做 JSON 结构审计(嵌套深度 >200 或单键 >8192 字节就告警),对同一提交里包含多个字典序相邻 .ipynb 的情况提高风险评分。

HIDS 侧: git 用户派生 sh/bash/curl/wget 立即告警。监控 Rails secrets 和凭证文件的异常读取。网络层关注 Puma worker 向非预期内部服务的横向连接。

应急检查: oj -v 确认版本 ≥ 3.17.3。版本不满足且无法立即升级的,限制 diffs_stream 接口的访问频率,挂个监控盯着 Puma worker 异常重启和长时间 CPU 占用——那个 5 分钟到 2 小时的 ASLR 探测窗口,就是你的响应窗口。

我个人对这条链最大的感受是:别信任"内存安全语言"这个标签。Ruby 是安全的,但它的 gem 堆里塞满了不安全的 C 扩展。Oj 不是特例——你跑 gem list | wc -l 看看你项目里有多少 gem,再想想每个 gem 的 ext/ 目录里藏了多少指针运算。下次升级依赖的时候,至少看一眼 C 扩展变化的 changelog。


免责声明

本文仅供安全研究与防御建设参考。所有技术细节基于公开披露的研究资料与上游补丁还原。请勿将文中技术用于未经授权的测试或攻击;因不当使用造成的一切后果由使用者自行承担。受影响用户应尽快升级至 18.10.8 / 18.11.5 / 19.0.2。

参考资料: Depthfirst 公开报告 / Oj commit ec368db / GitLab 19.0.2 安全补丁 / CVE-2026-54903(Oj 整数溢出,同族内存安全缺陷)

编程学习 技术分享 实战经验

相关新闻

2026上海财税公司十大优选评测榜 - 财税推荐官

2026/8/4 9:20:01

2026年亚马逊卖家TRO和解代理公司口碑全解析 正规合规服务商筛选攻略及避坑FAQ - 产业观察报

2026/8/4 9:20:01

艺术涂料赛道观察:从业者常问的十个现实问题

2026/8/4 9:20:01

最新新闻

从品牌店以旧换新到专业机构直接变现:宁波市民黄金处置全渠道对比 - 好物测评局

2026/8/4 10:23:12

安卓HTTPS证书验证全解析:从原理到实战避坑指南

2026/8/4 10:23:12

价值流图优化AI提示工程:方法论与实战

2026/8/4 10:23:13

Gradpaper稳居行业第一!全网最优秀的一站式论文工具

2026/8/4 10:22:52

Docker Compose部署Octopus:从环境隔离到生产级自动化工作流实战

2026/8/4 10:21:57

冰蓄冷空调与冷热电联供微网优化调度实践

2026/8/4 10:21:57

日新闻

终极指南:如何用AntdUI在10分钟内打造现代化WinForm桌面应用

2026/8/4 0:00:35

AI Agent白手起家26: 使用标准事件驱动大模型实践

2026/8/4 0:00:59

企业级AI搜索落地失败的7个隐形雷区(第4条90%团队至今未察觉——涉及知识图谱对齐与合规性审计双缺失)

2026/8/4 0:02:05

周新闻

怀化母婴除甲醛公司测甲醛中心怎么选:康之居母婴除甲醛标准、流程、避坑指南 - 信誉隆金银铂奢回收

2026/8/3 13:13:27

Penpot组件系统完全指南:三步打造企业级设计系统的终极方案

2026/8/3 13:13:29

如何快速掌握Penpot组件系统:开源设计平台的终极指南

2026/8/3 13:13:31

月新闻

ClickHouse版本管理深度实战:4步构建零风险升级与回滚体系

2026/8/2 11:50:07

Java 23 种设计模式:从踩坑到精通 | 番外:责任链模式 —— 物流审批流程实战

2026/8/2 11:50:07

华硕笔记本性能解放指南:G-Helper轻量级控制工具全面解析

2026/8/2 11:50:07

分类目录

  • 学习日记
  • 项目实战
  • 学习方法
  • 代码技巧
  • 避坑指南
  • 调试经验

热门标签

JavaScript Python Java 前端开发 后端开发 算法 数据结构 项目实战

关于三亩地

三亩地是一个专注于编程学习的平台,以真实学习日记为载体,分享编程学习经验、项目实操技巧和高效学习方法。

快速链接

学习日记

项目实战

学习方法

资讯中心

联系方式

邮箱:contact@mfbz.cn

微信:sanmudi_code

QQ 群:123456789

© 2026 三亩地 编程学习日记 版权所有 | mfbz.cn