Docker Breakout / Privilege Escalation
Last updated
Last updated
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Use Trickest to easily build and automate workflows powered by the world's most advanced community tools. Get Access Today:
linpeas: Μπορεί επίσης να καταμετρήσει τα κοντέινερ
CDK: Αυτό το εργαλείο είναι αρκετά χρήσιμο για να καταμετρήσει το κοντέινερ στο οποίο βρίσκεστε και να προσπαθήσει να διαφύγει αυτόματα
amicontained: Χρήσιμο εργαλείο για να αποκτήσετε τα δικαιώματα που έχει το κοντέινερ προκειμένου να βρείτε τρόπους να διαφύγετε από αυτό
deepce: Εργαλείο για να καταμετρήσετε και να διαφύγετε από κοντέινερ
grype: Αποκτήστε τα CVEs που περιέχονται στο λογισμικό που είναι εγκατεστημένο στην εικόνα
Αν με κάποιο τρόπο διαπιστώσετε ότι το docker socket είναι τοποθετημένο μέσα στο κοντέινερ docker, θα μπορείτε να διαφύγετε από αυτό. Αυτό συμβαίνει συνήθως σε κοντέινερ docker που για κάποιο λόγο χρειάζονται να συνδεθούν με το docker daemon για να εκτελέσουν ενέργειες.
Σε αυτή την περίπτωση μπορείτε να χρησιμοποιήσετε κανονικές εντολές docker για να επικοινωνήσετε με τον docker daemon:
Σε περίπτωση που το docker socket είναι σε απροσδόκητη τοποθεσία, μπορείτε να επικοινωνήσετε μαζί του χρησιμοποιώντας την εντολή docker
με την παράμετρο -H unix:///path/to/docker.sock
Ο Docker daemon μπορεί επίσης να ακούει σε μια θύρα (κατά προεπιλογή 2375, 2376) ή σε συστήματα βασισμένα σε Systemd, η επικοινωνία με τον Docker daemon μπορεί να συμβαίνει μέσω του socket Systemd fd://
.
Επιπλέον, δώστε προσοχή στα runtime sockets άλλων υψηλού επιπέδου runtimes:
dockershim: unix:///var/run/dockershim.sock
containerd: unix:///run/containerd/containerd.sock
cri-o: unix:///var/run/crio/crio.sock
frakti: unix:///var/run/frakti.sock
rktlet: unix:///var/run/rktlet.sock
...
Πρέπει να ελέγξετε τις δυνατότητες του κοντέινερ, αν έχει οποιαδήποτε από τις παρακάτω, μπορεί να είστε σε θέση να διαφύγετε από αυτό: CAP_SYS_ADMIN
, CAP_SYS_PTRACE
, CAP_SYS_MODULE
, DAC_READ_SEARCH
, DAC_OVERRIDE, CAP_SYS_RAWIO
, CAP_SYSLOG
, CAP_NET_RAW
, CAP_NET_ADMIN
Μπορείτε να ελέγξετε τις τρέχουσες δυνατότητες του κοντέινερ χρησιμοποιώντας τα προηγουμένως αναφερόμενα αυτόματα εργαλεία ή:
Στην παρακάτω σελίδα μπορείτε να μάθετε περισσότερα για τις δυνατότητες του linux και πώς να τις εκμεταλλευτείτε για να ξεφύγετε/ανεβάσετε δικαιώματα:
Ένα προνομιούχο κοντέινερ μπορεί να δημιουργηθεί με την επιλογή --privileged
ή απενεργοποιώντας συγκεκριμένες άμυνες:
--cap-add=ALL
--security-opt apparmor=unconfined
--security-opt seccomp=unconfined
--security-opt label:disable
--pid=host
--userns=host
--uts=host
--cgroupns=host
Mount /dev
Η επιλογή --privileged
μειώνει σημαντικά την ασφάλεια του κοντέινερ, προσφέροντας απεριόριστη πρόσβαση σε συσκευές και παρακάμπτοντας πολλές προστασίες. Για λεπτομερή ανάλυση, ανατρέξτε στην τεκμηρίωση σχετικά με τις πλήρεις επιπτώσεις του --privileged
.
Με αυτές τις άδειες μπορείτε απλά να μετακινηθείτε στο namespace μιας διαδικασίας που εκτελείται στον host ως root όπως το init (pid:1) απλά εκτελώντας: nsenter --target 1 --mount --uts --ipc --net --pid -- bash
Δοκιμάστε το σε ένα κοντέινερ εκτελώντας:
Απλά με την σημαία privileged μπορείτε να προσπαθήσετε να πρόσβαση στον δίσκο του host ή να προσπαθήσετε να ξεφύγετε εκμεταλλευόμενοι το release_agent ή άλλες διαφυγές.
Δοκιμάστε τις παρακάτω παρακάμψεις σε ένα κοντέινερ εκτελώντας:
Καλά ρυθμισμένα κοντέινερ docker δεν θα επιτρέψουν εντολές όπως fdisk -l. Ωστόσο, σε κακώς ρυθμισμένη εντολή docker όπου η σημαία --privileged
ή --device=/dev/sda1
με κεφαλαία έχει καθοριστεί, είναι δυνατόν να αποκτήσετε τα δικαιώματα για να δείτε τον δίσκο του host.
Έτσι, για να αναλάβετε τη μηχανή host, είναι απλό:
Και να το! Τώρα μπορείτε να έχετε πρόσβαση στο σύστημα αρχείων του κεντρικού υπολογιστή επειδή είναι τοποθετημένο στον φάκελο /mnt/hola
.
Μέσα στο κοντέινερ, ένας επιτιθέμενος μπορεί να προσπαθήσει να αποκτήσει περαιτέρω πρόσβαση στο υποκείμενο λειτουργικό σύστημα του κεντρικού υπολογιστή μέσω ενός εγγράψιμου hostPath volume που δημιουργήθηκε από το cluster. Παρακάτω είναι μερικά κοινά πράγματα που μπορείτε να ελέγξετε μέσα στο κοντέινερ για να δείτε αν μπορείτε να εκμεταλλευτείτε αυτόν τον επιθετικό διανύσμα:
Βρείτε μια εξήγηση της τεχνικής στο:
Στις προηγούμενες εκμεταλλεύσεις, η απόλυτη διαδρομή του κοντέινερ μέσα στο σύστημα αρχείων του host αποκαλύπτεται. Ωστόσο, αυτό δεν ισχύει πάντα. Σε περιπτώσεις όπου δεν γνωρίζετε την απόλυτη διαδρομή του κοντέινερ μέσα στον host, μπορείτε να χρησιμοποιήσετε αυτή την τεχνική:
Η εκτέλεση του PoC μέσα σε ένα προνομιούχο κοντέινερ θα πρέπει να παρέχει έξοδο παρόμοια με:
Υπάρχουν αρκετά αρχεία που μπορεί να είναι προσαρτημένα και να δίνουν πληροφορίες για τον υποκείμενο host. Ορισμένα από αυτά μπορεί ακόμη να υποδεικνύουν κάτι που θα εκτελείται από τον host όταν συμβεί κάτι (το οποίο θα επιτρέψει σε έναν επιτιθέμενο να διαφύγει από το κοντέινερ). Η κακή χρήση αυτών των αρχείων μπορεί να επιτρέψει:
release_agent (έχει καλυφθεί ήδη πριν)
Ωστόσο, μπορείτε να βρείτε άλλα ευαίσθητα αρχεία για να ελέγξετε σε αυτή τη σελίδα:
Σε πολλές περιπτώσεις θα διαπιστώσετε ότι το κοντέινερ έχει κάποιον όγκο προσαρτημένο από τον host. Εάν αυτός ο όγκος δεν έχει ρυθμιστεί σωστά, μπορεί να είστε σε θέση να πρόσβαση/τροποποιήσετε ευαίσθητα δεδομένα: Διαβάστε μυστικά, αλλάξτε ssh authorized_keys…
Αν έχετε πρόσβαση ως root μέσα σε ένα κοντέινερ που έχει κάποιον φάκελο από τον host τοποθετημένο και έχετε διαφύγει ως μη προνομιούχος χρήστης στον host και έχετε δικαιώματα ανάγνωσης πάνω από τον τοποθετημένο φάκελο. Μπορείτε να δημιουργήσετε ένα bash suid αρχείο στον τοποθετημένο φάκελο μέσα στο κοντέινερ και να το εκτελέσετε από τον host για privesc.
If you have access as root inside a container and you have escaped as a non privileged user to the host, you can abuse both shells to privesc inside the host if you have the capability MKNOD inside the container (it's by default) as explained in this post. With such capability the root user within the container is allowed to create block device files. Device files are special files that are used to access underlying hardware & kernel modules. For example, the /dev/sda block device file gives access to read the raw data on the systems disk.
Docker safeguards against block device misuse within containers by enforcing a cgroup policy that blocks block device read/write operations. Nevertheless, if a block device is created inside the container, it becomes accessible from outside the container via the /proc/PID/root/ directory. This access requires the process owner to be the same both inside and outside the container.
Exploitation example from this writeup:
Αν μπορείτε να έχετε πρόσβαση στις διεργασίες του host, θα μπορείτε να αποκτήσετε πρόσβαση σε πολλές ευαίσθητες πληροφορίες που είναι αποθηκευμένες σε αυτές τις διεργασίες. Εκτελέστε το εργαστήριο δοκιμών:
Για παράδειγμα, θα μπορείτε να καταγράψετε τις διεργασίες χρησιμοποιώντας κάτι όπως ps auxn
και να αναζητήσετε ευαίσθητες λεπτομέρειες στις εντολές.
Στη συνέχεια, καθώς μπορείτε να έχετε πρόσβαση σε κάθε διεργασία του host στο /proc/ μπορείτε απλά να κλέψετε τα env secrets τους εκτελώντας:
Μπορείτε επίσης να έχετε πρόσβαση στους περιγραφείς αρχείων άλλων διεργασιών και να διαβάσετε τα ανοιχτά τους αρχεία:
Μπορείτε επίσης να τερματίσετε διεργασίες και να προκαλέσετε DoS.
Εάν έχετε κάπως προνομιακή πρόσβαση σε μια διεργασία εκτός του κοντέινερ, θα μπορούσατε να εκτελέσετε κάτι όπως nsenter --target <pid> --all
ή nsenter --target <pid> --mount --net --pid --cgroup
για να εκτελέσετε ένα shell με τους ίδιους περιορισμούς ns (ελπίζουμε κανέναν) όπως αυτή η διεργασία.
Αν ένα κοντέινερ έχει ρυθμιστεί με τον Docker host networking driver (--network=host
), το δίκτυο του κοντέινερ δεν είναι απομονωμένο από τον Docker host (το κοντέινερ μοιράζεται το namespace δικτύου του host) και το κοντέινερ δεν αποκτά τη δική του διεύθυνση IP. Με άλλα λόγια, το κοντέινερ δένει όλες τις υπηρεσίες απευθείας στη διεύθυνση IP του host. Επιπλέον, το κοντέινερ μπορεί να παρακολουθεί ΟΛΗ την κυκλοφορία δικτύου που στέλνει και λαμβάνει ο host στην κοινή διεπαφή tcpdump -i eth0
.
Για παράδειγμα, μπορείτε να το χρησιμοποιήσετε για να παρακολουθήσετε και ακόμη και να παραποιήσετε την κυκλοφορία μεταξύ του host και της μεταδεδομένων.
Όπως στα παρακάτω παραδείγματα:
Θα μπορείτε επίσης να έχετε πρόσβαση σε υπηρεσίες δικτύου που είναι δεσμευμένες στο localhost μέσα στον host ή ακόμη και να έχετε πρόσβαση στις άδειες μεταδεδομένων του κόμβου (οι οποίες μπορεί να είναι διαφορετικές από αυτές που μπορεί να έχει πρόσβαση ένα κοντέινερ).
Με το hostIPC=true
, αποκτάτε πρόσβαση στους πόρους επικοινωνίας διεργασιών (IPC) του host, όπως η κοινή μνήμη στο /dev/shm
. Αυτό επιτρέπει την ανάγνωση/εγγραφή όπου οι ίδιοι πόροι IPC χρησιμοποιούνται από άλλες διεργασίες host ή pod. Χρησιμοποιήστε το ipcs
για να εξετάσετε περαιτέρω αυτούς τους μηχανισμούς IPC.
Εξετάστε το /dev/shm - Αναζητήστε οποιαδήποτε αρχεία σε αυτήν την τοποθεσία κοινής μνήμης: ls -la /dev/shm
Εξετάστε τις υπάρχουσες εγκαταστάσεις IPC – Μπορείτε να ελέγξετε αν χρησιμοποιούνται οποιεσδήποτε εγκαταστάσεις IPC με το /usr/bin/ipcs
. Ελέγξτε το με: ipcs -a
Εάν η syscall unshare
δεν απαγορεύεται, μπορείτε να ανακτήσετε όλες τις δυνατότητες εκτελώντας:
Η δεύτερη τεχνική που εξηγείται στην ανάρτηση https://labs.withsecure.com/blog/abusing-the-access-to-mount-namespaces-through-procpidroot/ υποδεικνύει πώς μπορείτε να καταχραστείτε τις bind mounts με user namespaces, για να επηρεάσετε αρχεία μέσα στον host (σε αυτή την συγκεκριμένη περίπτωση, να διαγράψετε αρχεία).
Χρησιμοποιήστε Trickest για να δημιουργήσετε και να αυτοματοποιήσετε ροές εργασίας που υποστηρίζονται από τα πιο προηγμένα εργαλεία της κοινότητας. Αποκτήστε πρόσβαση σήμερα:
Σε περίπτωση που μπορείτε να εκτελέσετε docker exec
ως root (πιθανώς με sudo), προσπαθήστε να κλιμακώσετε τα δικαιώματα σας ξεφεύγοντας από ένα container καταχρώντας το CVE-2019-5736 (εκμετάλλευση εδώ). Αυτή η τεχνική θα επικαλύψει το /bin/sh δυαδικό αρχείο του host από ένα container, έτσι οποιοσδήποτε εκτελεί docker exec μπορεί να ενεργοποιήσει το payload.
Αλλάξτε το payload αναλόγως και κατασκευάστε το main.go με go build main.go
. Το προκύπτον δυαδικό αρχείο θα πρέπει να τοποθετηθεί στο docker container για εκτέλεση.
Κατά την εκτέλεση, μόλις εμφανιστεί το [+] Overwritten /bin/sh successfully
πρέπει να εκτελέσετε το εξής από τη μηχανή host:
docker exec -it <container-name> /bin/sh
Αυτό θα ενεργοποιήσει το payload που είναι παρόν στο αρχείο main.go.
Για περισσότερες πληροφορίες: https://blog.dragonsector.pl/2019/02/cve-2019-5736-escape-from-docker-and.html
Υπάρχουν άλλες CVEs στις οποίες το container μπορεί να είναι ευάλωτο, μπορείτε να βρείτε μια λίστα στο https://0xn3va.gitbook.io/cheat-sheets/container/escaping/cve-list
Namespaces: Η διαδικασία θα πρέπει να είναι εντελώς απομονωμένη από άλλες διαδικασίες μέσω namespaces, έτσι δεν μπορούμε να ξεφύγουμε αλληλεπιδρώντας με άλλες διαδικασίες λόγω namespaces (κατά προεπιλογή δεν μπορούν να επικοινωνούν μέσω IPCs, unix sockets, υπηρεσιών δικτύου, D-Bus, /proc
άλλων διαδικασιών).
Χρήστης root: Κατά προεπιλογή, ο χρήστης που εκτελεί τη διαδικασία είναι ο χρήστης root (ωστόσο τα δικαιώματά του είναι περιορισμένα).
Δυνατότητες: Το Docker αφήνει τις εξής δυνατότητες: cap_chown,cap_dac_override,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_net_bind_service,cap_net_raw,cap_sys_chroot,cap_mknod,cap_audit_write,cap_setfcap=ep
Syscalls: Αυτές είναι οι syscalls που ο χρήστης root δεν θα μπορεί να καλέσει (λόγω έλλειψης δυνατοτήτων + Seccomp). Οι άλλες syscalls θα μπορούσαν να χρησιμοποιηθούν για να προσπαθήσουν να ξεφύγουν.
If you are in userspace (no kernel exploit involved) the way to find new escapes mainly involve the following actions (these templates usually require a container in privileged mode):
Find the path of the containers filesystem inside the host
You can do this via mount, or via brute-force PIDs as explained in the second release_agent exploit
Find some functionality where you can indicate the path of a script to be executed by a host process (helper) if something happens
You should be able to execute the trigger from inside the host
You need to know where the containers files are located inside the host to indicate a script you write inside the host
Have enough capabilities and disabled protections to be able to abuse that functionality
You might need to mount things o perform special privileged actions you cannot do in a default docker container
Use Trickest to easily build and automate workflows powered by the world's most advanced community tools. Get Access Today:
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)