Menu

Jakov M. Vežić

Obrana od Slowloris napada na HTTP poslužitelj

Na slici: Spori Loris (Nycticebus coucang) – otrovni primat bezazlenog izgleda

Uvodno

Napadi uskraćivanja usluge (DOS – Denial of service), kao i napadi distribuiranog uskraćivanja usluge (DDOS – Distributed denial of service) česti su u svijetu sigurnosti mreža i poslužitelja. Većina napada ove vrste usmjerena je na slanje velikih količina podataka prema poslužitelju ili potraživanje velikih količina podataka kako bi se iscrpili resursi poslužitelja (flooding metoda). Uspješnim DOS ili DDOS napadom, poslužitelj “pada”, odnosno postaje nedostupan, čime se legitimnim posjetiteljima uskraćuje usluga.

S obzirom na učestalost napada flooding metodom, sigurnost poslužitelja i mreža obično se gradi oko mogućnosti prepoznavanja i odbijanja velikog broja zahtjeva i velikog broja TCP i UDP paketa poslanih prema poslužitelju. Međutim, pretjeranim fokusiranjem na odbijanje takvih napada, zanemaruju se suptilnije, a u nekim slučajevima i znatno učinkovitije, metode DOS napada.

Jedna od takvih metoda je i Slowloris, koju je 2009. godine razvio Robert “RSnake” Hansen. Za razliku od većine drugih DOS metoda, Slowloris je vrlo lagan za računalo i mrežu iz kojeg potječe iz razloga što koristi minimalno mrežne propusnosti te minimalno CPU snage – može se pokrenuti i s laptopa u sporoj bežičnoj mreži. Slowloris funkcionira na način da šalje nepotpune HTTP GET zahtjeve s ciljem da forsira poslužitelj da čeka ostatak zahtjeva. Dok poslužitelj čeka ostatak jednog zahtjeva, Slowloris metodom šalje se još jedan nepotpuni zahtjev, zatim još jedan, i tako dalje sve dok poslužitelj ne ostane bez slobodnih otvorenih veza u svom pool-u ili bez memorije ili ostalih resursa. U tom trenutku, poslužitelj nije u mogućnost otvoriti još veza te prestaje posluživati, odnosno uskraćuje uslugu, ostalim posjetiteljima. Kako bi se Slowloris održao na životu, potrebno je pronaći dobru ravnotežu između broja veza koje će Slowloris otvoriti, brzine otvaranja novih veza, broja otvaranja veza nakon što poslužitelj zatvori jednu, itd.

Slowloris je u mogućnosti srušiti jednostavno konfigurirane poslužitelje i mreže u vrlo kratkom roku (unutar nekoliko sekundi), što ćemo vidjeti kasnije u tekstu na primjeru lokalnog Debian poslužitelja. Iz tog razloga, Slowloris je popularan alat za “rušenje” jednostavnijih i nepopularnih stranica koje ne računaju na ovu vrstu napada.

U ovom tekstu dat će se primjer Slowloris napada na Debian poslužitelj s osnovnom instalacijom Apache2 HTTP poslužitelja te savjeti o metodama koje funkcioniraju i ne funkcioniraju u svrhu izbjegavanja i mitigacije napada.

Testni sustavi

Za potrebe testiranja koristit će se dva virtualna poslužitelja sa sljedećim specifikacijama:

Meta napada
Procesor AMD Ryzen 5 1600 Six-Core Processor
Maks. brzina 3.7 GHz
Jezgri 2
RAM 2 GB DDR4-2133 MHz
OS Debian 9.5.0
Apache2 2.4.25
Napadač
Procesor AMD Ryzen 5 1600 Six-Core Processor
Maks. brzina 3.7 GHz
Jezgri 1
RAM 1 GB DDR4-2133 MHz
OS Debian 9.5.0

Na oba sustava nije instalirano grafičko sučelje. Meta napada, osim standardnih paketa koji dolaze s Debian instalacijom te Apache2 poslužitelja, ima instalirane i pakete htop i openssh-server te u stanju mirovanja koristi 49 MB od ukupno 2 GB RAM-a.

Alati

S obzirom na prirodu ove metode, teško je provjeriti je li određeni poslužitelj podložan napadu Slowloris bez pokretanja potpunog napada. U vrijeme pisanja ovog teksta, jedina skripta za provjeru ranjivosti bez izvedbe napada koju sam pronašao je http-slowloris-check iz Nmap paketa. Međutim, ni http-slowloris-check ni http-slowloris skripta ne funkcioniraju kako treba u navedenom paketu, o čemu je podnesen izvještaj na Github-u.

Iz navedenih razloga, za potrebe testiranja ranjivosti poslužitelja provedeni su potpuni Slowloris napadi u trajanju od 5 minuta i 5 sekundi. Za napade se koristi naredba SlowHTTPTest s navedenim parametrima:

slowhttptest -u http://192.168.0.19 -c 10000 -i 5 - l 308 -r 30 -p 8 -g -o results

To znači da će se u navedenih 5 minuta i 5 sekundi (305 sekundi) otvoriti maksimalno 10 tisuća veza (-c 10000). Nove veze otvarat će se po stopi od 30 u sekundi ukoliko to poslužitelj može podnijeti (-r 30), u suprotnom nove veze gomilat će se u pending fazi, spremne za spajanje čim poslužitelj to dozvoli.

Međutim, kako paket SlowHTTPTest, odnosno funkcija provjere dostupnosti HTTP poslužitelja u istom nije pouzdana (IP adresa napadača može biti blokirana a alat javljati kako je poslužitelj nedostupan kada zapravo je), za potrebe ovog testiranja koristit će se Python skripta kućne izrade:

import requests
import datetime
import time


def url_ok():
    total = 0
    uptime = 0
    finish_time = datetime.datetime.now() + datetime.timedelta(seconds=302)
    while datetime.datetime.now() < finish_time:
        try:
            total += 1
            r = requests.head("http://192.168.0.19", timeout=8.000)
            if r.status_code == 200:
                print("Available.")
                uptime += 1
            else:
                print("NOT available.")
        except:
            print("NOT available.")
        time.sleep(3)
    print(total)
    print(uptime)
    print("Uptime", round(uptime/total, 1)*100, "%")


url_ok()
Skripta za provjeru dostupnosti HTTP poslužitelja

Skriptu ćemo pokrenuti s host računala, iz PyCharm Community programa, 5 sekundi nakon početka napada, čime dobivamo točno 5 minuta praćenja dostupnosti poslužitelja. Skripta pokreće funkciju provjere 3 sekunde nakon rezultata prošle provjere (time.sleep(3)) te čeka odgovor poslužitelja 8 sekundi (timeout=8.000). U slučaju da HTTP poslužitelj ne odgovori u 8 sekundi, smatra se da nije dostupan, tj. da se srušio.

Rezultat napada na osnovni poslužitelj

Poslužitelj se ruši odmah po početku napada te je u potpunosti nedostupan kroz ostatak napada. To znači da je uptime poslužitelja tijekom 5 minuta napada bio 0% (0 od ukupno 28 provjera je vratilo kod 200 – OK).

Kao što se može vidjeti iz grafikona, Slowloris tijekom napada uspijeva držati broj otvorenih veza na oko 470 (najviše 481). Poslužitelj počinje zatvarati veze tek nakon nešto manje od 2 minute (116 sekundi) te ih nastavlja zatvarati otprilike jednakim tempom. Međutim, do tada Slowloris uspijeva staviti nevjerojatnih 3425 veza u pending fazu te ih počinje spajati čim može, zbog čega poslužitelj nije u stanju vratiti uslugu (kako zatvara stare veze, Slowloris otvara nove).

Rezultat napada stoga je kako slijedi:

Konfiguracija Ukupni uptime (5 minuta) Najveći broj otvorenih veza Najveći broj pending veza Najveći broj zatvorenih veza
Zadana Apache konfiguracija 0% 481 3451 4805

Mitigacija napada

mod_reqtimeout

Za prvi pokušaj mitigacije Slowloris napada na lokalni virtualni poslužitelj koristit ćemo Apache modul reqtimeout. Pomoću navedenog modula moguće je konfigurirati timeout za neaktivne veze i minimalnu količinu podataka koju klijent smije slati prema poslužitelju. Ukoliko klijent ne poštuje zahtjeve modula, Apache će zatvoriti vezu i vratiti 408 REQUEST TIME OUT.

Navedeni modul aktivan je odmah pri instalaciji Apache 2.4.25 na Debian, ali koristi vrlo “lagane” postavke:

RequestReadTimeout header=20-40,minrate=500
RequestReadTimeout body=10,minrate=500

Za header zahtjeva modul dopušta 20 do 40 sekundi da se header pošalje uz minimalnu stopu od 500 bajtova u sekundi. Za body zahtjeva modul dopušta 10 sekundi da se body pošalje uz minimualnu stopu od 500 bajtova u sekundi. Za potrebe obrane od novog napada, prilagodit ćemo postavke na način da budu malo strože:

RequestReadTimeout header=8-15,minrate=700
RequestReadTimeout body=8,minrate=700

Rezultati napada su sljedeći:

Kao što možemo vidjeti, poslužitelj se već puno lakše nosi s napadom: brže zatvara veze i ne dozvoljava previše sporih, otvorenih veza. Ovog puta uptime poslužitelja bio je čak 70% (24 od 36 provjera):

Ukupni uptime (5 minuta) Najveći broj otvorenih veza Najveći broj pending veza Najveći broj zatvorenih veza
Zadana Apache konfiguracija 0% 481 3451 4805
Apache + mod_reqtimeout 70% 451 455 7838

Naravno, mogli bismo dodatno postrožiti postavke modula reqtimeout. Međutim, u tom slučaju počeli bi utjecati na kvalitetu usluge za posjetitelje na sporim i lošim mrežama i potencijalno odbijati legitimne zahtjeve.

mod_reqtimeout + mod_qos

Umjesto dodatnog postrožavanja modula reqtimeout, pozabavit ćemo se modulom qos. Ovaj modul ne dolazi s Apache2 paketom, već ga je potrebno zasebno instalirati. Sami paketi mogu se preuzeti ovdje. Kao postavke modula qos, postavit ćemo:

QS_ClientEntries 100000
QS_SrvMaxConnClose 600
QS_SrvMaxConnPerIP 100

Navedena konfiguracija pratit će 100 tisuća klijenata (IP adresa) te dopustiti maksimalno 100 veza s iste IP adrese. Dodatne zahtjeve za otvaranjem veza će odbacivati. Nadalje, u trenutku kad poslužitelj dođe do 600 otvorenih veza, podrška za keepalive će se ukinuti. Pogledajmo rezultate:

Kao što možemo vidjeti, mod_qos sada drži broj otvorenih veza na stabilnih 100, dok mod_reqtimeout konzistentno i stabilno zatvara postojeće veze koje su spore ili neaktivne. Kombinacijom ova dva modula i njihovih konfiguracija napokon dolazimo do 100% (101 od 101) uptime-a:

Ukupni uptime (5 minuta) Najveći broj otvorenih veza Najveći broj pending veza Najveći broj zatvorenih veza
Zadana Apache konfiguracija 0% 481 3451 4805
Apache + mod_reqtimeout 70% 451 455 7838
Apache + mod_reqtimeout + mod_qos 100% 102 2 8649

Prevencija napada

Nginx

Popularna prevencija od Slowloris napada je upotreba Nginx-a kao HTTP poslužitelja. S obzirom na način na koji rukuje s velikim brojem veza, znatno je teže izvesti uspješni Slowloris napad na Nginx nego na Apache. Ipak, postoje varijante Slowloris skripte, kao što su Goloris koje mogu srušiti loše postavljen Nginx, što znači da samo upotreba Nginx-a ne znači ništa protiv Slowloris napada ukoliko Nginx nije dobro konfiguriran.

Cloudflare

Cloudflare je iznimno popularna “mreža za dostavljanje sadržaja” (Content Delivery Network). To znači da Cloudflare poslužitelji stoje između poslužitelja i klijenta te nadziru više aspekata komunikacije: cache, DNS, SSL, firewall, prevencija DDOS-a, itd. Cloudflare će za pokušaj Slowloris napada poslati Connection refused nakon otprilike 150 brzo zatvorenih veza.

DigitalOcean

Popularni cloud servisi poput DigitalOcean-a koji nude virtualne poslužitelje mogli bi se činiti kao dobro rješenje. Međutim, čini se da su i mrežna mjesta na takvim servisima podložna Slowloris napadu ukoliko koriste zadanu Apache konfiguraciju i ne koriste dodatne usluge poput load balancera i sl.

Na grafici se vidi rezultat Slowloris napada na virtualni poslužitelj sljedeće konfiguracije:

DigitalOcean virtualni poslužitelj
Procesor Intel(R) Xeon(R) CPU E5-2650L v3 @ 1.80GHz
Maks. brzina 2.5 GHz
Jezgri 1
RAM 2 GB DDR4 1600/1866/2133 (nepoznato)
OS Debian 8.10
Apache2 2.4.10

Rezultat napada sličan je prvom napadu na lokalni virtualni poslužitelj: uptime poslužitelja je 0% (0 od 27). Iako je DO poslužitelj brže zatvarao veze od lokalnog (i zatvorio više veza), Slowloris je također poboljšao svoj doprinos pa je tako uspio održati više otvorenih veza u odnosu na lokalni poslužitelj.

Zaključno

Tijekom svih napada i testiranja, Slowloris je koristio skoro pa ništa RAM-a, procesorske snage i propusnosti mreže na računalima na kojima je testiran i sa kojih je pokrenut. To ga čini i dalje efikasnim alatom za DOS napade na jednostavnije stranice koje nisu dobro konfigurirane.

Dobrom konfiguracijom i upotrebom modula kao što su reqtimeout i qos, moguće je u potpunosti se zaštititi od Slowloris napada. Naravno, ovisno o poslužitelju koji je meta napada, moguće da će biti potrebno koristiti druge konfiguracije modula od onih prikazanih u ovom tekstu, a možda i dodatne alate kao što su Fail2Ban. U svakom slučaju, Slowloris je očito još uvijek efektivan način napada koji je često zanemaren u odnosu na druge DOS tehnike. Ovim tekstom htio sam podignuti svijest o DOS napadima slow vrste, kao što je Slowloris, te dati prijedloge za izbjegavanje i načine rukovanja s istim.