[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