聚焦源代码安全,网罗国内外最新资讯!
编译:代码卫士
专栏·供应链安全
数字化时代,软件无处不在。软件如同社会中的“虚拟人”,已经成为支撑社会正常运转的最基本元素之一,软件的安全性问题也正在成为当今社会的根本性、基础性问题。
随着软件产业的快速发展,软件供应链也越发复杂多元,复杂的软件供应链会引入一系列的安全问题,导致信息系统的整体安全防护难度越来越大。近年来,针对软件供应链的安全攻击事件一直呈快速增长态势,造成的危害也越来越严重。
为此,我们推出“供应链安全”栏目。本栏目汇聚供应链安全资讯,分析供应链安全风险,提供缓解建议,为供应链安全保驾护航。
注:以往发布的部分供应链安全相关内容,请见文末“推荐阅读”部分。
GoCD是用Java 编写的热门 CI/CD 解决方案,是非政府组织和每年收入达数十亿的财富500强公司等大批用户的首选。GoCD 因此成为关键基础设施以及极受攻击者欢迎的目标。为自动化构建和发布流程,一款集中化的 CI/CD 解决方案可访问多种生产环境和私密的源代码库。
GoCD 被赋予如此多的信任和责任,其软件交付管道如被攻陷,将对用户造成巨大影响。如攻击者控制发布管道中的任何组件,则可泄露知识财产或在该公司公开发布或内部使用的软件中包含后门。例如SolarWinds 供应链攻击中,攻击者获得对软件交付管道的访问权限并在关键软件中增添后门,触发迄今为止影响力最大的供应链事件。
文本将详述的漏洞可导致未验证攻击者泄露易受攻击 GoCD 服务器实例中的高度敏感信息,如存储在服务器中的所有加密机密。另外,该漏洞可用于模拟 GoCD Agent 即 GoCD worker,并接管软件交付管道。本文还将讨论该漏洞如何可被用于接管 GoCD 服务器并在该服务器上执行任意代码。
影响
SonarSource 公司的研究人员发现并向 GoCD 安全团队提交了多个漏洞。本文探讨的漏洞和验证崩溃有关,可导致未认证攻击者查看高度敏感信息并读取 GoCD 服务器实例上的任意文件。本文将探讨攻击者如何可滥用该漏洞访问已认证的攻击面。研究人员将发布新文章说明攻击者如何利用已认证攻击面,利用其它漏洞,对 GoCD 服务器实例造成 RCE 影响。
研究人员将本漏洞的严重程度评级为“极其严重”,理由是未认证共精子和可提取用于所有 build 管道中的令牌和机密信息。例如,攻击者可将 API 密钥泄露给外部服务如 Docker Hub 和 GitHub、窃取私密源代码、访问生产环境并覆写正被正成为 build 进程部分的文件,从而导致供应链攻击。
版本 v20.6.0至v21.2.0 中的所有 GoCD 实例均受影响,即所有包含提交 291d3d3485da818cd9067e487850c8153c6ba1e7 和 dd13d401f4b8cad1e7ef3846a86f11f6d2a2f9f2 的GoCD 实例均受影响。该漏洞已在 v21.3.0版本中修复。
利用这些漏洞,无需具备目标GoCD 服务器实例的知识。这些漏洞在默认配置下起作用,而且即使验证机制部署在 GoCD 服务器实例上也可被触发。为此,强烈建议尽快应用补丁。尽管在内网上托管CI/CD实例时最佳实践,但实际上仍有数百个实例暴露在互联网中。
研究人员发布视频,演示了 GoCD 实例如何可被远程轻易攻陷。
技术细节
首先将说明 GoCD 如何运作的背景知识,之后拆解漏洞根因。接着将说明攻击者通过第一阶段获得的信息如何攻陷 GoCD 服务器。
背景:GoCD 服务器和 Agent 架构
一般而言,公司在版本控制系统如 Git 中管理源代码。无论何时出现代码变更或发布时,GoCD 服务器都会知晓并自动运行和源库相关联的一个或多个 build 和发布管道。GoCD 中的管道实际上是需要以某种顺序运行的任务集合。一个高级别的管道例子如下:
1、编译源代码
2、运行单元测试和集成测试
3、构建 Docker 镜像并推送至公司注册表
为了委托这些工作,GoCD 服务器将管道运行分配给一个或多个 GoCD Agent。GoCD 生态系统中的 Agent 只是定期 ping 服务器并检查是否为其分配工作的worker。如存在worker,则 GoCD 服务器回复 Agent 要求的信息:要运行的命令以及要应用的环境变量。一般而言,这些环境变量将包括管道需访问服务的机密和访问令牌。
GoCD Agent 通过服务器分配的访问令牌验证 GoCD 服务器。在默认情况下,启用新的agent时,它会联系 GoCD 服务器并注册。之后管理员负责启用 Agent使其活跃并成为工作轮换的一部分。
业务持续性附件中的认证破坏
GoCD 使用流行的 Spring 框架并依靠 FilterChainProcy 来确保多种端点的正确验证。如下代码片段展示了不同过滤器如何和注册的URL一起被添加到过滤器链:
server/src/main/java/com/thoughtworks/go/server/newsecurity/filterchains/AuthenticationFilterChain.java
25 @Component("authenticationFilterChain")
26 public class AuthenticationFilterChain extends FilterChainProxy {
27
28 @Autowired
29 public AuthenticationFilterChain(
30 @Qualifier("agentAuthenticationFilter") Filter x509AuthenticationFilter,
31 // ...
32 @Qualifier("accessTokenAuthenticationFilter") Filter accessTokenAuthenticationFilter,
33 @Qualifier("assumeAnonymousUserFilter") Filter assumeAnonymousUserFilter) {
34 super(FilterChainBuilder.newInstance()
35 // X509 for agent remoting
36 .addFilterChain("/remoting/**", x509AuthenticationFilter)
37
38 // For addons
39 .addFilterChain("/add-on/**", assumeAnonymousUserFilter)
40
41 // ... more filters omitted
向 GoCD 服务器提出 HTTP 请求时,Spring 框架在将执行传递到控制器前会将请求URL映射到负责该请求的过滤器清单。如上代码片段展示了以 “/add-on/” 开头的所有请求路径通过第39行的 assumeAnonymousFilter 过滤。如该名称所提示,该过滤器实际上并未执行认证,允许任意请求。这就意味着附件暴露的端点负责确保正确认证和许可,因为可被任意未认证攻击者访问。
快速调查显示,该行为并非一直如此;提交291d3d3485da818cd9067e487850c8153c6ba1e7 更改了这一点。在此提交之前,仅有已认证用户可访问这些端点。研究人员发现这一变化将导致附件易受未认证攻击影响,因为附件的开发人员可能并未意识到这种责任传递。
研究人员在 GoCD 的业务可持续性附件中发现了一个任意文件读漏洞。从版本20.6.0 开始就安装了该附件并默认启用。如下代码片段中显示了易受攻击代码:
server/src/main/java/com/thoughtworks/go/addon/businesscontinuity/primary/controller/PrimaryStatusProviderController.java
119 @RequestMapping(value = "/plugin", method = RequestMethod.GET)
120 public void getPluginFile(
121 @RequestParam("folderName") String folderName,
122 @RequestParam("pluginName") String pluginName,
123 HttpServletResponse response) {
124 String pluginFolderPath = isBlank(folderName) || folderName.equalsIgnoreCase("bundled") ? systemEnvironment.getBundledPluginAbsolutePath() : systemEnvironment.get
ExternalPluginAbsolutePath();
125 File pluginFile = new File(pluginFolderPath, pluginName);
126 serveFile(pluginFile, response, "application/octet-stream");
127 }
pluginName 参数可被攻击者控制,被传递给新的File 对象的构建器中。该文件随后被读取并发给提出请求的用户。例如,通过设置/../../../../../../../../etc/passwd, 的pluginName 参数,可读取 GoCD 服务器的 /etc/passwd 文件。
还有两个端点暴露,泄露了极其敏感的信息,如下:
server/src/main/java/com/thoughtworks/go/addon/businesscontinuity/primary/controller/PrimaryStatusProviderController.java
92 @RequestMapping(value = "/cruise_config", method = RequestMethod.GET)
93 public void getLatestCruiseConfigXML(HttpServletResponse response) {
94 serveFile(ConfigFileType.CRUISE_CONFIG_XML.load(systemEnvironment), respon
se, "text/xml");
95 }
...
102 @RequestMapping(value = "/cipher.aes", method = RequestMethod.GET)
103 public void getLatestAESCipher(HttpServletResponse response) {
104 serveFile(ConfigFileType.AES_CIPHER.load(systemEnvironment), response, "te
xt/plain");
105 }
第一个, /cipher.aes 泄露了用于加密敏感机密如访问令牌的加密密钥,第二个,/cruise_config 泄露了 GoCD 服务器的主配置文件。该 XML 配置文件包含所有管道的所有环境变量。虽然其中某些环境变量是加密的且包含机密信息,但可通过被泄露的 AES 密码进行解密。该配置还包括其它敏感数据,这一部分内容将在下面章节提到。
总结一下,攻击者能够通过两个请求(窃取加密密钥的请求和获取所有加密机密的请求)提取 GoCD 服务器中的所有机密信息。攻击者还可读取 GoCD 服务器上的任意文件,因此读取 git 凭据、主数据库文件(默认使用 Hibernate)以及其它敏感文件。
GoCD 机密
之前我们讨论了攻击者如何滥用属于业务持续性附件的端点上缺失认证这一点,泄露高度敏感信息。本节讨论的是可造泄露的机密以及攻击者可能如何滥用这些机密攻击 GoCD 服务器,他们以管理员身份或Agent 身份获取合法会话。之后我们将零写一篇文章,详细说明我们如何找到经认证攻击面中的漏洞以及如何设法使 RCE 链运作。
首先了解下 GoCD服务器主配置文件中的一些配置选项。如下代码片段使关于默认包含的配置的例子:
Cruise_config.xml
<server
agentAutoRegisterKey="xxx-xxx-xxx-xxx-xxx-xxx"
webhookSecret="xxx-xxx-xxx-xxx-xxx-xxx"
tokenGenerationKey="xxx-xxx-xxx-xxx-xxx-xxx">
AgentAutoRegisterKey
该机密可用于注册新的 GoCD worker或 GoCD Agent,在它们被 GoCD 生态系统调用时可注册,无需获得管理员的统一。这意味着攻击者可疑在worker 论坛中注册多个恶意 Agent 并劫持 build 管道;也意味着可获得可从 GoCD Agent 触及的已认证攻击面的访问权限。
tokenGeneratonKey
Pulse Security 此前的研究工作展示了该令牌如何可用于假冒已处于 worker 轮换和已收到管理员同意的GoCD Agent。
webhookSecret
该 webhook 机密用于认证源自 GitHub、GitLab 或 BitBucket 的webhook 请求。该机密的知识可被滥用于触发管道运行。它海会打开更多的之前无法触及的攻击面。
认证配置
在默认情况下,GoCD 配有两个认证插件:Password和基于 LDAP 的认证。如下章节展示了基于密码文件的认证可被认证的方式:
Cruise_config.xml
<authConfig id="file" pluginId="cd.go.authentication.passwordfile">
<property>
<key>PasswordFilePath</key>
<value>/opt/godata/password.txt</value>
</property>
</authConfig>
如上代码片段展示了 GoCD 服务器如何被配置为从 /opt/godata/password.txt 文件读取密码。该文件按照 htpasswd 文件格式含有一个用户名和哈希密码)。该插件文档指出,密码哈希或者以 SHA1、Bcrypt 或 PBKFD2 格式存储。
另外,GoCD 还默认支持 LDAP 认证。在最糟糕的情况下,攻击者可泄露服务器的 LDAP 密码,获得对公司 LDAP 的访问权限。
补丁
GoCD 安全团队快速响应。在收到漏洞报告的两天后就发布新版本 v21.3.0 修复了这两个漏洞。他们从核心中删除了业务持续性附件,解决了本文中提到的漏洞。
鉴于漏洞的严重性,建议尽快修复这些漏洞。如无法立即运行更新,则设置防火墙规则,阻止针对 /add-on/** 和/或 /add-on/business-continuity/** 的HTTP 请求。
时间线
2021-10-16:通过 HackerOne 平台向 GoCD 报告被暴露的附件端点问题
2021-10-18:通过HackerOne 平台向 GoCD 报告其它研究成果
2021-10-18:GoCD 确认所有问题
2021-10-18:GoCD 通过 GitHub 库推出附件端点和其它问题的补丁
2021-10-22:GoCD 通过公开的谷歌论坛预告重要安全修复方案信息
2021-10-24:GoCD 发送v21.3.0的实验安装程序
2021-10-24:研究员验证新版本不受这些漏洞影响
2021-10-25:GoCD指出已发送邮件列表
2021-10-26:GoCD 发布版本 v21.3.0
总结
本文拆解了可导致攻击者无需认证即可查看GoCD 服务器中高度敏感信息的一个漏洞。该漏洞因一年前引入的针对附件认证的重大变化而引发。强烈建议所有 GoCD 用户立即更新至最新版本!
感谢 GoCD 安全团队在漏洞披露过程中极其优秀的响应速度。他们反应迅速并和我们一起高效地修复了漏洞。
推荐阅读
GitHub 在 “tar” 和 npm CLI 中发现7个高危的代码执行漏洞
速修复!热门npm 库 netmask 被曝严重的软件供应链漏洞,已存在9年
Npm 恶意包试图窃取 Discord 敏感信息和浏览器文件
微软“照片”应用Raw 格式图像编码器漏洞 (CVE-2021-24091)的技术分析
速修复!热门npm 库 netmask 被曝严重的软件供应链漏洞,已存在9年
SolarWinds 供应链事件后,美国考虑实施软件安全评级和标准机制
揭秘新的供应链攻击:一研究员靠它成功入侵微软、苹果等 35 家科技公司
开源OS FreeBSD 中 ftpd chroot 本地提权漏洞 (CVE-2020-7468) 的技术分析
集结30+漏洞 exploit,Gitpaste-12 蠕虫影响 Linux 和开源组件等
原文链接
https://blog.sonarsource.com/gocd-pre-auth-pipeline-takeover
题图:Pixabay License
本文由奇安信编译,不代表奇安信观点。转载请注明“转自奇安信代码卫士 https://codesafe.qianxin.com”。
奇安信代码卫士 (codesafe)
国内首个专注于软件开发安全的产品线。
觉得不错,就点个 “在看” 或 "赞” 吧~