文章总结: 本文记录了针对Ruby应用的依赖混淆攻击及RCE过程。作者通过挖掘GitHub识别未注册内部包,在公共仓库发布同名高版本恶意包。当开发者误用geminstall时触发恶意代码,导致主机回连。文章分析了Bundler配置差异,指出供应链安全风险并提供了Gemfile源隔离配置建议。 综合评分: 88 文章分类: 供应链安全,漏洞分析,SRC活动,实战经验
我是如何在 Ruby 应用中发现一个依赖混淆漏洞并最终导致 RCE 的
haidragon haidragon
安全狗的自我修养
2026年1月20日 16:29 湖南
官网:http://securitytech.cc
大家好,我又带着新的安全发现回来了。
今天我想分享一个我发现的非常有意思的 依赖混淆(Dependency Confusion)漏洞,并且最终成功实现了 远程代码执行(RCE)。
泡杯咖啡,我们开始吧 ☕
理解目标
和大多数漏洞赏金一样,一切从信息收集开始。
我通过以下方式审计目标:
- 浏览他们的 GitHub 公共仓库
- 分析技术栈
- 理解依赖管理方式
在查看公开代码时,我注意到他们大量使用 Ruby。这让我开始好奇 Ruby 的依赖是如何管理的,是否存在由于配置错误而暴露的内部包。
什么是 Ruby Gem?
Ruby Gem 是 Ruby 的包或库,用于共享和复用代码。
开发者不需要重复造轮子,可以直接依赖 gem 来实现框架、工具和内部功能。
Gem 分两种:
- 公共 Gem:托管在 RubyGems.org,任何人都能下载
- 私有 / 内部 Gem:托管在公司私有服务器,只允许员工访问
公司通常创建内部 gem 来保护业务逻辑和内部工具。
什么是依赖混淆?
依赖混淆(也叫替换攻击)是指:
公司内部使用了一个私有包名,而攻击者在公共仓库注册了一个同名包。
如果包管理器配置错误,就可能优先安装攻击者的包。
如果攻击者发布一个很高的版本号,比如:
90002.0
包管理器就会认为它是最新版本。
这个问题不仅存在于 Ruby,也影响 npm、pip、Maven、NuGet 等生态。
经典攻击方式
Gemfile 示例:
source 'https://rubygems.org'
source 'https://internal-gems.company.com'
gem 'rails'
gem 'internal-gem'
Bundler 会从:
- rubygems.org
- internal-gems.company.com
同时拉取。
由于 internal-gem 没指定来源,Bundler 允许从任意源解析。
执行 bundle install:
Found 'internal-gem' in multiple sources:
- rubygems.org: version 90002.0 (攻击者)
- internal-gems: version 1.0 (公司真实)
Bundler 选择最高版本 → 安装恶意 gem
安装时,恶意代码会自动执行。
正确配置方式
source 'https://rubygems.org'
gem 'rails'
gem 'sidekiq'
source 'https://internal-gems.company.com'do
gem 'internal-gem'
end
这样 Bundler 永远不会从公共仓库解析 internal-gem。
为什么危险
bundle install 经常自动运行在:
- 开发者机器
- CI/CD
- Docker 构建
- 部署阶段
特点:
- 无需用户操作
- 自动执行
- 容易打入生产链路
侦察阶段
使用 ghorg 克隆仓库:
ghorg clone <org> -t <token>
提取 Gemfile:
find . -type f -name Gemfile | \
xargs -n1 -I{} awk '/^\s*gem / {gsub(/[",'\''()]/, "", $2); print $2}' {} | \
sort -u
检测哪些 gem 不存在于 RubyGems:
xargs -n1 -I{} httpx -silent -status-code -mc 404 "https://rubygems.org/gems/{}"
404 表示公共仓库没有该包。
构建 PoC
创建恶意 Gem
我创建同名 gem,并将版本设为极高值 90002.0。
添加回调代码
Ruby gem 在安装阶段即可执行代码。
回调只采集:
- 主机名
- 用户名
- 时间戳
没有采集任何敏感数据。
设置回调服务器
部署 HTTPS 服务器用于接收回连。
发布到 RubyGems
gem build internal-gem.gemspec
gem push internal-gem-90002.0.gem
等待命中
几天后收到回连。
说明恶意 gem 已在目标环境被安装。
分析回调
结果表明:
- 主机名是开发者工作站
- 用户名是真实工程师账号
- 不是 CI 或生产服务器
真正发生了什么
Ruby 有两种安装方式:
Bundler
- 读取 Gemfile
- 遵守 source
- 使用锁文件
- 更安全
gem install
- 忽略 Gemfile
- 使用全局源
- 选择最高版本
- 可被混淆
开发者执行了:
gem install internal-gem
从而绕过了 Bundler。
影响
开发者机器通常拥有:
- 源码
- Token
- SSH Key
- 云权限
- 内网访问能力
因此风险依然很高。
厂商响应
厂商确认生产与 CI/CD 安全。
漏洞评级:HIGH。
✅ 总结一句话
依赖混淆不仅能打生产,也能控制开发者机器,是供应链攻击的重要入口。
- 公众号:安全狗的自我修养
- vx:2207344074
- http://gitee.com/haidragon
- http://github.com/haidragon
- bilibili:haidragonx
#
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:安全狗的自我修养 haidragon haidragon《我是如何在 Ruby 应用中发现一个依赖混淆漏洞并最终导致 RCE 的》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。









评论