潜伏5年!GitLab高危RCE漏洞爆发,低权限即可控服
漏洞概要2026年7月24日Depthfirst研究团队发布了一个针对GitLab的远程代码执行RCE漏洞利用工具。该漏洞链是将Ruby JSON解析器OjOj使用原生C实现中的两个内存损坏漏洞组合起来最终在GitLab Puma worker进程中实现完整命令执行。任何能够向项目推送代码并查看提交diff的已认证用户均可触发该漏洞。研究人员指出无需管理员权限、无需CI访问权限也无需受害者交互。GitLab已于2026年6月10日修补了这两个漏洞但将其归类为“Bug修复”而非安全补丁因此在评估该版本时运维人员没有理由将其视为紧急事件。Depthfirst发布的报告指出“系统列出的18个优先处理漏洞中包含7个内存安全漏洞。其中两个——越界写入和堆指针泄露——在Oj中已存在近五年。Oj是GitLab使用的底层依赖我们将两个漏洞组合后在默认GitLab安装上实现了远程代码执行。”技术分析这两个漏洞于2021年8月8日被引入Oj解析器潜伏了1753天。易受攻击的notebook路径随GitLab 15.2.0版本2022年7月发布引入直到2026年6月10日才被修复。攻击路径始于GitLab的notebook diff渲染器——一个名为ipynbdiff的内嵌gem它负责将Jupyter的.ipynb文件转换为人类可读的diff。当用户打开notebook文件的commit diff时GitLab会将原始仓库字节传递给Oj::Parser.usual.parse该调用发生在Puma worker进程中。这个parse调用就是攻击入口。报告继续写道“调查是反向进行的Depthfirst首先发现了应用底层的脆弱解析器然后通过调用链回溯到用户可操控的产品边界。真正的请求则沿着相反方向从GitLab commit diff进入原生C代码。”由于Oj::Parser.usual返回的是进程级解析器单例该单例在同一Puma worker中的所有线程间共享因此一次损坏会影响该进程中后续的所有解析操作。第一个漏洞是未校验的嵌套栈溢出。Oj在解析器对象内部使用一个固定大小的1024字节数组来跟踪JSON嵌套深度。当攻击者打开超过1024层嵌套数组时Oj会持续向该缓冲区之后的一个字节集合选择器写入数据覆盖相邻的解析器字段。攻击者无法精确控制每个字节数组始终写入0x01但可以控制写入的深度。当嵌套层数足够多时这个单字节修改会改变buf.head解析器内部缓冲区起始指针将其向后移动127字节落入解析器未拥有的内存区域。随后强制调用realloc会缓存这个伪造的内部指针而Ruby的Array分配会回收该区域并且Array的元素内容虽然被限制为有效的Ruby值但仍受攻击者影响会用一个选择的地址覆盖解析器的p-start回调指针。第二个漏洞提供了所需的地址。一个超长的对象键65565字节的长度被从size_t截断为有符号16位整数从而回绕为29。Oj为完整键分配堆内存并存储指向它的指针但截断后的长度告诉返回路径从内联缓冲区读取29字节。巧合的是这29字节的第6到第13字节恰好包含堆指针。GitLab在渲染diff时将其作为单元ID的一部分输出。报告指出“返回的字节0到5来自外部视图的对齐填充。字节6到13是活跃的key指针。最后15个返回字节来自联合存储区该区域未被外部视图写入可能包含陈旧的键条目内容。这是一种固定的29字节泄露而非任意地址读取它只暴露了该Key条目中已存在的字节且从未解引用攻击者选择的指针。这些偏移量来自测试所用的x86_64 ABI因此编译器布局是这一原语边界的一部分。”获得堆指针后攻击者通过将自循环指令地址写入p-start并观察哪个解析操作会挂起来探测候选的libc基址。在一个全新的双worker GitLab实例上ASLR搜索耗时5到10分钟在成熟的长运行实例上预计时间为1到2小时。一旦恢复库基址利用程序会在单个diffs_stream请求中链式使用两个原语。同一个commit中的两个按字典序排列的notebook文件各自承载一个阶段第一个notebook设置回调指针抛出异常以避免立即执行并让GitLab继续流式传输diff第二个notebook的旧侧触发同一Puma worker中的p-start通过两个libruby跳板进入system()同时攻击者的命令处于正确的寄存器中。命令以git用户身份运行即Puma所属账户该账户可访问源代码、Rails密钥、服务凭证以及应用能触及的任何内部服务。报告总结道“成功利用后攻击者可以以git运行GitLab Puma worker的账户身份执行命令。其实际影响范围取决于部署隔离程度但可能包括仓库数据、Rails密钥、服务凭证以及应用可访问的内部服务。这可能导致源代码泄露、凭证窃取、代码库修改、持久化或横向移动。”影响范围与修复建议受影响的GitLab CE和EE版本包括15.2.0至18.10.7、18.11.0至18.11.4以及19.0.0至19.0.1所有层级。15.2之前的版本在该路径中使用了不同的JSON解析器因此不存在漏洞。15.2至18.9版本不在GitLab安全维护的补丁轨道内不会收到后向移植——这些实例需要迁移到受支持的版本。对于Helm和Operator部署相关版本是运行Puma的Webservice镜像内部GitLab的版本而非chart版本。请升级至18.10.8、18.11.5或19.0.2。截至目前Depthfirst和GitLab均未验证任何纯配置层面的缓解措施。

相关新闻