Krótko: Aby sprawdzić pliki rdzenia CMS, porównują Państwo zainstalowane pliki z czystym oryginałem tej samej wersji: w WordPress za pomocą oficjalnych sum kontrolnych, w innych systemach za pomocą świeżo pobranego pakietu lub odtworzenia z composer.lock. Każda rozbieżność to zadanie do sprawdzenia. Porównanie wykrywa także nieznany złośliwy kod, ale obejmuje tylko pliki, dla których istnieje oryginał.
Dlaczego porównanie znajduje więcej niż jakakolwiek sygnatura
Skanery malware szukają znanych wzorców. Czego nie znają, to pomijają. Porównanie z oryginałem działa odwrotnie: nie pyta, czy plik wygląda podejrzanie, lecz czy dokładnie odpowiada temu, co dostarczył producent. Każda rozbieżność rzuca się w oczy, niezależnie od tego, czy odpowiada znanemu wzorcowi.
Po PHP2Shell jest to szczególnie cenne. Dla luk CVE-2026-109618 i CVE-2026-109619 nie ma opublikowanych, potwierdzonych wskaźników włamania (Indicators of Compromise). Skanery nie mogą więc celowo szukać śladów PHP2Shell. Porównanie z oryginałem wykrywa natomiast każdą zmianę w rdzeniu, niezależnie od tego, jak powstała. Dlaczego same skanery nie wystarczają, wyjaśnia artykuł Skanery malware dla stron WWW: co znajdują, a czego nie.
Zasada: ta sama wersja, czyste źródło
Porównanie jest tak dobre, jak jego wzorzec. Muszą być spełnione trzy warunki:
- Dokładnie ta sama wersja: porównanie z nowszą wersją pokazuje setki nieszkodliwych różnic. Wersję zainstalowaną ustala się z aplikacji lub z
composer.lock. - Oficjalne źródło: oryginał pochodzi od producenta, z oficjalnego katalogu pakietów lub z własnego systemu kontroli wersji. Nie ze starej kopii zapasowej dotkniętego serwera.
- Porównanie na kopii: proszę pracować na zabezpieczonej kopii katalogu strony, aby zachować znaczniki czasu i ślady.
| System | Wzorzec | Narzędzie |
|---|---|---|
| Rdzeń WordPress i wtyczki z katalogu | sumy kontrolne z WordPress.org | wp core verify-checksums, wp plugin verify-checksums |
| Projekty Composera (np. Shopware 6, Laravel, Symfony, Drupal, TYPO3 w trybie Composera) | odtworzenie z composer.lock |
composer install w pustym katalogu, następnie diff |
| CMS z pakietem do pobrania | pakiet tej samej wersji od producenta | diff -rq |
| Własne projekty z Git | ostatni znany commit | git status, git diff |
| Pakiety systemowe serwera | baza pakietów dystrybucji | dpkg --verify, rpm -Va |
WordPress: więcej niż verify-checksums
Jak sprawdzić rdzeń i wtyczki za pomocą WP-CLI, opisuje poradnik Wyszukiwanie backdoorów w WordPress. Warto dodać jedno uzupełnienie: według dokumentacji WP-CLI opcja --include-root sprawdza wszystkie pliki i katalogi w katalogu głównym i ostrzega przed wpisami, które nie należą do WordPress. Atakujący chętnie umieszczają tam pliki o nazwach przypominających pliki rdzenia.
# Rdzeń względem oficjalnych sum kontrolnych, łącznie z obcymi plikami w katalogu głównym
wp core verify-checksums --include-root
Komercyjnych wtyczek i motywów ta droga nie obejmuje. W ich przypadku pobierają Państwo oryginalny pakiet tej samej wersji od dostawcy i porównują za pomocą diff.
Sprawdzanie plików rdzenia CMS w projektach Composera
Wiele nowoczesnych aplikacji PHP składa się w większości z pakietów instalowanych przez Composera, menedżera pakietów dla PHP. Jak działa, wyjaśnia strona Composer: menedżer pakietów dla PHP. Plik composer.lock zapisuje, jakie dokładnie wersje są zainstalowane. Według dokumentacji Composera composer install używa dokładnie tych wersji. Dzięki temu można odtworzyć stan dostarczony:
# Na czystym systemie, nie na dotkniętym serwerze
mkdir /tmp/referenz && cd /tmp/referenz
cp /pfad/zur/kopie/composer.json /pfad/zur/kopie/composer.lock .
composer install --no-scripts --no-plugins --no-autoloader
# Wypisać różnice w katalogu vendor
diff -rq /tmp/referenz/vendor /pfad/zur/kopie/vendor
Opcje --no-scripts i --no-plugins zapobiegają wykonywaniu skryptów z pakietów podczas odtwarzania. Jeśli produkcję zainstalowano z --no-dev, proszę użyć tej opcji także przy odtwarzaniu, w przeciwnym razie pakiety deweloperskie pojawią się jako różnica. Proszę zwrócić uwagę na dwa rodzaje wyników: pliki, które się różnią, i pliki, które istnieją tylko na serwerze. Ta druga grupa jest często ciekawsza. Jak dodatkowo sprawdzić zainstalowane pakiety pod kątem znanych luk, opisuje poradnik Sprawdzanie zależności Composera pod kątem luk.
Porównać także system operacyjny
Jeśli atakujący miał uprawnienia roota, mógł też podmienić programy systemowe. Menedżery pakietów mają własne porównanie:
# Debian, Ubuntu: pliki, których zawartość różni się od pakietu
sudo dpkg --verify
# RHEL, AlmaLinux, Rocky: sprawdzić wszystkie pakiety
sudo rpm -Va
Cyfra 5 na trzeciej pozycji wyniku oznacza, że zawartość pliku się zmieniła. Według podręcznika dpkg porównanie zawartości jest tam obecnie jedyną skuteczną kontrolą. Zmienione pliki konfiguracyjne są normalne i oznaczone literą c. Zmieniony program w /usr/bin jest natomiast poważnym sygnałem alarmowym. Proszę pamiętać: atakujący z uprawnieniami roota może też zmanipulować bazę pakietów. Przy podejrzeniu dostępu roota przebudowa jest wiarygodniejsza niż jakiekolwiek porównanie.
System kontroli wersji dla kodu aplikacji sprawia, że przyszłe porównania zajmują sekundy. git status pokazuje wtedy każdą rozbieżność względem zatwierdzonego stanu.
Ocena rozbieżności i znajomość ograniczeń
Nie każda rozbieżność jest atakiem. Niektóre agencje dawniej modyfikowały pliki rdzenia bezpośrednio, zamiast używać rozszerzeń. Pakiety językowe, zakończenia wierszy po przesłaniu przez FTP lub później wgrane poprawki także powodują różnice. Decydujące jest, czy ktoś potrafi tę zmianę wyjaśnić.
Proszę przejść każdą rozbieżność osobno i zanotować wynik: znana i udokumentowana, nieszkodliwa i możliwa do wyjaśnienia lub niejasna. Niejasne pliki otwiera się wyłącznie jako tekst na kopii i zastępuje z czystego źródła. W przypadku plików istniejących tylko na serwerze pytanie jest prostsze: kto ich nie zna, powinien je zabezpieczyć i usunąć po sprawdzeniu ich zawartości.
Uploady, pliki konfiguracyjne takie jak wp-config.php lub .env, własne modyfikacje i pamięci podręczne nie mają oryginału. Trzeba je sprawdzać celowo, podobnie jak bazę danych, zadania cron, konta użytkowników i klucze SSH. Czyste porównanie jest więc ważnym elementem, ale nie uniewinnia całego serwera.
Jak konkretnie pomaga PHP SOS?
- Ustalamy zainstalowane wersje i budujemy czysty wzorzec z oficjalnych źródeł.
- Porównujemy rdzeń, rozszerzenia, pakiety Composera i programy systemowe oraz oceniamy każdą rozbieżność.
- Celowo sprawdzamy obszary bez oryginału i zastępujemy zmienione pliki czystymi z oficjalnego źródła w ramach usuwania malware.
- Na życzenie konfigurujemy stan wersji, względem którego odbywają się przyszłe kontrole.
Częste pytania
Jak sprawdzić, czy pliki rdzenia WordPress zostały zmienione?
Za pomocą WP-CLI i polecenia wp core verify-checksums. Porównuje ono pliki z sumami kontrolnymi, które WordPress.org publikuje dla zainstalowanej wersji. Z opcją --include-root WP-CLI ostrzega dodatkowo przed plikami w katalogu głównym, które nie należą do WordPress.
Co zrobić przy CMS bez wbudowanej funkcji sprawdzania?
Pobierają Państwo dokładnie tę samą wersję z oficjalnego źródła producenta i porównują oba katalogi za pomocą diff. W projektach Composera odtwarzają Państwo stan z pliku composer.lock w pustym katalogu i porównują katalog vendor.
Czy porównanie wykrywa też złośliwy kod we wtyczkach i motywach?
Tylko jeśli istnieje dla nich czysty oryginał, na przykład z oficjalnego katalogu lub od dostawcy. Własne modyfikacje, uploady i pliki konfiguracyjne nie mają oryginału i trzeba je sprawdzać osobno.
Czy porównanie zastępuje skaner malware?
Uzupełnia go. Porównanie wykrywa każdą zmianę w znanych plikach, także nieznany złośliwy kod. Nie mówi jednak nic o plikach bez oryginału, o bazie danych, zadaniach cron ani o dostępach.