Radzenie sobie z atakami HTTP w00tw00t

82

Mam serwer z Apache i niedawno zainstalowałem mod_security2, ponieważ często mnie atakują:

Moja wersja apache to apache v2.2.3 i używam mod_security2.c

To były wpisy z dziennika błędów:

[Wed Mar 24 02:35:41 2010] [error] 
[client 88.191.109.38] client sent HTTP/1.1 request without hostname 
(see RFC2616 section 14.23): /w00tw00t.at.ISC.SANS.DFind:)

[Wed Mar 24 02:47:31 2010] [error] 
[client 202.75.211.90] client sent HTTP/1.1 request without hostname 
(see RFC2616 section 14.23): /w00tw00t.at.ISC.SANS.DFind:)

[Wed Mar 24 02:47:49 2010] [error]
[client 95.228.153.177] client sent HTTP/1.1 request without hostname
(see RFC2616 section 14.23): /w00tw00t.at.ISC.SANS.DFind:)

[Wed Mar 24 02:48:03 2010] [error] 
[client 88.191.109.38] client sent HTTP/1.1 request without hostname
(see RFC2616 section 14.23): /w00tw00t.at.ISC.SANS.DFind:)

Oto błędy z dziennika dostępu:

202.75.211.90 - - 
[29/Mar/2010:10:43:15 +0200] 
"GET /w00tw00t.at.ISC.SANS.DFind:) HTTP/1.1" 400 392 "-" "-"
211.155.228.169 - - 
[29/Mar/2010:11:40:41 +0200] 
"GET /w00tw00t.at.ISC.SANS.DFind:) HTTP/1.1" 400 392 "-" "-"
211.155.228.169 - - 
[29/Mar/2010:12:37:19 +0200] 
"GET /w00tw00t.at.ISC.SANS.DFind:) HTTP/1.1" 400 392 "-" "-" 

Próbowałem skonfigurować mod_security2 w następujący sposób:

SecFilterSelective REQUEST_URI "w00tw00t\.at\.ISC\.SANS\.DFind"
SecFilterSelective REQUEST_URI "\w00tw00t\.at\.ISC\.SANS"
SecFilterSelective REQUEST_URI "w00tw00t\.at\.ISC\.SANS"
SecFilterSelective REQUEST_URI "w00tw00t\.at\.ISC\.SANS\.DFind:"
SecFilterSelective REQUEST_URI "w00tw00t\.at\.ISC\.SANS\.DFind:\)"

Rzeczą w mod_security2 jest to, że SecFilterSelective nie może być używany, daje mi błędy. Zamiast tego używam następującej reguły:

SecRule REQUEST_URI "w00tw00t\.at\.ISC\.SANS\.DFind"
SecRule REQUEST_URI "\w00tw00t\.at\.ISC\.SANS"
SecRule REQUEST_URI "w00tw00t\.at\.ISC\.SANS"
SecRule REQUEST_URI "w00tw00t\.at\.ISC\.SANS\.DFind:"
SecRule REQUEST_URI "w00tw00t\.at\.ISC\.SANS\.DFind:\)"

Nawet to nie działa. Nie wiem już, co mam robić. Czy ktoś ma jakąś radę?

Aktualizacja 1

Widzę, że nikt nie może rozwiązać tego problemu za pomocą mod_security. Jak dotąd używanie ip-tabel wydaje się najlepszą opcją, ale myślę, że plik stanie się bardzo duży, ponieważ ip zmienia się kilka razy dziennie.

Wymyśliłem 2 inne rozwiązania, czy ktoś może komentować je jako dobre, czy nie.

  1. Pierwszym rozwiązaniem, jakie przychodzi mi do głowy, jest wykluczenie tych ataków z moich dzienników błędów apache. Ułatwi mi to wykrycie innych pilnych błędów, gdy się pojawią, i nie muszę przeszukiwać długiego dziennika.

  2. Myślę, że druga opcja jest lepsza i polega na blokowaniu hostów, które nie są wysyłane w prawidłowy sposób. W tym przykładzie atak w00tw00t jest wysyłany bez nazwy hosta, więc myślę, że mogę zablokować hosty, które nie są w prawidłowej formie.

Aktualizacja 2

Po przejrzeniu odpowiedzi doszedłem do następujących wniosków.

  1. Aby mieć niestandardowe rejestrowanie dla apache, zużyjesz trochę niepotrzebnych odwołań, a jeśli naprawdę istnieje problem, prawdopodobnie będziesz chciał zajrzeć do pełnego dziennika bez niczego brakującego.

  2. Lepiej po prostu zignorować trafienia i skoncentrować się na lepszym sposobie analizy dzienników błędów. Dobrym rozwiązaniem jest stosowanie filtrów do dzienników.

Ostatnie przemyślenia na ten temat

Wspomniany wyżej atak nie dotrze do twojej maszyny, jeśli masz przynajmniej aktualny system, więc zasadniczo nie martw się.

Po pewnym czasie może być trudno odfiltrować wszystkie fałszywe ataki od prawdziwych, ponieważ zarówno dzienniki błędów, jak i dzienniki dostępu stają się bardzo duże.

Zapobieganie temu w jakikolwiek sposób będzie cię kosztować zasoby i dobrą praktyką jest nie marnowanie zasobów na nieistotne rzeczy.

Rozwiązaniem, którego teraz używam, jest Linux Logwatch . Wysyła mi podsumowania dzienników, które są filtrowane i grupowane. W ten sposób możesz łatwo oddzielić to, co ważne, od tego, co nieistotne.

Dziękuję wszystkim za pomoc i mam nadzieję, że ten post może być pomocny także dla kogoś innego.

Saif Bechan
źródło

Odpowiedzi:

34

Z Twojego dziennika błędów wysyłają żądanie HTTP / 1.1 bez części Host: żądanie. Z tego, co przeczytałem, Apache odpowiada błędem 400 (niepoprawne żądanie) na to żądanie, przed przekazaniem go do mod_security. Więc nie wygląda na to, że Twoje reguły zostaną przetworzone. (Apache radzi sobie z tym przed wymaganiem przekazania do mod_security)

Spróbuj sam:

nazwa hosta telnet 80
GET /blahblahblah.html HTTP / 1.1 (enter)
(wchodzić)

Powinieneś dostać błąd 400 i zobaczyć ten sam błąd w swoich logach. To zła prośba, a Apache podaje prawidłową odpowiedź.

Prawidłowe żądanie powinno wyglądać następująco:

POBIERZ /blahblahblah.html HTTP / 1.1
Host: blah.com

Rozwiązaniem tego problemu może być załatanie mod_uniqueid w celu wygenerowania unikalnego identyfikatora nawet dla nieudanego żądania, aby apache przekazał żądanie do swoich programów obsługi żądań. Poniższy adres URL to dyskusja na temat tego obejścia i zawiera łatkę dla mod_uniqueid, której możesz użyć: http://marc.info/?l=mod-security-users&m=123300133603876&w=2

Nie mogłem znaleźć innych rozwiązań i zastanawiałem się, czy rozwiązanie jest rzeczywiście wymagane.

Imo
źródło
Teraz widzę problem. Czy polecasz rozwiązanie podane w tym artykule, czy uważasz, że lepiej jest po prostu zostawić je bez zmian? Jest to skaner do wszystkich tylnych drzwi w systemie. Jeśli zostawię to skanowanie, mógłbym kiedyś zostać zaatakowany.
Saif Bechan
1
Witaj Saif, myślę, że dopóki aktualizujesz instalację apache za pomocą swoich poprawek bezpieczeństwa (lub ręcznych), wszystko powinno być w porządku. Źle ustrukturyzowane żądanie HTTP / 1.1 (jak widzieliście) nie powinno zwracać niczego innego niż błąd 400 z apache. Wygląda na to, że mógł to być rodzaj skanowania w poszukiwaniu luk w zabezpieczeniach routerów DLink. (Według niektórych innych źródeł)
Imo
Czy istnieje przynajmniej sposób na usunięcie tych pól z mojego apache error_log
Saif Bechan
Być może będziesz w stanie to zrobić poprzez mod_log :: httpd.apache.org/docs/2.2/mod/mod_log_config.html#customlog
Imo
Moja dodatkowa wskazówka brzmi: skonfiguruj domyślnego wirtualnego hosta obok aktualnie używanych. Powyższe próby zakończą się zapisaniem domyślnego wirtualnego hosta w logach .
Koos van den Hout
16

Filtrowanie adresów IP nie jest dobrym pomysłem, imho. Dlaczego nie spróbować filtrować znanego ciągu?

Mam na myśli:

iptables -I INPUT -p tcp --dport 80 -m string --to 60 --algo bm --string 'GET /w00tw00t' -j DROP
Des
źródło
spamcleaner.org/en/misc/w00tw00t.html podobne rozwiązanie, ale nieco bardziej szczegółowe.
Izaak,
Jednym z problemów z filtrowaniem ciągów w zaporze ogniowej jest to, że działa ona „dość wolno”.
Alexis Wilke,
@AlexisWilke czy masz dowody sugerujące, że filtrowanie napisów w iptables jest wolniejsze niż filtrowanie na poziomie apache?
jrwren
@ jrwren Właściwie może być dość powolny tylko wtedy, gdy nie przekroczysz przesunięcia pakietu, aby zatrzymać wyszukiwanie, tzn. „--to 60” tutaj. Domyślnie przeszukuje cały pakiet, maksymalny limit jest ustawiony na 65 535 bajtów, maksymalna długość pakietu IP: blog.nintechnet.com/… Instrukcja wyraźnie mówi „Jeśli nie zostanie przekroczony, domyślny jest rozmiar pakietu”.
gouessej
to teoretycznie maks. bardziej realistyczna maksymalna długość w Internecie wynosi ~ 1500.
jrwren,
11

Iv również zaczął widzieć tego typu wiadomości w moich plikach dziennika. Jednym ze sposobów zapobiegania tego typu atakom jest skonfigurowanie fail2ban ( http://www.fail2ban.org/ ) i skonfigurowanie określonych filtrów, aby czarna lista tych adresów IP znajdowała się w twoich regułach iptables.

Oto przykład filtra, który blokowałby adres IP związany z tworzeniem tych wiadomości

[Wtorek 16 02:35:23 2011] [błąd] [klient] Plik nie istnieje: /var/www/skraps/w00tw00t.at.blackhats.romanian.anti-sec :) === apache w00t w00t wiadomości więzienie - regex and filter === Więzienie

 [apache-wootwoot]
 enabled  = true
 filter   = apache-wootwoot
 action   = iptables[name=HTTP, port="80,443", protocol=tcp]
 logpath  = /var/log/apache2/error.log
 maxretry = 1
 bantime  = 864000
 findtime = 3600

Filtr

 # Fail2Ban configuration file
 #
 # Author: Jackie Craig Sparks
 #
 # $Revision: 728 $
 #
 [Definition]
 #Woot woot messages
 failregex = ^\[\w{1,3} \w{1,3} \d{1,2} \d{1,2}:\d{1,2}:\d{1,2} \d{1,4}] \[error] \[client 195.140.144.30] File does not exist: \/.{1,20}\/(w00tw00t|wootwoot|WootWoot|WooTWooT).{1,250}
 ignoreregex =
Jackie Craig Sparks
źródło
2
To prawda, że ​​możesz je zablokować, ale nie ma takiej potrzeby, ponieważ są to po prostu złe żądania. Lepiej je po prostu zignorować, zaoszczędzić pracę i uwolnić trochę zasobów.
Saif Bechan
Racja @ Saif Bechan, jeśli ktoś martwi się, że „ataki testowe” odniosą sukces, powinien lepiej naprawić własną aplikację, zamiast marnować czas na znalezienie sposobu na jej zablokowanie.
Thomas Berger,
Dał ci +1, dziękuję za odpowiedź.
Saif Bechan
4
@SaifBechan, nie zgadzam się. w00tw00t to skaner podatności na zagrożenia, a na maszynie, która wysyła takie żądania, nie można ufać próbie innych typów żądań, więc jeśli jestem administratorem systemu, a banowanie takich klientów przez kilka dni zajmuje mi 2 minuty, ja zrobiłbym to. Jednak nie oparłbym całej mojej implementacji bezpieczeństwa na takim podejściu.
Izaak
3

w00tw00t.at.blackhats.romanian.anti-sec to próba hakowania, która wykorzystuje fałszywe adresy IP, więc wyszukiwania takie jak VisualRoute zgłaszają Chiny, Polskę, Danię itp. zgodnie z adresatem IP w tym czasie. Dlatego skonfigurowanie Odmówienia adresu IP lub możliwej do rozwiązania nazwy hosta jest prawie niemożliwe, ponieważ zmieni się ono w ciągu godziny.

PRW
źródło
Te skanowania narażenia na atak nie używają sfałszowanych adresów IP. Jeśli tak, potrójny uścisk protokołu TCP nie zostanie zakończony, a Apache nie zarejestruje żądania. Ostrzeżenia (nieuczciwy dostawca usług internetowych, operatorzy routerów itp.) Można znaleźć na stronie security.stackexchange.com/q/37481/53422
Anthony Geoghegan
2

Osobiście napisałem skrypt Pythona do automatycznego dodawania reguł IPtables.

Oto nieco skrócona wersja bez logowania i innych śmieci:

#!/usr/bin/python
from subprocess import *
import re
import shlex
import sys

def find_dscan():
        p1 = Popen(['tail', '-n', '5000', '/usr/local/apache/logs/error_log'], stdout=PIPE)
        p2 = Popen(['grep', 'w00t'], stdin=p1.stdout, stdout=PIPE)

        output = p2.communicate()[0].split('\n')

        ip_list = []

        for i in output:
                result = re.findall(r"\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b", i)
                if len(result):
                        ip_list.append(result[0])

        return set(ip_list)

for ip in find_dscan():
        input = "iptables -A INPUT -s " + ip + " -j DROP"
        output = "iptables -A OUTPUT -d " + ip + " -j DROP"
        Popen(shlex.split(input))
        Popen(shlex.split(output))

sys.exit(0)
Xorlev
źródło
Czy to ma zapobiec atakowi w00tw00t
Saif Bechan
Tak, mam skanować dzienniki błędów Apache w poszukiwaniu adresów IP „w00tw00t” i dodawać je, jeśli nie istnieją, chociaż dla uproszczenia nie dodałem sprawdzania duplikatów.
Xorlev,
Skrypt ten prawdopodobnie powinien używać tabeli, dodanie ton dodatkowych reguł do łańcuchów iptables spowolni przetwarzanie.
Eric
Używa tabeli. Jednak uprościłem wiele z nich, ponieważ były one dostosowane do mojego systemu.
Xorlev,
czy uważasz, że jest to lepsze rozwiązanie niż użycie mod_security
Saif Bechan
2

Uważam, że powodem, dla którego mod_security nie działa, jest to, że Apache nie był w stanie samodzielnie przeanalizować żądań, ponieważ są one niespecyfikowane. Nie jestem pewien, czy masz tutaj problem - apache rejestruje dziwne gówno, które dzieje się w sieci, jeśli się nie zaloguje, nie będziesz wiedział, że to się dzieje. Zasoby wymagane do zarejestrowania żądań są prawdopodobnie minimalne. Rozumiem, że frustrujące jest to, że ktoś wypełnia twoje logi - ale będzie to bardziej frustrujące, jeśli wyłączysz rejestrowanie tylko po to, aby naprawdę go potrzebujesz. Jakby ktoś włamał się do twojego serwera i potrzebujesz dzienników, aby pokazać, jak się włamał.

Jednym z rozwiązań jest skonfigurowanie funkcji ErrorLogging poprzez syslog, a następnie za pomocą rsyslog lub syslog-ng można w szczególności filtrować i odrzucać naruszenia RFC dotyczące w00tw00t. Ewentualnie możesz je przefiltrować do osobnego pliku dziennika, aby główny dziennik błędów był łatwy do odczytania. Rsyslog jest pod tym względem niezwykle potężny i elastyczny.

W httpd.conf możesz zrobić:

ErrorLog syslog:user 

następnie w rsyslog.conf możesz mieć:

:msg, contains, "w00tw00t.at.ISC.SANS.DFind" /var/log/httpd/w00tw00t_attacks.log

Należy pamiętać, że takie podejście zużywa wielokrotnie więcej zasobów niż pierwotnie używane logowanie bezpośrednio do pliku. Jeśli twój serwer jest bardzo zajęty, może to stanowić problem.

Najlepszą praktyką jest wysyłanie wszystkich dzienników do zdalnego serwera rejestrowania tak szybko, jak to możliwe, a to przyniesie korzyść w przypadku włamania, ponieważ znacznie trudniej jest usunąć ścieżkę audytu tego, co zostało zrobione.

Blokowanie IPTables jest pomysłem, ale możesz skończyć z bardzo dużą listą bloków iptables, która sama w sobie może mieć wpływ na wydajność. Czy w adresach IP jest jakiś wzorzec, czy pochodzi on z dużego rozproszonego botnetu? Będziesz musiał uzyskać X% duplikatów, zanim będziesz mógł skorzystać z iptables.

hellomynameisjoel
źródło
Dobra odpowiedź, podoba mi się różne podejście. Myśląc o tym, posiadanie niestandardowego rejestrowania zwiększy wykorzystanie regresu, ponieważ wszystko musi być najpierw sprawdzone, myślę, że ta opcja również odpada. Mam teraz włączony logwatch. To wysyła mi raport 2 razy dziennie z podsumowaniami całych systemów. Dzienniki apache są również sprawdzane i mówi tylko, że w00tw00t próbuje 300 razy. Myślę, że na razie opuści konfigurację.
Saif Bechan
1

Mówisz w aktualizacji 2:

Problem, który nadal występuje Problem, który nadal występuje, jest następujący. Te ataki pochodzą od botów, które wyszukują określone pliki na twoim serwerze. Ten konkretny skaner szuka pliku /w00tw00t.at.ISC.SANS.DFind :).

Teraz możesz po prostu zignorować to, co jest najbardziej zalecane. Problem polega na tym, że jeśli pewnego dnia masz ten plik na serwerze, masz jakieś problemy.

Z mojej poprzedniej odpowiedzi stwierdziliśmy, że Apache zwraca komunikaty o błędach z powodu źle sformułowanego zapytania HTML 1.1. Wszystkie serwery obsługujące HTTP / 1.1 powinny prawdopodobnie zwrócić błąd po otrzymaniu tego komunikatu (nie sprawdziłem dwukrotnie RFC - być może RFC2616 mówi nam).

Posiadanie w00tw00t.at.ISC.SANS.DFind: na twoim serwerze gdzieś nie oznacza mistycznie „masz kłopoty” ... Jeśli utworzysz plik w00tw00t.at.ISC.SANS.DFind: w twoim DocumentRoot lub nawet DefaultDocumentRoot to nie ma znaczenia ... skaner wysyła zepsute żądanie HTTP / 1.1, a apache mówi „nie, to złe żądanie ... do widzenia”. Dane w pliku w00tw00t.at.ISC.SANS.DFind: nie będą obsługiwane.

Użycie mod_security w tym przypadku nie jest wymagane, chyba że naprawdę chcesz (nie ma sensu?) ... w takim przypadku możesz spojrzeć na łatanie go ręcznie (link w innej odpowiedzi).

Inną rzeczą, na którą możesz spojrzeć przy użyciu, jest funkcja RBL w mod_security. Być może istnieje RBL online, który zapewnia adresy IP w00tw00t (lub inne znane złośliwe adresy IP). Oznaczałoby to jednak, że mod_security sprawdza DNS dla każdego żądania.

Imo
źródło
Nie sądzę, że apache je odrzuca, po prostu zgłasza błąd, ale wyszukiwanie wciąż mija. Mam ten sam plik w00tw00t.at.ISC.SANS.D. Znajdź dziennik dostępu. Robi się GET. Wyszukiwanie jest zakończone i jeśli masz plik na swoim komputerze, zostanie on wykonany. Mogę publikować wpisy dziennika dostępu, ale wyglądają tak samo jak dziennik błędów tylko z GET przed nimi. Apache zgłasza błąd, ale żądanie mija. Dlatego zapytałem, czy dobrym pomysłem byłoby zablokowanie tych żądań bez nazw hostów. Ale nie chcę blokować zwykłych użytkowników.
Saif Bechan
1
Jasne, masz ten sam wpis w dzienniku dostępu, ale spójrz na kod błędu ... 400. Nie jest przetwarzany. HTTP / 1.1 (nazwa hosta) służy do informowania apache, do którego wirtualnego hosta ma wysłać zapytanie ... bez nazwy hosta część HTTP / 1.1 apache nie wie, gdzie wysłać żądanie i zwraca błąd „400 złych żądań” z powrotem do klienta.
Imo
Spróbuj sam ... utwórz sobie stronę HTML na swoim serwerze i spróbuj dostać się do niej ręcznie za pomocą „telnet hostname 80” ... pozostałe kroki są w mojej pierwszej odpowiedzi. Złożyłbym na to dużą nagrodę, że nie można wyświetlić pliku HTML do wyświetlenia za pomocą HTTP / 1.1 bez nazwy hosta.
Imo
Ach tak tak za wskazanie mi tego. Zawsze myślałem, że access_log to wpisy, które zostały przekazane przez dziennik błędów i faktycznie weszły na twój komputer. Dziękuję za wskazanie mi tego, a ja zmodyfikuję swój post. Doceniam twoją pomoc.
Saif Bechan
Cześć Saif, nie ma problemów, cieszę się, że pomogłem. Pozdrawiam, Imo
Imo
1

Co powiesz na dodanie reguły do ​​modsecurity? Coś takiego:

   SecRule REQUEST_URI "@rx (?i)\/(php-?My-?Admin[^\/]*|mysqlmanager
   |myadmin|pma2005|pma\/scripts|w00tw00t[^\/]+)\/"
   "severity:alert,id:'0000013',deny,log,status:400,
   msg:'Unacceptable folder.',severity:'2'"
Kreker
źródło
1

Widzę, że większość rozwiązań jest już omówionych powyżej, jednak chciałbym zauważyć, że nie wszyscy klienci wysyłający żądania HTTP / 1.1 bez ataków na nazwy hosta są skierowani bezpośrednio na twój serwer. Istnieje wiele różnych prób pobrania odcisków palców i / lub wykorzystania systemu sieciowego poprzedzającego serwer, np. Przy użyciu:

client sent HTTP/1.1 request without hostname (see RFC2616 section 14.23): /tmUnblock.cgi

aby celować w routery Linksys itp. Czasami pomaga to zwiększyć koncentrację i podzielić wysiłki obronne między wszystkie systemy z jednakowym udziałem, tj .: wdrożyć reguły routera, wdrożyć reguły zapory ogniowej (mam nadzieję, że twoja sieć je posiada), wdrożyć zaporę serwera / tabelę adresów IP reguły i powiązane usługi, tj. mod_security, fail2ban i tak dalej.

Mediolan
źródło
1

co powiesz na to ?

iptables -I INPUT -p tcp --dport 80 -m string --to 70 --algo bm --string 'GET /w00tw00t.at.ISC.SANS.DFind' -j DROP
iptables -I INPUT -p tcp --dport 80 -m string --to 70 --algo bm --string 'GET /w00tw00t.at.ISC.SANS.DFind' -j LOG --log-level 4 --log-prefix Hacktool.DFind:DROP:

działa dobrze dla mnie.

Urbach-Webhosting
źródło
Poleciłem OWASP_CRS / 2.2.5 lub większy zestaw reguł dla mod_security
Urbach-Webhosting
To naprawdę nie jest dobry pomysł. Skończysz z wieloma wiszącymi połączeniami. Dodatkowo, jeśli Twoja witryna zawiera dyskusje na temat tych żądań, możesz skończyć z fałszywymi pozytywami.
kasperd
0

Jeśli używasz hiawathaserwera internetowego jako reverse proxyskanu, skany są automatycznie usuwane jako śmieci i clientzbanowane. Filtruje również XSSi CSRFwykorzystuje.

Stuart Cardall
źródło