span.fullpost {display:inline;}

mercoledì 5 agosto 2009

Toc Toc... bussa e ti sarà aperto...

Spesso capita che, nonostante si cerchi di blindare al massimo un sistema, ci sia il solito furbacchione che, magari con uno 0-day pagato a peso d'oro, riesce a penetrare il sistema, con tutto quello che ne consegue. Infatti, anche mettendo le policy più stringenti sugli accessi (anche in termini di ip) il fatto che un servizio rimanga esposto alla rete 24h/24 amplifica la possibilità che il servizio stesso venga exploitato.
Anche variare le porte sulle quali ascolta il servizio può risultare di scarsa utilità se l'aggressore è motivato e deciso. Analogo discorso per gli IDS, se l'attaccante è abbastanza esperto riuscirà facilmente a bypassare i meccanismi di allarme. L'idea è quella di fare in modo che il servizio necessario sia attivo solo quando serve realmente. Facciamo un esempio concreto: supponiamo di avere un fw perimetrale. Per prima cosa è bene che il fw non esporti nessun servizio, salvo ad esempio dns/dhcp preferibilmente solo verso la rete interna. Per amministrare il fw supponiamo di utilizzare una connessione ssh. Il fatto di permettere la sola autenticazione con chiave pubblica, di limitare il range di ip che possono connettersi e di variare la porta del servizio non mi garantisce che qualche utente possa bucare il sistema anche dal lato "sicuro" (il fatto che l'interfaccia interna di un fw sia "sicura" è del tutto opinabile...).
Dunque cosa possiamo fare? La necessità è che il servizio ssh sia attivo solo quando devo amministrare il fw.
Un approccio potrebbe essere questo: bussare ad una sequenza nota di porte e, come conseguenza, ottenere l'apertura della porta sulla quale ascolta il server.
La tecnica si chiama, appunto, Port Knocking. Un demone ascolta tutte le connessioni in entrata sul sistema, quando riceve la sequenza di SYN sulle porte indicate apre la porta relativa al servizio.
Esempio: supponiamo che il servizio ssh giri sulla porta 22, le porte da bussare siano 5641, 8942, 9265 e 5476. Inviando un pacchetto SYN (cioè di richiesta connessione) sulle porte, nell'ordine impostato, il demone di cui si diceva prima provvederà ad aprire la porta 22 e a rendere accessibile il servizio. Analogamente possiamo definire una sequenza di "bussata" che provveda a chiudere la porta 22 quando non è più necessaria. Credo che il demone più usato per il Port Knocking sia knockd che dovrebbe essere presente su tutte le piattaforme linux (non ho idea per i sistemi m$). Qui c'è il sito di knockd.
Per l'esempio fatto prima il file di configurazione /etc/knockd.conf potrebbe essere

[options]
logfile = /var/log/knockd.log

[openSSH]
sequence = 5641,8942,9265,5476
seq_timeout = 10
tcpflags = syn
command = /usr/sbin/iptables -A INPUT -s %IP% -p tcp --dport 22 -j ACCEPT

[closeSSH]
sequence = 5476,9265,8942,5641
seq_timeout = 10
tcpflags = syn
command = /usr/sbin/iptables -D INPUT -s %IP% -p tcp --dport 22 -j ACCEPT

quindi quando il demone intercetta la sequenza corretta di porte apre il servizio ssh. La sintassi della configurazione è piuttosto semplice e permette alcune interessanti variazioni. Avete presente il wake on lan? Bene si può implementare semplicemente il contrario, cioè visto che esiste l'opzione command perché non estendere la cosa implementando una cosa del tipo:

[options]
logfile = /var/log/knockd.log

[openSSH]
sequence = 5641,8942,9265,5476
seq_timeout = 10
tcpflags = syn
command = /usr/sbin/iptables -A INPUT -s %IP% -p tcp --dport 22 -j ACCEPT

[closeSSH]
sequence = 5476,9265,8942,5641
seq_timeout = 10
tcpflags = syn
command = /usr/sbin/iptables -D INPUT -s %IP% -p tcp --dport 22 -j ACCEPT

[shutdown]
sequence = 5521,6275,4462,2631
seq_timeout = 10
tcpflags = urg
command = /sbin/shutdown -h now


Come si può vedere in questo caso per spegnere la macchina bisogna inviare 4 pacchetti, uno per porta, con il flag "urg" invece che "syn".
Alcune considerazioni:
1) occhio ai flag che si usano per identificare i pacchetti. Il fw potrebbe essere configurato per droppare i pacchetti non syn che si riferiscono a connessioni non stabilite.
2) Implementare un meccanismo di port knocking non è, di per se stesso, un sistema per mettere in sicurezza una macchina. Un attaccante potrebbe, sniffando il vostro traffico, determinare la sequenza di bussata ed utilizzarla per aprire l'ssh. Quindi questo metodo deve essere usato assieme a tutti gli altri strumenti di protezione.
3) In questi esempi ho sempre usato porte tcp. Per usare porte udp basta modificare la configurazione inserendo, dopo il numero della porta, :udp. Così, ad esempio, potrebbe essere:

[openSSH]
sequence = 5641:udp,8942,9265:udp,5476
seq_timeout = 10
tcpflags = syn
command = /usr/sbin/iptables -A INPUT -s %IP% -p tcp --dport 22 -j ACCEPT

chiaramente poi il campo tcpflags ha valore solo per i pacchetti inviati alle porte tcp.
4) Siccome l'invio fuori sequenza o il bussare su una porta sbagliata porta al reset (cioè se la sequenza è 5641:udp,8942,9265:udp,5476 e io busso su 5641:udp,8942,9265:udp,5477) è bene evitare porte in uso, utilizzando porte "alte" per il knocking.

Come bussare? Ci sono vari metodi, se la combinazione di porte non è troppo complessa si può usare netcat, hping o, al limite, lo stesso nmap.

Mi pare sia più o meno tutto... provate a sperimentare e fatemi sapere.

0 commenti: