Złośliwy kod w sklepie internetowym klienta pokazywał kupującym fałszywą weryfikację „Nie jestem robotem” i próbował zainstalować na ich komputerach program kradnący hasła. Ślady włamania znalazłem też w pozostałych sklepach na tym samym koncie hostingowym. W pięć dni usunąłem infekcję ze wszystkich sześciu sklepów, jeden odbudowałem od zera i zamknąłem drogi, którymi wchodził atakujący.
Sklepy działają, przyjmują zamówienia i płatności, a całość sprawdziłem testowymi zamówieniami. Dla zachowania poufności nie podaję nazw sklepów ani branży klienta.
- 6 sklepów WooCommerce (Polska i kilka rynków zagranicznych) na jednym koncie hostingowym
- 1 podmieniony plik rdzenia WordPressa: jQuery urósł z ok. 87 KB do 1,26 MB, ponad 14 razy
- 17 fałszywych kont administratorów w jednym sklepie, zakładanych od około dwóch miesięcy
- 18 529 zdjęć i plików PDF przeniesionych do odbudowanego sklepu po weryfikacji
- Ponad 24 godziny pracy w pięć dni, od dnia zgłoszenia, także w weekend
- Testy zamówień i wszystkich form płatności w każdym sklepie na koniec prac
Co się stało: fałszywa CAPTCHA w sklepie
Atakujący dokleił ok. 1,17 MB zaciemnionego kodu na końcu pliku jQuery, czyli biblioteki, którą WordPress ładuje na każdej stronie sklepu. Plik należy do rdzenia WordPressa, więc mało kto do niego zagląda, a wiele skanerów sprawdza głównie wtyczki i motywy.
To znany schemat ataku nazywany ClearFake. Działał tak:
- Klient wchodzi na stronę sklepu, a przeglądarka uruchamia zainfekowany plik jQuery.
- Skrypt odczytuje ze smart kontraktu w blockchainie Ethereum adres serwera atakującego (technika EtherHiding). Takiego adresu nie da się zablokować ani wyłączyć, a atakujący może go zmienić w każdej chwili.
- Na stronie pojawia się fałszywa weryfikacja „Nie jestem robotem”. Każe nacisnąć Win+R (na Macu otworzyć Terminal), wkleić polecenie ze schowka i nacisnąć Enter. Ta sztuczka nazywa się ClickFix.
- Polecenie instaluje program wykradający hasła zapisane w przeglądarce i aktywne sesje logowania.
- Jeśli ofiarą jest osoba z dostępem do panelu sklepu, atakujący loguje się jej prawdziwym hasłem i infekuje dalej.
[embed: node/6b8b7f25-c137]
Koło da się przerwać w dwóch miejscach: nie wklejając poleceń z „weryfikacji” i wymagając logowania dwuetapowego, przy którym samo skradzione hasło nie wystarczy.
W tym przypadku zadziałał także ostatni krok: jedna z osób z dostępem administratora wykonała polecenie z fałszywej weryfikacji, a jej hasło posłużyło później do zalogowania się do sklepu. Klientom sklepu groziło to samo: każdy, kto posłuchał instrukcji, mógł stracić hasła do banku, poczty czy mediów społecznościowych. Do tego dochodzi ryzyko, że Google oznaczy stronę jako niebezpieczną i odetnie ruch z wyszukiwarki.
Diagnoza: jak szukałem infekcji
Zasada pierwsza: nie uruchamiać zainfekowanego kodu. Wszystkie sprawdzenia robiłem przez SSH i WP-CLI z wyłączonymi wtyczkami i motywem, żeby złośliwy kod nie zadziałał w trakcie analizy.
- Sumy kontrolne. Porównałem każdy plik rdzenia WordPressa i wtyczek z oficjalnymi wersjami z wordpress.org. To wykrywa każdy zmieniony bajt i pliki, których w ogóle nie powinno być.
- Przeszukanie plików i baz danych. Szukałem typowych śladów: zaciemnionego kodu, wywołań eval i base64, obcych skryptów w treściach, opcjach, snippetach i własnym kodzie page buildera.
- Konta użytkowników. Sprawdziłem wszystkie konta z uprawnieniami administratora, także ukryte. W jednym sklepie było 17 fałszywych administratorów.
- Logi serwera i historia skanera hostingu. Pokazały logowanie do panelu z zagranicznego adresu VPN prawdziwym hasłem oraz to, co skaner wcześniej wykrywał i usuwał.
- Ukryte furtki. Klucze SSH, zadania cron, pliki .htaccess (ukryte przekierowania), konfiguracja PHP (doklejanie kodu do każdej strony) i przekierowania poczty.
Zanim cokolwiek usunąłem, zabezpieczyłem kopie zainfekowanych plików jako dowody. Pozwalają odtworzyć przebieg ataku.
Ustaliłem dwie drogi wejścia. Pierwsza to automatyczne wykorzystanie luki w jednym ze sklepów około dwóch miesięcy wcześniej, po którym zostały fałszywe konta administratorów. Druga to logowanie hasłem wykradzionym przez fałszywą CAPTCHA.
Skalę zwiększało to, że wszystkie sklepy działały na jednym koncie hostingowym, pod jednym użytkownikiem systemowym. Dostęp do plików jednego sklepu oznaczał więc dostęp do plików wszystkich.
Pierwszy priorytet: ochrona klientów sklepu
Zanim zacząłem sprzątać, odciąłem kupujących od złośliwego skryptu. Podmieniłem zainfekowany plik jQuery na oryginalny z wordpress.org, a zainfekowaną kopię zachowałem jako dowód.
Sama podmiana pliku nie wystarczała. Przeglądarki trzymają jQuery w pamięci podręcznej nawet przez rok, więc stali klienci dalej uruchamialiby zainfekowaną kopię. Zmieniłem numer wersji skryptu, co zmusza każdą przeglądarkę do pobrania czystego pliku.
Na koniec sprawdziłem sklep w przeglądarce: ładuje się czysty plik, a strona nie łączy się już z blockchainem ani z obcymi serwerami.
Sklep z najpoważniejszą infekcją wyłączyłem do czasu odbudowy. Dzięki temu nie zagrażał ani klientom, ani pozostałym sklepom.
Sprzątanie i odbudowa sklepów
Pięć sklepów: czyszczenie i wymiana kodu
Nie poprzestałem na usunięciu znalezionych plików. Cały kod sklepów wymieniłem na pochodzący z oficjalnych źródeł, bo tylko wtedy wiadomo, że nic nie zostało.
- Rdzeń WordPressa zweryfikowany sumami kontrolnymi i przywrócony z oryginalnych plików.
- Wszystkie darmowe wtyczki zainstalowane ponownie z wordpress.org, a nie tylko zaktualizowane.
- Płatne wtyczki i motyw (page builder, motyw sklepu, rozszerzenia WooCommerce) pobrane na nowo od producentów, z ważnymi licencjami. Bez wersji „nulled” i bez kopiowania z innych serwerów.
- Usunięte: fałszywe wtyczki podszywające się pod prawdziwe, menedżer plików w panelu WordPressa, stare kopie wtyczek, pozostałości nieużywanych motywów i puste pliki zostawione przez atakującego.
- Jeden sklep miał przestarzałą wersję WordPressa. Zaktualizowałem rdzeń, WooCommerce i 11 wtyczek.
Na prośbę właściciela usunąłem też archiwalne zamówienia i konta klientów, przechowywane już w zewnętrznym systemie do obsługi zamówień. Przed tą operacją zrobiłem kopię baz danych. Mniej danych osobowych w sklepie to mniej do wykradzenia.
Jeden sklep od zera
W jednym sklepie infekcja trwała około dwóch miesięcy: 17 fałszywych kont administratorów i fałszywe wtyczki. Żadna dostępna kopia zapasowa nie sięgała sprzed włamania, więc przywrócenie kopii oznaczałoby przywrócenie włamania.
Dlatego zbudowałem sklep od nowa:
- Zabezpieczyłem kopię zainfekowanej instalacji jako dowód.
- Postawiłem nową instalację WordPressa, wszystkich wtyczek i motywu z oryginalnych źródeł.
- Napisałem od nowa czysty motyw potomny.
- Ze starej instalacji przeniosłem wyłącznie zdjęcia i pliki PDF (18 529 plików), po sprawdzeniu, że to naprawdę multimedia.
- Zablokowałem uruchamianie plików PHP w katalogu ze zdjęciami.
- Bazę danych (produkty, ustawienia, treści) oczyściłem z fałszywych kont i wtyczek.
- Po testach uruchomiłem sklep na nowej instalacji.
Zabezpieczenie konta, haseł i panelu
Usunięcie wirusa nic nie da, jeśli atakujący może wrócić tą samą drogą. Dlatego zamknąłem wszystkie drogi powrotu, także te, z których mógłby skorzystać dzięki skradzionym danym.
| Zabezpieczenie | Co daje |
|---|---|
| Nowe hasła wszystkich administratorów | Skradzione hasła przestają działać |
| Nowe klucze bezpieczeństwa WordPressa (SALT) | Wylogowanie wszystkich sesji, także atakującego |
| Nowe, osobne hasła do bazy danych każdego sklepu | Dane z wykradzionych plików konfiguracyjnych są bezużyteczne |
| Blokada edycji plików i instalacji wtyczek z panelu | Nawet ze skradzionym hasłem nie da się wgrać wtyczki ani zmienić kodu |
| Logowanie dwuetapowe dla administratorów | Samo hasło nie wystarcza do wejścia |
| Zapora i powiadomienia o logowaniach (Wordfence) | Blokada znanych ataków i szybka informacja o każdym logowaniu |
| Kontrola kluczy SSH, zadań cron, .htaccess, konfiguracji PHP i poczty | Pewność, że atakujący nie zostawił furtki |
| Zamknięcie publicznego dostępu do katalogu z dokumentami finansowymi | Dokumentów nie da się pobrać z internetu |
| Nowe hasło i logowanie dwuetapowe do panelu hostingu | Ochrona dostępu do całego konta |
Nowe hasła mają sens tylko wtedy, gdy wpisuje się je na czystym urządzeniu. Dlatego właściciel dostał też zalecenia: wyczyszczenie lub reinstalację zainfekowanego komputera, zmianę haseł z czystego urządzenia i włączenie logowania dwuetapowego na każdym koncie administratora.
Testy: sklepy działają i przyjmują płatności
Po tak dużych zmianach najważniejsze jest, żeby sklep dalej sprzedawał. Dlatego na koniec przetestowałem każdy sklep tak, jak robi to klient.
- Zamówienia testowe w każdym sklepie, od koszyka po potwierdzenie.
- Wszystkie formy płatności dostępne w danym sklepie.
- Logowanie do panelu z logowaniem dwuetapowym.
- Kontrola końcowa: porównanie plików z oryginalnymi i sprawdzenie, czy strony nie ładują obcych skryptów.
Efekt: wszystkie sześć sklepów jest czystych, działa i przyjmuje zamówienia oraz płatności. Pliki zgadzają się z oryginalnymi, a do panelu nie da się wejść samym hasłem.
Wnioski: dlaczego kopia zapasowa nie wystarcza
Przywrócenie kopii usuwa skutki, nie przyczynę. Jeśli luka zostaje otwarta, a hasła się nie zmieniają, atakujący wraca tą samą drogą. Po każdym włamaniu trzeba wymienić wszystkie hasła, klucze i sesje.
Kopia może być już zainfekowana. Tutaj włamanie trwało około dwóch miesięcy, dłużej niż sięgały dostępne kopie. W takiej sytuacji bezpieczniej jest zbudować sklep od nowa i przenieść tylko sprawdzone treści.
Najlepszy serwer nie pomoże, gdy atakujący ma prawdziwe hasło. Logowanie skradzionym hasłem wygląda w logach jak zwykłe logowanie właściciela. Przed tym chroni dopiero logowanie dwuetapowe.
Jedno konto hostingowe dla wielu stron to wspólne ryzyko. Jeśli strony działają pod jednym użytkownikiem systemowym, infekcja jednej daje dostęp do plików wszystkich. Niezależne sklepy warto trzymać na osobnych kontach.
Żadna prawdziwa weryfikacja nie każe niczego wklejać. CAPTCHA, która prosi o naciśnięcie Win+R albo otwarcie Terminala, to zawsze atak. Warto powiedzieć o tym każdemu, kto ma dostęp do panelu sklepu.
Checklista dla właścicieli sklepów
Sprawdź, ile z tych punktów ma Twój sklep. Każdy brakujący to otwarta droga dla atakującego.
- Logowanie dwuetapowe na każdym koncie administratora
- Unikalne hasła trzymane w menedżerze haseł, a nie tylko w przeglądarce
- Zasada dla całego zespołu: nigdy nie wklejamy poleceń z „weryfikacji” do Win+R, PowerShella ani Terminala
- Wtyczki i motywy wyłącznie z oficjalnych źródeł, bez wersji „nulled”
- Usunięte nieużywane wtyczki, motywy i stare kopie folderów
- Wyłączona edycja plików i instalacja wtyczek z panelu WordPressa
- Regularne aktualizacje WordPressa, WooCommerce i wtyczek
- Kopie zapasowe przechowywane poza serwerem, z historią sięgającą kilku miesięcy
- Okresowe porównanie plików z oryginalnymi (sumy kontrolne)
- Lista administratorów przeglądana co najmniej raz w miesiącu
- Niezależne strony na osobnych kontach hostingowych
- W sklepie tylko te dane klientów, które są naprawdę potrzebne
Opieka nad WordPressem: jak mogę pomóc
Zajmuję się opieką nad stronami i sklepami na WordPressie i WooCommerce. Ten przypadek pokazuje, jak wygląda moja praca przy włamaniu: najpierw chronię klientów sklepu, potem usuwam infekcję u źródła, zamykam drogi powrotu i sprawdzam, czy sklep dalej sprzedaje.
W ramach stałej opieki zajmuję się między innymi:
- aktualizacjami WordPressa, WooCommerce, wtyczek i motywów, z testem sklepu po zmianach,
- kopiami zapasowymi przechowywanymi poza serwerem,
- monitorowaniem plików, logowań i nowych kont administratorów,
- konfiguracją logowania dwuetapowego i zapory,
- reakcją na incydenty: diagnozą, usunięciem infekcji i zabezpieczeniem strony.
Podejrzewasz, że Twoja strona została zainfekowana, albo widzisz na niej dziwne okienka weryfikacji? Napisz do mnie przez formularz kontaktowy na wpit.pl. W sytuacjach awaryjnych reaguję priorytetowo.


Dodaj komentarz