Dlaczego to boli, nawet gdy się nie udaje
Każde uderzenie w formularz logowania popularnego CMS-a to pełny cykl: uruchomienie procesu PHP, połączenie do bazy, odczyt użytkownika, kosztowne obliczenie skrótu hasła. Funkcje haszujące są celowo powolne, żeby utrudnić łamanie offline. Przy kilkunastu żądaniach na sekundę ta sama właściwość obraca się przeciwko serwerowi: procesor idzie w górę, pula procesów PHP zapełnia się, a normalne żądania czekają w kolejce. Klient widzi wolną stronę i nie ma pojęcia, że trwa atak.
Warstwy, które zakładamy
- ograniczenie liczby żądań do adresu logowania na poziomie serwera WWW, zanim zapytanie dotrze do PHP - to jest najtańsza warstwa i najskuteczniejsza
- automatyczne blokowanie adresów po serii nieudanych prób (fail2ban czytający logi serwera WWW, nie tylko SSH)
- zmiana domyślnego adresu panelu - nie zatrzyma ukierunkowanego ataku, ale odcina większość automatów
- wymuszone drugie składnik uwierzytelnienia dla kont z uprawnieniami administratora
- blokada wykonywania PHP w katalogach, do których CMS zapisuje pliki
Kolejność ma znaczenie. Wtyczka bezpieczeństwa wewnątrz CMS-a odrzuca żądanie dopiero po uruchomieniu całego frameworka, czyli po poniesieniu kosztu, który chcieliśmy uniknąć. Limit na serwerze WWW kosztuje ułamek tego.
XML-RPC i inne zapomniane wejścia
Panel logowania to nie jedyne drzwi. Interfejsy zdalnego zarządzania, API i stare pliki instalacyjne przyjmują próby uwierzytelnienia równie chętnie, a często bez żadnego limitu. Przy przejęciu serwera przechodzimy listę wystawionych adresów i wyłączamy to, czego klient nie używa. Najczęściej okazuje się, że nie używa niczego z tej listy.
Jak to wygląda w monitoringu
Na serwerach pod naszą opieką nagły wzrost liczby procesów PHP przy niezmienionym ruchu na stronie jest osobnym alertem. To zwykle pierwszy sygnał ataku słownikowego - wcześniejszy niż skarga klienta, że sklep zwalnia.