Jenkins Security
基本信息
Jenkins 是一个工具,提供了一种简单的方法来建立几乎任何编程语言和源代码库组合的 持续集成 或 持续交付 (CI/CD) 环境,使用管道。此外,它自动化了各种常规开发任务。虽然 Jenkins 并没有消除为每个步骤创建脚本的需要,但它确实提供了一种比手动构建更快、更强大的方式来集成整个构建、测试和部署工具的序列。
Basic Jenkins Information未经身份验证的枚举
为了在没有身份验证的情况下搜索有趣的 Jenkins 页面(如 /people 或 /asynchPeople,这列出了当前用户),您可以使用:
检查您是否可以在不需要身份验证的情况下执行命令:
在没有凭据的情况下,您可以查看 /asynchPeople/ 路径或 /securityRealm/user/admin/search/index?q= 以获取 用户名。
您可能能够从路径 /oops 或 /error 获取 Jenkins 版本。
已知漏洞
登录
在基本信息中,您可以检查 所有登录 Jenkins 的方式:
Basic Jenkins Information注册
您将能够找到 允许您创建帐户并登录的 Jenkins 实例。就这么简单。
SSO 登录
如果 SSO 功能/插件 存在,您应该尝试使用测试帐户(即测试 Github/Bitbucket 帐户)登录应用程序。从 这里 获取技巧。
暴力破解
Jenkins 缺乏 密码策略 和 用户名暴力破解缓解。对用户进行 暴力破解 是至关重要的,因为可能使用 弱密码 或 用户名作为密码,甚至 反向用户名作为密码。
密码喷洒
使用 这个 python 脚本 或 这个 powershell 脚本。
IP 白名单绕过
许多组织将 基于 SaaS 的源代码管理 (SCM) 系统(如 GitHub 或 GitLab)与 内部自托管 CI 解决方案(如 Jenkins 或 TeamCity)结合使用。此设置允许 CI 系统 接收来自 SaaS 源代码控制供应商的 webhook 事件,主要用于触发管道作业。
为了实现这一点,组织 将 SCM 平台的 IP 范围列入白名单,允许它们通过 webhooks 访问 内部 CI 系统。然而,重要的是要注意 任何人 都可以在 GitHub 或 GitLab 上创建一个 账户 并将其配置为 触发 webhook,可能会向 内部 CI 系统 发送请求。
内部 Jenkins 滥用
在这些场景中,我们假设您拥有访问 Jenkins 的有效账户。
根据 Jenkins 中配置的 授权 机制和被攻陷用户的权限,您 可能能够或无法执行以下攻击。
有关更多信息,请查看基本信息:
Basic Jenkins Information列出用户
如果您已访问 Jenkins,您可以在 http://127.0.0.1:8080/asynchPeople/ 列出其他注册用户。
转储构建以查找明文秘密
使用 这个脚本 转储构建控制台输出和构建环境变量,以希望找到明文秘密。
窃取 SSH 凭证
如果被攻击的用户具有 足够的权限来创建/修改新的 Jenkins 节点,并且 SSH 凭证已经存储以访问其他节点,他可以通过创建/修改一个节点并 设置一个将记录凭证的主机 而不验证主机密钥来 窃取这些凭证:
您通常可以在 全局提供者 (/credentials/
) 中找到 Jenkins ssh 凭证,因此您也可以像转储任何其他秘密一样转储它们。更多信息请参见 转储秘密部分。
Jenkins 中的 RCE
在 Jenkins 服务器上获得 shell 使攻击者有机会泄露所有 秘密 和 环境变量,并 利用同一网络中的其他机器,甚至 收集云凭证。
默认情况下,Jenkins 将 以 SYSTEM 身份运行。因此,攻陷它将使攻击者获得 SYSTEM 权限。
创建/修改项目的 RCE
创建/修改项目是获得 Jenkins 服务器 RCE 的一种方式:
Jenkins RCE Creating/Modifying Project执行 Groovy 脚本的 RCE
您还可以通过执行 Groovy 脚本来获得 RCE,这可能比创建新项目更隐蔽:
Jenkins RCE with Groovy Script创建/修改管道的 RCE
您还可以通过 创建/修改管道 来获得 RCE:
Jenkins RCE Creating/Modifying Pipeline管道利用
要利用管道,您仍然需要访问 Jenkins。
构建管道
管道 也可以用作 项目中的构建机制,在这种情况下,可以配置一个 存储库中的文件,该文件将包含管道语法。默认情况下使用 /Jenkinsfile
:
也可以 将管道配置文件存储在其他地方(例如在其他存储库中),目的是 分离 存储库 访问 和管道访问。
如果攻击者对该文件具有 写入权限,他将能够 修改 它并 潜在触发 管道,而无需访问 Jenkins。 攻击者可能需要 绕过一些分支保护(根据平台和用户权限,这些保护可能会被绕过或不被绕过)。
执行自定义管道的最常见触发器是:
对主分支的拉取请求(或可能对其他分支)
推送到主分支(或可能对其他分支)
更新主分支 并等待以某种方式执行
如果您是 外部用户,您不应该期望创建 PR 到其他用户/组织的主分支 并 触发管道... 但如果配置 不当,您可能会通过利用这一点完全 攻陷公司。
管道 RCE
在之前的 RCE 部分中已经指明了一种技术来 通过修改管道获取 RCE。
检查环境变量
可以为整个管道或特定阶段声明 明文环境变量。这些环境变量 不应包含敏感信息,但攻击者始终可以 检查所有管道 配置/Jenkinsfiles:
Dumping secrets
有关Jenkins通常如何处理秘密的信息,请查看基本信息:
Basic Jenkins Information凭据可以作用于全局提供者(/credentials/
)或特定项目(/job/<project-name>/configure
)。因此,为了提取所有凭据,您需要至少妥协所有包含秘密的项目并执行自定义/被污染的管道。
还有另一个问题,为了在管道的env中获取秘密,您需要知道秘密的名称和类型。例如,如果您尝试将**usernamePassword
** 秘密作为**string
** 秘密加载,您将收到此错误:
这里是加载一些常见秘密类型的方法:
在本页面的末尾,您可以找到所有凭证类型:https://www.jenkins.io/doc/pipeline/steps/credentials-binding/
触发器
来自文档:triggers
指令定义了管道应重新触发的自动方式。对于与 GitHub 或 BitBucket 等源集成的管道,triggers
可能不是必需的,因为基于 webhook 的集成可能已经存在。目前可用的触发器有cron
、pollSCM
和upstream
。
Cron 示例:
检查 文档中的其他示例。
节点与代理
一个 Jenkins 实例 可能在 不同的机器上运行不同的代理。从攻击者的角度来看,访问不同的机器意味着 不同的潜在云凭证 可以被窃取或 不同的网络访问 可能被滥用以利用其他机器。
有关更多信息,请查看基本信息:
Basic Jenkins Information您可以在 /computer/
中枚举 配置的节点,通常会找到 内置节点
(即运行 Jenkins 的节点)以及可能更多的节点:
攻陷内置节点 特别有趣,因为它包含敏感的 Jenkins 信息。
要指示您想在 内置 Jenkins 节点 中 运行 管道,您可以在管道中指定以下配置:
完整示例
在特定代理中的管道,带有 cron 触发器,具有管道和阶段环境变量,在一个步骤中加载 2 个变量并发送反向 shell:
任意文件读取到 RCE
Jenkins Arbitrary File Read to RCE via "Remember Me"RCE
Jenkins RCE with Groovy ScriptJenkins RCE Creating/Modifying ProjectJenkins RCE Creating/Modifying Pipeline利用后
Metasploit
Jenkins Secrets
您可以通过访问 /credentials/
列出秘密,如果您拥有足够的权限。请注意,这只会列出 credentials.xml
文件中的秘密,但 构建配置文件 可能还包含 更多凭据。
如果您可以 查看每个项目的配置,您也可以在其中看到用于访问存储库的 凭据名称(秘密) 和 项目的其他凭据。
From Groovy
Jenkins Dumping Secrets from GroovyFrom disk
这些文件用于 解密 Jenkins 秘密:
secrets/master.key
secrets/hudson.util.Secret
这样的 秘密通常可以在:
credentials.xml
jobs/.../build.xml
jobs/.../config.xml
这是一个查找它们的正则表达式:
离线解密Jenkins秘密
如果您已经转储了 解密秘密所需的密码,请使用 这个脚本 来解密这些秘密。
从 Groovy 解密 Jenkins 秘密
创建新管理员用户
访问 Jenkins config.xml 文件在
/var/lib/jenkins/config.xml
或C:\Program Files (x86)\Jenkins\
搜索词
<useSecurity>true</useSecurity>
并将true
改为false
。sed -i -e 's/<useSecurity>true</<useSecurity>false</g' config.xml
重启 Jenkins 服务器:
service jenkins restart
现在再次访问 Jenkins 门户,Jenkins 这次不会询问任何凭据。您可以导航到 "管理 Jenkins" 以重新设置 管理员密码。
通过将设置更改为
<useSecurity>true</useSecurity>
再次 启用 安全性 并 再次重启 Jenkins。
参考文献
Last updated