Wirus wraca po wyczyszczeniu strony: samoodbudowujący się backdoor i jak usunąć wszystkie kopie naraz
- Typowe objawy
- Usunięty plik lub wtyczka pojawia się ponownie po minutach albo godzinach, wraca obce konto administratora
- Najczęstsza przyczyna
- Kilka kopii backdoora, które nawzajem się odtwarzają, albo niezałatana luka
- Czas naprawy
- Zwykle jeden dzień roboczy plus obserwacja przez kolejne dni
- Czy zrobisz to sam?
- Diagnozę częściowo tak. Usuwanie wymaga SSH, phpMyAdmin i czasem współpracy z hostingiem
Szybka odpowiedź
Jeśli wirus wraca kilka minut po usunięciu, prawie na pewno masz backdoor z wieloma kopiami: w plikach (.user.ini, drop-iny, wtyczki must-use, motyw), w bazie danych, w zadaniach cron, a czasem w pamięci współdzielonej serwera. Każda ocalała kopia odtwarza pozostałe. Najpierw odetnij ruch na poziomie serwera i zatrzymaj cron, potem rozbrój .user.ini, usuń wszystkie kopie w jednym przebiegu, wyczyść bazę, zrestartuj serwer lub poproś o to hosting, a dopiero na końcu zmień hasła i klucze.
Infekcja, która wraca, to jedna z najbardziej frustrujących sytuacji przy stronach. Usuwasz podejrzany plik, sprawdzasz po kwadransie i plik znowu jest. Usuwasz obce konto administratora, a następnego dnia jest z powrotem. Trzy klasyczne powody (zostawiona tylna furtka, niezałatana luka, zainfekowana sąsiednia strona na tym samym koncie) opisałem w poradniku wirus na stronie WordPress. Tutaj zajmuję się czwartym, najtrudniejszym: backdoorem zaprojektowanym tak, żeby odbudowywał się sam.
Backdoor, czyli tylna furtka, to ukryty kod, przez który włamywacz wraca na stronę, kiedy chce. Przykładem z jesieni 2026 jest infekcja nazwana SC, opisana przez badaczy Sucuri (analiza Gabriela Barbosy, omówiona przez The Hacker News 1 października 2026). Na niej pokażę mechanizm i sposób usuwania, który działa także na inne infekcje tego typu. Stan na początek listopada 2026.
Jak działa backdoor, który odbudowuje się sam
Według badaczy Sucuri infekcja SC żyje „w co najmniej ośmiu miejscach jednocześnie”: w plikach, w bazie danych i w pamięci współdzielonej serwera. Każda kopia potrafi odtworzyć pozostałe. Usuniesz wtyczkę, to drop-in zapisze ją od nowa. Usuniesz drop-in, to odtworzy go kod w motywie. Wyczyścisz wszystkie pliki, to przy następnym żądaniu wrócą z bazy albo z pamięci. Badacze piszą, że malware odtwarza się z dowolnej ocalałej kopii przy kolejnym żądaniu.
Co robią poszczególne elementy, w prostych słowach:
.user.inito plik ustawień PHP dla katalogu. Wpisauto_prepend_filekaże PHP uruchomić wskazany plik przed każdym skryptem, także zanim w ogóle wystartuje WordPress. Dokumentacja PHP podaje, że takie pliki czyta PHP działające jako FastCGI (typowe na hostingach) i że zmiany w nich wchodzą w życie z opóźnieniem do 5 minut.- Drop-iny (
db.php,advanced-cache.php) to pojedyncze pliki wwp-content, które WordPress ładuje bardzo wcześnie, przed zwykłymi wtyczkami. Legalnie tworzą je wtyczki cache i niektóre narzędzia diagnostyczne, dlatego sam ich widok nie jest dowodem infekcji. - Wtyczki must-use z
wp-content/mu-pluginsdziałają zawsze, bez aktywacji, i nie da się ich wyłączyć z panelu. - Pamięć współdzielona System V to obszar pamięci RAM serwera, z którego mogą korzystać różne procesy. Badacze Sucuri podają, że payload ląduje w segmencie o stałym numerze, przeżywa usunięcie plików i czyszczenie bazy, a na hostingu współdzielonym może należeć do innego konta systemowego.
- Cron to harmonogram zadań. WP-Cron to zadania WordPressa uruchamiane przy wizytach; cron systemowy uruchamia je o stałych porach z serwera, więc odbudowa działa nawet bez odwiedzających.
Według opisu infekcja zakłada też ukryte konto administratora, ukrywa się przed ekranem wtyczek i sprawdzaniem aktualizacji, a polecenia odbiera przez blockchain Ethereum, więc nie da się jej wyłączyć, blokując jeden serwer. Sposób wejścia nie został ustalony.
Czy to Twój przypadek
Sygnały, że masz do czynienia z mechanizmem odtwarzania, a nie z pojedynczym plikiem:
- usunięty plik lub wtyczka wraca po kilku minutach, czyli po kolejnym wejściu na stronę albo przebiegu crona,
- w katalogu strony jest
.user.iniz wpisemauto_prepend_file, którego nie dodawałeś, - w zakładce Wymuszane lub Zamiennik (Must-Use, Drop-in) na liście wtyczek widzisz pozycje, których nie potrafisz wyjaśnić,
- w
wp-contentsą pliki z kropką na początku nazwy (ukryte w wielu menedżerach plików) albo archiwa ZIP o losowych nazwach, - obce konto administratora wraca po usunięciu albo jest w bazie, a nie ma go w panelu.

Jak sprawdzić wszystkie kryjówki bez uruchamiania wirusa
Tu jest pułapka, o której mało kto mówi. Każde otwarcie strony w przeglądarce uruchamia PHP, a więc i backdoor. To samo dotyczy WP-CLI, czyli narzędzia do obsługi WordPressa z terminala: sprawdziłem na kopii testowej instalacji, że wp plugin list, wp user list i wp cron event list ładują wtyczki must-use nawet z parametrem --skip-plugins (pomoc WP-CLI mówi to wprost: mu-plugins are still loaded). Nie ładuje ich natomiast wp db query, które tylko wysyła zapytanie do bazy. Dlatego diagnozę robisz plikami i SQL, a polecenia WordPressa zostawiasz na kontrolę po czyszczeniu.
Pliki
Polecenia poniżej tylko czytają dane. Uruchamiasz je przez SSH w katalogu strony. Bez SSH to samo zobaczysz w kliencie FTP po włączeniu pokazywania ukrytych plików.
# pliki ustawień PHP i wpisy auto_prepend_file
find . -name ".user.ini" -o -name "php.ini"
grep -rn "auto_prepend_file" --include=".user.ini" \
--include="php.ini" --include=".htaccess" .
# wszystko w wp-content, łącznie z plikami ukrytymi (z kropką)
ls -la wp-content wp-content/mu-plugins
# archiwa ZIP w wp-content (kopie odtworzeniowe)
find wp-content -name "*.zip" -printf "%TY-%Tm-%Td %TH:%TM %p\n"
# motywy: czy jest katalog, którego nie instalowałeś
ls wp-content/themes
Na instalacji testowej dwa pierwsze polecenia nic nie zwracają, a ls -la wp-content/mu-plugins pokazuje to (fragment):
-rw-r--r-- 1 root root 140 Nov 2 11:23 hyper-engine-kit.php
-rw-r--r-- 1 root root 125 Oct 16 09:28 wp-cache-helper.php
Oba pliki podłożyliśmy celowo. Zwróć uwagę na daty: plik nowszy od reszty instalacji zawsze wymaga wyjaśnienia (choć daty da się podrobić, więc ich zgodność niczego nie gwarantuje).

Baza danych
Zapytania uruchomisz w phpMyAdmin albo przez wp db query "…". Prefiks wp_ zamień na swój. Pierwsze pokazuje wszystkich administratorów prosto z tabel, z pominięciem panelu, który backdoor może oszukiwać:
SELECT u.ID, u.user_login, u.user_email, u.user_registered
FROM wp_users u JOIN wp_usermeta m ON m.user_id = u.ID
WHERE m.meta_key LIKE '%capabilities'
AND m.meta_value LIKE '%administrator%';
-- największe wpisy w opcjach: tu chowa się zakodowana kopia
SELECT option_name, LENGTH(option_value) AS dlugosc
FROM wp_options ORDER BY dlugosc DESC LIMIT 10;
-- wyzwalacze w bazie (na zwykłym WordPressie zwykle brak)
SHOW TRIGGERS;
Prawdziwy wynik pierwszego zapytania na instalacji testowej. Dwa ostatnie konta są podłożone do przykładu:
ID user_login user_email user_registered
1 admin admin@sklep-przyklad.pl 2026-10-16 07:23:56
2 grzegorz grzegorz@sklep-przyklad.pl 2026-10-16 07:25:02
3 wpsupport_adm wpsupport.adm@protonmail.example 2026-10-16 07:25:02
4 developer_api1x7 dev.api.x7@mailbox.example 2026-11-02 10:23:02
Porównaj tę listę z ekranem Użytkownicy w panelu. Konto, które jest w bazie, a nie ma go w panelu, to niemal pewny znak backdoora ukrywającego administratora.

Na liście największych opcji szukaj nazw losowych lub niepasujących do żadnej wtyczki z długą wartością. Na instalacji testowej górę listy zajmują wpisy WordPressa typu _transient_dirsize_cache i rewrite_rules. Według relacji z analizy SC kopia siedzi w wierszu opcji o losowej nazwie, a opcje sterujące mają przedrostek sc_.
Pamięć współdzielona i cron systemowy
Na VPS lub serwerze dedykowanym polecenie ipcs -m wypisuje segmenty pamięci współdzielonej System V. Na serwerze bez takich segmentów wynik to sam nagłówek:
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
Segmenty tworzą też legalne programy, więc niczego nie usuwaj na ślepo. Zadania crona systemowego zobaczysz poleceniem crontab -l albo w panelu hostingu, w sekcji zadań cron. Typowy, legalny wpis uruchamia wp-cron.php co kilka minut; podejrzany wywołuje plik, którego nie znasz, albo pobiera coś z internetu.
Kolejność usuwania: wszystko naraz, w dobrej kolejności
Badacze Sucuri podkreślają, że skuteczne usunięcie wymaga zajęcia się wszystkimi mechanizmami jednocześnie, a nie po kolei, i najpierw zatrzymania wykonywania kodu. Poniższa kolejność wynika z ich zaleceń i z tego, jak działa PHP.
-
Zrób kopię i odetnij ruch na poziomie serwera
Najpierw kopia plików i bazy w obecnym stanie, opisana jako zainfekowana, oraz logi serwera. Potem zatrzymaj ruch, ale nie wtyczką trybu konserwacji: ona działa wewnątrz WordPressa, a backdoor startuje wcześniej. Użyj opcji wyłączenia strony w panelu hostingu, poproś o to hosting albo dodaj na początku głównego
.htaccess(Apache 2.4) regułę wpuszczającą tylko Twój adres IP (przykładowy numer niżej zamień na swój; sprawdzisz go, wpisując w Google „mój adres IP”). Odwiedzający dostaną wtedy błąd 403, więc trzymaj ją tylko na czas czyszczenia:Require ip 203.0.113.17Ta reguła działa na serwerach Apache 2.4. Jeśli po jej dodaniu strona pokaże błąd 500, usuń ją i poproś hosting o zablokowanie dostępu z innych adresów.
W panelu hostingu wstrzymaj zadania cron tej strony. Zmień hasła do panelu hostingu, FTP i SSH, żeby nikt nie wrócił w trakcie.
-
Rozbrój
.user.iniw dwóch ruchachBadacze Sucuri ostrzegają: jeśli najpierw usuniesz plik wskazany w
auto_prepend_file, a wpis zostanie, PHP może przez kolejne minuty próbować go wczytać i strona przestanie działać (ustawienia z.user.iniPHP pamięta domyślnie przez 300 sekund). Dlatego najpierw zastąp zawartość wskazanego pliku pustą treścią (sama linia<?php), potem usuń wpis z.user.ini. Odczekaj 5 minut albo poproś hosting o restart PHP. Sprawdź teżphp.inii.htaccess: tam również da się ustawić ten sam wpis. -
Usuń wszystkie kopie w plikach w jednym przebiegu
Ładowarki, drop-iny niepochodzące od Twojej wtyczki cache, obie kopie wtyczki (must-use i zwykłą), archiwa ZIP i obcy motyw. Z legalnego motywu, w którym dopisano kod, usuń tylko wstrzyknięty fragment albo wgraj motyw na nowo. Dla infekcji SC lista ścieżek z analizy wygląda tak; usuwaj tylko to, co u siebie znalazłeś i sprawdziłeś:
wp-content/c1b12371.php wp-content/.c1b12371.php wp-content/db.php wp-content/advanced-cache.php wp-content/mu-plugins/hyper-engine-kit.php wp-content/plugins/hyper-engine-kit/ wp-content/themes/khorshidi/Najpewniej działa podmiana całości: świeży rdzeń WordPressa, wtyczki i motywy pobrane od nowa. Opisuję to w poradniku usuwanie wirusa krok po kroku.
-
Wyczyść bazę w ustalonej kolejności
Usuń wiersze opcji z zakodowaną kopią i opcje sterujące. Usuń złośliwe zadania WP-Cron (po usunięciu plików możesz już użyć WP-CLI, niżej). Dopiero potem sprawdź wyzwalacze, czyli zapisane w bazie reguły uruchamiane automatycznie przy zmianie danych: badacze zalecają przejrzeć je przed usunięciem ukrytych administratorów, bo w podobnych infekcjach wyzwalacz odtwarzał konto. Na końcu usuń obce konta. Przed każdą zmianą w bazie zrób jej kopię.
-
Wyczyść pamięć współdzieloną
Segment System V istnieje, dopóki ktoś go jawnie nie usunie albo serwer się nie uruchomi ponownie. Sam restart PHP może więc nie wystarczyć. Na VPS najprościej zrestartować cały serwer; kto wie, który segment należy do infekcji, może go usunąć poleceniem
ipcrm -mz numerem z kolumnyshmid(alboipcrm -Mz wartością z kolumnykey). Na hostingu współdzielonym zostaje prośba do hostingu, wzór niżej. -
Zmień hasła i klucze, potem kontroluj
Hasła administratorów, hasło użytkownika bazy danych (backdoor korzysta z danych z
wp-config.php), nowe klucze bezpieczeństwa (wp config shuffle-salts), które unieważnią także podrobione ciasteczka logowania. Zamknij lukę, przez którą weszli atakujący. Potem sprawdź pliki i bazę po 5 minutach, po godzinie i następnego dnia. Każdy plik, który wróci, oznacza niedokończone czyszczenie: szukaj kopii, którą przeoczyłeś, zamiast powtarzać to samo usuwanie.
WP-Cron i cron systemowy po czyszczeniu
Gdy pliki są już czyste, sprawdź zadania WordPressa. Polecenie wypisuje nazwę zadania (hook), czas do następnego uruchomienia i częstotliwość. Prawdziwy wynik na instalacji testowej (fragment):
$ wp cron event list --fields=hook,next_run_relative,recurrence
hook next_run_relative recurrence
recovery_mode_clean_expired_keys now 1 day
wp_privacy_delete_old_export_files now 1 hour
action_scheduler_run_queue now 1 minute
wc_admin_process_orders_milestone now 1 hour
wp_version_check now 12 hours
Legalne zadania mają czytelne nazwy, zwykle z przedrostkiem WordPressa (wp_) albo wtyczki (wc_, action_scheduler_). Według badaczy infekcja SC rejestruje zadania o losowych nazwach. Takie usuniesz poleceniem wp cron event delete nazwa_zadania. Bez terminala listę zadań pokaże wtyczka do zarządzania cronem; po sprzątaniu ją odinstaluj.
Na koniec przywróć cron systemowy, ale tylko wpisy, które znasz. Jeśli wcześniej sam ustawiłeś wywoływanie wp-cron.php z serwera i masz w wp-config.php stałą DISABLE_WP_CRON, zostaw tę konfigurację; usuń wszystko inne, czego nie potrafisz wyjaśnić.
Jeśli masz hosting współdzielony
Na hostingu współdzielonym nie zrestartujesz serwera ani nie zobaczysz cudzych segmentów pamięci. Napisz do hostingu, na przykład tak:
Dzień dobry, na koncie [login] w katalogu [ścieżka] usuwam infekcję typu samoodbudowujący się backdoor, który według opisu badaczy przechowuje kopię w pamięci współdzielonej System V. Proszę o: restart PHP dla mojego konta, sprawdzenie i usunięcie segmentów pamięci współdzielonej powiązanych z moim kontem, listę zadań cron na koncie oraz logi dostępu z ostatnich 30 dni. Czy na innych stronach na tym serwerze wykryli Państwo podobne pliki (hyper-engine-kit, c1b12371.php)?
Jeśli hosting zablokował już konto z powodu infekcji, zacznij od poradnika hosting zablokował stronę przez wirusa.
Właściciel sklepu trzeci raz usuwa z panelu podejrzaną wtyczkę o nazwie kojarzącej się z przyspieszaniem strony. Za każdym razem wraca po kilkunastu minutach, a w dodatku znika z listy wtyczek, choć skaner hostingu dalej ją zgłasza. Dopiero przegląd katalogów przez SSH pokazuje .user.ini z wpisem auto_prepend_file, ukryty plik z kropką w wp-content, nieużywany motyw i drop-in, mimo że sklep nie ma wtyczki cache. Po zablokowaniu ruchu, rozbrojeniu .user.ini, usunięciu wszystkich plików naraz, wyczyszczeniu dużego wpisu w opcjach i restarcie serwera infekcja nie wraca, a kontrola po dobie nie pokazuje nowych plików.
Kiedy nie robić tego samemu
Ten rodzaj infekcji karze za każdy pominięty krok. Lepiej oddać go specjaliście, gdy:
- wirus wrócił już po jednym Twoim czyszczeniu,
- nie masz dostępu SSH albo nie czujesz się pewnie w phpMyAdmin,
- strona to sklep z danymi klientów, a na kasie może działać skimmer (zobacz skimmer na stronie kasy WooCommerce),
- na jednym koncie hostingowym jest kilka stron,
- nie wiesz, którędy weszli atakujący, więc nie wiesz, co załatać.
Ceny i zakres opisuję w artykule ile kosztuje usunięcie wirusa ze strony.
Wirus wraca mimo czyszczenia?
Usuwam samoodbudowujące się infekcje w całości: pliki, bazę, cron i pamięć serwera, w jednym przebiegu i we współpracy z Twoim hostingiem. Odwirusowanie: 499 zł netto, reakcja 24/7, 30 dni gwarancji czystości.
Najczęstsze pytania
Dlaczego wirus wraca kilka minut po usunięciu pliku?
Bo usunąłeś tylko jedną kopię. Samoodbudowujący się backdoor trzyma się w kilku miejscach naraz: w plikach, w bazie danych, czasem w pamięci serwera. Przy następnym wejściu na stronę lub uruchomieniu zadania cron dowolna ocalała kopia odtwarza pozostałe. Usuwać trzeba wszystkie jednocześnie, po odcięciu ruchu.
Czy przywrócenie kopii zapasowej rozwiąże problem?
Tylko jeśli kopia pochodzi sprzed infekcji, a tego zwykle nie wiesz. Kopia plików nie czyści też pamięci współdzielonej serwera ani zadań systemowego crona. Po przywróceniu i tak trzeba sprawdzić wszystkie kryjówki, zmienić hasła i zamknąć lukę, przez którą weszli atakujący.
Czy plik advanced-cache.php albo db.php to zawsze wirus?
Nie. To tak zwane drop-iny, które legalnie tworzą wtyczki cache i niektóre narzędzia diagnostyczne. Podejrzane są wtedy, gdy nie używasz takiej wtyczki, gdy zawierają długi zakodowany ciąg albo gdy wracają po usunięciu. W razie wątpliwości porównaj plik z tym, który tworzy Twoja wtyczka.
Czy tryb konserwacji z wtyczki wystarczy na czas czyszczenia?
Nie. Wtyczka trybu konserwacji działa wewnątrz WordPressa, a backdoor uruchamia się wcześniej, przez .user.ini, drop-iny i wtyczki must-use. Ruch trzeba zatrzymać na poziomie serwera: w panelu hostingu, regułą w .htaccess albo prośbą do hostingu.
Co zrobić, jeśli mam hosting współdzielony i nie mogę zrestartować serwera?
Poproś hosting o restart PHP dla Twojego konta i o sprawdzenie, czy w pamięci współdzielonej serwera nie zostały segmenty związane z Twoim kontem. Opisz, że chodzi o backdoor przechowujący kopię w pamięci współdzielonej System V. Bez tego czyszczenie plików i bazy może nie wystarczyć.