Concourse Enumeration & Attacks
Last updated
Last updated
Μάθετε & εξασκηθείτε στο AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Μάθετε & εξασκηθείτε στο GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Το Concourse διαθέτει πέντε ρόλους:
Concourse Admin: Αυτός ο ρόλος δίνεται μόνο στους ιδιοκτήτες της κύριας ομάδας (προεπιλεγμένη αρχική ομάδα concourse). Οι διαχειριστές μπορούν να διαμορφώσουν άλλες ομάδες (π.χ.: fly set-team
, fly destroy-team
...). Οι άδειες αυτού του ρόλου δεν μπορούν να επηρεαστούν από το RBAC.
owner: Οι ιδιοκτήτες ομάδας μπορούν να τροποποιήσουν τα πάντα εντός της ομάδας.
member: Τα μέλη της ομάδας μπορούν να διαβάσουν και να γράψουν εντός των πόρων της ομάδας αλλά δεν μπορούν να τροποποιήσουν τις ρυθμίσεις της ομάδας.
pipeline-operator: Οι χειριστές pipeline μπορούν να εκτελούν λειτουργίες pipeline όπως η εκκίνηση κατασκευών και η σταθεροποίηση πόρων, ωστόσο δεν μπορούν να ενημερώσουν τις ρυθμίσεις του pipeline.
viewer: Οι θεατές της ομάδας έχουν "μόνο ανάγνωση" πρόσβαση σε μια ομάδα και τα pipelines της.
Επιπλέον, οι άδειες των ρόλων owner, member, pipeline-operator και viewer μπορούν να τροποποιηθούν ρυθμίζοντας το RBAC (ρυθμίζοντας πιο συγκεκριμένα τις ενέργειές του). Διαβάστε περισσότερα γι' αυτό στο: https://concourse-ci.org/user-roles.html
Σημειώστε ότι το Concourse ομαδοποιεί τα pipelines μέσα σε Ομάδες. Επομένως, οι χρήστες που ανήκουν σε μια Ομάδα θα μπορούν να διαχειρίζονται αυτά τα pipelines και πολλές Ομάδες μπορεί να υπάρχουν. Ένας χρήστης μπορεί να ανήκει σε πολλές Ομάδες και να έχει διαφορετικές άδειες σε κάθε μία από αυτές.
Στα YAML configs μπορείτε να ρυθμίσετε τιμές χρησιμοποιώντας τη σύνταξη ((_source-name_:_secret-path_._secret-field_))
.
Από τα docs: Το source-name είναι προαιρετικό, και αν παραληφθεί, θα χρησιμοποιηθεί ο credential manager σε επίπεδο cluster, ή η τιμή μπορεί να παρασχεθεί στατικά.
Το προαιρετικό _secret-field_ καθορίζει ένα πεδίο στο ανακτηθέν μυστικό για ανάγνωση. Αν παραληφθεί, ο credential manager μπορεί να επιλέξει να διαβάσει ένα 'προεπιλεγμένο πεδίο' από το ανακτηθέν credential αν το πεδίο υπάρχει.
Επιπλέον, το secret-path και secret-field μπορεί να περιβάλλεται από διπλά εισαγωγικά "..."
αν περιέχουν ειδικούς χαρακτήρες όπως .
και :
. Για παράδειγμα, ((source:"my.secret"."field:1"))
θα ορίσει το secret-path σε my.secret
και το secret-field σε field:1
.
Οι στατικές μεταβλητές μπορούν να καθοριστούν σε βήματα εργασιών:
Or χρησιμοποιώντας τα παρακάτω fly
arguments:
-v
ή --var
NAME=VALUE
ορίζει τη συμβολοσειρά VALUE
ως την τιμή για τη μεταβλητή NAME
.
-y
ή --yaml-var
NAME=VALUE
αναλύει το VALUE
ως YAML και το ορίζει ως την τιμή για τη μεταβλητή NAME
.
-i
ή --instance-var
NAME=VALUE
αναλύει το VALUE
ως YAML και το ορίζει ως την τιμή για τη μεταβλητή στιγμής NAME
. Δείτε Grouping Pipelines για να μάθετε περισσότερα σχετικά με τις μεταβλητές στιγμής.
-l
ή --load-vars-from
FILE
φορτώνει το FILE
, ένα έγγραφο YAML που περιέχει αντιστοίχιση ονομάτων μεταβλητών σε τιμές, και τα ορίζει όλα.
Υπάρχουν διάφοροι τρόποι με τους οποίους μπορεί να καθοριστεί ένας Διαχειριστής Διαπιστευτηρίων σε μια ροή εργασίας, διαβάστε πώς στο https://concourse-ci.org/creds.html. Επιπλέον, το Concourse υποστηρίζει διάφορους διαχειριστές διαπιστευτηρίων:
Σημειώστε ότι αν έχετε κάποιο είδος δικαιώματος εγγραφής στο Concourse μπορείτε να δημιουργήσετε εργασίες για να εξάγετε αυτά τα μυστικά καθώς το Concourse πρέπει να μπορεί να έχει πρόσβαση σε αυτά.
Για να απαριθμήσετε ένα περιβάλλον concourse πρέπει πρώτα να συγκεντρώσετε έγκυρα διαπιστευτήρια ή να βρείτε ένα επικυρωμένο διακριτικό πιθανώς σε ένα αρχείο ρυθμίσεων .flyrc
.
Για να συνδεθείτε πρέπει να γνωρίζετε το endpoint, το όνομα ομάδας (προεπιλογή είναι το main
) και μια ομάδα στην οποία ανήκει ο χρήστης:
fly --target example login --team-name my-team --concourse-url https://ci.example.com [--insecure] [--client-cert=./path --client-key=./path]
Λάβετε τις ρυθμισμένες στόχους:
fly targets
Ελέγξτε αν η ρυθμισμένη σύνδεση στόχου είναι ακόμα έγκυρη:
fly -t <target> status
Λάβετε το ρόλο του χρήστη σε σχέση με τον καθορισμένο στόχο:
fly -t <target> userinfo
Σημειώστε ότι το API token είναι αποθηκευμένο στο $HOME/.flyrc
από προεπιλογή, εάν ελέγχετε μια μηχανή μπορείτε να βρείτε εκεί τα διαπιστευτήρια.
Λάβετε μια λίστα με τις Ομάδες
fly -t <target> teams
Λάβετε ρόλους μέσα στην ομάδα
fly -t <target> get-team -n <team-name>
Λάβετε μια λίστα χρηστών
fly -t <target> active-users
Λίστα ροών εργασίας:
fly -t <target> pipelines -a
Λάβετε yaml ροής εργασίας (ευαίσθητες πληροφορίες μπορεί να βρεθούν στον ορισμό):
fly -t <target> get-pipeline -p <pipeline-name>
Λάβετε όλες τις δηλωμένες μεταβλητές ρυθμίσεων της ροής εργασίας
for pipename in $(fly -t <target> pipelines | grep -Ev "^id" | awk '{print $2}'); do echo $pipename; fly -t <target> get-pipeline -p $pipename -j | grep -Eo '"vars":[^}]+'; done
Λάβετε όλα τα ονόματα μυστικών ροών εργασίας που χρησιμοποιούνται (αν μπορείτε να δημιουργήσετε/τροποποιήσετε μια εργασία ή να καταλάβετε ένα κοντέινερ μπορείτε να τα εξάγετε):
Λίστα workers:
fly -t <target> workers
Λίστα containers:
fly -t <target> containers
Λίστα builds (για να δείτε τι τρέχει):
fly -t <target> builds
admin:admin
test:test
Στην προηγούμενη ενότητα είδαμε πώς μπορείτε να πάρετε όλα τα ονόματα και τις μεταβλητές των μυστικών που χρησιμοποιούνται από την pipeline. Οι μεταβλητές μπορεί να περιέχουν ευαίσθητες πληροφορίες και το όνομα των μυστικών θα είναι χρήσιμο αργότερα για να προσπαθήσετε να τα κλέψετε.
Αν έχετε αρκετά δικαιώματα (member role ή περισσότερα) θα μπορείτε να καταγράψετε pipelines και ρόλους και απλά να αποκτήσετε μια session μέσα στο <pipeline>/<job>
container χρησιμοποιώντας:
Με αυτές τις άδειες μπορεί να είστε σε θέση να:
Κλέψετε τα μυστικά μέσα στο container
Προσπαθήσετε να ξεφύγετε στον κόμβο
Αριθμήσετε/Κακοποιήσετε το cloud metadata endpoint (από το pod και από τον κόμβο, αν είναι δυνατόν)
Αν έχετε αρκετά προνόμια (ρόλος μέλους ή περισσότερα) θα μπορείτε να δημιουργήσετε/τροποποιήσετε νέα pipelines. Ελέγξτε αυτό το παράδειγμα:
Με την τροποποίηση/δημιουργία μιας νέας ροής εργασίας θα είστε σε θέση να:
Κλέψετε τα μυστικά (μέσω της εκτύπωσής τους ή μπαίνοντας μέσα στο κοντέινερ και εκτελώντας env
)
Δραπετεύσετε στη μονάδα (δίνοντάς σας αρκετά δικαιώματα - privileged: true
)
Αριθμήσετε/Καταχραστείτε το cloud metadata endpoint (από το pod και από τη μονάδα)
Διαγράψετε τη δημιουργημένη ροή εργασίας
Αυτό είναι παρόμοιο με την προηγούμενη μέθοδο, αλλά αντί να τροποποιήσετε/δημιουργήσετε μια εντελώς νέα ροή εργασίας, μπορείτε απλώς να εκτελέσετε μια προσαρμοσμένη εργασία (η οποία πιθανότατα θα είναι πολύ πιο αόρατη):
Στις προηγούμενες ενότητες είδαμε πώς να εκτελέσουμε μια προνομιούχα εργασία με το concourse. Αυτό δεν θα δώσει στο κοντέινερ ακριβώς την ίδια πρόσβαση όπως η προνομιούχα σημαία σε ένα κοντέινερ docker. Για παράδειγμα, δεν θα δείτε τη συσκευή του συστήματος αρχείων του κόμβου στο /dev, οπότε η διαφυγή θα μπορούσε να είναι πιο "πολύπλοκη".
Στην παρακάτω PoC θα χρησιμοποιήσουμε τον release_agent για να διαφύγουμε με κάποιες μικρές τροποποιήσεις:
Όπως μπορεί να έχετε παρατηρήσει, αυτό είναι απλώς μια κανονική απελευθέρωση_agent escape απλά τροποποιώντας τη διαδρομή της εντολής στο node
Μια κανονική απελευθέρωση_agent escape με μια μικρή τροποποίηση είναι αρκετή για αυτό:
Ακόμα και αν το web container έχει κάποιες άμυνες απενεργοποιημένες, δεν τρέχει ως κοινό προνομιακό container (για παράδειγμα, δεν μπορείτε να mount και οι ικανότητες είναι πολύ περιορισμένες, οπότε όλοι οι εύκολοι τρόποι για να ξεφύγετε από το container είναι άχρηστοι).
Ωστόσο, αποθηκεύει τοπικά διαπιστευτήρια σε καθαρό κείμενο:
Μπορείτε να χρησιμοποιήσετε αυτά τα διαπιστευτήρια για να συνδεθείτε στον διακομιστή ιστού και να δημιουργήσετε ένα προνομιακό κοντέινερ και να διαφύγετε στον κόμβο.
Στο περιβάλλον μπορείτε επίσης να βρείτε πληροφορίες για να αποκτήσετε πρόσβαση στην περίπτωση postgresql που χρησιμοποιεί το concourse (διεύθυνση, όνομα χρήστη, κωδικός πρόσβασης και βάση δεδομένων μεταξύ άλλων πληροφοριών):
Αυτές είναι απλώς μερικές ενδιαφέρουσες σημειώσεις σχετικά με την υπηρεσία, αλλά επειδή ακούει μόνο σε localhost, αυτές οι σημειώσεις δεν θα έχουν καμία επίδραση που δεν έχουμε ήδη εκμεταλλευτεί πριν.
Από προεπιλογή, κάθε concourse worker θα εκτελεί μια Garden υπηρεσία στη θύρα 7777. Αυτή η υπηρεσία χρησιμοποιείται από τον Web master για να υποδείξει στον worker τι χρειάζεται να εκτελέσει (να κατεβάσει την εικόνα και να εκτελέσει κάθε εργασία). Αυτό ακούγεται αρκετά καλό για έναν επιτιθέμενο, αλλά υπάρχουν μερικές καλές προστασίες:
Είναι απλώς εκτεθειμένο τοπικά (127..0.0.1) και νομίζω ότι όταν ο worker αυθεντικοποιείται απέναντι στον Web με την ειδική υπηρεσία SSH, δημιουργείται μια σήραγγα ώστε ο web server να μπορεί να μιλήσει σε κάθε υπηρεσία Garden μέσα σε κάθε worker.
Ο web server παρακολουθεί τους εκτελούμενους κοντέινερ κάθε λίγα δευτερόλεπτα, και μη αναμενόμενα κοντέινερ διαγράφονται. Έτσι, αν θέλετε να τρέξετε ένα προσαρμοσμένο κοντέινερ, πρέπει να παρέμβετε στην επικοινωνία μεταξύ του web server και της υπηρεσίας garden.
Οι concourse workers εκτελούνται με υψηλά δικαιώματα κοντέινερ:
Ωστόσο, τεχνικές όπως το mounting της συσκευής /dev του κόμβου ή του release_agent δεν θα λειτουργήσουν (καθώς η πραγματική συσκευή με το filesystem του κόμβου δεν είναι προσβάσιμη, μόνο μία εικονική). Δεν μπορούμε να έχουμε πρόσβαση σε διαδικασίες του κόμβου, οπότε η διαφυγή από τον κόμβο χωρίς exploits πυρήνα γίνεται περίπλοκη.
Στην προηγούμενη ενότητα είδαμε πώς να διαφύγουμε από ένα προνομιούχο κοντέινερ, οπότε αν μπορούμε να εκτελέσουμε εντολές σε ένα προνομιούχο κοντέινερ που δημιουργήθηκε από τον τρέχοντα εργάτη, θα μπορούσαμε να διαφύγουμε στον κόμβο.
Σημειώστε ότι παίζοντας με το concourse παρατήρησα ότι όταν δημιουργείται ένα νέο κοντέινερ για να τρέξει κάτι, οι διαδικασίες του κοντέινερ είναι προσβάσιμες από το κοντέινερ του εργάτη, οπότε είναι σαν ένα κοντέινερ να δημιουργεί ένα νέο κοντέινερ μέσα σε αυτό.
Μπαίνοντας σε ένα τρέχον προνομιούχο κοντέινερ
Δημιουργία ενός νέου προνομιακού κοντέινερ
Μπορείτε πολύ εύκολα να δημιουργήσετε ένα νέο κοντέινερ (απλώς εκτελέστε ένα τυχαίο UID) και να εκτελέσετε κάτι σε αυτό:
Ωστόσο, ο διακομιστής ιστού ελέγχει κάθε λίγα δευτερόλεπτα τα κοντέινερ που εκτελούνται, και αν ανακαλυφθεί κάποιο απροσδόκητο, θα διαγραφεί. Καθώς η επικοινωνία πραγματοποιείται μέσω HTTP, θα μπορούσατε να παραποιήσετε την επικοινωνία για να αποφύγετε τη διαγραφή απροσδόκητων κοντέινερ:
https://concourse-ci.org/vars.html
Μάθετε & εξασκηθείτε στο AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Μάθετε & εξασκηθείτε στο GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)