Krótko: Jeśli PHP-FPM, Apache lub inny proces serwera WWW uruchamia powłokę taką jak sh czy bash, jest to jeden z najsilniejszych sygnałów ostrzegawczych włamania przez stronę internetową. Zanim cokolwiek Państwo zakończą, proszę sprawdzić drzewo procesów, wiersz poleceń i katalog roboczy powłoki. Pojedyncze, krótkie powłoki mogą być uzasadnione; długo działające powłoki z narzędziami sieciowymi prawie nigdy.
Dlaczego ten wzorzec mówi tak wiele
Serwer WWW odpowiada na żądania. PHP-FPM, czyli menedżer procesów, który wykonuje skrypty PHP dla serwera WWW, zwykle nie uruchamia w tym celu żadnych dalszych programów. Powłoka pod serwerem WWW oznacza, że kod PHP celowo wywołał program. Albo robi to aplikacja z założenia, albo ktoś inny wprowadził kod.
Dla PHP2Shell nie ma opublikowanych, potwierdzonych wskaźników kompromitacji (Indicators of Compromise), czyli listy stałych cech rozpoznawczych. Wykrywanie opiera się na zachowaniu. Według znanych nam doniesień procesy serwera WWW lub PHP-FPM uruchamiające powłokę należą do najsilniejszych ogólnych sygnałów ostrzegawczych. Dotyczy to każdej luki, przez którą atakujący mogą wykonywać kod na serwerze. Przegląd dalszych oznak daje artykuł Czy już zostałem skompromitowany?.
Dlaczego powłoka jest dla atakującego tak ważna? Dzięki luce może on początkowo wydawać tylko pojedyncze polecenia przez proces PHP. Powłoka zamienia to w wygodne stanowisko pracy: może się rozejrzeć, doładować narzędzia, odczytać dane dostępowe z plików konfiguracyjnych i urządzić się na stałe. Kto rozpozna powłokę, często rozpoznaje więc atakującego w chwili, gdy przechodzi od pierwszego dostępu do właściwego zamiaru.
PHP-FPM uruchamia bash: czytanie drzewa procesów
Każdy proces w Linuxie ma proces nadrzędny. Pytanie brzmi, czy powłoka działa jako dziecko procesu serwera WWW. Poniższe polecenia tylko odczytują dane:
# Drzewo procesów z użytkownikiem, PID rodzica i czasem startu
ps -eo user,pid,ppid,lstart,cmd --forest | grep -B2 -A4 -E "[p]hp-fpm|[a]pache2|[h]ttpd|[l]sphp"
# Powłoki działające pod typowymi użytkownikami serwera WWW
ps -eo user,pid,ppid,lstart,cmd | grep -E "^(www-data|apache|nginx) " | grep -E "[ /](ba|da)?sh( |$)"
# Drzewo od najstarszego procesu PHP-FPM
pstree -alp "$(pgrep -o php-fpm)"
Jeśli znaleźli Państwo podejrzaną powłokę, wpisy w /proc dostarczają dalszych wskazówek, również tylko do odczytu:
PID=12345 # PID podejrzanej powłoki
tr '\0' ' ' < /proc/$PID/cmdline; echo # pełny wiersz poleceń
ls -l /proc/$PID/cwd /proc/$PID/exe # katalog roboczy i plik programu
ls -l /proc/$PID/fd 2>/dev/null | grep socket # otwarte połączenia sieciowe
Nazwy procesów w Debianie i Ubuntu brzmią często php8.3-fpm lub podobnie; wzorce wyszukiwania proszę dostosować. Katalogi robocze w /tmp, /dev/shm lub w katalogach uploadu to wyraźny znak.
Uzasadnione wyjątki i prawdziwe sygnały ostrzegawcze
Niektóre aplikacje wywołują programy przez PHP. Może przy tym na krótko powstać powłoka, na przykład gdy PHP przekazuje pocztę przez sendmail_path albo aplikacja przetwarza obrazy zewnętrznym narzędziem. Takie powłoki żyją tylko sekundy i zawsze wywołują ten sam program. Proszę raz porządnie udokumentować te oczekiwane przypadki; wtedy każde odstępstwo od nich od razu rzuca się w oczy, zamiast utonąć w powodzi znanych komunikatów.
| Obserwacja | Raczej niegroźna, gdy | Podejrzana, gdy |
|---|---|---|
| Krótka powłoka pod PHP-FPM | uruchamia znany program aplikacji | cel i przeznaczenie są niejasne |
| Dłużej działająca powłoka | nigdy | działa minutami lub godzinami |
| Narzędzia sieciowe jako proces potomny | znane zapytanie o aktualizację lub API aplikacji | następują pobrania do katalogów tymczasowych |
| Katalog roboczy | folder projektu aplikacji | /tmp, /dev/shm, katalogi uploadu |
| Moment | pasuje do znanej akcji, np. wysyłki poczty | w nocy, bez aktywności użytkowników, w skupiskach |
Jeśli nie wiedzą Państwo, czy aplikacja wywołuje programy, proszę zapytać programistę lub poszukać w kodzie funkcji takich jak exec, shell_exec, system, passthru, proc_open i popen. Trafienia we własnym kodzie są normalne, trafienia w nieznanych plikach nie.
Monitorować stale zamiast zajrzeć raz
Zdjęcie chwilowe przez ps wyłapuje tylko powłoki, które właśnie działają. Krótkotrwałe procesy się prześlizgują. Wiarygodniejsze jest stałe protokołowanie uruchomień programów przez użytkownika serwera WWW. W Linuxie robi to usługa audytu auditd z regułą dla uruchomień programów przez użytkownika serwera WWW. Analiza odbywa się tylko do odczytu:
# Wyświetlić zaprotokołowane uruchomienia programów pod kluczem reguły (klucz jako przykład)
sudo ausearch -k web_exec --start today -i | grep -E "exe=|proctitle="
Jak wygląda reguła, zależy od dystrybucji i identyfikatora użytkownika; proszę ją najpierw przetestować, ponieważ na mocno obciążonych serwerach powstaje wiele wpisów.
Dwa uzupełnienia czynią monitoring odpornym. Po pierwsze, protokoły powinny dodatkowo trafiać do systemu centralnego, ponieważ atakujący z uprawnieniami roota może usunąć logi lokalne. Po drugie, potrzebne jest alarmowanie: uruchomienie programu przez użytkownika serwera WWW, którego nie ma na krótkiej liście oczekiwanych programów, powinno wywołać komunikat, a nie tylko wpis w logu. Kto już używa rozwiązania do wykrywania na urządzeniach końcowych lub serwerach, może odwzorować tę samą regułę tam. Prewencyjnie przez disable_functions można zablokować to, czego aplikacja nie potrzebuje. Nie zamyka to luki w interpreterze, ale utrudnia atakującemu następny krok. Szczegóły znajdą Państwo w Prawidłowe użycie disable_functions.
Co robić, gdy znajdą Państwo powłokę pod serwerem WWW
- Udokumentować: Zapisać wynik
ps, wiersz poleceń, katalog roboczy i otwarte połączenia do pliku poza katalogiem WWW. - Nie sprzątać: Nie usuwać plików i nie kończyć procesów, zanim ślady nie zostaną zabezpieczone.
- Izolować: Odłączyć serwer od sieci lub mocno ograniczyć dostęp.
- Szukać przyczyny: Sprawdzić logi, nowe pliki i mechanizmy trwałości, takie jak zadania cron, zob. Znajdowanie podejrzanych procesów na serwerach Linux.
- Zmienić dostępy: Wszystkie hasła i klucze, które leżały na serwerze, należy uznać za znane.
Jeśli aplikacja działa w kontenerach, ta sama zasada obowiązuje w małej skali. Powłoka w kontenerze PHP jest tak samo podejrzana jak na klasycznym serwerze, a obrazy kontenerów często ją zawierają tylko dlatego, że przynosi ją obraz bazowy. Przed restartem kontenera proszę zabezpieczyć jego stan, ponieważ wraz z kontenerem znikają także ślady w ulotnym systemie plików.
Proszę sprawdzić też sąsiedztwo. Atakujący z powłoką na serwerze WWW często próbuje stamtąd dotrzeć do innych systemów, na przykład do bazy danych, pamięci kopii zapasowych czy wewnętrznych interfejsów administracyjnych. Dane dostępowe w plikach konfiguracyjnych aplikacji bardzo mu to ułatwiają.
Długo działająca powłoka pod PHP-FPM na serwerze z danymi klientów to incydent bezpieczeństwa. Proszę go tak traktować: zabezpieczyć, izolować, opracować w sposób uporządkowany, kazać sprawdzić obowiązki zgłoszeniowe.
Jak konkretnie pomaga PHP SOS?
- Ocenić ustalenia: Sprawdzamy drzewo procesów, wiersze poleceń i połączenia oraz odróżniamy zachowanie aplikacji od śladów włamania.
- Zabezpieczyć ślady: Zabezpieczamy stan systemu w sposób możliwy do prześledzenia, zanim cokolwiek zostanie zmienione.
- Obsłużyć incydent: W ramach Incident Response prowadzimy od powstrzymania do udokumentowanego zamknięcia.
- Zabezpieczyć na stałe: Konfigurujemy protokołowanie uruchomień programów i ograniczamy funkcje PHP do tego, co konieczne. Jak PHP-FPM działa wewnętrznie, wyjaśnia PHP-FPM wyjaśnione.
Częste pytania
Czy każda powłoka pod PHP-FPM to atak?
Nie każda. Niektóre aplikacje celowo wywołują przez PHP programy, na przykład do obróbki obrazów lub wysyłki poczty, i wtedy może na krótko powstać powłoka. Podejrzane staje się to, gdy powłoka działa dłużej, uruchamia narzędzia sieciowe lub pracuje z nietypowych katalogów.
Czy powinienem od razu zakończyć podejrzany proces?
Najpierw udokumentować, potem działać. Proszę zapisać dane procesu, wiersz poleceń, katalog roboczy i połączenia sieciowe. Następnie izolować serwer. Pochopne zakończenie niszczy ślady i nie zapobiega powrotowi atakującego.
Czy dla PHP2Shell istnieją potwierdzone cechy rozpoznawcze?
Nie. Nie ma opublikowanych, potwierdzonych wskaźników kompromitacji (IoC). Powłoki pod serwerem WWW są ogólnym sygnałem ostrzegawczym włamań przez aplikacje webowe, nie specyficznym dla PHP2Shell.
Jak zapobiec, by PHP w ogóle uruchamiało powłoki?
Przez disable_functions można zablokować funkcje takie jak exec, shell_exec, system i proc_open, jeśli aplikacja ich nie potrzebuje. Nie zamyka to luki w interpreterze PHP, ale utrudnia wykorzystanie.