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: Może również enumerować kontenery
CDK: To narzędzie jest dość przydatne do enumeracji kontenera, w którym się znajdujesz, a nawet próby automatycznego ucieczki
amicontained: Przydatne narzędzie do uzyskania uprawnień, jakie ma kontener, aby znaleźć sposoby na ucieczkę z niego
deepce: Narzędzie do enumeracji i ucieczki z kontenerów
grype: Uzyskaj CVE zawarte w oprogramowaniu zainstalowanym w obrazie
Jeśli w jakiś sposób odkryjesz, że gniazdo docker jest zamontowane wewnątrz kontenera docker, będziesz mógł z niego uciec. Zwykle zdarza się to w kontenerach docker, które z jakiegoś powodu muszą łączyć się z demonem docker, aby wykonać działania.
W tym przypadku możesz użyć standardowych poleceń docker do komunikacji z demonem dockera:
W przypadku gdy gniazdo dockera znajduje się w nieoczekiwanym miejscu, nadal możesz się z nim komunikować, używając polecenia docker
z parametrem -H unix:///path/to/docker.sock
Demon Dockera może również nasłuchiwać na porcie (domyślnie 2375, 2376) lub w systemach opartych na Systemd, komunikacja z demonem Dockera może odbywać się przez gniazdo Systemd fd://
.
Dodatkowo zwróć uwagę na gniazda uruchomieniowe innych wysokopoziomowych środowisk:
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
...
Powinieneś sprawdzić możliwości kontenera, jeśli ma którąkolwiek z następujących: 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
Możesz sprawdzić aktualne możliwości kontenera, używając wcześniej wspomnianych automatycznych narzędzi lub:
Na poniższej stronie możesz dowiedzieć się więcej o możliwościach linuxa i jak je nadużywać, aby uciec/escalować uprawnienia:
Linux CapabilitiesUprzywilejowany kontener może być stworzony z flagą --privileged
lub poprzez wyłączenie konkretnych zabezpieczeń:
--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
Flaga --privileged
znacznie obniża bezpieczeństwo kontenera, oferując nieograniczony dostęp do urządzeń i omijając kilka zabezpieczeń. Aby uzyskać szczegółowy opis, zapoznaj się z dokumentacją na temat pełnych skutków --privileged
.
Z tymi uprawnieniami możesz po prostu przenieść się do przestrzeni nazw procesu działającego na hoście jako root jak init (pid:1) po prostu uruchamiając: nsenter --target 1 --mount --uts --ipc --net --pid -- bash
Przetestuj to w kontenerze wykonując:
Tylko z flagą privileged możesz spróbować uzyskać dostęp do dysku hosta lub spróbować uciec, wykorzystując release_agent lub inne metody ucieczki.
Przetestuj następujące obejścia w kontenerze, wykonując:
Dobrze skonfigurowane kontenery docker nie pozwolą na polecenia takie jak fdisk -l. Jednak w przypadku źle skonfigurowanego polecenia docker, gdzie określono flagę --privileged
lub --device=/dev/sda1
z uprawnieniami, możliwe jest uzyskanie uprawnień do zobaczenia dysku hosta.
Aby przejąć maszynę hosta, jest to trywialne:
And voilà ! Możesz teraz uzyskać dostęp do systemu plików hosta, ponieważ jest zamontowany w folderze /mnt/hola
.
W obrębie kontenera, atakujący może próbować uzyskać dalszy dostęp do podstawowego systemu operacyjnego hosta za pomocą zapisywalnej objętości hostPath utworzonej przez klaster. Poniżej znajdują się niektóre powszechne rzeczy, które możesz sprawdzić w kontenerze, aby zobaczyć, czy możesz wykorzystać ten wektor ataku:
Znajdź wyjaśnienie techniki w:
Docker release_agent cgroups escapeW poprzednich exploitach ujawniona jest absolutna ścieżka kontenera wewnątrz systemu plików hosta. Jednak nie zawsze tak jest. W przypadkach, gdy nie znasz absolutnej ścieżki kontenera wewnątrz hosta, możesz użyć tej techniki:
release_agent exploit - Relative Paths to PIDsWykonanie PoC w uprzywilejowanym kontenerze powinno dać wynik podobny do:
Istnieje kilka plików, które mogą być zamontowane i które dają informacje o podstawowym hoście. Niektóre z nich mogą nawet wskazywać coś, co ma być wykonane przez hosta, gdy coś się wydarzy (co pozwoli atakującemu uciec z kontenera). Nadużycie tych plików może pozwolić na:
release_agent (już omówione wcześniej)
Jednak możesz znaleźć inne wrażliwe pliki, które warto sprawdzić na tej stronie:
Sensitive MountsW kilku przypadkach zauważysz, że kontener ma zamontowany jakiś wolumin z hosta. Jeśli ten wolumin nie został poprawnie skonfigurowany, możesz być w stanie uzyskać dostęp/modyfikować wrażliwe dane: Czytać sekrety, zmieniać ssh authorized_keys…
Jeśli masz dostęp jako root wewnątrz kontenera, który ma zamontowany jakiś folder z hosta i udało ci się uciec jako użytkownik bez uprawnień do hosta oraz masz dostęp do odczytu zamontowanego folderu. Możesz stworzyć plik bash suid w zamontowanym folderze wewnątrz kontenera i wykonać go z hosta, aby uzyskać wyższe uprawnienia.
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 zabezpiecza przed niewłaściwym użyciem urządzeń blokowych w kontenerach, egzekwując politykę cgroup, która blokuje operacje odczytu/zapisu urządzeń blokowych. Niemniej jednak, jeśli urządzenie blokowe jest utworzone wewnątrz kontenera, staje się dostępne z zewnątrz kontenera poprzez katalog /proc/PID/root/. Ten dostęp wymaga, aby właściciel procesu był taki sam zarówno wewnątrz, jak i na zewnątrz kontenera.
Exploitation example from this writeup:
Jeśli masz dostęp do procesów hosta, będziesz mógł uzyskać dostęp do wielu wrażliwych informacji przechowywanych w tych procesach. Uruchom laboratorium testowe:
Na przykład, będziesz mógł wylistować procesy używając czegoś takiego jak ps auxn
i szukać wrażliwych szczegółów w poleceniach.
Następnie, ponieważ masz dostęp do każdego procesu hosta w /proc/, możesz po prostu ukraść ich sekrety środowiskowe uruchamiając:
Możesz również uzyskać dostęp do deskryptorów plików innych procesów i odczytać ich otwarte pliki:
Możesz również zabić procesy i spowodować DoS.
Jeśli w jakiś sposób masz uprzywilejowany dostęp do procesu poza kontenerem, możesz uruchomić coś takiego jak nsenter --target <pid> --all
lub nsenter --target <pid> --mount --net --pid --cgroup
, aby uruchomić powłokę z tymi samymi ograniczeniami ns (mam nadzieję, że żadnymi) jak ten proces.
Jeśli kontener został skonfigurowany z użyciem Docker host networking driver (--network=host
), stos sieciowy tego kontenera nie jest izolowany od hosta Docker (kontener dzieli przestrzeń nazw sieciową hosta), a kontener nie otrzymuje przydzielonego własnego adresu IP. Innymi słowy, kontener wiąże wszystkie usługi bezpośrednio z adresem IP hosta. Ponadto kontener może przechwytywać WSZYSTKI ruch sieciowy, który host wysyła i odbiera na współdzielonym interfejsie tcpdump -i eth0
.
Na przykład, możesz to wykorzystać do podsłuchiwania, a nawet fałszowania ruchu między hostem a instancją metadanych.
Jak w poniższych przykładach:
Będziesz mógł również uzyskać dostęp do usług sieciowych powiązanych z localhost wewnątrz hosta lub nawet uzyskać dostęp do uprawnień metadanych węzła (które mogą różnić się od tych, do których może uzyskać dostęp kontener).
Z hostIPC=true
zyskujesz dostęp do zasobów komunikacji międzyprocesowej (IPC) hosta, takich jak pamięć dzielona w /dev/shm
. Umożliwia to odczyt/zapis, gdzie te same zasoby IPC są używane przez inne procesy hosta lub pod. Użyj ipcs
, aby dokładniej zbadać te mechanizmy IPC.
Zbadaj /dev/shm - Sprawdź, czy są jakiekolwiek pliki w tej lokalizacji pamięci dzielonej: ls -la /dev/shm
Zbadaj istniejące obiekty IPC – Możesz sprawdzić, czy jakiekolwiek obiekty IPC są używane za pomocą /usr/bin/ipcs
. Sprawdź to za pomocą: ipcs -a
Jeśli wywołanie systemowe unshare
nie jest zabronione, możesz przywrócić wszystkie uprawnienia, uruchamiając:
Druga technika opisana w poście https://labs.withsecure.com/blog/abusing-the-access-to-mount-namespaces-through-procpidroot/ wskazuje, jak można nadużyć montowania powiązań z przestrzeniami nazw użytkownika, aby wpłynąć na pliki wewnątrz hosta (w tym konkretnym przypadku, usunąć pliki).
Użyj Trickest, aby łatwo budować i automatyzować przepływy pracy zasilane przez najbardziej zaawansowane narzędzia społecznościowe na świecie. Uzyskaj dostęp już dziś:
W przypadku, gdy możesz wykonać docker exec
jako root (prawdopodobnie z sudo), spróbuj podnieść uprawnienia, uciekając z kontenera, nadużywając CVE-2019-5736 (eksploit tutaj). Ta technika zasadniczo nadpisze binarny plik /bin/sh hosta z kontenera, więc każdy, kto wykonuje docker exec, może uruchomić ładunek.
Zmień ładunek odpowiednio i zbuduj main.go za pomocą go build main.go
. Otrzymany plik binarny powinien być umieszczony w kontenerze docker do wykonania.
Po wykonaniu, gdy tylko wyświetli [+] Overwritten /bin/sh successfully
, musisz wykonać następujące polecenie z maszyny hosta:
docker exec -it <nazwa-kontenera> /bin/sh
To uruchomi ładunek, który jest obecny w pliku main.go.
Aby uzyskać więcej informacji: https://blog.dragonsector.pl/2019/02/cve-2019-5736-escape-from-docker-and.html
Istnieją inne CVE, na które kontener może być podatny, możesz znaleźć listę w https://0xn3va.gitbook.io/cheat-sheets/container/escaping/cve-list
Przestrzenie nazw: Proces powinien być całkowicie oddzielony od innych procesów za pomocą przestrzeni nazw, więc nie możemy uciec, wchodząc w interakcję z innymi procesami z powodu przestrzeni nazw (domyślnie nie mogą komunikować się za pomocą IPC, gniazd unixowych, usług sieciowych, D-Bus, /proc
innych procesów).
Użytkownik root: Domyślnie użytkownik uruchamiający proces to użytkownik root (jednak jego uprawnienia są ograniczone).
Możliwości: Docker pozostawia następujące możliwości: 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: To są syscalls, które użytkownik root nie będzie mógł wywołać (z powodu braku możliwości + Seccomp). Inne syscalls mogą być użyte do próby ucieczki.
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)