Qualche settimana fa rispetto a questo post Paolo Perego ha annunciato e pubblicato un video sull’analisi e l’exploiting di una macchina vulnhub: Breakout. In quel momento stavo valutando che contenuti presentare live su Twitch per il mese di agosto avendo previsto una minor partecipazione e volendo dedicare del tempo ad affinare un po’ le tecniche di red teaming. Ho quindi pensato di non guardare subito il video e di proporre live una sessione in cui eseguire lo stesso esercizio e, in un secondo momento, organizzare un confronto con Paolo per discutere i differenti approcci che possono essere utilizzati.
La scorsa settimana ho quindi tenuto la live in cui abbiamo, assieme ai presenti, giocato con la macchina fino a guadagnarci una shell come root. Da qui sono nate un po’ di riflessioni su come un attacker potrebbe agire in un contesto simile anche se, come discusso, per certi versi non proprio così realistico. Oltre al tema dell’accesso al sistema ci sono almeno altri due argomenti da approfondire: il post-exploiting e l’accesso permanente tramite un Command and Control (C2). Andiamo con ordine.
Scenario
La macchina è disponibile in formato OVA sul sito di vulnhub a questo link, è possibile quindi scaricare ed importare rapidamente il sistema sia su VMware Workstation/ESXi che su VirtualBox. La configurazione di default del sistema presenta una NIC configurata in DHCP, una volta accesa la macchina e collegata la NIC il sistema chiederà al DHCP server della rete in cui lo avrete posizionato un indirizzo IP usabile.

Nel laboratorio presentato durante la live abbiamo fatto tutto praticamente solo con due VMs: la macchina Kali utilizzata come base di partenza delle azioni offensive e la macchina Breakout. Il laboratorio che utilizzeremo in questa sessione è lievemente più esteso per avvicinarci ad un contesto reale ed è composto da:
- il mio laptop con la wls Kali dietro NAT
- un server/host per ospitare le guest:
- una VM ubuntu che utilizzeremo come macchina d’appoggio
- la VM target
Fatta eccezione per la Kali tutte le altre VM connesse alla rete LAN del laboratorio e sono quindi nello stesso dominio di broadcast.

Ovviamente non ci sono particolari vincoli nella configurazione del laboratorio, accertatevi sono di avere almeno un sistema di grado di dialogare in modo bidirezionale con la macchina target in modo da lasciarci aperte più opzioni di comunicazione.
Rilevamento della macchina target e delle applicazioni
In questo caso è un’operazione superflua in quando siamo perfettamente a conoscenza dell’indirizzo IP della macchina target. In un contesto reale saremmo partiti da una serie di rilevamenti utilizzando tecniche di scansione passiva e attiva. Facendo un semplice scansione con nmap possiamo renderci conto di cosa c’è in rete, solitamente io inizio con qualcosa di molto leggero usando la funzione TCP Connect Scan o anche semplicemente con un hping:
$ nmap -sT 192.168.1.8

$ sudo hping3 192.168.1.x --rand-dest --interface eth0
Una volta individuata la macchina target ha sicuramente senso intensificare la scansione per raccogliere qualche info aggiuntiva sul sistema, in particolare ci interessa capire tutto ciò che espone a livello di servizi e, se possibile, qualche dato sulle applicazioni che stanno dietro. Continuiamo con nmap ma andiamo a verificare tutte le porte ed utilizziamo anche tutti gli script disponibili di default:
$ nmap -p- -sV --script=default 192.168.1.8 -oA breakout-scan.txt
Per comodità l’output lo salviamo su in file in modo da annotare quanto rilevato e consultarlo in caso di necessità senza eseguire nuove scansioni.

Abbiamo un bel po’ di dati, andiamo con ordine e vediamo cosa ci racconta di se il nostro target.
Porta 80/tcp aperta
La porta 80 è tra le più famose e ci fa pensare che il sistema abbia un web server attivo che nmap rileva come Apache versione 2.4.51. Viene anche individuato il sistema operativo Debian. Se è veramente disponibile un web server possiamo verificarlo facilmente semplicemente aprendo il browser e puntando all’IP della macchina target:

La default page di Apache2 è sufficientemente eloquente.
Porte 139\tcp e 445\tcp
Viene identificato un servizio Samba versione 4.6.2 che ci potrebbe aiutare ad approfondire qualche dato utilizzando specifici tools di enumerazione e verifica delle configurazioni “disponibili”.
Porte 10000\tcp e 20000\tcp
Viene rilevata l’applicazione “Webmin” in due differenti versioni: sulla porta 10000 è attiva la versione 1.981, sulla porta 20000 è attiva la versione 1.830. Durante la live mi sono documentato sull’applicazione che non avevo mai incontrato, si tratta di un tool per gestire server e applicazioni di uso comune come sistemi di pubblicazione contenuti, database, job.
Le due porte tcp sono di fatto utilizzate per esporre le interfacce web dell’applicazione Webmin e possiamo dare una sbirciata a ciò che si vede semplicemente accedendo con il nostro browser in https e specificando la porta da utilizzare:

Mentre la porta 10000 presenta la schermata di login per l’area amministrativa, sulla porta 20000 si potrà notare un’interfaccia leggermente diversa che fa riferimento a Usermin. Si tratta di fatto di due diverse applicazioni con scopi differenti ma soprattutto i relativi utenti hanno privilegi di accesso al sistema molto differenti: la parte amministrativa potrebbe infatti accedere con privilegi di root.
Analisi dei contenuti web
Durante la mia live a questo punto sono passato ad analizzare ciò che era visibile, ovvero le pagine web e le relative componenti, cercando documentazione specifica sull’applicazione che evidentemente viene pubblicata dal sistema. Paolo nella sua analisi ha eseguito anche un altro controllo che sul momento a me non era venuto in mente: con GoBuster ha dato un’occhiata alle directory pubblicate.
Per usare tools come GoBuster è indispensabile disporre di qualche wordlist e se usate kali troverete un patrimonio di file in /usr/share/wordlist. Anche per questo lab sto utilizzando kali ma è una installazione minima su wls2, devo quindi prima installare il pacchetto:

Altre wordlist sono facilmente reperibili online, personalmente utilizzo quella di dirbuster disponibile qui: https://github.com/daviddias/node-dirbuster/tree/master/lists.
Abbiamo tutto il necessario per iniziare la scansione. Vi suggerisco, vista la dimensione dell’output, di buttare tutto in un file dedicato. L’operazione potrebbe richiedere qualche minuto e non è detto che si trovino informazioni utili.
$ gobuster dir -w /usr/share/wordlists/dirb/directory-list-lowercase-2.3-medium.txt -u https://192.168.1.8:10000 --wildcard -k > breakout_p10000.txt

E’ interessante osservare l’effetto di un’attività di questo tipo sulla macchina target: nel mio caso ho creato una VM con una vCPU a cui è stato assegnato il 70% di un vCORE della macchina host. Con la scansione attiva la macchina guest si trova ad avere il 100% di CPU usage a testimoniare che alcune azioni possono essere anche molto invasive in termini di system load. Se un attacker utilizzasse una tecnica di questo tipo senza eseguire prima del tuning a livello di richieste per secondo è molto probabile che i sistemi di monitoraggio segnalino anomalie di carico.

Nota tecnica sui tools di Directory Discovery: che sia GoBuster, DirBuster, fuff, […] il principio non cambia, usate quello che vi pare.
Oltre alla directory è opportuno verificare il contenuto delle pagine web. In questo caso abbiamo tre contenuti html: la default page di apache e le due login page di Webmin. Su questi specifici contenuti è possibile dare una semplice occhiata al sorgente o, per analisi più approfondite, utilizzare tools come BurpSuite (nella versione pro) per eseguire una scansione dell’applicazione a caccia di specifiche vulnerabilità.
In questo caso siamo in un contesto CTF e non è raro che vengano disseminati piccoli indizi qua e la nei sistemi, una veloce verifica del sorgente HTML porta infatti in evidenza uno di questi indizi: alla default page di apache è stata fatta un’aggiunta.

Si tratta di un commento HTML che riporta un testo cifrato con un metodo noto come Brain F*ck. Google è vostro, non farete nessuna fatica a trovare un tool di decodifica da cui uscirà una stringa che qui in parte nascondo: .2uqPEfj3D<P’*** .
Ha l’aspetto di una password e visto il messaggio nel commento HTML probabilmente lo è ma non abbiamo idea dell’utente associato. Durante la live ho provato ad utilizzare questa potenziale password associata all’utente root e admin su entrambe le interfacce di login ma senza successo.
Analisi dei servizi SMB
La scansione delle porte ha riportato la presenza di un servizio Samba 4.6.2 attivo sul sistema per il quale possiamo fare diverse verifiche a caccia di ulteriori informazioni o anche di livelli di accesso specifici. Per fare enumeration di smb abbiamo moltissimi tools a disposizione, primo tra tutti citerei enum4linux che di fatto ho utilizzato per primo anche in questo caso:

In questo caso la caccia è andata bene, la verifica ha fatto emergere un utente smb: cyber.

Da notare che nell’analisi dei contenuti era saltata fuori quella che sembrava essere una password.
Analisi delle applicazioni
Ci siamo imbattuti in un’applicazione web-based per la gestione del server: Webmin. La scansione ci aveva indicato le versioni delle applicazioni esposte, ha quindi senso verificare se esistono vulnerabilità note ed eventuali exploit. Basta una rapida ricerca su exploit-db.com per accorgersi che di vulnerabilità ne esistono diverse:

Meglio ancora, senza neanche lasciare la nostra cli come fatto durante la live, una query con searchploit ci da subito lo status di cosa è disponibile subito:

Le vulnerabilità non mancano ma le versioni non corrispondono, in questo caso ha poso senso tentare questa strada in quanto la probabilità di successo è praticamente nulla salvo incappare per puro caso in una versione vulnerabile ma non documentata.
Anche in relazione alla versione di Apache è opportuno fare un approfondimento (non fatto durante la live). Nmap ha rilevato la versione 2.4.51 a cui sono associate un paio di CVE:
Su queste CVE non ci sono exploit noti ma esiste documentazione interessante in relazione ad un p-o-c per la vulnerabilità del modulo “mod_lua” che non abbiamo ancora avuto modo di verificare in questa installazione. In questo contesto non procedo oltre ma potrebbe essere interessante approfondire in futuro ovviamente in un contesto dove è presente uno script lua. Metto in ToDo 😉
Accesso all’applicazione
Come emerso dalle nostre ricerche abbiamo un utente ed una credenziale che a questo punto vale la pena provare. L’unico punto di accesso incontrato sono le due applicazioni Webmin e Usermin ed è qui che facciamo il primo tentativo. La login page dell’applicazione Usermin (porta tcp\20000) vi darà accesso al portale; navigando un po’ le funzionalità dell’applicazione ci si imbatte in una web-shell all’interno del menu Login >> Command Shell:

In questa situazione la prima cosa da fare è raccogliere informazioni sul sistema cercando di capire come è configurato e che software è in uso. Partiamo con questa sequenza di comandi:
pwd && ls -l && id && ps ax
Per ottengo questo output:
> pwd && ls -l && id && ps ax
/home/cyber
total 616
-rwxr-xr-x 1 root root 531928 Oct 19 2021 tar
-rw-r--r-- 1 cyber cyber 48 Oct 19 2021 user.txt
uid=1000(cyber) gid=1000(cyber) groups=1000(cyber),24(cdrom),25(floppy),29(audio),30(dip),44(video),46(plugdev),109(netdev)
PID TTY STAT TIME COMMAND
[...]
284 ? Ssl 0:00 /sbin/dhclient -4 -v -i -pf /run/dhclient.eth0.pid -lf /var/lib/dhcp/dhclient.eth0.leases -I -df /var/lib/dhcp/dhclient6.eth0.leases eth0
313 ? Ss 0:00 /usr/sbin/cron -f
314 ? Ss 0:00 /usr/bin/dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation --syslog-only
325 ? Ss 0:00 /usr/sbin/nmbd --foreground --no-process-group
329 ? Ssl 0:00 /usr/sbin/rsyslogd -n -iNONE
330 ? Ss 0:00 /lib/systemd/systemd-logind
385 tty1 Ss+ 0:00 /sbin/agetty -o -p -- \u --noclear tty1 linux
392 ? Ss 0:00 /usr/sbin/apache2 -k start
524 ? Sl 0:00 /usr/sbin/apache2 -k start
525 ? Sl 0:00 /usr/sbin/apache2 -k start
596 ? Ss 0:00 /usr/bin/perl /usr/share/usermin/miniserv.pl /etc/usermin/miniserv.conf
598 ? Ss 0:00 /usr/bin/perl /usr/share/webmin/miniserv.pl /etc/webmin/miniserv.conf
668 ? Ssl 0:00 /lib/systemd/systemd-timesyncd
691 ? Ss 0:00 /usr/sbin/smbd --foreground --no-process-group
693 ? S 0:00 /usr/sbin/smbd --foreground --no-process-group
694 ? S 0:00 /usr/sbin/smbd --foreground --no-process-group
696 ? S 0:00 /usr/sbin/smbd --foreground --no-process-group
774 ? I 0:00 [kworker/u2:0-flush-8:0]
793 ? I 0:01 [kworker/0:0-events]
872 ? S 0:00 /usr/share/usermin/shell/index.cgi
875 ? S 0:00 sh -c /bin/su cyber -c cd\ \/home\/cyber\ \&\&\ pwd\ \&\&\ ls\ \-l\ \&\&\ id\ \&\&\ ps\ ax 2>&1
876 ? S 0:00 /bin/su cyber -c cd /home/cyber && pwd && ls -l && id && ps ax
878 ? Ss 0:00 /lib/systemd/systemd --user
879 ? S 0:00 (sd-pam)
897 ? Rs 0:00 ps ax
Siamo della home dell’utente cyber dove troviamo due file: un binario di tar (già questo è curioso) ed il file user.txt.
Altra cosa che mi viene naturale fare è buttare un occhio alla /usr/bin per rendermi conto di che utility possiamo disporre:

Stessa cosa per la /var a caccia di info nei logs e dove si nota una directory backups:

> ls -la /var/backups
total 32
drwxr-xr-x 2 root root 4096 Aug 26 18:33 .
drwxr-xr-x 14 root root 4096 Oct 19 2021 ..
-rw-r--r-- 1 root root 1467 Oct 19 2021 apt.extended_states.1.gz
-rw------- 1 root root 17 Oct 20 2021 .old_pass.bak
Salta abbastanza all’occhio il file .old_pass.bak in un path che spesso cerco volutamente, ovvero tutto ciò che ha a che fare con backup e dump. Il file è accessibile solo per l’utente root.
Teniamo sempre presente che il contesto in cui siamo è quello di una macchina preparata appositamente per essere compromessa, sono quindi presenti delle tracce o degli indizi più o meno visibili. In questo caso quel “tar” nella home dell’utente salta anche fin troppo all’occhio e, considerando le funzionalità del tool, potrebbe tornare utile se volessimo “leggere” in modo alternativo il contenuto di un file.
Esistono diversi modi per accedere ad un file che è accessibile solo all’utente root senza essere root: il più noto è forse l’utility sudo che ci consente di eseguire un comando con i privilegi super user (Super User DO) con il “problema” di concedere forse troppo agli utenti. Un altro metodo, che personalmente utilizzo poco, è quelle di assegnare ad un eseguibile (e quindi al suo processo) delle capacità aggiuntive chiamate appunto capabilities.
Quanto abbiamo a disposizione – la shell dell’utente cyber – ci consente di eseguire questo tipo di verifica:

Con il comando getcap possiamo verificare che capabilities sono state assegnato ad uno specifico file/processo, in questo caso abbiamo come output cap_dac_read_search=ep. Diamo un occhio alla documentazione ufficiale in tema di capabilities:

Molto eloquente direi, l’eseguibile tar è stato dotato della capacità di leggere un file a prescindere dai permessi a questo associati, in parole povere il nostro /home/cyber/tar può leggere qualsiasi file e noi abbiamo un file da leggere che richiede di essere super user. Idee?
Privilege escalation
Il nome del file a cui stiamo puntando è “old_pass.bak”, la nostra speranza è quindi quella di trovare le info per accedere come root al sistema. Visto che il nostro tar può leggere questo file proviamo a creare un archivio:

L’archivio viene comunque creato e l’owner è ovviamente l’utente cyber, possiamo quindi procedere ad una estrazione del contenuto usando anche l’utility tar di sistema visto che la letture del file ormai è avvenuta correttamente e l’archivio è di proprietà del nostro utente:

I più attenti noteranno che viene estratta una directory (var), tutto corretto visto che quando abbiamo creato l’archivio abbiamo puntato ad un path assoluto (/var/backups) e non solo al file di nostro interesse. Dentro la directory troveremo finalmente il nostro file a cui sono ora attribuiti i permessi sufficienti per essere letto anche dall’utente cyber:

Non resta che provare questa potenziale password per l’utente root, la prima verifica è per la web-shell che abbiamo utilizzato sino ad ora:

Passando la password al comando “su” evitiamo che ci venga chiesta a livello prompt, azione necessario visto che tramite la web-shell poi non potremmo inserirla. In live avevamo subito utilizzato una reverse shell quindi fu possibile inserire la password dopo aver dato il comando “su”.
Abbiamo però appurato che la password è corretta avendo come output del comando “id” la stringa “uid=0(root)”. Possiamo quindi sicuramente dare comandi come root da questa web-shell ma ancora meglio potremmo utilizzare questa credenziale per accedere alla parte amministrativa dell’applicazione disponibile sulla porta tcp\10000.

Anche in questa sezione dell’applicazione abbiamo un comoda web-shell che questa volta accede al sistema come root:

A questo punto la macchina è nostra.
Prossimi step
Come da premesse in questo post volevo illustrare gli step e le analisi che ci hanno condotto ad ottenere un accesso root al sistema. Possiamo andare ben oltre e iniziare a lavorare sulla macchina per comprendere il contesto in cui si trova, le configurazione base e come potrebbe essere governata da remoto.
Ovviamente alcuni di questi ragionamenti li farò assieme ai presenti alle prossime live (questa sera, 16 settembre, affrontiamo parte dell’argomento) e seguiranno gli articoli di resoconto.