La tecnica del port knocking – Parte 2

Riprendiamo il nostro discorso sul port knocking. Dopo aver visto brevemente in cosa consiste concettualmente questa tecnica, cerchiamo di approfondirne alcuni aspetti.
Tramite il port knocking è possibile cambiare dinamicamente le regole di filtraggio del firewall, aprendo determinate porte sul server solo quando necessario. Questa tecnica, seppur molto semplice, risulta un’utile risorsa per la sicurezza.
Sempre dal lato della sicurezza, il nostro server Linux che si appoggi su iptables può essere configurato in modo che venga utilizzata l’azione DROP anzichè REJECT in modo che il server, invece che restituire errori, si limiti a scartare il pacchetto arrivato senza inviare alcun messaggio di errore a chi ha fatto richiesta del servizio. In questo modo, oltre ad avere le porte chiuse, il nostro server non darà modo di distinguere tra il rifiuto del pacchetto e l’assenza del server stesso.
Come abbiamo già visto nel precedente articolo, è possibile quindi che nel server sia attivo SSH ma la relativa porta di comunicazione, cioè la 22, sia in stato closed.

Con questa tecnica, solo un utente che è a conoscenza della corretta sequenza di knocking potrà aprire la porta ed avere accesso al servizio, in quanto il server, riconoscendo la sequenza, è in grado attraverso il demone dedicato di cambiare dinamicamente le proprie regole iptables, cioè il filtraggio applicato dal firewall.

Con il comando

iptables -P INPUT DROP

si può appunto fare in modo che il server non invii messaggi di errore a chi richiede i servizi. In questo modo, un utente che provi ad inviare una sequenza di knocking tipo quella che abbiamo visto nell’articolo precedente:

knock -v 10.0.0.1 7000 8000 9000

non riceverà dal server alcun messaggio, come se la “bussata” non avesse avuto successo, proprio come se la macchina di destinazione non esistesse.
Però il server interpreta silenziosamente la sequenza e, nel caso risulti valida, esegue il comando relativo a quella specifica bussata.

Come abbiamo già accennato nell’articolo sugli attacchi brute force e a dizionario, il servizio SSH è spesso soggetto a tentativi di intrusione in seguito a port scan. Configurando il server con l’opzione DROP, si inibisce questo tentativo perchè il server non può venire rintracciato con una normale attività di port scanning.
Oltre a questo, se si pensa che il servizio SSH può essere protetto nel modo già visto nel nostro articolo “Rendere sicuro SSH“, nel caso in cui il tentativo di intrusione con port knocking avesse successo, rimarrebbe comunque da superare il meccanismo di sicurezza basato su chiavi.

Il port knocking è quindi un’ottima forma di hardening del nostro sistema, infatti grazie a questa tecnica possiamo ridurre la superficie di attacco del nostro server limitando così i problemi legati alla sicurezza.

Oltre agli esempi già visti la scorsa volta, vediamo oggi altri tipi di configurazione.

AUMENTARE LA COMPLESSITA’ DELLE BUSSATE
Rispetto al nostro precedente articolo, potremmo modificare il file  /etc/knockd.conf in questo modo:

[openSSH]
sequence = 7000:udp,8000:tcp,9000:udp
seq_timeout = 5
command = /sbin/iptables -A INPUT -s %IP% -p tcp –dport 22 -j ACCEPT
tcpflags = syn

Mentre prima, non avendo specificato il tipo di protocollo, per default la sequenza veniva interpretata utilizzando il solo protocollo TCP, adesso specificando il protocollo TCP o UDP possiamo aumentare la complessità della bussata e quindi la sicurezza.

IMPOSTARE UN TIMEOUT
Si può anche impostare un timeout per la chiusura automatica delle porte dopo che il client abbia ottenuto l’accesso senza che il canale venga chiuso. Vediamo un esempio di utilizzo.

Per impostare la chiusura automatica di una porta invece di dover inviare una sequenza di knock, potremmo configurare il demone in questo modo:

[openSSH]
sequence = 7000,8000,9000
seq_timeout = 5
tcpflags = syn
start_command = /sbin/iptables -A INPUT -s %IP% -p tcp –dport 22 -j ACCEPT
cmd_timeout = 25
stop_command = /sbin/iptables -D INPUT -s %IP% -p tcp –dport 22 -j ACCEPT

Così facendo, dopo il timeout impostato, verrà lanciato automaticamente il comando di chiusura senza intervento da parte del client.

APRIRE PIU’ PORTE CONTEMPORANEAMENTE
Se vi fosse la necessità di aprire più porte contemporaneamente, si potrebbero creare script da far eseguire:

[openSSH]
sequence = 7000,8000,9000
seq_timeout = 5
command = /usr/local/bin/open_ports %IP%
tcpflags = syn

[closeSSH]
sequence = 9000,8000,7000
seq_timeout = 5
command = /usr/local/bin/close_ports %IP%
tcpflags = syn

I due script in questione conterranno il seguente codice:
open_ports:

#! /bin/bash
iptables -A INPUT -s $1 -p tcp –dport 21 -j ACCEPT
iptables -A INPUT -s $1 -p tcp –dport 22 -j ACCEPT
iptables -A INPUT -s $1 -p tcp –dport 80 -j ACCEPT

close_ports:

#! /bin/bash
iptables -D INPUT -s $1 -p tcp –dport 21 -j DROP
iptables -D INPUT -s $1 -p tcp –dport 22 -j DROP
iptables -D INPUT -s $1 -p tcp –dport 80 -j DROP

Come è facilmente intuibile il parametro %IP% viene passato allo script, che successivamente viene richiamato dentro allo stesso con la variabile $1.

Sebbene il port knocking trovi il suo principale ambito di utilizzo come sistema di manipolazione delle regole di filtraggio, esso permette anche di associare comandi shell arbitrari alle diverse sequenze di knock.

Purtroppo, il port knocking è spesso usato dai creatori di malware per l’apertura di backdoor su sistemi vittima. Infatti, piuttosto che cercare di aprire una porta sul server, evento facilmente intercettabile dall’amministratore, viene introdotto un trojan che, se riconosce una sequenza di knock predeterminata, apre una specifica porta sul server. Questo sistema è difficilmente intercettabile e costringe l’amministratore ad un’attenta analisi del traffico di rete. E’ necessario infatti scoprire la giusta sequenza di knock per poter uccidere la backdoor.

Vediamo come sia possibile attraverso il port knocking analizzare i log di sistema.
Su server che sostengono un elevato traffico e che quindi necessitano di soluzioni robuste per l’analisi di rete, sono presenti sistemi di intrusion detection (IDS). Questi sistemi sono in grado anche di fare analisi in tempo reale senza gravare in modo pesante, in termini di calcolo computazionale, sul sistema. Su server di più basso profilo che invece non sono soggetti a grandi carichi, un amministratore può facilmente analizzare i log di sistema vista la ridotta mole di dati. Il logging tramite iptables viene abilitato facendo uso del target LOG in questo modo:

iptables -A INPUT -p tcp –dport 7000:7255 -j LOG

Attraverso questo comando si possono controllare le porte tcp dalla 7000 alla 7255.
Il target LOG lavora in kernel space e usa syslog per scrivere i log. Loggando solo i pacchetti che vengono bloccati, si possono ottenere informazioni utili ai fini di troubleshooting (in fase di configurazione e test del firewall) e sicurezza (per capire i volumi e la qualità del traffico non desiderato).
Con il comando precedente vengono monitorizzati i log di sistema, ma ai fini del port knocking questo metodo grava inutilmente sul carico del server. Una soluzione più elegante per ovviare a questo problema è fare in modo di filtrare solo le informazioni di interesse. Per fare questo è utile ricorrere all’opzione –log-prefix di iptables:

iptables -A INPUT -p tcp –dport 7000:7255 -j LOG –log-prefix “portknock”

Aggiungendo questa opzione al comando, è possibile aggiungere una specifica
stringa come prefisso alle linee dei log generate in modo da filtrare le informazioni.

Port Knocking per leggere in tail i log remoti (in arrivo)