AD-ventures in offensive security – Parte 3/9 – Unquoted Service Path
“Disclaimer: Gli strumenti e le tecniche descritte in questo articolo sono destinati esclusivamente a scopi educativi e di ricerca nel campo della sicurezza informatica. L’uso di tali strumenti e tecniche contro sistemi informatici senza il consenso esplicito del proprietario è illegale e può comportare gravi conseguenze legali. L’autore e gli editori declinano qualsiasi responsabilità per l’abuso o l’uso improprio di queste informazioni da parte degli utenti. Si consiglia vivamente di ottenere il consenso scritto prima di condurre qualsiasi tipo di test o di valutazione della sicurezza su sistemi informatici.”
Questo articolo è parte della serie AD-ventures: La battaglia per la sicurezza di Active Directory – ICT Power
Nell’articolo precedente abbiamo parlato di LLMNR/NBT-NS Poisoning Attack ed abbiamo visto come sia possibile, in determinate circostanze, ottenere delle credenziali da utilizzare per un accesso valido in un sistema. Continuiamo il nostro percorso tentando di utilizzare una delle possibili tecniche che permettono di ottenere maggiori privilegi. Ne esistono svariate che hanno impatti sulle configurazioni più disparate ma, in questo caso, parleremo di Unquoted Service Path.
Unquoted Service Path
La Unquoted Service Path è una tecnica di privilege escalation che sfrutta una vulnerabilità nelle configurazioni dei percorsi degli eseguibili all’interno degli ambienti Windows.
Quando si crea un servizio è necessario specificare il percorso dell’eseguibile che dovrà essere utilizzato. Tuttavia, se questi contiene spazi e non è racchiuso tra virgolette (doppi apici), si introduce una vulnerabilità conosciuta come Unquoted Service Path. In questo scenario, un utente malintenzionato può sfruttare questa debolezza per ottenere privilegi amministrativi elevati, specialmente se il servizio vulnerabile viene eseguito con tali privilegi, circostanza non rara purtroppo.
Nel caso in cui siano presenti degli spazi nel cosiddetto execution path, il sistema operativo interpreta erroneamente il percorso “rompendo” il path al primo spazio ed eseguendo il resto come se fossero dei parametri da passare come argomento all’eseguibile. Qual è la causa questo comportamento? Una funzione presente nelle Windows API utilizzata per la creazione di nuovi processi, precisamente la CreateProcessA.
Figura 1 – Funzione CreateProcessA
Non voglio dilungarmi sulla descrizione di questa funzione, non è lo scopo di questo articolo. Ciò di cui è importante conoscerne il funzionamento è relativo alla prima dichiarazione nella funzione: LPCSTR lpApplicationName, ovvero un puntatore a una stringa costante “null-terminata” con set di caratteri Windows ANSI a 8 bit. A cosa serve questa informazione? Questa stringa contiene il full path ed il filename di ciò che dovrà essere eseguito con tanto di set di caratteri. Che succede, quindi, se è presente uno spazio?
La stringa, se non delimitata da doppi apici, viene presa in esame da sinistra a destra fino al raggiungimento dello spazio, viene troncata e si aggiunge l’estensione “.exe”.
Facciamo un esempio:
Immaginiamo di avere un eseguibile ubicato nel path C:\Program Files\ICT Power\ict.exe
Il sistema tenterà di gestire l’eseguibile interpretando la stringa in questo preciso ordine:
- C:\Program.exe
- C:\Program Files\ICT.exe
- C:\Program Files\ICT Power\ict.exe
Se “Program.exe”, punto 1, non viene trovato il sistema passa al punto successivo, e così via.
Quindi, dobbiamo prestare attenzione al path di un eseguibile, soprattutto se questi viene gestito da Windows. A tale proposito apriamo lo snap-in dei servizi per recuperare altre informazioni
Figura 2 – Elenco servizi
Il processo che li gestisce si chiama Service Control Manager, ubicato in %SystemRoot%\System32\services.exe e si occupa di interagire con i servizi attraverso le Windows API. Le possibili configurazioni sono varie, ad esempio relative alla tipologia di startup, utenze, stato, ecc…
Lo Startup Type rappresenta le modalità di avvio del servizio e può essere configurato in quattro modi:
- Automatico (Ritardato): l’avvio del servizio avviene dopo un breve intervallo di tempo a seguito del completamento di operazioni critiche per il boot, in questo modo l’avvio di Windows avviene più velocemente
- Automatico: l’esecuzione del servizio avviene all’avvio del sistema
- Manuale: il servizio viene avviato da un utente o da un’applicazione
- Disabilitato: il servizio è nello stato disabilitato che ne impedisce l’esecuzione
Figura 3 – Startup Type di un servizio
Come è possibile notare nell’immagine in figura 2, nella colonna “Log On As” ci sono degli utenti “predefiniti” denominati Service Account:
- LocalService Account
- NetworkService Account
- LocalSystem Account
Ognuno di questi definisce il perimetro di sicurezza in cui viene eseguito il servizio specifico, vediamo il dettaglio.
LocalService account: è un account di servizio pensato per eseguire servizi con meno privilegi. Accede alla rete come utente anonimo.
- Il nome completo è NT AUTHORITY\LocalService
- L’account non ha password e qualsiasi informazione in merito passata in fase di configurazione viene ignorata
- Il profilo di questo utente è presente sotto HKEY_USERS\S-1-5-19
- Ha privilegi minimi sul computer locale
NetworkService account: è un account di servizio pensato per eseguire servizi con qualche privilegio. Questo account è molto più limitato di un amministratore e accede alla rete come macchina; quindi, presenta le credenziali del computer ai server remoti.
- Il nome completo è NT AUTHORITY\NetworkService
- L’account non ha password e qualsiasi informazione in merito passata in fase di configurazione viene ignorata
- Il profilo di questo utente è presente sotto HKEY_USERS\S-1-5-20
- Ha privilegi minimi sul computer locale
- Presenta le credenziali del computer ai server remoti quando contattati
LocalSystem account: è un account di servizio più affidabile dell’account Administrator. Può fare qualunque cosa sulla macchina ed ha la possibilità di accedere alla rete come macchina (previa configurazione di Active Directory e relative grant)
- Il nome completo è <COMPUTERNAME>\LocalSystem
- L’account non ha password e qualsiasi informazione in merito passata in fase di configurazione viene ignorata
- Il profilo di questo utente è presente sotto HKEY_USERS\S-1-5-18 che non è specifico per LocalSystem bensì associato all’utente predefinito (default user).
- Ha privilegi ampi sul computer locale
- Presenta le credenziali del computer ai server remoti quando contattati
Figura 4 – Registro di sistema
Con queste informazioni di base possiamo immaginare una strategia da applicare per eseguire una privilege escalation, dobbiamo solo cercare bene e capire il giusto ordine di passi da seguire. Un esempio è trovare quei servizi il cui startup type è configurato su automatico, eseguiti con l’utente LocalSystem, il path (executable path) abbia degli spazi e sia senza doppi apici.
Attacco
Dopo aver carpito delle credenziali valide con la tecnica NTLM Relay descritta nell’articolo precedente ed aver effettuato un accesso ad una VM, utilizziamo le informazioni descritte nel primo articolo di questa rubrica, ovvero la ricerca delle informazioni del dominio Active Directory per capire cosa sfruttare. Tra le varie attività di ricerca controlliamo anche i servizi per capire se la tecnica Unquoted Service Path è applicabile.
Le credenziali che assumiamo di aver acquisito sono relative all’utente LAB\dcaldarelli, un domain user semplice
Figura 5 – Informazioni utente
Figura 6 – Privilegi utente
Procediamo cercando i servizi che sono configurati con Startup Type configurato su automatico. Per farlo utilizziamo PowerShell, evitando di cercare nella directory C:\Windows poiché, di default, non ci sono servizi senza doppi apici e con spazi e, contestualmente, escludendo dalla ricerca quelli tra doppi apici. Il comando può essere il seguente:
1 |
Get-WmiObject -class Win32_Service -Property Name, DisplayName, PathName, StartMode | Where {$_.PathName -notlike "C:\Windows*" -and $_.PathName -notlike '"*'} | select Name,DisplayName,StartMode,PathName |
Figura 7 – Ricerca servizio vulnerabile
Possiamo verificare ulteriori dettagli del servizio da CMD
Figura 8 – Dettagli servizio
Verifichiamo di avere la possibilità di scrivere all’interno di questa directory
Figura 9 – Verifica privilegi
Possono scriverci i “BUILTIN\Users“. Quindi proviamo ad accedere alla directory che contiene l’eseguibile
Figura 10 – Verifica contenuto directory
Bene! A questo punto il servizio “ICT Power Service” può essere utilizzato per tentare una privilege escalation. Secondo quanto detto all’inizio dell’articolo, possiamo sfruttare la vulnerabilità inserendo un eseguibile creato ad hoc nella directory “ICT Power”, un eseguibile contenente, ad esempio, una reverse shell. Identificata la directory “Dom Test”, ubichiamo al suo fianco l’eseguibile il cui nome inizierà con le prime lettere del nome della directory, in modo da essere invocato prima della directory stessa.
Figura 11 – Strategia attacco
Assumendo di non avere i privilegi per effettuare stop e start del servizio possiamo riavviare la macchina dopo aver posizionato l’eseguibile per ottenere lo stesso risultato. Il servizio è eseguito da LocalSystem, utente che lo gestisce come visto in figura 8, ma non eseguirà ICT.exe, bensì Dom.exe nella directory “ICT Power”, consentendoci di completare la privilege escalation ottenendo una nuova shell.
Per creare la reverse shell possiamo utilizzare il framework MSFVenom preinstallato nelle distro Kali linux.
Figura 12 – Creazione eseguibile con reverse shell
In questo caso ho utilizzato il payload windows/shell_reverse_tcp e la porta 4444.
Per effettuare l’upload del file Dom.exe possiamo utilizzare vari metodi, io ho preferito python per eseguire un webserver sulla macchina kali linux
Figura 13 – Esecuzione webserver
Dalla macchina Windows, è sufficiente utilizzare curl per effettuare il download dell’eseguibile
Figura 14 – Download eseguibile
Figura 15 – Verifica download
Mettiamo un listener in ascolto sulla porta scelta in fase di creazione dell’eseguibile, in questo caso, la porta 4444, in attesa di ricevere la shell
Figura 16 – Esecuzione listener
Se abbiamo fatto tutto bene, al riavvio della VM Windows il servizio eseguirà Dom.exe fornendoci la shell privilegiata.
Figura 17 – Ricezione della reverse shell privilegiata
Come difendersi
Per evitare che questa vulnerabilità sia sfruttata è sufficiente assicurarsi che il path dei servizi sia incluso tra doppi apici quando sono presenti spazi.
L’azione più veloce è utilizzando il registro di sistema, navigare fino a HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services e verificare la chiave “ImagePath” di ogni servizio
Figura 18 – Path servizio vulnerabile
Figura 19 – Path servizio non vulnerabile
Conclusioni
Anche in questo caso è facile notare come una leggerezza possa avere conseguenze devastanti. Questo è un tipico esempio di come sia necessario estendere la cultura della sicurezza a tutti per evitare che un deploy e/o un’installazione di un servizio rendere vulnerabile un sistema creduto sicuro.
Come sempre abbiamo a disposizione tanti strumenti per migliorare le nostre infrastrutture, per prendercene cura. La consapevolezza deve essere il mantra del 2024, in modo da concentrare l’attenzione dove realmente è necessario.
Stay tuned!