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ホワイトリストバイパス
多くの組織は、GitHubやGitLabのようなSaaSベースのソース管理(SCM)システムを、JenkinsやTeamCityのような内部の自己ホスト型CIソリューションと組み合わせています。このセットアップにより、CIシステムはSaaSソース管理ベンダーからのWebhookイベントを受信し、主にパイプラインジョブをトリガーすることができます。
これを実現するために、組織はSCMプラットフォームのIP範囲をホワイトリストに登録し、Webhookを介して内部CIシステムにアクセスできるようにしています。しかし、誰でもGitHubやGitLabにアカウントを作成し、Webhookをトリガーするように設定できるため、内部CIシステムにリクエストを送信する可能性があります。
内部Jenkinsの悪用
これらのシナリオでは、Jenkinsにアクセスするための有効なアカウントを持っていると仮定します。
Jenkinsに設定された認証メカニズムと侵害されたユーザーの権限によっては、以下の攻撃を実行できる場合とできない場合があります。
詳細については、基本情報を確認してください:
Basic Jenkins Informationユーザーのリスト表示
Jenkinsにアクセスした場合、http://127.0.0.1:8080/asynchPeople/で他の登録ユーザーをリスト表示できます。
プレーンテキストの秘密を見つけるためのビルドダンプ
このスクリプトを使用して、ビルドコンソール出力とビルド環境変数をダンプし、プレーンテキストの秘密を見つけることを期待します。
SSH資格情報の盗難
もし侵害されたユーザーが新しいJenkinsノードを作成/変更するのに十分な権限を持っている場合、SSH資格情報が他のノードにアクセスするためにすでに保存されていると、彼はノードを作成/変更し、資格情報を記録するホストを設定することによってそれらの資格情報を盗むことができる。ホストキーを検証せずに:
通常、JenkinsのSSH資格情報はグローバルプロバイダー(/credentials/
)に見つかるので、他の秘密をダンプするのと同様にそれらをダンプすることもできます。詳細は秘密のダンプセクションを参照してください。
JenkinsにおけるRCE
Jenkinsサーバーでシェルを取得することは、攻撃者にすべての秘密や環境変数を漏洩させ、同じネットワークにある他のマシンを悪用する機会を与え、さらにはクラウド資格情報を収集することができます。
デフォルトでは、JenkinsはSYSTEMとして実行されます。したがって、これを侵害することで攻撃者はSYSTEM権限を得ることになります。
プロジェクトの作成/変更によるRCE
プロジェクトを作成/変更することは、Jenkinsサーバー上でRCEを取得する方法です:
Jenkins RCE Creating/Modifying ProjectGroovyスクリプトの実行によるRCE
Groovyスクリプトを実行することでRCEを取得することもでき、これは新しいプロジェクトを作成するよりも目立たないかもしれません:
Jenkins RCE with Groovy Scriptパイプラインの作成/変更によるRCE
パイプラインを作成/変更することでRCEを取得することもできます:
Jenkins RCE Creating/Modifying Pipelineパイプラインの悪用
パイプラインを悪用するには、Jenkinsへのアクセスが必要です。
ビルドパイプライン
パイプラインはプロジェクトのビルドメカニズムとしても使用でき、その場合、パイプライン構文を含むリポジトリ内のファイルを設定できます。デフォルトでは/Jenkinsfile
が使用されます:
他の場所(例えば他のリポジトリ)にパイプライン設定ファイルを保存することも可能で、リポジトリアクセスとパイプラインアクセスを分離することを目的としています。
攻撃者がそのファイルに対して書き込みアクセスを持っている場合、彼はそれを変更し、Jenkinsにアクセスせずにパイプラインをトリガーする可能性があります。 攻撃者はいくつかのブランチ保護を回避する必要があるかもしれません(プラットフォームやユーザー権限によっては回避できる場合もあります)。
カスタムパイプラインを実行するための最も一般的なトリガーは次のとおりです:
メインブランチへのプルリクエスト(または他のブランチへのプルリクエスト)
メインブランチへのプッシュ(または他のブランチへのプッシュ)
メインブランチの更新を行い、何らかの方法で実行されるのを待つ
もしあなたが外部ユーザーであれば、他のユーザー/組織のリポジトリのメインブランチにPRを作成し、パイプラインをトリガーすることを期待すべきではありません...しかし、不適切に設定されている場合、あなたはこの方法で企業を完全に侵害することができるかもしれません。
パイプラインRCE
前のRCEセクションでは、パイプラインを変更することでRCEを取得する技術がすでに示されています。
環境変数の確認
平文の環境変数をパイプライン全体または特定のステージのために宣言することが可能です。これらの環境変数は機密情報を含むべきではありませんが、攻撃者は常にすべてのパイプライン設定/Jenkinsfileを確認することができます:
秘密のダンプ
Jenkinsが秘密を通常どのように扱うかについての情報は、基本情報を確認してください:
Basic Jenkins Information資格情報はグローバルプロバイダー(/credentials/
)または特定のプロジェクト(/job/<project-name>/configure
)にスコープを設定できます。したがって、すべての秘密を抽出するには、秘密を含むすべてのプロジェクトを少なくとも侵害する必要があり、カスタム/毒入りパイプラインを実行する必要があります。
もう一つの問題は、パイプラインのenv内の秘密を取得するには、秘密の名前とタイプを知っている必要があることです。たとえば、usernamePassword
秘密を**string
** 秘密としてロードしようとすると、次のエラーが発生します:
ここでは、いくつかの一般的な秘密のタイプをロードする方法を示します:
このページの最後にすべての認証情報タイプを見つけることができます: https://www.jenkins.io/doc/pipeline/steps/credentials-binding/
すべての秘密を一度にダンプする最良の方法は、Jenkinsマシンを侵害することです(例えば、組み込みノードでリバースシェルを実行する)そして、マスターキーと暗号化された秘密を漏洩させ、それらをオフラインで復号化します。 これを行う方法については、ノードとエージェントのセクションおよびポストエクスプロイテーションのセクションを参照してください。
トリガー
ドキュメントから: triggers
ディレクティブは、パイプラインが再トリガーされる自動化された方法を定義します。GitHubやBitBucketなどのソースと統合されたパイプラインの場合、triggers
は必要ないかもしれません。なぜなら、ウェブフックベースの統合がすでに存在する可能性が高いからです。現在利用可能なトリガーはcron
、pollSCM
、およびupstream
です。
Cronの例:
Check other examples in the docs.
Nodes & Agents
A Jenkins instance might have different agents running in different machines. From an attacker perspective, access to different machines means different potential cloud credentials to steal or different network access that could be abuse to exploit other machines.
For more information check the basic information:
Basic Jenkins InformationYou can enumerate the configured nodes in /computer/
, you will usually find the Built-In Node
(which is the node running Jenkins) and potentially more:
It is 特に興味深いのはBuilt-Inノードを妥協することです。なぜなら、それには敏感なJenkins情報が含まれているからです。
To indicate you want to run the pipeline in the built-in Jenkins node you can specify inside the pipeline the following config:
完全な例
特定のエージェントでのパイプライン、cronトリガーを使用し、パイプラインとステージの環境変数を持ち、ステップで2つの変数を読み込み、リバースシェルを送信します:
任意ファイル読み取りから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の秘密を復号化する
新しい管理者ユーザーを作成する
/var/lib/jenkins/config.xml
またはC:\Program Files (x86)\Jenkins\
にあるJenkinsのconfig.xmlファイルにアクセスします。<useSecurity>true</useSecurity>
という単語を検索し、**true
をfalse
**に変更します。sed -i -e 's/<useSecurity>true</<useSecurity>false</g' config.xml
Jenkinsサーバーを再起動します:
service jenkins restart
もう一度Jenkinsポータルに移動すると、Jenkinsは認証情報を要求しません。管理者パスワードを再設定するために「Manage Jenkins」に移動します。
設定を
<useSecurity>true</useSecurity>
に変更して再度セキュリティを有効にし、Jenkinsを再起動します。
参考文献
Last updated