Docker Breakout / Privilege Escalation
Last updated
Last updated
Dowiedz się i ćwicz Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE) Dowiedz się i ćwicz Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)
Użyj Trickest do łatwego tworzenia i automatyzacji prac z wykorzystaniem najbardziej zaawansowanych narzędzi społeczności. Zdobądź dostęp już dziś:
linpeas: Może również wyliczać kontenery
CDK: To narzędzie jest dość przydatne do wyliczania kontenera, w którym się znajdujesz, a nawet próby automatycznej ucieczki
amicontained: Przydatne narzędzie do uzyskania uprawnień kontenera w celu znalezienia sposobów ucieczki z niego
deepce: Narzędzie do wyliczania i ucieczki z kontenerów
grype: Pobierz CVE zawarte w oprogramowaniu zainstalowanym w obrazie
Jeśli w jakiś sposób zauważysz, że gniazdo dockera jest zamontowane wewnątrz kontenera dockera, będziesz mógł z niego uciec. Zazwyczaj dzieje się to w kontenerach dockera, które z jakiegoś powodu muszą połączyć się z demonem dockera, aby wykonać akcje.
W tym przypadku możesz używać zwykłych poleceń docker do komunikacji z demonem dockera:
W przypadku, gdy gniazdo dockerowe znajduje się w nieoczekiwanym miejscu, nadal możesz się z nim komunikować, używając polecenia docker
z parametrem -H unix:///ścieżka/do/docker.sock
Docker daemon 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ę za pomocą gniazda Systemd fd://
.
Dodatkowo zwróć uwagę na gniazda uruchomieniowe innych środowisk uruchomieniowych:
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ć uprawnienia kontenera, jeśli ma któreś z następujących, możesz z niego uciec: 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ć obecne uprawnienia kontenera za pomocą wcześniej wspomnianych narzędzi automatycznych lub:
Na następnej stronie możesz dowiedzieć się więcej o zdolnościach systemu Linux i jak je wykorzystać do ucieczki/escalacji uprawnień:
Uprzywilejowany kontener może być utworzony z flagą --privileged
lub wyłączeniem 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
znacząco 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ą dotyczącą pełnych skutków użycia --privileged
.
Dzięki tym uprawnieniom możesz po prostu przejść do przestrzeni nazw procesu uruchomionego na hoście jako root, na przykład init (pid:1), wykonując po prostu: nsenter --target 1 --mount --uts --ipc --net --pid -- bash
Wypróbuj to w kontenerze wykonując:
Tylko dzięki flagowi privileged możesz spróbować uzyskać dostęp do dysku hosta lub spróbować uciec, wykorzystując release_agent lub inne ucieczki.
Przetestuj następujące obejścia w kontenerze wykonując:
Poprawnie skonfigurowane kontenery Docker nie pozwolą na wykonanie komendy takiej jak fdisk -l. Jednakże w przypadku błędnie skonfigurowanej komendy Docker, gdzie flaga --privileged
lub --device=/dev/sda1
z uprawnieniami jest określona, możliwe jest uzyskanie uprawnień do przeglądania dysku hosta.
Więc przejęcie maszyny hosta jest trywialne:
I oto jest! Teraz możesz uzyskać dostęp do systemu plików hosta, ponieważ jest on zamontowany w folderze /mnt/hola
.
Wewnątrz kontenera atakujący może próbować uzyskać dalszy dostęp do systemu operacyjnego hosta poprzez zapisywalny wolumin hostPath utworzony przez klaster. Poniżej znajdziesz kilka powszechnych rzeczy, które możesz sprawdzić wewnątrz kontenera, aby zobaczyć, czy wykorzystasz ten wektor ataku:
Znajdź wyjaśnienie techniki w:
W poprzednich atakach ujawniona jest bezwzględna ścieżka kontenera w systemie hosta. Jednak nie zawsze jest to przypadkiem. W sytuacjach, gdy nie znasz bezwzględnej ścieżki kontenera w systemie hosta, możesz skorzystać z tej techniki:
Wykonanie PoC w uprzywilejowanym kontenerze powinno dostarczyć wynik podobny do:
Istnieje kilka plików, które mogą być zamontowane i dają informacje o hostingu podstawowym. Niektóre z nich mogą nawet wskazywać na coś, co ma być wykonane przez hosta, gdy coś się stanie (co pozwoli atakującemu uciec z kontenera). Nadużycie tych plików może spowodować, że:
release_agent (już omówiony wcześniej)
Możesz jednak znaleźć inne wrażliwe pliki, które warto sprawdzić na tej stronie:
W wielu przypadkach zauważysz, że kontener ma pewien wolumin zamontowany z hosta. Jeśli ten wolumin nie został poprawnie skonfigurowany, możesz uzyskać dostęp/modyfikować wrażliwe dane: Odczytywać tajemnice, zmieniać ssh authorized_keys...
Jeśli masz dostęp jako root wewnątrz kontenera, który ma pewny folder z hosta zamontowany i uciekłeś jako użytkownik bez uprawnień do hosta i masz dostęp do odczytu w zamontowanym folderze. Możesz utworzyć plik bash suid w zamontowanym folderze wewnątrz kontenera i wykonać go z hosta w celu eskalacji uprawnień.
Jeśli masz dostęp jako root wewnątrz kontenera i udało ci się wydostać jako użytkownik bez uprawnień do hosta, możesz wykorzystać obie powłoki do eskalcji uprawnień wewnątrz hosta, jeśli masz zdolność MKNOD wewnątrz kontenera (domyślnie jest dostępna) jak wyjaśniono w tym poście. Dzięki tej zdolności użytkownik root wewnątrz kontenera może tworzyć pliki urządzeń blokowych. Pliki urządzeń są specjalnymi plikami używanymi do dostępu do sprzętu i modułów jądra. Na przykład plik urządzenia blokowego /dev/sda umożliwia odczytanie surowych danych na dysku systemowym.
Docker zabezpiecza przed nadużyciem plików urządzeń blokowych wewnątrz kontenerów, stosując politykę cgroup, która blokuje operacje odczytu/zapisu na plikach urządzeń blokowych. Niemniej jednak, jeśli plik urządzenia blokowego jest utworzony wewnątrz kontenera, staje się on dostępny z zewnątrz kontenera poprzez katalog /proc/PID/root/. Ten dostęp wymaga, aby właścicielem procesu był ten sam zarówno wewnątrz, jak i na zewnątrz kontenera.
Przykład wykorzystania z tego opisu:
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 testowe laboratorium:
Na przykład, będziesz mógł wyświetlić procesy, używając czegoś w stylu ps auxn
i szukać w poleceniach poufnych informacji.
Następnie, ponieważ możesz uzyskać dostęp do każdego procesu hosta w /proc/, możesz po prostu ukraść ich tajne zmienne środowiskowe wykonują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ś w rodzaju nsenter --target <pid> --all
lub nsenter --target <pid> --mount --net --pid --cgroup
aby uruchomić powłokę z tymi samymi ograniczeniami ns (oby żadne) jak ten proces.
Jeśli kontener został skonfigurowany z sterownikiem sieci hosta Dockera (--network=host
), stos sieciowy tego kontenera nie jest izolowany od hosta Dockera (kontener dzieli przestrzeń sieciową hosta), i kontener nie otrzymuje przydzielonego własnego adresu IP. Innymi słowy, kontener łączy 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żna użyć tego do przechwytywania i nawet podszywania się pod ruch między hostem a instancją metadanych.
Tak jak w poniższych przykładach:
Będziesz również mógł uzyskać dostęp do usług sieciowych powiązanych z localhostem wewnątrz hosta lub nawet uzyskać dostęp do uprawnień metadanych węzła (które mogą być inne niż te, do których dostęp ma kontener).
Z hostIPC=true
uzyskujesz dostęp do zasobów komunikacji międzyprocesowej (IPC) hosta, takich jak pamięć współdzielona w /dev/shm
. Pozwala to na odczyt/zapis tam, gdzie te same zasoby IPC są używane przez inne procesy hosta lub moduły. Użyj ipcs
, aby dokładniej zbadać te mechanizmy IPC.
Sprawdź /dev/shm - Sprawdź, czy istnieją jakieś pliki w tym miejscu pamięci współdzielonej: ls -la /dev/shm
Sprawdź istniejące obiekty IPC - Możesz sprawdzić, czy jakiekolwiek obiekty IPC są używane za pomocą /usr/bin/ipcs
. Sprawdź to poleceniem: ipcs -a
Jeśli wywołanie systemowe unshare
nie jest zabronione, możesz odzyskać wszystkie uprawnienia, uruchamiając:
Druga technika wyjaśniona w poście https://labs.withsecure.com/blog/abusing-the-access-to-mount-namespaces-through-procpidroot/ wskazuje, jak można nadużyć powiązanych montaży 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. Otrzymaj dostęp już dziś:
W przypadku, gdy możesz wykonać docker exec
jako root (prawdopodobnie z sudo), możesz próbować eskalować uprawnienia uciekając z kontenera, nadużywając CVE-2019-5736 (wykorzystaj tutaj). Ta technika polega głównie na nadpisaniu binarnego pliku /bin/sh hosta z kontenera, dzięki czemu każdy wykonujący docker exec może uruchomić ładunek.
Zmień ładunek odpowiednio i skompiluj main.go za pomocą go build main.go
. Wynikowy plik binarny powinien być umieszczony w kontenerze docker do wykonania.
Po wykonaniu, gdy wyświetli [+] Pomyślnie nadpisano /bin/sh
, musisz wykonać następujące polecenie z maszyny hosta:
docker exec -it <nazwa-kontenera> /bin/sh
Spowoduje to uruchomienie ładunku obecnego w pliku main.go.
Więcej informacji: https://blog.dragonsector.pl/2019/02/cve-2019-5736-escape-from-docker-and.html
Kontener może być podatny na inne CVE, można znaleźć listę pod tym linkiem
Przestrzenie nazw: Proces powinien być całkowicie oddzielony od innych procesów za pomocą przestrzeni nazw, więc nie możemy uciec interakcji z innymi procesami ze względu na przestrzenie nazw (domyślnie nie można 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).
Uprawnienia: Docker pozostawia następujące uprawnienia: 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
Syscalle: To są syscalle, których użytkownik root nie będzie mógł wywołać (ze względu na brak uprawnień + Seccomp). Inne syscalle mogą być użyte do próby ucieczki.
Opis
Ten skrypt Pythona pozwala na eskalację uprawnień w kontenerze Docker, umożliwiając dostęp do hosta.
Użycie
Uruchom skrypt na kontenerze Docker z uprawnieniami root:
Wymagania
Python 2.7 lub 3.x
Dostęp do kontenera Docker z uprawnieniami root
Sposób działania
Wykorzystuje błąd w mechanizmie montowania systemu plików Docker.
Tworzy plik suid w systemie plików hosta.
Uruchamia nowy kontener z opcją montowania systemu plików hosta.
Wykorzystuje plik suid do uzyskania dostępu roota na hoście.
Zabezpieczenia
Ogranicz uprawnienia kontenerów Docker.
Regularnie aktualizuj system Docker.
Monitoruj działania podejrzane w kontenerach.
Autor
John Doe
Licencja
Ten skrypt jest udostępniony na licencji MIT. Możesz dowolnie go używać, zmieniać i rozpowszechniać.
Wzrost uprawnień w kontenerze Docker może być osiągnięty poprzez wykorzystanie błędu w systemie plików `overlayfs`. Ten atak wymaga dostępu do kontenera Docker z uprawnieniami `CAP_SYS_ADMIN`. Atakujący może skorzystać z tego błędu, aby uzyskać dostęp do hosta i zwiększyć swoje uprawnienia. Aby przeprowadzić ten atak, należy skompilować i uruchomić poniższy kod.
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)