Attacco al server web di antirez.com

Monday, 21 May 07
Questa mattina ad un certo punto il server web che ospita antirez.com ha cessato completamente di funzionare. La causa e' un attacco informatico di proporzioni abbastanza severe, e questo e' un piccolo resoconto su cosa e' successo e su come ho momentaneamente posto fine ai problemi, nella speranza che possa essere utile agli altri.

Il problema

  • Quando mi sono loggato sul server via SSH il carico mostrato da top era di... 330!
  • Nei log di Apache c'erano due elementi che facevano capire subito di cosa si trattava: un warning in cui Apache mi avvisava che MaxClients era stato superato (era impostato a 200), e il fatto che in error.log era pieno di messaggi simili al seguente:
  • request failed: erroneous characters after protocol string: $MyNick
     (comhem)Dzij|$Lock EXTENDEDPROTOCOLABCABCABCABCABCABC
    Pk=DCPLUSPLUS0.690ABCABC|
    
Una veloce ricerca su google ha evidenziato come queste stringhe siano parte del protocollo dei client peer to peer Direct Connect, dunque il povero server era stato preso d'assalto da migliaia di client p2p che eseguivano centinaia di richieste al secondo sulla porta 80.

In queste condizioni ci sono due possibili scenari:
  • Con MaxClients troppo alto il server si pianta completamente
  • Con MaxClients ragionevole il server smette di servire le pagine perche' oltre le 200 (nel mio caso specifico) mette gli altri client in coda.


Insomma il web server non serviva piu' una pagina... i client continuavano (e stanno continuando) a bombardare il server da migliaia di IP diversi. Come fronteggiare la situazione?

Firewalling

Il firewalling da solo non mi aiutava molto, i client infatti accedevano ad una porta nota, e la porta di origine era anche assolutamente normale, come quella di un normale web browser. L'unico modo per filtrare sarebbe stato utilizzare una regola di firewalling che cercasse dentro il pacchetto pezzi del protocollo binario (la stringa EXTENDEDPROTOCOL .... non veniva spedita sempre infatti, molto spesso le richieste sembravano di tipo binario).

Cio' era abbastanza complesso da fare al volo perche' era necessario andarsi a studiare il protocollo e se mi ricordo bene iptables non e' in grado di andare a fare il match tra i byte del pacchetto.

Tcpdump e un piccolo programma in Tcl

La soluzione finale e' stata di utilizzare l'output di tcpdump e un piccolo programma in Tcl scritto sul momento per aggiungere al volo regole di firewalling che filtrassero tutti i client che stavano eseguendo piu' di 50 richieste al web server in poco tempo.

Ecco lo script in questione:
debian:~# cat p2p.tcl
while {[gets stdin line]} {
    regexp {IP ([0-9\.]+) >} $line => ip
    if {[string first 62.149.233.114 $ip] == -1} {
        set s [split $ip .]
        set ip [join [lrange $s 0 3] .]
        if {![info exists x($ip)]} {
#           puts $ip
            set x($ip) 0
        } else {
            incr x($ip)
            if {$x($ip) == 50} {
                puts $ip
                exec iptables -I INPUT -p tcp --dport 80 -s $ip -j DROP
            }
        }
    }
}
Anche questo poneva un problema: infatti quando l'attacco iniziava a scemare, i client veri potevano accedere e rapidamente scambiavano 50 pacchetti col server, entrando nella blacklist anche loro.

Per risolvere questo problema e' bastato spegnere Apache, in modo che i client legittimati avrebbero visto la pagina di rifiuto di connessione senza scambiare altri dati con il server, mentre i client malvagi avrebbero continuato a provare incessantemente.

Infatti l'esecuzione di questo script per alcuni minuti ha creato alcune migliaia di regole che filtrano gran parte dei client p2p che tentano di accedere al server. Il risultato e' che la macchina e' nuovamente up.

A questo ho aggiunto una piccola modifica al file di configurazione di Apache:
#Timeout 300
Timeout 10
Insomma il Timeout per mancato scambio dati in una connessione e' stato portato da 300 a 10 secondi temporaneamente, in modo da far andare in timeout i client p2p che non sono riuscito a filtrare perche' stanno facendo troppe poche richieste al secondo e dunque liberare spazio piu' velocemente per i client reali che non rimangono appesi ad aspettare.

Domande

Ne ho un bel po'
  • Chi e' stato ;)
  • Come e' possibile far credere a migliaia di client che il mio Server e' un client che ha qualcosa che tutti vogliono condividere o che e' un server della rete (non so quale delle due tecniche sia stata usata)
  • E' stato doloso o un errore?
Penso che finiro' per custodire questo script sul server per la prossima volta... anche se sarebbe piu' simpatico non finire nuovamente sotto attacco in breve tempo ;)

In ogni caso sono ancora pesantemente sotto attacco... e il traffico e' enorme, gli IP man mano cambiano, dunque niente di strano che ogni tanto devo rimettere il server down per filtrare nuovamente gli IP maligni.

Quando finira'?

Aggiornamento: Ho settato MaxClients a 500 e Timeout a 5 nella speranza di riuscire a tenere un carico di attacco maggiore.

Edit 27 Maggio 2007: Ecco la spiegazione di come e' stato eseguito l'attacco.
8365 views*
Posted at 07:58:04 | permalink | 18 comments | print
Do you like this article?
Subscribe to the RSS feed of this blog or use the newsletter service in order to receive a notification every time there is something of new to read here.

Note: you'll not see this box again if you are a usual reader.

Comments

davidonzo writes:
21 May 07, 08:48:43
Avevo notato il down stamane.

La prima cosa sarebbe chiedere all'intestatario dell'IP cui fa capo la tua macchina, se ha subito (o sta subendo) altri attacchi simili.
antirez writes:
21 May 07, 08:51:40
@davidonzo: buona idea, la macchina e' in housing da Aruba, potremmo chiedere a quest'ultima se altri loro clienti hanno avuto simili problemi.

Sarebbe abbastanza allucinante se ci avessero attaccati in prima persona. Comunque maxclients 500 + timeout 5 + filtering degli IP nuovi di tanto in tanto sembra abbia recuperato la situazione per ora. Spero che la smettano presto.
antirez writes:
21 May 07, 08:56:06
Ho trovato un nuovo modo per filtrare gli IP cattivi, infatti in access.log di apache globale, che non e' collegato ad alcun virtual domain configurato sulla macchina si legge:

87.10.17.252 - - [21/May/2007:14:53:02 +0200] "-" 408 - "-" "-"
87.10.17.252 - - [21/May/2007:14:53:03 +0200] "-" 408 - "-" "-"
87.10.17.252 - - [21/May/2007:14:53:03 +0200] "-" 408 - "-" "-"
62.195.165.78 - - [21/May/2007:14:53:11 +0200] "-" 408 - "-" "-"
62.195.165.78 - - [21/May/2007:14:53:12 +0200] "-" 408 - "-" "-"
62.195.165.78 - - [21/May/2007:14:53:13 +0200] "-" 408 - "-" "-"

E cosi' via... in pratica si vedono gli IP delle richieste che vanno in timeout per un dominio che non esiste. Questi sono esattamente tutti i client che io vorrei filtrare.

Modifichero' dunque lo script in Tcl per leggere gli IP da quel file e aggiungere le regole per filtrare tali IP se vedo che la macchina ricomincia a soffrire.

Se funziona tutto mi piace molto di piu' riuscire a resistere all'attacco grazie al bilanciamento dei parametri. Mi sembra piu' una soluzione "di sistema" :)
riffraff writes:
21 May 07, 12:14:00
afair iptables supporta il filtering stateful e il matching di stringhe, una cosa tipo -m string --string "EXTENDEDPROTOCOL". Immagino dovrai combinarlo con una regola che matchi altro altrimenti uno che ha cercato questo problema su google non può accedere :)

Cmq fico :D (ah, refuso in "malvagi")
antirez writes:
21 May 07, 12:17:12
@riffraff: grazie per la dritta, infatti dopo avevo visto sul manuale ma non potevo usare tale feature :(

Ecco cosa accade: poiche' il server e' carico i client arrivano giusto a fare la three way handshake TCP, solo pochissimi di loro riescono davvero a spedire pezzi del protocollo, la maggior parte vanno in timeout prima.

Filtrando queste connessioni tramite il firewall avrei eliminato una percentuale insignificante di client. Alla fine la soluzione vera e' venuta dall'error.log che mi permette di vedere la lista degli IP di connessioni che vanno in timeout. Filtrando quelle che superano un tot di tentativi di connessione che hanno come effetto un timeout sembra funzionare bene.

Anche se stanno continuando :-\

Grazie per il commento.
antirez writes:
21 May 07, 12:21:07
@riffraff: dimenticavo, malvaggi non era un refuso, sbaglio totalmente le doppie quando scrivo di fretta ;) Grazie per la segnalazione.
dat writes:
21 May 07, 12:30:19
a me è successa la stessa cosa ma col pc di casa, insomma, ho un cessoso 56k, mi collego e vedo il traffico a palla, colpa di bittorrent e di chi usava l'ip prima di me. col consiglio di qualche amico mi è bastato sconnettermi e riconnettermi per sistemare la questione ma non credo funzioni su un server ;)
Navigatore Anonimo writes:
21 May 07, 20:49:05
mi chiederei se sei convinto che sia stato UN attacker : la rete dc++ , a differenza di emule, mi pare non si appoggi ad un server : funziona come la rete kad in emule o come skype , appoggiandosi ai nodi con più risorse e che sono da più tempo online (hubs) ... se si ipotizzasse invece che "qualcuno" su cui passa molto di quel traffico abbia un filtro a livello applicazione che sia in grado di individuare il traffico dc++ e che abbia impostato una regola che redirige questo traffico che passa su quel tratto di rete direttamente sul tuo IP ???
al0ha writes:
21 May 07, 22:33:43
Antir, io ho avuto a che fare molto da vicino con la rete direct connect un paio di anni fa. L'attacco che hai ricevuto sembra un attacco di IP Spoofing e veniva utilizzato per impedire l'accesso agli hub (una specie di canali irc per chi non li conoscesse).
In particolare si utilizzavano dei software nei quali si indicavano solitamente IP server vittima e numero di porta, dopo aver deciso questo si collegavano a diversi hub su direct connect e una volta collegati a questi ricevevano la lista degli utenti (migliaia) utilizzandoli per fare richieste contemporanee al server vittima come se ogni utente dell'hub avesse effettuato la richiesta inondando proprio il server vittima e provocando un denial of service.

Spero di esserti stato d'aiuto antir.
Mdx writes:
22 May 07, 09:12:43
Una curiosità, come mai hai deciso di fare gli script in tcl piuttosto che perl o altro? Il tcl è un linguaggio più "leggero"?
michele writes:
22 May 07, 10:16:26
Questo ti piacera' di sicuro noi lo usiamo per blacklistare chi fa troppe query contemporanee sui DNS, ma va bene per qualsiasi protocollo/porta: http://www.digitalgenesis.com/software/phrel/
Navigatore Anonimo writes:
28 May 07, 12:21:14
sembra che antirez.com sia in buona compagnia :
http://news.netcraft.com/archives/2007/05/23/p2p_n...
antirez writes:
28 May 07, 12:41:39
@Navigatore Anonimo: si... e' esattamente l'attacco che ho ricevuto io. Dunque e' relativo ad un bug dei client, e basta avere il controllo di uno o piu' hub per eseguire l'attacco. A quanto pare le ultime versioni del client DC++ sono state corrette.
Navigatore Anonimo writes:
28 May 07, 17:49:02
in sostanza (IMHO) l'attacco può essere portato se si ha già il controllo di uno o più hub : in quel caso lo status di operatore dovrebbe garantire la possibilità di aggiungere altri hubs ; ciò che ha fatto questo "operatore" è inserire antirez.com nella lista degli hubs di dc++ con la conseguenza che i client collegati al suo/ ai suoi hub(s) hanno iniziato a inoltrare richieste verso antirez.com : le versioni precedenti del client non è che siano buggati nel senso stretto della parola ; semplicemente "credono" che ogni hub nella lista sia valido e quindi continuano a inoltrare le richieste. Ciò che la nuova versione del client ha introdotto è un limite ai tentativi di connessione verso un hub che risponde "picche" : in sostanza dopo un tot di tentativi non andati a buon fine (rifiuto di connessione da parte dell'hub) , il client lo esclude dagli hubs validi e non tenta più di connettersi. Su emule ad esempio questo limite è di tre tentativi. Tuttavia finchè tutti i client della rete dc++ non sono aggiornati , il problema potrebbe ripresentarsi per via delle stesso o di un altro "mattacchione" di turno.

C'è una patch per iptables specifica per questo tipo di problemi : http://ipp2p.org/ ... oppure potresti vagliare la possibilità di usare mod_security http://www.modsecurity.org/ che è un modulo per apache capace di filtrare il traffico a livello HTTP , capace cioè di risolvere questo e ben altri problemi ;-)

Ciao e buon lavoro ;-)
antirez writes:
28 May 07, 18:16:00
@Navigatore Anonimo: spiegazione perfetta, solo che IMHO mod_security non aiuta, una volta che sei arrivato al web server e' troppo tardi. Alla fine cio' che mi ha salvato e' stato il firewalling, perche' come traffico 380 pacchetti al secondo (il picco a cui siamo arrivati) anche se e' tanto e' sostenibile se si tratta solo di SYN TCP e non permetti di completare la three way handshake. Dunque penso che monitorare le richieste e segnare gli IP sorgente di ognuna e bloccare tramite iptables gli IP che effettuano troppe richieste sia una soluzione.

Anche se ha funzionato molto meglio nella mia esperienza la soluzione "B", ovvero guardare quali client andavano in timeout (perche' non sanno parlare davvero il protocollo HTTP!) per filtrarli.

Grazie del commento :)
boverix writes:
29 May 07, 09:27:45
stesso problema... 4-8 connessioni da 200mila ip differenti...

installato kernel patchato L7 (l7-filter.sourceforge.net) e intercettato tutti i "$MyNick". Riduce quello che passa, ma almeno riconosce che sono pacchetti DC++. Adesso provo a configurare fail2ban per droppare gli ip qualche ora (di notte si riducono notevolmente, probabile che tanti client DC++ spengono il pc).

non è la soluzione, ma almeno apache resta su...

(PS kernel patchato non da me che sono una pippa con il .config del kernel...)
Navigatore Anonimo writes:
29 May 07, 13:32:13
Mi correggo : http://ipp2p.org/ non è una patch ma un modulo per iptables ;-) ... non c'è da patchare il kernel ;-) ... bastano i sorgenti di iptables ...

in effetti la soluzione B potrebbe difendere anche da altri attacchi di questo tipo indipendentemente dal sistema o dal programma usato ... il tutto deve comunque entrare a regime , ci sarà un picco sul server che andrà scemando man mano che il filtro aggiunge gli IP ad iptables ... tuttavia una soluzione che "banni" il traffico p2p in anticipo , cioè prima che raggiunga il server sarebbe la soluzione ottimale
mordha writes:
05 Dec 07, 12:54:58
ip inserito lista aggiornamento server ramaloopster o simili.
comments closed