对于针对持续集成和持续交付/持续部署(CI/CD)通道的网络攻击,攻击者和防御者都越来越明白,构建通道是一个重要的攻击面高权限目标。但是CI/CD管道的潜在攻击面是什么?这种类型的攻击实际上是什么样的?通过不同的安全评估,NCC组织发现了很多攻击路径,这些路径可以导致大大小小的企业的CI/CD通道受到攻击。在本文中,我们通过展示针对可能的可利用渠道的多种不同类型的攻击来强调保护软件供应链的重要性。Jenkins隐藏多个攻击面,从S3存储桶发起攻击S3存储桶中常见的错误配置往往会导致对整个DevOps环境的攻击。最初的攻击媒介是通过Web应用程序。该攻击方案的攻击流程包括:Web应用程序->S3bucket上的目录列表->脚本文件中的硬编码Git凭据->Git访问->使用相同的硬编码Git凭据访问Jenkins->从Jenkins中转储凭据->横向运动->游戏结束->事件->内部调查NCC组织通过匿名访问面向Web的Web应用程序进行了黑盒Web应用程序评估。在测试开始时,在站点地图文件夹中发现了一个站点地图文件。站点地图文件夹是一个启用了目录列表的S3存储桶。查看S3存储桶中的文件时,发现了一个bashshell脚本。经过仔细检查,我们发现了一个带有证书的硬编码git命令。该证书允许NCCGroup顾问以受限用户身份访问JenkinsMasterWeb登录界面,该界面只能在内部访问,不能从互联网访问。单击几下并四处查看后,他们能够切换到管理员帐户。凭借管理员权限,该顾问在脚本控制台中使用了Groovy单行程序并转储了大约200个不同的凭证,例如AWS访问令牌、SAST/DAST令牌、EC2SSH证书、Jenkins用户和其他Jenkins凭证。在评估结束时,客户与顾问就事件响应进行密切合作以进行补救。NCC为客户提供了一份包含补救和强化步骤的详细报告,其中一些建议如下:1.删除S3的目录列表;2.删除shell脚本文件和硬编码凭据;3、去掉权限,允许任何拥有GitHub权限的人都可以访问Jenkins连接;4.安装和查看审计跟踪和作业配置历史插件;5.在我们现场测试的情况下,Jenkins应该是无法通过互联网访问的;6.更改和降低Jenkins账户拥有的权限;7.为管理员帐户部署和使用MFA;HardeningEnvironments中的PrivilegeEscalationAdvisors在不同的评估中发现的另一种特权升级路径如下:LoginwithSSOCredentials->TestSeparated,Locked,andDocumentedRoles->Arolewithbuild/replaycodeexecution->Thepurposeofthecredentialdump评估是审查新实施的强化Jenkins环境,其中包含使用最小权限原则创建的记录用户角色。Jenkins在非root用户下运行,最新版本的核心和插件,具有SSL身份验证和SSO,使用MFA进行登录。NCC组织顾问每天访问具有特定角色的用户并测试任何权限升级路径。Builder角色还具有构建/重放权限,允许使用修改后的脚本或其他Groovy代码重放Pipeline构建,而不仅仅是构建作业的构建权限。这允许NCCOrgAdvisor运行Groovy代码并转储Jenkins用户的凭证和其他秘密。插件中的混淆语言最后一条途径是在Jenkins插件中找到的一个混淆选项,它导致广泛的开放访问:GitHub授权->具有读取权限的经过身份验证的Git用户->使用Gmail帐户的Jenkins访问GitHubOAuth插件部署在Jenkins中并提供身份验证和授权。“Grantreadaccesstoallauthenticatedusers”和“UseGitHubrepositorypermissions”选项被选中以允许任何拥有GitHub帐户的人(甚至是外部用户)访问Jenkins网络登录UI。NCC能够注册并使用他们自己的托管电子邮件帐户来访问他们的程序。GitLabCI/CD通道攻击NCC小组已经做了大量工作来研究正在使用的另一个著名工具GitLab。结果,NCCOrganizationalAdvisors发现了一些有趣的攻击路径。利用受保护的分支在一项特定的工作中,GitLab运行器设置有几个主要漏洞。第一个主要漏洞是运行器使用特权容器,这意味着它们配置了“-privileged”标志,这将允许它们启动其他可以轻松逃逸到主机的特权容器。这是一个非常简单的攻击媒介,可以让您到达主机。但有趣的是,这些GitLabrunners也共享runners,而不是孤立的。只应将代码推送到特定存储库的开发人员也可以访问机密和高权限存储库。此外,这些共享运行器使用普通环境变量来存储高度敏感的秘密,例如身份验证令牌和密码。对存储库的推送访问权限有限的用户可以获得高特权的秘密。受保护的分支是可以由GitLab中具有Maintainer角色的人维护的分支,只有那些人有权推送到那些源代码存储库或分支,并且有一个与之关联的变更请求(CR)链。这些受保护的分支可以与受保护的跑步者相关联。您可以将其锁定,因此开发人员必须获得CR批准才能推送代码。但在这种情况下,CR和受保护的分支没有得到实施和强制执行。任何人都可以推送到一个不受保护的分支,然后链接以前的漏洞利用。这4-5个漏洞的链接提供了所有访问权限。还有许多不同的路径。即使使用“-privileged”标志,还有另一条路径可以访问特权容器。操作员需要能够运行docker命令。主机的docker守护进程与GitLab共享共享Runner。这导致访问主机并在容器之间切换。顾问要求客户了解并帮助纠正这些问题,但有兴趣了解这些选择的根本原因。他们为什么做出这些配置选择,他们考虑了哪些权衡?除了这些选择之外,还有更安全的选择吗?他们了解他们吗?如果是这样,他们为什么不选择它们?公司想要权限容器的原因是对推送的代码进行静态分析,顾问解释说他们应该使用隔离运行器而不是共享运行器,并且应该有进一步的访问控制限制。请注意,可以运行特权容器并仍然在一定程度上限制暴露的敏感信息量。GitLab执行作业的许多CI/CD安全机制都依赖于这样的前提,即受保护的分支仅包含受信任的构建作业和由项目维护者管理的内容。项目维护者权限级别或更高级别的用户可以将管理和推送到特定的受保护分支委托给其他用户。这些授权用户是代表项目中什么是可信的,什么不是项目中的网关。做出这种区分对于减轻对不受信任的构建作业的特权暴露很重要。使用特权容器的GitLab运行器在另一个操作中,GitLab运行器被配置为使用Docker的“--privileged”标志执行CI/CD作业。此标志将取消Docker提供的任何安全隔离,以保护主机免受潜在不安全容器的影响。通过禁用这些安全功能,容器进程可以通过各种功能将其权限提升为主机上的root权限。一些工具被打包为Docker镜像,为了支持这一点,客户端在Docker(DIND)的许可容器中使用Docker执行嵌套容器。如果需要特权CI/CD作业,则应将相应的运行器配置为仅在已知的合法受保护项目分支上执行。这将防止任意攻击者提交可能导致主机危害的未经审查的脚本。Maintainer角色管理项目受保护分支的能力意味着他们控制由关联的受保护Runner提供的任何权限。高权限共享Runner可能会请求与敏感环境变量和权限Kubernetes环境相关的工作权限。跑步者不应配置为共享跑步者或广泛的群体。相反,它们应该根据特定项目或组的需要进行配置。或组被认为在维护者级别或更高级别的用户之间具有相同的权限级别。Runner向调用API端点的不受信任的CI/CD作业运行器公开秘密,这些API端点使用各种令牌和密码进行身份验证。因为这些是共享运行器,所以任何有权将源代码提交到GitLab的用户都可以轻松访问身份验证令牌和密码。跑步者被配置为通过环境变量公开秘密。Secrets管理,尤其是CI/CD通道,是一个很难解决的问题。为了减轻这些类型的风险,请确保运行器在所有构建作业中配置的环境变量不包含任何特权凭据。适当范围的GitLab变量可以用作替换。环境变量应该只包含信息配置值,相关项目和组中的任何被剥削人员都应该认为这些值是可以访问的。如果Runners必须通过环境变量或挂载的卷为他们的工作提供凭证,那么Runners应该限制他们暴露的工作负载。因此,此类Runner应仅与最具体的项目/组相关联。此外,它们应标记为“受保护”,以便它们只能处理受保护分支上的作业。主机Docker守护进程暴露给共享的GitLabRunner在一个操作中,GitLab共享的Runner在运行时将主机的Docker套接字挂载到CI/CD作业容器中。虽然这允许合法开发人员出于构建目的在主机上运行任意Docker命令,但它也允许构建作业在主机上部署特权容器以逃避它们的约束。这也为攻击者提供了一个窗口,他们可以通过该窗口攻击主机上运行的其他构建作业。从本质上讲,这否定了Docker提供的所有隔离,防止包含的进程访问其他容器和主机。在这种情况下,建议采取以下缓解措施:1.不允许开发人员直接与不受其控制的主机上的Docker守护程序交互。考虑使用支持无根Docker构建的工具(例如kaniko)运行Docker构建作业。2.开发一个进程,在源代码存储库上运行一组静态的Docker命令来构建它们。此过程不应在CI/CD作业本身内执行,因为作业脚本是用户定义的并且可以覆盖命令。3.如果这必须通过CI/CD作业来实现,那么在这些运行器上执行的构建作业应该被认为是特权的,因此应该限制Docker运行器接受对受保护和已知安全存储库的提交,以确保任何用户定义的CI/CD作品已经通过了正式的审批程序。运行特定功能的Kubernetespod有时会使用不同的pod身份验证机制,这些机制可以连接到各种服务,AWS凭证就是一个例子。很多时候,人们使用插件并且不限制插件周围的API路径。例如,Kube2IAM是一个经常看到的插件,如果你没有从pod中正确配置它,你可以获得权限容器,这些权限容器可以导致具有特权的API凭据,让你可以看到底层主机在做什么.Kube2IAMKube2IAM使用pod注释。它拦截来自容器pod的AWSAPI(169254)调用。NCC组织的一名顾问发现了一个有趣的情况,即每个开发人员都可以对pod进行注释。在Kube2IAM使用的AWS角色中,有一个配置了“stsassume-role*”行的设置。这使得任何能够创建/注释pod的可利用人员继承AWS管理员角色。这意味着任何可以创建任意pod并指定注释的人都可以获得对银行的AWSmastertools账户的管理访问权限。此帐户配置了VPC对等连接,可以查看任何pod和非pod环境。您可以使用该访问权限去任何地方。这是一个构建pod的通道,攻击者所要做的就是在最后输出一些东西的评论中添加评论。NCC组织的一名顾问完成了另一项类似的工作,在这种情况下,他们无法对豆荚进行注释。相反,在Kube2IAM中有标签“WhitelistRouteRegex”,您可以在其中提及AWSAPI路径。你可以指定你想去或不想去哪条路径,DevOps管理员已将其配置为白色字符以允许某人访问权限路径,从而产生底层节点凭证。笔记本电脑攻击NCC组织顾问进行了基于场景的评估——利用开发人员的笔记本电脑。顾问所能做的就是使用Maven项目将代码提交到单个Java库中。他们将一个预先需要的文件设置为一个任意文件,该文件将从构建环境中提供一个shell。他们将其更改为反向Meterpretershell负载。他们发现pod在磁盘上有一个SSH密钥,该密钥进入Jenkins主节点,然后从Jenkins中转储所有变量。然后他们发现这是一个真正的部署通道,可以对Kubernetes工作负载进行写入访问和集群管理。因此,他们现在可以访问完整的生产环境。在另一项行动中,NCCOrganizationalAdvisors成功入侵了一个用户帐户,并获得了被利用团队访问经过身份验证的渠道的权限。不可能在通道中运行自定义代码,但他们可以告诉通道构建不同的分支,即使它不存在。通道崩溃并转储环境变量。环境变量之一是Windows域管理员帐户。在此攻击场景中,他们能够对基础设施进行端口扫描,从而构建隧道。他们发现了许多功能未知的应用程序。其中一个应用程序容易受到服务器端请求伪造(SSRF)的攻击,并且它们在AWSEC2实例上运行。AWS节点能够编辑配置映射,允许在集群内的AWS用户帐户和角色之间进行映射。因此,这不会检查集群和帐户是否在同一用户帐户中。因此,顾问可以指定另一个AWS账户来控制集群,并拥有ElasticKubernetesService集群(EKS)的管理权限。本文翻译自:https://research.nccgroup.com/2022/01/13/10-real-world-stories-of-how-weve-compromised-ci-cd-pipelines/如有转载请注明原地址。
