Linux Capabilities
RootedCON è l'evento di sicurezza informatica più rilevante in Spagna e uno dei più importanti in Europa. Con la missione di promuovere la conoscenza tecnica, questo congresso è un punto di incontro bollente per professionisti della tecnologia e della sicurezza informatica in ogni disciplina.\
Linux Capabilities
Le Linux capabilities dividono i privilegi di root in unità più piccole e distinte, consentendo ai processi di avere un sottoinsieme di privilegi. Ciò riduce al minimo i rischi non concedendo inutilmente i pieni privilegi di root.
Il problema:
Gli utenti normali hanno autorizzazioni limitate, che influiscono su attività come l'apertura di un socket di rete che richiede l'accesso di root.
Set di capabilities:
Inherited (CapInh):
Scopo: Determina le capabilities ereditate dal processo padre.
Funzionalità: Quando viene creato un nuovo processo, eredita le capabilities dal processo padre in questo set. Utile per mantenere determinati privilegi tra le generazioni di processi.
Limitazioni: Un processo non può acquisire capabilities che il suo processo padre non possedeva.
Effective (CapEff):
Scopo: Rappresenta le capabilities effettive che un processo sta utilizzando in un determinato momento.
Funzionalità: È l'insieme di capabilities controllate dal kernel per concedere l'autorizzazione a varie operazioni. Per i file, questo set può essere un flag che indica se le capabilities consentite del file devono essere considerate effettive.
Importanza: L'insieme effettivo è fondamentale per i controlli immediati dei privilegi, agendo come l'insieme attivo di capabilities che un processo può utilizzare.
Permitted (CapPrm):
Scopo: Definisce l'insieme massimo di capabilities che un processo può possedere.
Funzionalità: Un processo può elevare una capability dall'insieme consentito al suo insieme effettivo, conferendogli la capacità di utilizzare quella capability. Può anche rimuovere capabilities dal suo insieme consentito.
Limite: Agisce come un limite superiore per le capabilities che un processo può avere, garantendo che un processo non superi il proprio ambito di privilegi predefinito.
Bounding (CapBnd):
Scopo: Impone un limite alle capabilities che un processo può acquisire durante il suo ciclo di vita.
Funzionalità: Anche se un processo ha una determinata capability nel suo insieme ereditabile o consentito, non può acquisire quella capability a meno che non sia anche nell'insieme di bounding.
Caso d'uso: Questo insieme è particolarmente utile per limitare il potenziale di escalation dei privilegi di un processo, aggiungendo un ulteriore livello di sicurezza.
Ambient (CapAmb):
Scopo: Consente di mantenere determinate capabilities durante una chiamata di sistema
execve
, che normalmente comporterebbe un reset completo delle capabilities del processo.Funzionalità: Garantisce che i programmi non SUID che non hanno capabilities di file associate possano mantenere determinati privilegi.
Limitazioni: Le capabilities in questo insieme sono soggette ai vincoli degli insiemi ereditabili e consentiti, garantendo che non superino i privilegi consentiti al processo.
Per ulteriori informazioni, controlla:
Capacità dei processi e dei binari
Capacità dei processi
Per visualizzare le capacità di un determinato processo, utilizza il file status nella directory /proc. Poiché fornisce maggiori dettagli, limitiamoci solo alle informazioni relative alle capacità di Linux. Nota che per tutti i processi in esecuzione le informazioni sulle capacità sono mantenute per thread, mentre per i binari nel file system sono memorizzate negli attributi estesi.
Puoi trovare le capacità definite in /usr/include/linux/capability.h
Puoi trovare le capacità del processo corrente con cat /proc/self/status
o utilizzando capsh --print
e di altri utenti in /proc/<pid>/status
Questo comando dovrebbe restituire 5 righe sulla maggior parte dei sistemi.
CapInh = Capacità ereditate
CapPrm = Capacità consentite
CapEff = Capacità effettive
CapBnd = Insieme di limitazione
CapAmb = Insieme di capacità ambientali
Questi numeri esadecimali non hanno senso. Utilizzando l'utilità capsh possiamo decodificarli nel nome delle capacità.
Verifichiamo ora le capabilities utilizzate da ping
:
Anche se quella soluzione funziona, c'è un altro modo più semplice. Per visualizzare le capacità di un processo in esecuzione, basta utilizzare lo strumento getpcaps seguito dal suo ID di processo (PID). È anche possibile fornire un elenco di ID di processo.
Verifichiamo qui le capacità di tcpdump
dopo aver fornito al binario le capacità sufficienti (cap_net_admin
e cap_net_raw
) per intercettare il traffico di rete (tcpdump è in esecuzione nel processo 9562):
Come puoi vedere, le capacità fornite corrispondono ai risultati dei 2 modi per ottenere le capacità di un binario. Lo strumento getpcaps utilizza la chiamata di sistema capget() per interrogare le capacità disponibili per un determinato thread. Questa chiamata di sistema richiede solo di fornire il PID per ottenere ulteriori informazioni.
Capacità dei binari
I binari possono avere capacità che possono essere utilizzate durante l'esecuzione. Ad esempio, è molto comune trovare il binario ping
con la capacità cap_net_raw
:
Puoi cercare binari con le capability utilizzando:
Eliminazione delle capacità con capsh
Se eliminiamo le capacità CAP_NET_RAW per ping, l'utilità ping non dovrebbe più funzionare.
Oltre all'output di capsh stesso, il comando tcpdump stesso dovrebbe generare un errore.
/bin/bash: /usr/sbin/tcpdump: Operazione non consentita
L'errore mostra chiaramente che il comando ping non è autorizzato ad aprire un socket ICMP. Ora sappiamo con certezza che questo funziona come previsto.
Rimuovere le Capacità
È possibile rimuovere le capacità di un eseguibile con
Capacità degli Utenti
Apparentemente è possibile assegnare le capacità anche agli utenti. Ciò significa probabilmente che ogni processo eseguito dall'utente sarà in grado di utilizzare le sue capacità.
Basandosi su questo, questo e questo alcuni file devono essere configurati per dare a un utente determinate capacità, ma quello che assegna le capacità a ciascun utente sarà /etc/security/capability.conf
.
Esempio di file:
Capacità dell'ambiente
Compilando il seguente programma è possibile generare una shell bash all'interno di un ambiente che fornisce capacità.
All'interno della bash eseguita dal binario ambientale compilato è possibile osservare le nuove capacità (un utente normale non avrà alcuna capacità nella sezione "corrente").
Puoi aggiungere solo le capacità presenti sia nell'insieme dei permessi che in quello ereditabile.
Binari consapevoli delle capacità / Binari ignoranti delle capacità
I binari consapevoli delle capacità non utilizzeranno le nuove capacità fornite dall'ambiente, mentre i binari ignoranti delle capacità le utilizzeranno poiché non le rifiuteranno. Ciò rende i binari ignoranti delle capacità vulnerabili all'interno di un ambiente speciale che concede capacità ai binari.
Capacità del servizio
Per impostazione predefinita, un servizio in esecuzione come root avrà assegnate tutte le capacità, e in alcune occasioni ciò può essere pericoloso. Pertanto, un file di configurazione del servizio consente di specificare le capacità che si desidera che abbia, e l'utente che dovrebbe eseguire il servizio per evitare di eseguire un servizio con privilegi non necessari:
Capacità nei container Docker
Di default, Docker assegna alcune capacità ai container. È molto facile verificare quali sono queste capacità eseguendo:
RootedCON è l'evento di sicurezza informatica più rilevante in Spagna e uno dei più importanti in Europa. Con la missione di promuovere la conoscenza tecnica, questo congresso è un punto di incontro vivace per i professionisti della tecnologia e della sicurezza informatica in ogni disciplina.
Privesc/Container Escape
Le capacità sono utili quando si desidera limitare i propri processi dopo aver eseguito operazioni privilegiate (ad esempio, dopo aver impostato chroot e collegato a una socket). Tuttavia, possono essere sfruttate passando loro comandi o argomenti dannosi che vengono quindi eseguiti come root.
È possibile forzare le capacità sui programmi utilizzando setcap
e interrogarle utilizzando getcap
:
Il +ep
significa che stai aggiungendo la capacità ("-" la rimuoverebbe) come Effettiva e Consentita.
Per identificare i programmi in un sistema o una cartella con le capacità:
Esempio di sfruttamento
Nell'esempio seguente viene individuata una vulnerabilità di escalation dei privilegi nel binario /usr/bin/python2.6
:
Capacità necessarie da tcpdump
per consentire a qualsiasi utente di intercettare pacchetti:
After setting the capabilities, any user will be able to run tcpdump
and sniff packets without requiring root privileges.
Per consentire a qualsiasi utente di intercettare pacchetti con tcpdump
, è necessario impostare le seguenti capacità:
CAP_NET_RAW
: Questa capacità consente all'utente di creare socket raw, che è necessario per l'intercettazione dei pacchetti.
Per impostare queste capacità, è possibile utilizzare il comando setcap
:
Dopo aver impostato le capacità, qualsiasi utente sarà in grado di eseguire tcpdump
e intercettare pacchetti senza richiedere privilegi di root.
Il caso speciale delle "capabilities" vuote
Dalla documentazione: Si noti che è possibile assegnare insiemi di "capabilities" vuoti a un file di programma e quindi è possibile creare un programma con set-user-ID-root che cambia l'ID utente effettivo e salvato del processo che esegue il programma a 0, ma non conferisce alcuna "capability" a tale processo. In altre parole, se si dispone di un binario che:
non è di proprietà di root
non ha impostati i bit
SUID
/SGID
ha un insieme di "capabilities" vuoto (ad esempio:
getcap myelf
restituiscemyelf =ep
)
allora quel binario verrà eseguito come root.
CAP_SYS_ADMIN
CAP_SYS_ADMIN
è una "capability" di Linux molto potente, spesso equiparata a un livello quasi di root a causa dei suoi ampi privilegi amministrativi, come il montaggio di dispositivi o la manipolazione delle funzionalità del kernel. Sebbene indispensabile per i contenitori che simulano interi sistemi, CAP_SYS_ADMIN
presenta significativi problemi di sicurezza, specialmente in ambienti containerizzati, a causa del suo potenziale per l'elevazione dei privilegi e la compromissione del sistema. Pertanto, il suo utilizzo richiede rigorose valutazioni di sicurezza e una gestione cauta, con una forte preferenza per la rimozione di questa "capability" nei contenitori specifici dell'applicazione per aderire al principio del privilegio minimo e ridurre al minimo la superficie di attacco.
Esempio con binario
Utilizzando python è possibile montare un file passwd modificato sopra il vero file passwd:
E infine monta il file passwd
modificato su /etc/passwd
:
E sarai in grado di su
come root utilizzando la password "password".
Esempio con ambiente (Docker breakout)
Puoi verificare le capacità abilitate all'interno del container Docker utilizzando:
All'interno dell'output precedente è possibile vedere che la capacità SYS_ADMIN è abilitata.
Montaggio
Ciò consente al container docker di montare il disco dell'host e accedervi liberamente:
Accesso completo
Nel metodo precedente siamo riusciti ad accedere al disco dell'host Docker. Nel caso in cui tu scopra che l'host sta eseguendo un server ssh, potresti creare un utente all'interno del disco dell'host Docker e accedervi tramite SSH:
CAP_SYS_PTRACE
Questo significa che puoi sfuggire al contenitore iniettando uno shellcode all'interno di un processo in esecuzione nell'host. Per accedere ai processi in esecuzione nell'host, il contenitore deve essere eseguito almeno con --pid=host
.
CAP_SYS_PTRACE
concede la possibilità di utilizzare funzionalità di debug e tracciamento delle chiamate di sistema fornite da ptrace(2)
e chiamate di attacco cross-memory come process_vm_readv(2)
e process_vm_writev(2)
. Sebbene potente per scopi di diagnostica e monitoraggio, se CAP_SYS_PTRACE
è abilitato senza misure restrittive come un filtro seccomp su ptrace(2)
, può compromettere significativamente la sicurezza del sistema. In particolare, può essere sfruttato per eludere altre restrizioni di sicurezza, in particolare quelle imposte da seccomp, come dimostrato da proof of concept (PoC) come questo.
Esempio con binario (python)
Esempio con binario (gdb)
gdb
con la capacità ptrace
:
Creare uno shellcode con msfvenom per l'iniezione in memoria tramite gdb
Questo comando crea uno shellcode utilizzando msfvenom per l'iniezione in memoria tramite gdb. Assicurati di sostituire <IP>
con l'indirizzo IP del tuo listener e <PORT>
con la porta del tuo listener. Il parametro -f c
specifica il formato di output come codice C. Il parametro -b "\x00"
esclude i byte null dallo shellcode. Infine, l'opzione -o shellcode.c
specifica il nome del file di output come "shellcode.c".
Debugga un processo root con gdb e copia-incolla le righe gdb generate in precedenza:
Esempio con ambiente (Docker breakout) - Un altro abuso di gdb
Se GDB è installato (o puoi installarlo con apk add gdb
o apt install gdb
, ad esempio) puoi debuggare un processo dall'host e farlo chiamare la funzione system
. (Questa tecnica richiede anche la capacità SYS_ADMIN
).
Non sarai in grado di vedere l'output del comando eseguito, ma verrà eseguito da quel processo (quindi ottieni una shell inversa).
Se ricevi l'errore "No symbol "system" in current context.", controlla l'esempio precedente caricando uno shellcode in un programma tramite gdb.
Esempio con ambiente (Docker breakout) - Iniezione di shellcode
Puoi verificare le capacità abilitate all'interno del container Docker utilizzando:
Elencare i processi in esecuzione nell'host ps -eaf
Ottenere l'architettura
uname -m
Trovare uno shellcode per l'architettura (https://www.exploit-db.com/exploits/41128)
Trovare un programma per iniettare lo shellcode nella memoria di un processo (https://github.com/0x00pf/0x00sec_code/blob/master/mem_inject/infect.c)
Modificare lo shellcode all'interno del programma e compilarlo
gcc inject.c -o inject
Iniettarlo e ottenere la tua shell:
./inject 299; nc 172.17.0.1 5600
CAP_SYS_MODULE
CAP_SYS_MODULE
permette a un processo di caricare e scaricare moduli del kernel (chiamate di sistema init_module(2)
, finit_module(2)
e delete_module(2)
), offrendo un accesso diretto alle operazioni principali del kernel. Questa capacità presenta rischi di sicurezza critici, in quanto consente l'escalation dei privilegi e la compromissione totale del sistema, consentendo modifiche al kernel e bypassando tutti i meccanismi di sicurezza di Linux, inclusi i moduli di sicurezza di Linux e l'isolamento dei container. Ciò significa che è possibile inserire/rimuovere moduli del kernel nel/dal kernel della macchina host.
Esempio con un binario
Nell'esempio seguente, il binario python
ha questa capacità.
Di default, il comando modprobe
controlla la lista delle dipendenze e i file di mappatura nella directory /lib/modules/$(uname -r)
.
Per sfruttare ciò, creiamo una falsa cartella lib/modules:
Quindi compila il modulo del kernel che puoi trovare 2 esempi di seguito e copialo in questa cartella:
Infine, esegui il codice Python necessario per caricare questo modulo del kernel:
Esempio 2 con binario
Nell'esempio seguente, il binario kmod
ha questa capacità.
Ciò significa che è possibile utilizzare il comando insmod
per inserire un modulo del kernel. Segui l'esempio di seguito per ottenere una shell inversa sfruttando questo privilegio.
Esempio con ambiente (Docker breakout)
È possibile verificare le capacità abilitate all'interno del container Docker utilizzando:
All'interno dell'output precedente è possibile vedere che la capacità SYS_MODULE è abilitata.
Creare il modulo del kernel che eseguirà una shell inversa e il Makefile per compilarlo:
Lo spazio vuoto prima di ogni parola make nel Makefile deve essere una tabulazione, non spazi!
Esegui make
per compilarlo.
Infine, avvia nc
all'interno di una shell e carica il modulo da un'altra shell e catturerai la shell nel processo nc:
Il codice di questa tecnica è stato copiato dal laboratorio "Abusing SYS_MODULE Capability" da https://www.pentesteracademy.com/
Un altro esempio di questa tecnica può essere trovato in 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
CAP_DAC_READ_SEARCH permette a un processo di bypassare le autorizzazioni per la lettura dei file e per la lettura ed esecuzione delle directory. Il suo utilizzo principale è per la ricerca o la lettura dei file. Tuttavia, consente anche a un processo di utilizzare la funzione open_by_handle_at(2)
, che può accedere a qualsiasi file, incluso quelli al di fuori dello spazio dei nomi di montaggio del processo. L'handle utilizzato in open_by_handle_at(2)
dovrebbe essere un identificatore non trasparente ottenuto tramite name_to_handle_at(2)
, ma può includere informazioni sensibili come i numeri di inode che sono vulnerabili a manomissioni. Il potenziale di sfruttamento di questa capacità, in particolare nel contesto dei container Docker, è stato dimostrato da Sebastian Krahmer con l'exploit shocker, come analizzato qui. Ciò significa che è possibile bypassare i controlli di autorizzazione per la lettura dei file e i controlli di autorizzazione per la lettura/esecuzione delle directory.
Esempio con un binario
Il binario sarà in grado di leggere qualsiasi file. Quindi, se un file come tar ha questa capacità, sarà in grado di leggere il file shadow:
Esempio con binary2
In questo caso supponiamo che il binario python
abbia questa capacità. Per elencare i file di root è possibile eseguire il seguente comando:
E per leggere un file potresti fare:
Esempio in ambiente (Docker breakout)
Puoi verificare le capacità abilitate all'interno del container Docker utilizzando:
All'interno dell'output precedente è possibile vedere che la capacità DAC_READ_SEARCH è abilitata. Di conseguenza, il contenitore può eseguire il debug dei processi.
È possibile apprendere come funziona lo sfruttamento seguendo il link https://medium.com/@fun_cuddles/docker-breakout-exploit-analysis-a274fff0e6b3, ma in sintesi CAP_DAC_READ_SEARCH non solo ci consente di attraversare il file system senza controlli di autorizzazione, ma rimuove esplicitamente anche qualsiasi controllo su open_by_handle_at(2) e potrebbe consentire al nostro processo di accedere a file sensibili aperti da altri processi.
L'exploit originale che sfrutta queste autorizzazioni per leggere file dall'host può essere trovato qui: http://stealth.openwall.net/xSports/shocker.c, di seguito è riportata una versione modificata che consente di indicare il file da leggere come primo argomento e di salvarlo in un file.
L'exploit deve trovare un puntatore a qualcosa montato sull'host. L'exploit originale utilizzava il file /.dockerinit e questa versione modificata utilizza /etc/hostname. Se l'exploit non funziona, potrebbe essere necessario impostare un file diverso. Per trovare un file montato sull'host, esegui semplicemente il comando mount:
Il codice di questa tecnica è stato copiato dal laboratorio "Abusing DAC_READ_SEARCH Capability" di https://www.pentesteracademy.com/
RootedCON è l'evento sulla sicurezza informatica più rilevante in Spagna e uno dei più importanti in Europa. Con la missione di promuovere la conoscenza tecnica, questo congresso è un punto di incontro vivace per i professionisti della tecnologia e della sicurezza informatica in ogni disciplina.
CAP_DAC_OVERRIDE
Questo significa che puoi aggirare i controlli di autorizzazione in scrittura su qualsiasi file, quindi puoi scrivere qualsiasi file.
Ci sono molti file che puoi sovrascrivere per ottenere privilegi elevati, puoi trovare idee qui.
Esempio con un binario
In questo esempio, vim ha questa capacità, quindi puoi modificare qualsiasi file come passwd, sudoers o shadow:
Esempio con il binario 2
In questo esempio il binario python
avrà questa capacità. Potresti utilizzare python per sovrascrivere qualsiasi file:
Esempio con ambiente + CAP_DAC_READ_SEARCH (Docker breakout)
Puoi verificare le capacità abilitate all'interno del container Docker utilizzando:
Prima di tutto, leggi la sezione precedente che sfrutta la capacità DAC_READ_SEARCH per leggere file arbitrari dell'host e compila l'exploit. Successivamente, compila la seguente versione dell'exploit shocker che ti permetterà di scrivere file arbitrari nel filesystem dell'host:
Per scappare dal container Docker, è possibile scaricare i file /etc/shadow
e /etc/passwd
dall'host, aggiungere ad essi un nuovo utente e utilizzare shocker_write
per sovrascriverli. Successivamente, è possibile accedere tramite ssh.
Il codice di questa tecnica è stato copiato dal laboratorio "Abusing DAC_OVERRIDE Capability" da https://www.pentesteracademy.com
CAP_CHOWN
Ciò significa che è possibile cambiare la proprietà di qualsiasi file.
Esempio con un binario
Supponiamo che il binario python
abbia questa capacità, è possibile cambiare il proprietario del file shadow, cambiare la password di root ed elevare i privilegi:
Oppure con il binario ruby
che ha questa capacità:
CAP_FOWNER
Questo significa che è possibile modificare i permessi di qualsiasi file.
Esempio con un binario
Se Python ha questa capacità, è possibile modificare i permessi del file shadow, cambiare la password di root ed elevare i privilegi:
CAP_SETUID
Questo significa che è possibile impostare l'ID utente effettivo del processo creato.
Esempio con un binario
Se Python ha questa abilità, è possibile sfruttarla facilmente per ottenere privilegi di root:
Un altro modo:
CAP_SETGID
Questo significa che è possibile impostare l'ID del gruppo effettivo del processo creato.
Ci sono molti file che è possibile sovrascrivere per ottenere privilegi elevati, puoi trovare idee qui.
Esempio con un binario
In questo caso, dovresti cercare file interessanti che un gruppo può leggere perché puoi impersonare qualsiasi gruppo:
Una volta che hai trovato un file che puoi sfruttare (tramite lettura o scrittura) per ottenere privilegi elevati, puoi ottenere una shell impersonando il gruppo interessante con:
In questo caso è stata impersonata il gruppo shadow in modo da poter leggere il file /etc/shadow
:
Se docker è installato, potresti impersonare il gruppo docker e abusarne per comunicare con il socket docker e ottenere privilegi elevati.
CAP_SETFCAP
Questo significa che è possibile impostare le capacità su file e processi
Esempio con un binario
Se Python ha questa capacità, puoi facilmente abusarne per ottenere privilegi elevati come root:
Nota che se imposti una nuova capacità al binario con CAP_SETFCAP, perderai questa capacità.
Una volta ottenuta la capacità SETUID, puoi passare alla sua sezione per vedere come ottenere privilegi elevati.
Esempio con ambiente (Docker breakout)
Per impostazione predefinita, la capacità CAP_SETFCAP viene data al processo all'interno del container in Docker. Puoi verificarlo facendo qualcosa come:
Questa capacità consente di assegnare qualsiasi altra capacità ai binari, quindi potremmo pensare di evadere dal contenitore abusando di uno dei precedenti exploit di capacità menzionati in questa pagina. Tuttavia, se si prova ad assegnare ad esempio le capacità CAP_SYS_ADMIN e CAP_SYS_PTRACE al binario gdb, si scoprirà che è possibile assegnarle, ma il binario non sarà in grado di eseguire dopo questo:
Dalla documentazione: Permitted: Questo è un superset limitante per le capacità effettive che il thread può assumere. È anche un superset limitante per le capacità che possono essere aggiunte all'insieme ereditabile da un thread che non ha la capacità CAP_SETPCAP nel suo insieme effettivo. Sembra che le capacità consentite limitino quelle che possono essere utilizzate. Tuttavia, Docker concede anche il CAP_SETPCAP per impostazione predefinita, quindi potresti essere in grado di impostare nuove capacità all'interno dell'insieme ereditabile. Tuttavia, nella documentazione di questa capacità: CAP_SETPCAP : […] aggiunge qualsiasi capacità dall'insieme di bounding del thread chiamante al suo insieme ereditabile. Sembra che possiamo solo aggiungere all'insieme ereditabile le capacità dall'insieme di bounding. Ciò significa che non possiamo inserire nuove capacità come CAP_SYS_ADMIN o CAP_SYS_PTRACE nell'insieme ereditabile per l'escalation dei privilegi.
CAP_SYS_RAWIO
CAP_SYS_RAWIO fornisce una serie di operazioni sensibili, tra cui l'accesso a /dev/mem
, /dev/kmem
o /proc/kcore
, la modifica di mmap_min_addr
, l'accesso alle chiamate di sistema ioperm(2)
e iopl(2)
, e vari comandi del disco. L'ioctl(2)
FIBMAP
è anche abilitato tramite questa capacità, il che ha causato problemi in passato (qui). Come indicato nella pagina man, questo consente anche al detentore di eseguire in modo descrittivo una serie di operazioni specifiche del dispositivo su altri dispositivi.
Questo può essere utile per l'escalation dei privilegi e l'evasione di Docker.
CAP_KILL
Ciò significa che è possibile terminare qualsiasi processo.
Esempio con un binario
Supponiamo che il binario python
abbia questa capacità. Se potessi modificare anche qualche configurazione di servizio o socket (o qualsiasi file di configurazione relativo a un servizio), potresti inserire un backdoor e quindi terminare il processo relativo a quel servizio e attendere l'esecuzione del nuovo file di configurazione con il tuo backdoor.
Privesc con kill
Se hai le capacità di kill e c'è un programma node in esecuzione come root (o come un utente diverso), probabilmente puoi inviargli il segnale SIGUSR1 e farlo aprire il debugger di node a cui puoi connetterti.
RootedCON è l'evento di sicurezza informatica più rilevante in Spagna e uno dei più importanti in Europa. Con la missione di promuovere la conoscenza tecnica, questo congresso è un punto di incontro bollente per professionisti della tecnologia e della sicurezza informatica in ogni disciplina.
CAP_NET_BIND_SERVICE
Ciò significa che è possibile ascoltare su qualsiasi porta (anche su quelle privilegiate). Non è possibile scalare i privilegi direttamente con questa capacità.
Esempio con binario
Se python
ha questa capacità, sarà in grado di ascoltare su qualsiasi porta e persino connettersi da essa a qualsiasi altra porta (alcuni servizi richiedono connessioni da porte privilegiate specifiche)
CAP_NET_RAW
La capacità CAP_NET_RAW permette ai processi di creare socket RAW e PACKET, consentendo loro di generare e inviare pacchetti di rete arbitrari. Ciò può comportare rischi per la sicurezza in ambienti containerizzati, come il falsificare pacchetti, l'iniettare traffico e il bypassare i controlli di accesso alla rete. Attori malevoli potrebbero sfruttare ciò per interferire con il routing dei container o compromettere la sicurezza della rete dell'host, specialmente senza adeguate protezioni del firewall. Inoltre, CAP_NET_RAW è fondamentale per i container privilegiati per supportare operazioni come il ping tramite richieste ICMP RAW.
Ciò significa che è possibile intercettare il traffico. Non è possibile scalare i privilegi direttamente con questa capacità.
Esempio con un binario
Se il binario tcpdump
ha questa capacità, sarà possibile utilizzarlo per catturare informazioni di rete.
Nota che se l'ambiente fornisce questa capacità, è possibile utilizzare anche tcpdump
per intercettare il traffico.
Esempio con il binario 2
L'esempio seguente è un codice python2
che può essere utile per intercettare il traffico dell'interfaccia "lo" (localhost). Il codice proviene dal laboratorio "The Basics: CAP-NET_BIND + NET_RAW" da https://attackdefense.pentesteracademy.com/
CAP_NET_ADMIN + CAP_NET_RAW
La capacità CAP_NET_ADMIN concede al possessore il potere di modificare le configurazioni di rete, inclusi le impostazioni del firewall, le tabelle di routing, i permessi dei socket e le impostazioni dell'interfaccia di rete all'interno dei namespace di rete esposti. Consente inoltre di attivare la modalità promiscua sulle interfacce di rete, consentendo di intercettare i pacchetti attraverso i namespace.
Esempio con un binario
Supponiamo che il binario python abbia queste capacità.
CAP_LINUX_IMMUTABLE
Questo significa che è possibile modificare gli attributi dell'inode. Non è possibile ottenere direttamente privilegi di escalation con questa capacità.
Esempio con un binario
Se scopri che un file è immutabile e Python ha questa capacità, puoi rimuovere l'attributo di immutabilità e rendere il file modificabile:
Nota che di solito questo attributo immutabile viene impostato e rimosso usando:
CAP_SYS_CHROOT
CAP_SYS_CHROOT consente l'esecuzione della chiamata di sistema chroot(2)
, che potenzialmente permette di evadere gli ambienti chroot(2)
attraverso vulnerabilità conosciute:
CAP_SYS_BOOT
CAP_SYS_BOOT non solo consente l'esecuzione della chiamata di sistema reboot(2)
per riavviare il sistema, inclusi comandi specifici come LINUX_REBOOT_CMD_RESTART2
adattati a determinate piattaforme hardware, ma consente anche l'uso di kexec_load(2)
e, a partire da Linux 3.17, kexec_file_load(2)
per caricare nuovi kernel di crash o kernel firmati rispettivamente.
CAP_SYSLOG
CAP_SYSLOG è stato separato dalla più ampia CAP_SYS_ADMIN in Linux 2.6.37, concedendo specificamente la possibilità di utilizzare la chiamata di sistema syslog(2)
. Questa capacità consente la visualizzazione degli indirizzi del kernel tramite /proc
e interfacce simili quando l'impostazione kptr_restrict
è impostata su 1, che controlla l'esposizione degli indirizzi del kernel. A partire da Linux 2.6.39, il valore predefinito per kptr_restrict
è 0, il che significa che gli indirizzi del kernel sono esposti, anche se molte distribuzioni lo impostano su 1 (nascondi gli indirizzi tranne da uid 0) o 2 (nascondi sempre gli indirizzi) per motivi di sicurezza.
Inoltre, CAP_SYSLOG consente di accedere all'output di dmesg
quando dmesg_restrict
è impostato su 1. Nonostante queste modifiche, CAP_SYS_ADMIN conserva la capacità di eseguire operazioni di syslog
a causa di precedenti storici.
CAP_MKNOD
CAP_MKNOD estende la funzionalità della chiamata di sistema mknod
oltre alla creazione di file regolari, FIFO (named pipes) o socket di dominio UNIX. Consente specificamente la creazione di file speciali, che includono:
S_IFCHR: File speciali di carattere, che sono dispositivi come terminali.
S_IFBLK: File speciali di blocco, che sono dispositivi come dischi.
Questa capacità è essenziale per i processi che richiedono la capacità di creare file di dispositivo, facilitando l'interazione diretta con l'hardware tramite dispositivi di carattere o blocco.
È una capacità predefinita di Docker (https://github.com/moby/moby/blob/master/oci/caps/defaults.go#L6-L19).
Questa capacità consente di eseguire escalation di privilegi (attraverso la lettura completa del disco) sull'host, in queste condizioni:
Avere accesso iniziale all'host (non privilegiato).
Avere accesso iniziale al container (privilegiato (EUID 0) ed effettivo
CAP_MKNOD
).Host e container devono condividere lo stesso namespace utente.
Passaggi per creare e accedere a un dispositivo di blocco in un container:
Sull'host come utente standard:
Determina il tuo ID utente corrente con
id
, ad esempiouid=1000(standarduser)
.Identifica il dispositivo di destinazione, ad esempio
/dev/sdb
.
All'interno del container come
root
:
Tornando all'host:
Questo approccio consente all'utente standard di accedere e potenzialmente leggere i dati da /dev/sdb
attraverso il container, sfruttando i namespace utente condivisi e i permessi impostati sul dispositivo.
CAP_SETPCAP
CAP_SETPCAP consente a un processo di modificare i set di capacità di un altro processo, consentendo l'aggiunta o la rimozione di capacità dai set effettivi, ereditabili e consentiti. Tuttavia, un processo può modificare solo le capacità che possiede nel proprio set consentito, garantendo che non possa elevare i privilegi di un altro processo oltre i propri. Gli aggiornamenti recenti del kernel hanno reso più rigide queste regole, limitando CAP_SETPCAP
solo alla diminuzione delle capacità all'interno del proprio set consentito o di quello dei discendenti, al fine di mitigare i rischi per la sicurezza. L'utilizzo richiede di avere CAP_SETPCAP
nel set effettivo e le capacità di destinazione nel set consentito, utilizzando capset()
per le modifiche. Questo riassume la funzione principale e le limitazioni di CAP_SETPCAP
, evidenziando il suo ruolo nella gestione dei privilegi e nell'incremento della sicurezza.
CAP_SETPCAP
è una capacità di Linux che consente a un processo di modificare i set di capacità di un altro processo. Concede la possibilità di aggiungere o rimuovere capacità dai set di capacità effettivi, ereditabili e consentiti di altri processi. Tuttavia, ci sono alcune restrizioni su come questa capacità può essere utilizzata.
Un processo con CAP_SETPCAP
può solo concedere o rimuovere capacità che sono nel proprio set di capacità consentito. In altre parole, un processo non può concedere una capacità a un altro processo se non possiede quella capacità stessa. Questa restrizione impedisce a un processo di elevare i privilegi di un altro processo oltre il proprio livello di privilegio.
Inoltre, nelle versioni recenti del kernel, la capacità CAP_SETPCAP
è stata ulteriormente limitata. Non consente più a un processo di modificare arbitrariamente i set di capacità di altri processi. Invece, consente solo a un processo di ridurre le capacità nel proprio set di capacità consentito o nel set di capacità consentito dei suoi discendenti. Questo cambiamento è stato introdotto per ridurre i potenziali rischi per la sicurezza associati alla capacità.
Per utilizzare CAP_SETPCAP
in modo efficace, è necessario avere la capacità nel proprio set di capacità effettivo e le capacità di destinazione nel proprio set di capacità consentito. È quindi possibile utilizzare la chiamata di sistema capset()
per modificare i set di capacità di altri processi.
In sintesi, CAP_SETPCAP
consente a un processo di modificare i set di capacità di altri processi, ma non può concedere capacità che non possiede. Inoltre, a causa di preoccupazioni per la sicurezza, la sua funzionalità è stata limitata nelle versioni recenti del kernel per consentire solo la riduzione delle capacità nel proprio set di capacità consentito o nei set di capacità consentiti dei suoi discendenti.
Riferimenti
La maggior parte di questi esempi sono tratti da alcuni laboratori di https://attackdefense.pentesteracademy.com/, quindi se vuoi esercitarti con queste tecniche di privilege escalation, consiglio questi laboratori.
Altri riferimenti:
RootedCON è l'evento sulla sicurezza informatica più rilevante in Spagna e uno dei più importanti in Europa. Con la missione di promuovere la conoscenza tecnica, questo congresso è un punto di incontro vivace per i professionisti della tecnologia e della sicurezza informatica in ogni disciplina.
Last updated