Linux Capabilities
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)
RootedCON to najważniejsze wydarzenie związane z cyberbezpieczeństwem w Hiszpanii i jedno z najważniejszych w Europie. Z misją promowania wiedzy technicznej, ten kongres jest gorącym punktem spotkań dla profesjonalistów z dziedziny technologii i cyberbezpieczeństwa w każdej dyscyplinie.\
Linux capabilities dzielą uprawnienia roota na mniejsze, odrębne jednostki, pozwalając procesom na posiadanie podzbioru uprawnień. Minimalizuje to ryzyko, nie przyznając niepotrzebnie pełnych uprawnień roota.
Zwykli użytkownicy mają ograniczone uprawnienia, co wpływa na zadania takie jak otwieranie gniazda sieciowego, które wymaga dostępu roota.
Inherited (CapInh):
Cel: Określa uprawnienia przekazywane z procesu nadrzędnego.
Funkcjonalność: Gdy tworzony jest nowy proces, dziedziczy on uprawnienia z procesu nadrzędnego w tym zestawie. Przydatne do utrzymania pewnych uprawnień podczas uruchamiania procesów.
Ograniczenia: Proces nie może uzyskać uprawnień, których nie posiadał jego proces nadrzędny.
Effective (CapEff):
Cel: Reprezentuje rzeczywiste uprawnienia, które proces wykorzystuje w danym momencie.
Funkcjonalność: To zestaw uprawnień sprawdzany przez jądro w celu przyznania zgody na różne operacje. Dla plików, ten zestaw może być flagą wskazującą, czy dozwolone uprawnienia pliku mają być uznawane za skuteczne.
Znaczenie: Zestaw skuteczny jest kluczowy dla natychmiastowych kontroli uprawnień, działając jako aktywny zestaw uprawnień, które proces może wykorzystać.
Permitted (CapPrm):
Cel: Definiuje maksymalny zestaw uprawnień, które proces może posiadać.
Funkcjonalność: Proces może podnieść uprawnienie z zestawu dozwolonego do swojego zestawu skutecznego, dając mu możliwość użycia tego uprawnienia. Może również zrezygnować z uprawnień z zestawu dozwolonego.
Granica: Działa jako górna granica dla uprawnień, które proces może mieć, zapewniając, że proces nie przekroczy swojego zdefiniowanego zakresu uprawnień.
Bounding (CapBnd):
Cel: Ustala sufit dla uprawnień, które proces może kiedykolwiek nabyć w trakcie swojego cyklu życia.
Funkcjonalność: Nawet jeśli proces ma określone uprawnienie w swoim zestawie dziedzicznym lub dozwolonym, nie może nabyć tego uprawnienia, chyba że jest ono również w zestawie ograniczającym.
Przykład użycia: Ten zestaw jest szczególnie przydatny do ograniczania potencjału eskalacji uprawnień procesu, dodając dodatkową warstwę bezpieczeństwa.
Ambient (CapAmb):
Cel: Pozwala na utrzymanie niektórych uprawnień podczas wywołania systemowego execve
, które zazwyczaj skutkowałoby pełnym resetem uprawnień procesu.
Funkcjonalność: Zapewnia, że programy nie-SUID, które nie mają związanych uprawnień plików, mogą zachować pewne uprawnienia.
Ograniczenia: Uprawnienia w tym zestawie podlegają ograniczeniom zestawów dziedzicznych i dozwolonych, zapewniając, że nie przekraczają one dozwolonych uprawnień procesu.
For further information check:
Aby zobaczyć możliwości dla konkretnego procesu, użyj pliku status w katalogu /proc. Ponieważ dostarcza więcej szczegółów, ograniczmy się tylko do informacji związanych z możliwościami Linuxa. Zauważ, że dla wszystkich działających procesów informacje o możliwościach są utrzymywane na poziomie wątku, a dla binariów w systemie pliki są przechowywane w atrybutach rozszerzonych.
Możesz znaleźć możliwości zdefiniowane w /usr/include/linux/capability.h
Możesz znaleźć możliwości bieżącego procesu w cat /proc/self/status
lub wykonując capsh --print
, a innych użytkowników w /proc/<pid>/status
To polecenie powinno zwrócić 5 linii w większości systemów.
CapInh = Dziedziczone uprawnienia
CapPrm = Dozwolone uprawnienia
CapEff = Efektywne uprawnienia
CapBnd = Zestaw ograniczający
CapAmb = Zestaw uprawnień otoczenia
Te liczby szesnastkowe nie mają sensu. Używając narzędzia capsh, możemy je zdekodować na nazwy uprawnień.
Sprawdźmy teraz capabilities używane przez ping
:
Chociaż to działa, istnieje inny, łatwiejszy sposób. Aby zobaczyć możliwości działającego procesu, po prostu użyj narzędzia getpcaps, a następnie jego identyfikatora procesu (PID). Możesz również podać listę identyfikatorów procesów.
Sprawdźmy tutaj możliwości tcpdump
po nadaniu binarnemu wystarczających uprawnień (cap_net_admin
i cap_net_raw
) do podsłuchiwania sieci (tcpdump działa w procesie 9562):
Jak widać, podane możliwości odpowiadają wynikom 2 sposobów uzyskiwania możliwości binarnego. Narzędzie getpcaps używa wywołania systemowego capget() do zapytania o dostępne możliwości dla konkretnego wątku. To wywołanie systemowe potrzebuje jedynie podać PID, aby uzyskać więcej informacji.
Binarne mogą mieć możliwości, które mogą być używane podczas wykonywania. Na przykład, bardzo często można znaleźć binarny ping
z możliwością cap_net_raw
:
Możesz wyszukiwać binaria z uprawnieniami za pomocą:
Jeśli zrzucimy uprawnienia CAP_NET_RAW dla ping, to narzędzie ping nie powinno już działać.
Oprócz wyjścia samego capsh, polecenie tcpdump również powinno zgłosić błąd.
/bin/bash: /usr/sbin/tcpdump: Operacja niedozwolona
Błąd wyraźnie pokazuje, że polecenie ping nie ma pozwolenia na otwarcie gniazda ICMP. Teraz mamy pewność, że to działa zgodnie z oczekiwaniami.
Możesz usunąć możliwości binarnego pliku za pomocą
Wyraźnie możliwe jest przypisanie możliwości również do użytkowników. To prawdopodobnie oznacza, że każdy proces wykonywany przez użytkownika będzie mógł korzystać z możliwości użytkownika.
Na podstawie tego, tego i tego należy skonfigurować kilka plików, aby nadać użytkownikowi określone możliwości, ale plik przypisujący możliwości do każdego użytkownika to /etc/security/capability.conf
.
Przykład pliku:
Kompilując następujący program, możliwe jest uruchomienie powłoki bash w środowisku, które zapewnia możliwości.
Wewnątrz bash uruchomionego przez skompilowany binarny ambient można zaobserwować nowe możliwości (zwykły użytkownik nie będzie miał żadnej możliwości w sekcji "bieżącej").
Możesz dodawać tylko te możliwości, które są obecne zarówno w zestawie dozwolonym, jak i dziedziczonym.
Binaries świadome możliwości nie będą używać nowych możliwości nadanych przez środowisko, jednak binaries nieświadome możliwości będą je używać, ponieważ ich nie odrzucą. To sprawia, że binaries nieświadome możliwości są podatne w specjalnym środowisku, które przyznaje możliwości binarnym.
Domyślnie usługa działająca jako root będzie miała przypisane wszystkie możliwości, a w niektórych przypadkach może to być niebezpieczne. Dlatego plik konfiguracji usługi pozwala określić możliwości, które chcesz, aby miała, oraz użytkownika, który powinien uruchomić usługę, aby uniknąć uruchamiania usługi z niepotrzebnymi uprawnieniami:
Domyślnie Docker przypisuje kilka możliwości do kontenerów. Bardzo łatwo jest sprawdzić, które to możliwości, uruchamiając:
RootedCON to najważniejsze wydarzenie związane z cyberbezpieczeństwem w Hiszpanii i jedno z najważniejszych w Europie. Z misją promowania wiedzy technicznej, ten kongres jest gorącym punktem spotkań dla profesjonalistów z dziedziny technologii i cyberbezpieczeństwa w każdej dyscyplinie.
Capabilities są przydatne, gdy chcesz ograniczyć własne procesy po wykonaniu operacji z uprawnieniami (np. po skonfigurowaniu chroot i powiązaniu z gniazdem). Mogą jednak być wykorzystywane przez przekazywanie im złośliwych poleceń lub argumentów, które są następnie uruchamiane jako root.
Możesz wymusić capabilities na programach za pomocą setcap
, a zapytać o nie za pomocą getcap
:
+ep
oznacza, że dodajesz zdolność („-” usunęłoby ją) jako Efektywną i Dozwoloną.
Aby zidentyfikować programy w systemie lub folderze z zdolnościami:
W następującym przykładzie binarny plik /usr/bin/python2.6
okazuje się być podatny na privesc:
Capabilities potrzebne przez tcpdump
, aby pozwolić dowolnemu użytkownikowi na sniffing pakietów:
Z dokumentacji: Należy zauważyć, że można przypisać puste zestawy możliwości do pliku programu, a zatem możliwe jest stworzenie programu z ustawionym identyfikatorem użytkownika-root, który zmienia efektywny i zapisany identyfikator użytkownika procesu wykonującego program na 0, ale nie przyznaje żadnych możliwości temu procesowi. Innymi słowy, jeśli masz binarny plik, który:
nie jest własnością roota
nie ma ustawionych bitów SUID
/SGID
ma pusty zestaw możliwości (np.: getcap myelf
zwraca myelf =ep
)
to ta binarka będzie działać jako root.
CAP_SYS_ADMIN
to bardzo potężna możliwość w systemie Linux, często porównywana do poziomu bliskiego roota z powodu swoich rozległych uprawnień administracyjnych, takich jak montowanie urządzeń czy manipulowanie funkcjami jądra. Chociaż jest niezbędna dla kontenerów symulujących całe systemy, CAP_SYS_ADMIN
stwarza znaczące wyzwania bezpieczeństwa, szczególnie w środowiskach kontenerowych, z powodu swojego potencjału do eskalacji uprawnień i kompromitacji systemu. Dlatego jej użycie wymaga rygorystycznych ocen bezpieczeństwa i ostrożnego zarządzania, z silnym naciskiem na rezygnację z tej możliwości w kontenerach specyficznych dla aplikacji, aby przestrzegać zasady najmniejszych uprawnień i zminimalizować powierzchnię ataku.
Przykład z binarką
Używając Pythona, możesz zamontować zmodyfikowany plik passwd na prawdziwym pliku passwd:
A na koniec zamontuj zmodyfikowany plik passwd
w /etc/passwd
:
I będziesz mógł su
jako root używając hasła "password".
Przykład z środowiskiem (Docker breakout)
Możesz sprawdzić włączone możliwości wewnątrz kontenera docker za pomocą:
W poprzednim wyjściu można zobaczyć, że zdolność SYS_ADMIN jest włączona.
Mount
To pozwala kontenerowi docker na zamontowanie dysku hosta i swobodne do niego uzyskanie dostępu:
Pełny dostęp
W poprzedniej metodzie udało nam się uzyskać dostęp do dysku hosta docker. W przypadku, gdy stwierdzisz, że host uruchamia serwer ssh, możesz utworzyć użytkownika wewnątrz dysku hosta docker i uzyskać do niego dostęp przez SSH:
Oznacza to, że możesz uciec z kontenera, wstrzykując shellcode do procesu działającego w hoście. Aby uzyskać dostęp do procesów działających w hoście, kontener musi być uruchomiony przynajmniej z --pid=host
.
CAP_SYS_PTRACE
przyznaje możliwość korzystania z funkcji debugowania i śledzenia wywołań systemowych dostarczanych przez ptrace(2)
oraz wywołań cross-memory attach, takich jak process_vm_readv(2)
i process_vm_writev(2)
. Chociaż jest to potężne narzędzie do celów diagnostycznych i monitorujących, jeśli CAP_SYS_PTRACE
jest włączone bez restrykcyjnych środków, takich jak filtr seccomp na ptrace(2)
, może to znacząco osłabić bezpieczeństwo systemu. W szczególności może być wykorzystywane do obejścia innych ograniczeń bezpieczeństwa, zwłaszcza tych nałożonych przez seccomp, co zostało udowodnione przez dowody koncepcyjne (PoC) takie jak ten.
Przykład z binarką (python)
Przykład z binarnym (gdb)
gdb
z uprawnieniem ptrace
:
Utwórz shellcode za pomocą msfvenom, aby wstrzyknąć go do pamięci za pomocą gdb
Debuguj proces root za pomocą gdb i skopiuj-wklej wcześniej wygenerowane linie gdb:
Przykład z otoczeniem (wyjście z Dockera) - Inne nadużycie gdb
Jeśli GDB jest zainstalowany (lub możesz go zainstalować za pomocą apk add gdb
lub apt install gdb
, na przykład) możesz debugować proces z hosta i sprawić, by wywołał funkcję system
. (Ta technika również wymaga uprawnienia SYS_ADMIN
).
Nie będziesz w stanie zobaczyć wyniku wykonanego polecenia, ale zostanie ono wykonane przez ten proces (więc uzyskaj rev shell).
Jeśli otrzymasz błąd "No symbol "system" in current context.", sprawdź poprzedni przykład ładowania shellcode w programie za pomocą gdb.
Przykład z użyciem środowiska (Docker breakout) - Wstrzykiwanie shellcode
Możesz sprawdzić włączone możliwości wewnątrz kontenera docker za pomocą:
List procesy działające w hoście ps -eaf
Uzyskaj architekturę uname -m
Znajdź shellcode dla architektury (https://www.exploit-db.com/exploits/41128)
Znajdź program do wstrzykiwania shellcode do pamięci procesu (https://github.com/0x00pf/0x00sec_code/blob/master/mem_inject/infect.c)
Zmień shellcode w programie i skompiluj go gcc inject.c -o inject
Wstrzyknij go i zdobądź swoją powłokę: ./inject 299; nc 172.17.0.1 5600
CAP_SYS_MODULE
upoważnia proces do ładowania i usuwania modułów jądra (init_module(2)
, finit_module(2)
i delete_module(2)
system calls), oferując bezpośredni dostęp do podstawowych operacji jądra. Ta zdolność stwarza poważne zagrożenia dla bezpieczeństwa, ponieważ umożliwia eskalację uprawnień i całkowite naruszenie systemu, pozwalając na modyfikacje jądra, a tym samym omijając wszystkie mechanizmy zabezpieczeń Linuxa, w tym moduły zabezpieczeń Linuxa i izolację kontenerów.
To oznacza, że możesz wstawiać/usuwać moduły jądra w/ze jądra maszyny hosta.
Przykład z binarnym
W poniższym przykładzie binarny python
ma tę zdolność.
Domyślnie polecenie modprobe
sprawdza listę zależności i pliki map w katalogu /lib/modules/$(uname -r)
.
Aby to wykorzystać, stwórzmy fałszywy folder lib/modules:
Następnie skompiluj moduł jądra, który możesz znaleźć w 2 przykładach poniżej i skopiuj go do tego folderu:
Na koniec wykonaj potrzebny kod Pythona, aby załadować ten moduł jądra:
Przykład 2 z binarnym
W następującym przykładzie binarny kmod
ma tę zdolność.
Co oznacza, że możliwe jest użycie polecenia insmod
do wstawienia modułu jądra. Postępuj zgodnie z poniższym przykładem, aby uzyskać reverse shell, nadużywając tego uprawnienia.
Przykład z środowiskiem (wyjście z Dockera)
Możesz sprawdzić włączone uprawnienia wewnątrz kontenera docker za pomocą:
W poprzednim wyjściu możesz zobaczyć, że zdolność SYS_MODULE jest włączona.
Utwórz moduł jądra, który będzie wykonywał powłokę odwrotną oraz Makefile, aby go skompilować:
Pusty znak przed każdym słowem make w pliku Makefile musi być tabulatorem, a nie spacjami!
Wykonaj make
, aby skompilować.
W końcu uruchom nc
w jednej powłoce i załaduj moduł z innej, a przechwycisz powłokę w procesie nc:
Kod tej techniki został skopiowany z laboratorium "Abusing SYS_MODULE Capability" z https://www.pentesteracademy.com/
Inny przykład tej techniki można znaleźć w https://www.cyberark.com/resources/threat-research-blog/how-i-hacked-play-with-docker-and-remotely-ran-code-on-the-host
CAP_DAC_READ_SEARCH umożliwia procesowi ominięcie uprawnień do odczytu plików oraz do odczytu i wykonywania katalogów. Jego główne zastosowanie dotyczy wyszukiwania lub odczytu plików. Jednak pozwala również procesowi na użycie funkcji open_by_handle_at(2)
, która może uzyskać dostęp do dowolnego pliku, w tym tych poza przestrzenią montowania procesu. Uchwycony użyty w open_by_handle_at(2)
powinien być nieprzezroczystym identyfikatorem uzyskanym za pomocą name_to_handle_at(2)
, ale może zawierać wrażliwe informacje, takie jak numery i-node, które są podatne na manipulacje. Potencjał do wykorzystania tej możliwości, szczególnie w kontekście kontenerów Docker, został zaprezentowany przez Sebastiana Krahmera za pomocą exploita shocker, jak analizowano tutaj. Oznacza to, że możesz ominięcie kontroli uprawnień do odczytu plików oraz kontroli uprawnień do odczytu/wykonywania katalogów.
Przykład z binarnym
Binarne będzie mogło odczytać dowolny plik. Więc, jeśli plik taki jak tar ma tę możliwość, będzie mógł odczytać plik shadow:
Przykład z binary2
W tym przypadku załóżmy, że binarka python
ma tę zdolność. Aby wylistować pliki roota, możesz zrobić:
Aby odczytać plik, możesz zrobić:
Przykład w środowisku (wyjście z Dockera)
Możesz sprawdzić włączone możliwości wewnątrz kontenera dockera, używając:
W poprzednim wyniku można zobaczyć, że zdolność DAC_READ_SEARCH jest włączona. W rezultacie kontener może debugować procesy.
Możesz dowiedzieć się, jak działa poniższe wykorzystanie w https://medium.com/@fun_cuddles/docker-breakout-exploit-analysis-a274fff0e6b3, ale w skrócie CAP_DAC_READ_SEARCH nie tylko pozwala nam przechodzić przez system plików bez sprawdzania uprawnień, ale także wyraźnie usuwa wszelkie kontrole do open_by_handle_at(2) i może pozwolić naszemu procesowi na dostęp do wrażliwych plików otwartych przez inne procesy.
Oryginalny exploit, który nadużywa tych uprawnień do odczytu plików z hosta, można znaleźć tutaj: http://stealth.openwall.net/xSports/shocker.c, poniżej znajduje się zmodyfikowana wersja, która pozwala wskazać plik, który chcesz odczytać jako pierwszy argument i zrzucić go do pliku.
Eksploit musi znaleźć wskaźnik do czegoś zamontowanego na hoście. Oryginalny exploit używał pliku /.dockerinit, a ta zmodyfikowana wersja używa /etc/hostname. Jeśli exploit nie działa, być może musisz ustawić inny plik. Aby znaleźć plik, który jest zamontowany w hoście, wystarczy wykonać polecenie mount:
Kod tej techniki został skopiowany z laboratorium "Abusing DAC_READ_SEARCH Capability" z https://www.pentesteracademy.com/
RootedCON to najważniejsze wydarzenie związane z cyberbezpieczeństwem w Hiszpanii i jedno z najważniejszych w Europie. Z misją promowania wiedzy technicznej, ten kongres jest gorącym punktem spotkań dla profesjonalistów z technologii i cyberbezpieczeństwa w każdej dziedzinie.
Oznacza to, że możesz obejść kontrole uprawnień do zapisu w dowolnym pliku, więc możesz zapisać dowolny plik.
Jest wiele plików, które możesz nadpisać, aby podnieść uprawnienia, możesz znaleźć pomysły tutaj.
Przykład z binarnym
W tym przykładzie vim ma tę zdolność, więc możesz modyfikować dowolny plik, taki jak passwd, sudoers lub shadow:
Przykład z binarnym 2
W tym przykładzie python
będzie miał tę zdolność. Możesz użyć pythona do nadpisania dowolnego pliku:
Przykład z środowiskiem + CAP_DAC_READ_SEARCH (wyjście z Dockera)
Możesz sprawdzić włączone możliwości wewnątrz kontenera dockera, używając:
Najpierw przeczytaj poprzednią sekcję, która wykorzystuje zdolność DAC_READ_SEARCH do odczytu dowolnych plików hosta i skompiluj exploit. Następnie skompiluj następującą wersję exploita shocker, która pozwoli ci zapisywać dowolne pliki w systemie plików hosta:
Aby wydostać się z kontenera docker, możesz pobrać pliki /etc/shadow
i /etc/passwd
z hosta, dodać do nich nowego użytkownika i użyć shocker_write
, aby je nadpisać. Następnie uzyskaj dostęp przez ssh.
Kod tej techniki został skopiowany z laboratorium "Abusing DAC_OVERRIDE Capability" z https://www.pentesteracademy.com
Oznacza to, że możliwe jest zmienienie właściciela dowolnego pliku.
Przykład z binarnym
Załóżmy, że python
ma tę zdolność, możesz zmienić właściciela pliku shadow, zmienić hasło roota i eskalować uprawnienia:
Lub z binarnym plikiem ruby
mającym tę zdolność:
Oznacza to, że możliwe jest zmienienie uprawnień dowolnego pliku.
Przykład z binarnym
Jeśli python ma tę zdolność, możesz zmodyfikować uprawnienia pliku shadow, zmienić hasło roota i eskalować uprawnienia:
Oznacza to, że możliwe jest ustawienie efektywnego identyfikatora użytkownika utworzonego procesu.
Przykład z binarnym
Jeśli python ma tę zdolność, możesz bardzo łatwo to wykorzystać do eskalacji uprawnień do roota:
Inny sposób:
Oznacza to, że możliwe jest ustawienie efektywnego identyfikatora grupy utworzonego procesu.
Jest wiele plików, które możesz nadpisać, aby zwiększyć uprawnienia, możesz zaczerpnąć pomysły stąd.
Przykład z binarnym
W tym przypadku powinieneś szukać interesujących plików, które grupa może odczytać, ponieważ możesz udawać dowolną grupę:
Gdy znajdziesz plik, który możesz wykorzystać (poprzez odczyt lub zapis) do eskalacji uprawnień, możesz uzyskać powłokę, udając interesującą grupę za pomocą:
W tym przypadku grupa shadow została podszyta, więc możesz odczytać plik /etc/shadow
:
Jeśli docker jest zainstalowany, możesz udawać grupę docker i nadużyć jej, aby komunikować się z gniazdem docker i eskalować uprawnienia.
Oznacza to, że możliwe jest ustawienie możliwości na plikach i procesach
Przykład z binarką
Jeśli python ma tę możliwość, możesz bardzo łatwo nadużyć jej, aby eskalować uprawnienia do roota:
Zauważ, że jeśli ustawisz nową zdolność dla binarnego pliku z CAP_SETFCAP, stracisz tę zdolność.
Gdy masz zdolność SETUID, możesz przejść do jej sekcji, aby zobaczyć, jak eskalować uprawnienia.
Przykład z środowiskiem (wyjście z Dockera)
Domyślnie zdolność CAP_SETFCAP jest przyznawana procesowi wewnątrz kontenera w Dockerze. Możesz to sprawdzić, wykonując coś takiego:
Ta zdolność pozwala na przyznanie dowolnej innej zdolności binarnym, więc możemy pomyśleć o ucieczce z kontenera wykorzystując dowolne inne wyłamania zdolności wspomniane na tej stronie. Jednakże, jeśli spróbujesz przyznać na przykład zdolności CAP_SYS_ADMIN i CAP_SYS_PTRACE binarnemu gdb, odkryjesz, że możesz je przyznać, ale binarne nie będzie mogło się wykonać po tym:
From the docs: Permitted: To jest ograniczający nadzbiór dla efektywnych możliwości, które wątek może przyjąć. Jest to również ograniczający nadzbiór dla możliwości, które mogą być dodane do zestawu dziedziczonego przez wątek, który nie ma możliwości CAP_SETPCAP w swoim efektywnym zestawie. Wygląda na to, że możliwości dozwolone ograniczają te, które mogą być używane. Jednak Docker również domyślnie przyznaje CAP_SETPCAP, więc możesz być w stanie ustawić nowe możliwości w dziedziczonych. Jednak w dokumentacji tej możliwości: CAP_SETPCAP : […] dodaje każdą możliwość z ograniczonego zestawu wątku wywołującego do jego zestawu dziedziczonego. Wygląda na to, że możemy tylko dodawać do zestawu dziedziczonego możliwości z zestawu ograniczonego. Co oznacza, że nie możemy umieścić nowych możliwości, takich jak CAP_SYS_ADMIN lub CAP_SYS_PTRACE w zestawie dziedzicznym, aby eskalować uprawnienia.
CAP_SYS_RAWIO zapewnia szereg wrażliwych operacji, w tym dostęp do /dev/mem
, /dev/kmem
lub /proc/kcore
, modyfikację mmap_min_addr
, dostęp do wywołań systemowych ioperm(2)
i iopl(2)
, oraz różne polecenia dyskowe. FIBMAP ioctl(2)
jest również włączone za pomocą tej możliwości, co spowodowało problemy w przeszłości. Zgodnie z dokumentacją, umożliwia to również posiadaczowi opisowe wykonywanie szeregu operacji specyficznych dla urządzeń na innych urządzeniach
.
Może to być przydatne do eskalacji uprawnień i wyjścia z Dockera.
To oznacza, że możliwe jest zabicie dowolnego procesu.
Przykład z binarnym
Załóżmy, że python
ma tę możliwość. Jeśli mógłbyś również zmodyfikować jakąś konfigurację usługi lub gniazda (lub jakikolwiek plik konfiguracyjny związany z usługą), mógłbyś wprowadzić tylne drzwi, a następnie zabić proces związany z tą usługą i czekać na wykonanie nowego pliku konfiguracyjnego z twoimi tylnymi drzwiami.
Privesc z kill
Jeśli masz uprawnienia kill i działa program node jako root (lub jako inny użytkownik), prawdopodobnie możesz wysłać mu sygnał SIGUSR1 i sprawić, że otworzy debugger node, do którego możesz się połączyć.
RootedCON to najważniejsze wydarzenie związane z cyberbezpieczeństwem w Hiszpanii i jedno z najważniejszych w Europie. Z misją promowania wiedzy technicznej, ten kongres jest gorącym punktem spotkań dla profesjonalistów z dziedziny technologii i cyberbezpieczeństwa w każdej dyscyplinie.
Oznacza to, że możliwe jest nasłuchiwanie na dowolnym porcie (nawet na portach uprzywilejowanych). Nie można bezpośrednio eskalować uprawnień za pomocą tej zdolności.
Przykład z binarnym
Jeśli python
ma tę zdolność, będzie mógł nasłuchiwać na dowolnym porcie i nawet łączyć się z niego z innym portem (niektóre usługi wymagają połączeń z portów o określonych uprawnieniach)
CAP_NET_RAW uprawnienie pozwala procesom na tworzenie gniazd RAW i PACKET, co umożliwia generowanie i wysyłanie dowolnych pakietów sieciowych. Może to prowadzić do zagrożeń bezpieczeństwa w środowiskach kontenerowych, takich jak fałszowanie pakietów, wstrzykiwanie ruchu i omijanie kontroli dostępu do sieci. Złośliwi aktorzy mogą to wykorzystać do zakłócania routingu kontenerów lub kompromitacji bezpieczeństwa sieci hosta, szczególnie bez odpowiednich zabezpieczeń zapory. Dodatkowo, CAP_NET_RAW jest kluczowe dla uprzywilejowanych kontenerów, aby wspierać operacje takie jak ping za pomocą żądań RAW ICMP.
To oznacza, że możliwe jest podsłuchiwanie ruchu. Nie możesz bezpośrednio eskalować uprawnień za pomocą tego uprawnienia.
Przykład z binarką
Jeśli binarka tcpdump
ma to uprawnienie, będziesz mógł jej użyć do przechwytywania informacji sieciowych.
Zauważ, że jeśli środowisko przyznaje tę zdolność, możesz również użyć tcpdump
, aby przechwycić ruch.
Przykład z binarnym 2
Poniższy przykład to kod python2
, który może być przydatny do przechwytywania ruchu interfejsu "lo" (localhost). Kod pochodzi z laboratorium "Podstawy: CAP-NET_BIND + NET_RAW" z https://attackdefense.pentesteracademy.com/
CAP_NET_ADMIN uprawnienie daje posiadaczowi moc zmiany konfiguracji sieci, w tym ustawień zapory, tabel routingu, uprawnień gniazd oraz ustawień interfejsów sieciowych w ramach wystawionych przestrzeni nazw sieci. Umożliwia również włączenie trybu promiskuitywnego na interfejsach sieciowych, co pozwala na sniffing pakietów w różnych przestrzeniach nazw.
Przykład z binarnym
Załóżmy, że binarne pliki python mają te uprawnienia.
To oznacza, że możliwe jest modyfikowanie atrybutów inode. Nie możesz bezpośrednio eskalować uprawnień za pomocą tej zdolności.
Przykład z binarnym
Jeśli odkryjesz, że plik jest niemodyfikowalny, a python ma tę zdolność, możesz usunąć atrybut niemodyfikowalności i uczynić plik modyfikowalnym:
Zauważ, że zazwyczaj ten atrybut niemutowalny jest ustawiany i usuwany za pomocą:
CAP_SYS_CHROOT umożliwia wykonanie wywołania systemowego chroot(2)
, co potencjalnie może pozwolić na ucieczkę z środowisk chroot(2)
poprzez znane luki:
CAP_SYS_BOOT nie tylko pozwala na wykonanie wywołania systemowego reboot(2)
w celu ponownego uruchomienia systemu, w tym na konkretne polecenia, takie jak LINUX_REBOOT_CMD_RESTART2
dostosowane do określonych platform sprzętowych, ale także umożliwia użycie kexec_load(2)
oraz, od wersji Linux 3.17, kexec_file_load(2)
do ładowania nowych lub podpisanych jąder awaryjnych.
CAP_SYSLOG został oddzielony od szerszego CAP_SYS_ADMIN w Linux 2.6.37, przyznając konkretną możliwość użycia wywołania syslog(2)
. Ta zdolność umożliwia przeglądanie adresów jądra za pośrednictwem /proc
i podobnych interfejsów, gdy ustawienie kptr_restrict
wynosi 1, co kontroluje ujawnianie adresów jądra. Od Linux 2.6.39 domyślna wartość dla kptr_restrict
wynosi 0, co oznacza, że adresy jądra są ujawniane, chociaż wiele dystrybucji ustawia to na 1 (ukryj adresy z wyjątkiem uid 0) lub 2 (zawsze ukrywaj adresy) z powodów bezpieczeństwa.
Dodatkowo, CAP_SYSLOG pozwala na dostęp do wyjścia dmesg
, gdy dmesg_restrict
jest ustawione na 1. Pomimo tych zmian, CAP_SYS_ADMIN zachowuje możliwość wykonywania operacji syslog
z powodu historycznych precedensów.
CAP_MKNOD rozszerza funkcjonalność wywołania systemowego mknod
poza tworzenie zwykłych plików, FIFO (nazwanych potoków) lub gniazd domeny UNIX. Specjalnie pozwala na tworzenie plików specjalnych, które obejmują:
S_IFCHR: Pliki specjalne znakowe, które są urządzeniami takimi jak terminale.
S_IFBLK: Pliki specjalne blokowe, które są urządzeniami takimi jak dyski.
Ta zdolność jest niezbędna dla procesów, które wymagają możliwości tworzenia plików urządzeń, ułatwiając bezpośrednią interakcję z hardwarem poprzez urządzenia znakowe lub blokowe.
Jest to domyślna zdolność dockera (https://github.com/moby/moby/blob/master/oci/caps/defaults.go#L6-L19).
Ta zdolność pozwala na eskalację uprawnień (poprzez pełne odczytywanie dysku) na hoście, pod tymi warunkami:
Mieć początkowy dostęp do hosta (bez uprawnień).
Mieć początkowy dostęp do kontenera (z uprawnieniami (EUID 0) i efektywnym CAP_MKNOD
).
Host i kontener powinny dzielić tę samą przestrzeń nazw użytkowników.
Kroki do utworzenia i uzyskania dostępu do urządzenia blokowego w kontenerze:
Na hoście jako standardowy użytkownik:
Określ swój aktualny identyfikator użytkownika za pomocą id
, np. uid=1000(standarduser)
.
Zidentyfikuj docelowe urządzenie, na przykład /dev/sdb
.
Wewnątrz kontenera jako root
:
Z powrotem na hoście:
To podejście pozwala standardowemu użytkownikowi na dostęp i potencjalne odczytanie danych z /dev/sdb
przez kontener, wykorzystując współdzielone przestrzenie nazw użytkowników i uprawnienia ustawione na urządzeniu.
CAP_SETPCAP umożliwia procesowi zmianę zestawów uprawnień innego procesu, co pozwala na dodawanie lub usuwanie uprawnień z zestawów efektywnych, dziedzicznych i dozwolonych. Jednak proces może modyfikować tylko te uprawnienia, które posiada w swoim własnym dozwolonym zestawie, co zapewnia, że nie może podnieść uprawnień innego procesu ponad swoje własne. Ostatnie aktualizacje jądra zaostrzyły te zasady, ograniczając CAP_SETPCAP
do jedynie zmniejszania uprawnień w swoim własnym lub dozwolonym zestawie swoich potomków, mając na celu złagodzenie ryzyk bezpieczeństwa. Użycie wymaga posiadania CAP_SETPCAP
w zestawie efektywnym oraz docelowych uprawnień w zestawie dozwolonym, wykorzystując capset()
do modyfikacji. To podsumowuje podstawową funkcję i ograniczenia CAP_SETPCAP
, podkreślając jego rolę w zarządzaniu uprawnieniami i poprawie bezpieczeństwa.
CAP_SETPCAP
to uprawnienie w systemie Linux, które pozwala procesowi na modyfikację zestawów uprawnień innego procesu. Daje możliwość dodawania lub usuwania uprawnień z efektywnych, dziedzicznych i dozwolonych zestawów uprawnień innych procesów. Jednak istnieją pewne ograniczenia dotyczące tego, jak to uprawnienie może być używane.
Proces z CAP_SETPCAP
może jedynie przyznawać lub usuwać uprawnienia, które znajdują się w jego własnym dozwolonym zestawie uprawnień. Innymi słowy, proces nie może przyznać uprawnienia innemu procesowi, jeśli sam go nie posiada. To ograniczenie zapobiega podnoszeniu uprawnień innego procesu ponad własny poziom uprawnień.
Ponadto, w ostatnich wersjach jądra, uprawnienie CAP_SETPCAP
zostało dodatkowo ograniczone. Już nie pozwala procesowi na dowolną modyfikację zestawów uprawnień innych procesów. Zamiast tego pozwala jedynie procesowi na obniżenie uprawnień w swoim własnym dozwolonym zestawie uprawnień lub w dozwolonym zestawie uprawnień swoich potomków. Ta zmiana została wprowadzona w celu zmniejszenia potencjalnych ryzyk bezpieczeństwa związanych z tym uprawnieniem.
Aby skutecznie używać CAP_SETPCAP
, musisz mieć to uprawnienie w swoim efektywnym zestawie uprawnień oraz docelowe uprawnienia w swoim dozwolonym zestawie uprawnień. Możesz następnie użyć wywołania systemowego capset()
, aby modyfikować zestawy uprawnień innych procesów.
Podsumowując, CAP_SETPCAP
pozwala procesowi na modyfikację zestawów uprawnień innych procesów, ale nie może przyznawać uprawnień, których sam nie posiada. Dodatkowo, z powodu obaw o bezpieczeństwo, jego funkcjonalność została ograniczona w ostatnich wersjach jądra do jedynie obniżania uprawnień w swoim własnym dozwolonym zestawie uprawnień lub w dozwolonych zestawach uprawnień swoich potomków.
Większość tych przykładów pochodzi z niektórych laboratoriów https://attackdefense.pentesteracademy.com/, więc jeśli chcesz ćwiczyć te techniki privesc, polecam te laboratoria.
Inne odniesienia:
RootedCON to najważniejsze wydarzenie związane z cyberbezpieczeństwem w Hiszpanii i jedno z najważniejszych w Europie. Z misją promowania wiedzy technicznej, ten kongres jest gorącym punktem spotkań dla profesjonalistów technologii i cyberbezpieczeństwa w każdej dziedzinie.
Ucz się i ćwicz Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE) Ucz się i ćwicz Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)