[bglug] Security through obscurity (REJECT vs DROP)
Dario Bertini
berdario@gmail.com
Ven 8 Feb 2013 19:16:52 CET
Nell'incontro di settimana scorsa, ho scoperto mio malgrado che è
parecchio diffusa l'opinione che sia più "sicuro" impostare il proprio
firewall per DROPpare le connessioni, invece che chiuderle
propriamente con un semplice REJECT
Visto che di materiale che spieghi esattamente la situazione in
italiano, ce n'è poco, sto scrivendo queste righe per esaminare tutte
le possibili ragioni di questa scelta:
Possibile ragione#1 si è "completamente invisibili" (oppure il
firewall è "invisibile"):
Falso: ci sono almeno 4 possibili risposte quando si prova ad aprire
una connessione TCP:
1-SYN/ACK: porta aperta
2-RST/ACK: porta chiusa/nessun servizio
3-ICMP destination unreachable (host unreachable: host offline/non
esistente, network unreachable: tutta la rete è offline, questo ci
verrà comunicato da un router a monte del nostro target,
administratively prohibited: chiusa da un firewall...)
4-(niente): porta con policy DROP
Il fatto che non si ritorni niente, è già un'informazione che si sta
fornendo... ok, la controparte non è (ancora) a conoscenza di dove sia
il firewall, ma non abbiamo guadagnato nulla
In compenso pare che si possano impostare dei firewall per ritornare
"host unreachable", ma questo ha senso solo se non hostate nessun
servizio sulla vostra macchina
Possibile ragione#2 rende più difficile/lungo/oneroso rilevare quali
servizi sono effettivamente disponibili:
Falso: non siamo più negli anni 90, e se anche il vostro attaccante
vuole ottenere subito una risposta (inusuale: è più pratico fare
girare gli scanner nottetempo su un grande numero di host) e se il
vostro attaccante scrive un tool di scanning in casa, non sarà così
sprovveduto da non sapere nemmeno come sfruttare il protocollo che
state usando
dal manuale di nmap:
SYN scan is the default and most popular scan option for
good reasons. It can be performed quickly, scanning thousands
of ports per second on a fast network not hampered by
restrictive firewalls. It is also relatively unobtrusive and
stealthy since it never completes TCP connections. SYN scan
works against any compliant TCP stack rather than depending
on idiosyncrasies of specific platforms as Nmap's
FIN/NULL/Xmas, Maimon and idle scans do. It also allows clear,
reliable differentiation between the open, closed, and
filtered states.
This technique is often referred to as half-open scanning,
because you don't open a full TCP connection. You send a SYN
packet, as if you are going to open a real connection and
then wait for a response. A SYN/ACK indicates the port is
listening (open), while a RST (reset) is indicative of a
non-listener. If no response is received after several
retransmissions, the port is marked as filtered. The port
is also marked filtered if an ICMP unreachable error (type 3,
code 1, 2, 3, 9, 10, or 13) is received. The port is also
considered open if a SYN packet (without the ACK flag) is
received in response. This can be due to an extremely rare
TCP feature known as a simultaneous open or split handshake
connection (see http://nmap.org/misc/split-handshake.pdf).
Ovviamente, non ha senso aspettare di ricevere una risposta, sapendo
che questa può non arrivare... ed nmap saggiamente può quindi
procedere in parallelo su tante diverse porte
Mi sono finalmente deciso di fare 2 o 3 prove, a sostegno di questa
tesi, in fondo potete trovare l'output completo, ma in sintesi:
nmap riesce a restituire le stesse informazioni in entrambi i casi, in
circa 19 secondi sia con DROP che con REJECT
Per essere esaustivi: il tempo può variare sensibilmente, sopratutto
se è la prima volta che vi collegate all'host (ho notato che anche
soltanto aver provato ad aprire una connessione ssh ed averla lasciata
fallire/andare in timeout cambia la prima misurazione, immagino che
questo sia dovuto al fatto che dei pacchetti sono già stati trasmessi
e che quindi da questi il kernel o nmap può ricavare informazioni sul
timeout/latenza da aspettarsi), e per assurdo... impostando la mia
macchina con policy REJECT, ed eseguendo nmap senza privilegi di root,
l'esecuzione risultava molto più lenta che non con policy DROP
(immagino che questo sia dovuto al fatto che con DROP, nmap è forzato
a passare alla porta successiva appena nota che la risposta non
arriva, mentre con REJECT, visto che la risposta arriva, e non ha la
possibilità di craftare i pacchetti come vuole, è "costretto" ad
aspettare)
Ancora: visto che m'era parso che alcune persone pensassero al
problema in certi termini: ci tengo a sottolineare che le informazioni
ritornate sono le stesse in entrambi i casi, e non aveva senso
aspettarsi altrimenti... pensare di essere più "vulnerabili" in un
modo o nell'altro, per quanto riguarda i servizi forniti, è
completamente assurdo
Se avete un demone senza le ultime patch di sicurezza, o se ssh è
aperto sulla porta di default-22 -o peggio- permettete
l'autenticazione ssh tramite password... queste cose sono quelle
veramente importanti
Possibile ragione#3 non siete vulnerabili ai DOS:
Falso (se usate la vostra macchina per hostare un qualunque tipo di servizio)
Ammettendo che esponiate un web server sulla porta 80, non potete
DROPpare bellamente la connessione a prescindere dai dettagli, ed a
questo punto la cosa più semplice è adottare la stessa regola sia per
tutte le porte:
Ovvero, rate-limiting (globale o discriminando sugli IP)... non ho
esperienza in quest'ambito, ma mi rendo comunque conto che potrebbe
non essere la scelta migliore:
Degradare intenzionalmente la qualità del servizio, potrebbe
facilitare il lavoro di un DOSer... a questo punto, sperando che
invece il vostro server regga al carico, potrebbe convenire non
limitare nulla
...O se invece avete tipi diversi di accessi alla macchina (anche solo
ssh per amministrazione), potrebbe invece convenire impostarli proprio
per salvaguardare gli usecase prioritari, insomma: _misurate_, e YMMV
Ok, questo spiega come mai DROP non sia l'idea fantastica che
pensavate fosse, ma ragioni _positive_ per fare altrimenti?
Beh, prima di tutto: il REJECT è il modo nel quale la gente si aspetta
che le cose funzionino, dall' RFC1122:
3.3.8 Error Reporting
Wherever practical, hosts MUST return ICMP error datagrams on
detection of an error, except in those cases where returning an
ICMP error message is specifically prohibited.
Quando voi DROPpate, in pratica state mostrando un GIGANTESCO dito
medio, al client che ha provato a connettersi a voi...
e il client, potreste essere voi stessi nell'arco di qualche mese/anno
(o i vostri colleghi), quando illudendovi di aver esposto un servizio
sulla vostra macchina, trovate che il vostro script sta impiegando un
numero di secondi inusualmente superiore a quello che vi aspettavate,
finchè non realizzate infine che è andato in timeout
Un'altra ragione per evitare DROP, è un attacco SYN flood, nel quale
viene fatto lo spoofing dell'indirizzo IP della vostra macchina
Difatti, quando il server sotto attacco riceve il SYN e prova a
rispondere all'indirizzo IP spoofato, se quest'ultimo corrisponde ad
una macchina offline la connessione verrà chiusa in pochi secondi
se corrisponde ad una macchina la cui porta è sia aperta oppure
chiusa, la connessione terminerà in pochi ms
se invece questa macchina attua un DROP per ogni richiesta, il server
sotto attacco per rispondere proverà a mantenere la connessione aperta
per _decine di secondi_ (da moltiplicare per ogni pacchetto SYN che la
botnet che vi sta attaccando riesce a generare)
Fatemi sapere se c'è un qualche motivo per il quale ancora dissentite
o se ho commesso un qualche madornale errore nella mia analisi
-----------------------
Qui sotto potete vedere l'output del test di cui ho scritto prima:
dario@uberc50 ~> # with DROP
dario@uberc50 ~> sudo nmap --top-ports 4000 -sV 192.168.1.24
Starting Nmap 5.21 ( http://nmap.org ) at 2013-02-08 17:18 CET
Nmap scan report for 192.168.1.24
Host is up (0.0059s latency).
Not shown: 3998 filtered ports
PORT STATE SERVICE VERSION
80/tcp open http Cherokee httpd 1.2.101 (Debian)
443/tcp closed https
MAC Address: 00:1D:4F:FC:AF:FC (Apple Computer)
Service Info: OS: Linux
Service detection performed. Please report any incorrect results at
http://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 18.96 seconds
dario@uberc50 ~> # now with REJECT on
dario@uberc50 ~> sudo nmap --top-ports 4000 -sV 192.168.1.24
Starting Nmap 5.21 ( http://nmap.org ) at 2013-02-08 17:13 CET
Nmap scan report for 192.168.1.24
Host is up (0.0056s latency).
Not shown: 3998 filtered ports
PORT STATE SERVICE VERSION
80/tcp open http Cherokee httpd 1.2.101 (Debian)
443/tcp closed https
MAC Address: 00:1D:4F:FC:AF:FC (Apple Computer)
Service Info: OS: Linux
Service detection performed. Please report any incorrect results at
http://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 19.45 seconds
-----------------------
e questo invece è l'iptables della macchina target:
root@macbook ~# iptables -L -v
Chain INPUT (policy DROP 0 packets, 0 bytes)
pkts bytes target prot opt in out source
destination
790 46769 ACCEPT tcp -- any any anywhere
anywhere tcp dpt:http
324 17680 ACCEPT tcp -- any any anywhere
anywhere tcp dpt:https
10173 6912K ACCEPT all -- any any anywhere
anywhere ctstate RELATED,ESTABLISHED
10227 917K ACCEPT all -- lo any anywhere
anywhere
532K 169M LOGGING all -- any any anywhere
anywhere
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source
destination
Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source
destination
Chain LOGGING (1 references)
pkts bytes target prot opt in out source
destination
683 168K LOG all -- any any anywhere
anywhere limit: avg 2/min burst 5 LOG level debug prefix
"IPTables Packet Dropped: "
root@macbook ~# iptables -A LOGGING -j REJECT
root@macbook ~# iptables -L -v
Chain INPUT (policy DROP 0 packets, 0 bytes)
pkts bytes target prot opt in out source
destination
817 48143 ACCEPT tcp -- any any anywhere
anywhere tcp dpt:http
352 18912 ACCEPT tcp -- any any anywhere
anywhere tcp dpt:https
11076 6978K ACCEPT all -- any any anywhere
anywhere ctstate RELATED,ESTABLISHED
11126 983K ACCEPT all -- lo any anywhere
anywhere
556K 170M LOGGING all -- any any anywhere
anywhere
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source
destination
Chain OUTPUT (policy ACCEPT 1214 packets, 90322 bytes)
pkts bytes target prot opt in out source
destination
Chain LOGGING (1 references)
pkts bytes target prot opt in out source
destination
711 170K LOG all -- any any anywhere
anywhere limit: avg 2/min burst 5 LOG level debug prefix
"IPTables Packet Dropped: "
7992 352K REJECT all -- any any anywhere
anywhere reject-with icmp-port-unreachable
Maggiori informazioni sulla lista
bglug