Odzyskiwanie sklepu internetowego po ataku hakerskim

Odzyskiwanie sklepu internetowego po ataku hakerskim

Kilka dni temu trafił do mnie sklep internetowy oparty o OpenCart. Właściciel podejrzewał infekcję, bo na serwerze zaczęły pojawiać się dziwne pliki, a sam sklep zachowywał się momentami dość podejrzanie.

Nie będę ukrywał – kiedy słyszę hasło „zainfekowany sklep internetowy”, to od razu przypomina mi się dżuma. Niby człowiek wie, że da się to opanować, ale i tak podchodzi do tematu z lekkim niepokojem. Szczególnie gdy trzeba zajrzeć do plików, które przez nie wiadomo jak długi czas były pod kontrolą kogoś innego.

W tym przypadku sklep działał na OpenCart 3.0.2.0. Ponieważ i tak planowałem postawić całość na czystej instalacji, od razu zdecydowałem się przejść na OpenCart 3.0.5.0. To ostatnia wersja z linii 3.x i moim zdaniem najbardziej dopracowana.

W internecie można znaleźć wiele poradników pokazujących jak usuwać pojedyncze wirusy, poprawiać zainfekowane pliki albo ręcznie czyścić fragmenty kodu. Problem polega na tym, że po udanym włamaniu bardzo często nie wiadomo już, którym plikom można jeszcze ufać.

Zdarzało mi się znajdować złośliwy kod w kontrolerach, bibliotekach, modyfikacjach OpenCart, a nawet w katalogach przeznaczonych wyłącznie na zdjęcia produktów. Czasem antywirus znajduje problem od razu. Czasem nie znajduje nic, a problem siedzi kilka katalogów dalej i spokojnie czeka na swoją kolej.

Dlatego od dłuższego czasu stosuję metodę, którą można nazwać „spalić wszystko”.

Brzmi groźnie, ale chodzi o coś znacznie prostszego. Nie próbuję ratować starej instalacji za wszelką cenę. Wolę pobrać czystego OpenCart, odbudować sklep od podstaw i przenieść tylko te elementy, które przejdą kontrolę bezpieczeństwa. Dzięki temu nie muszę zastanawiać się, czy gdzieś w zakamarkach serwera nie został jeszcze prezent od hakera. 

W tym artykule pokażę krok po kroku, jak wyglądała odbudowa tego sklepu. Będzie trochę terminala, trochę SQL-a, trochę skanowania plików i jeden bardzo ciekawy plik PHP znaleziony tam, gdzie teoretycznie powinny znajdować się wyłącznie zdjęcia produktów.

No to zakładamy rękawiczki ochronne i wchodzimy do sklepu z dżumą.

Warto zobaczyć:

 

1. Pierwsza zasada sklepu z dżumą – wyrzucić jak najwięcej plików

Przy ratowaniu zainfekowanego sklepu internetowego nie chodzi o to, żeby analizować każdy plik po kolei. Gdyby tak robić, można by nad jednym sklepem spędzić kilka dni, a czasem nawet tygodni.

Znacznie lepszym rozwiązaniem jest zmniejszenie liczby plików, które w ogóle musimy sprawdzić.

W przypadku OpenCart jest to szczególnie proste.

Czysta instalacja OpenCart 3.0.5.0 zawiera około 4736 plików. Do tego dochodzą jeszcze rozszerzenia, modyfikacje, szablony oraz dodatkowe biblioteki. W większych sklepach bez problemu można dojść do kilku, a nawet kilkunastu tysięcy plików.

I teraz najważniejsze pytanie.

Po co analizować tysiące plików rdzenia OpenCart, skoro mogę pobrać ich czystą kopię bezpośrednio ze strony projektu?

To samo dotyczy większości rozszerzeń. Jeżeli posiadam paczkę instalacyjną modułu, znacznie bezpieczniej jest pobrać ją ponownie lub wykorzystać archiwum producenta niż ufać plikom znajdującym się na zainfekowanym serwerze.

W praktyce oznacza to, że już na samym początku mogę wyrzucić z analizy ogromną część sklepu.

Zostają tylko te elementy, których nie da się pobrać ponownie jednym kliknięciem.

Przede wszystkim baza danych, ponieważ zawiera produkty, zamówienia, klientów oraz ustawienia sklepu.

Drugim elementem są obrazy produktów. Ich odtworzenie byłoby zwykle bardzo czasochłonne, dlatego warto je zachować i dokładnie sprawdzić.

Trzecią rzeczą jest szablon graficzny, który najczęściej zawiera indywidualne modyfikacje przygotowane specjalnie dla danego sklepu.

Sporadycznie dochodzą jeszcze własne moduły tworzone na zamówienie lub pojedyncze pliki integracji, których nie można pobrać ponownie od producenta.

Cała reszta przestaje mnie interesować.

Nie dlatego, że na pewno jest bezpieczna. Wręcz przeciwnie.

Po prostu znacznie szybciej, taniej i bezpieczniej jest zastąpić kilka tysięcy potencjalnie podejrzanych plików ich czystymi odpowiednikami niż próbować analizować każdy z nich osobno.

Dzięki temu zmniejszam zarówno czas potrzebny na naprawę sklepu, jak i ryzyko, że gdzieś pomiędzy tysiącami plików przeoczę jedną małą furtkę pozostawioną przez hakera.

 

2. Czyszczenie bazy danych

Pierwszą rzeczą, którą pobrałem ze starego sklepu, była baza danych. Nie analizuję takich rzeczy bezpośrednio na serwerze klienta. Wolę pracować na własnym środowisku, gdzie mogę spokojnie sprawdzać wszystko bez ryzyka, że przypadkiem coś uruchomię albo dodatkowo uszkodzę.

Importuję więc bazę danych do phpMyAdmin i zaczynam od prostych porządków.

Pierwszą ofiarą zostaje tabela oc_session.

W tym przypadku znajdowało się w niej ponad milion rekordów. Nie jest to nic niezwykłego w starszych sklepach. Problem polega na tym, że sklep od dłuższego czasu był wyłączony, więc wszystkie zapisane tam sesje dawno wygasły i nie przedstawiały żadnej wartości.

Usuwam więc całą zawartość tabeli.

To nie tylko przyspiesza dalszą pracę z bazą danych, ale również zmniejsza jej rozmiar.

Znacznie ważniejsza jest jednak druga tabela.

oc_modification.

To właśnie tutaj OpenCart przechowuje instrukcje służące do modyfikowania plików systemowych. Każde rozszerzenie może dodawać własne reguły, które podczas odświeżania modyfikacji są automatycznie wstrzykiwane do wygenerowanych plików systemowych.

Brzmi niewinnie, dopóki nie przypomnimy sobie, że analizujemy sklep po włamaniu.

Jeżeli napastnik dodał do tej tabeli własne instrukcje, to nawet po skopiowaniu czystych plików OpenCart złośliwy kod może wrócić przy pierwszym odświeżeniu modyfikacji.

Mówiąc inaczej – można przez kilka godzin czyścić sklep, wgrać świeże pliki, kliknąć „Odśwież modyfikacje”, a następnie samodzielnie ponownie zainfekować własny sklep.

Z tego powodu zawartość tabeli oc_modification usuwam w całości.

Nie ma sensu ryzykować.

Później i tak będę odtwarzał moduły z czystych paczek instalacyjnych.

Kolejnym krokiem jest szybkie sprawdzenie ustawień zapisanych w tabeli oc_setting.

Szukam przede wszystkim sytuacji, w których ktoś próbował ukryć fragment kodu JavaScript lub HTML bezpośrednio w ustawieniach sklepu.

Wykonuję proste zapytanie:

SELECT setting_id, `key`
FROM oc_setting
WHERE value LIKE '%<script%'
OR value LIKE '%iframe%'
OR value LIKE '%base64%';

Interesują mnie głównie znaczniki <script>, osadzone ramki <iframe> oraz ciągi zawierające słowo base64, które bardzo często pojawia się przy próbach ukrywania złośliwego kodu.

Oczywiście samo znalezienie takiego wpisu nie oznacza jeszcze infekcji. Niektóre moduły marketingowe, analityczne czy integracje zewnętrzne zapisują podobne dane całkowicie legalnie. Taki wynik jest jednak sygnałem, że warto przyjrzeć się danej konfiguracji bliżej.

Po wykonaniu tych kilku czynności baza danych była gotowa do dalszej pracy.

Dopiero teraz mogłem przejść do kolejnego etapu, czyli uruchomienia czystej instalacji OpenCart i sprawdzenia, które elementy starego sklepu rzeczywiście warto odzyskać.

 

3. Świeża instalacja OpenCart 3.0.5.0

Po wyczyszczeniu bazy danych mogłem przejść do postawienia nowego sklepu.

Pobieram czystą instalację OpenCart 3.0.5.0. Sklep działał wcześniej na wersji 3.0.2.0, więc przy okazji odbudowy postanowiłem od razu go zaktualizować.

Kopiuję pliki na localhost,  a następnie konfiguruję pliki config.php i admin/config.php, podając nowe dane dostępowe do bazy oraz ścieżki systemowe.

Kolejny krok to aktywacja pliku .htaccess. Zmieniam nazwę z htaccess.txt na .htaccess i uzupełniam katalog bazowy, ponieważ sklep działa lokalnie w dodatkowym podkatalogu.

Na końcu importuję wcześniej przygotowaną bazę danych.

Po chwili sklep zaczyna działać.

No dobrze... prawie działać.

Produkty są. Kategorie są. Zamówienia są. Panel administracyjny działa.

Problem w tym, że sklep wygląda jak świeżo zainstalowany OpenCart sprzed pięciu minut.

To całkowicie normalne. Nie odzyskałem jeszcze oryginalnego szablonu, więc OpenCart korzysta z domywnego motywu.

Najważniejsze jest jednak to, że działa już czysty rdzeń sklepu. Mogę więc przejść do kolejnego etapu i odzyskać szablon ze sklepu z dżumą.

Po podłączeniu bazy danych pojawiła się jeszcze jedna niespodzianka związana z aktualizacją z OpenCart 3.0.2.0 do 3.0.5.0.

Okazało się, że hasła użytkowników przestały działać poprawnie. Jest to związane ze zmianami w sposobie przechowywania i weryfikacji haseł w nowszych wersjach OpenCart.

Na szczęście nie jest to nic groźnego. W przypadku administratorów po prostu wygenerowałem nowe hasła i zapisałem je ponownie. Przy okazji i tak planowałem usunąć stare konta administracyjne oraz utworzyć nowe.

To kolejny powód, dla którego lubię wykonywać takie operacje na localhost. Lepiej odkryć podobne problemy na etapie odbudowy sklepu niż po uruchomieniu go na produkcji i odebraniu telefonu od klienta z informacją, że nie może zalogować się do panelu.

 

4. Dlaczego sklep wygląda inaczej po uruchomieniu?

Po uruchomieniu sklepu na czystej instalacji OpenCart właściciel mógłby doznać lekkiego zawału.

Sklep działa. Produkty są. Kategorie są. Zamówienia są.

Ale wygląd przypomina świeżo zainstalowanego OpenCart sprzed kilku minut.

Na szczęście jest to całkowicie normalne.

Mechanizm szablonów w OpenCart działa nieco inaczej niż w wielu innych systemach. Własny motyw nie musi zawierać wszystkich plików znajdujących się w szablonie domyślnym.

Najczęściej zawiera tylko te pliki, które zostały zmodyfikowane przez twórcę sklepu lub szablonu.

Jeżeli OpenCart nie znajdzie jakiegoś pliku w aktywnym motywie, automatycznie pobierze go z szablonu default.

Dzięki temu własne motywy są znacznie mniejsze i łatwiejsze w utrzymaniu. Zamiast kopiować setki plików wystarczy podmienić tylko te, które faktycznie zostały zmienione.

W moim przypadku oryginalny szablon nadal znajdował się w sklepie z dżumą i jeszcze nie został odzyskany. OpenCart nie miał więc innego wyjścia i załadował domyślny motyw.

To dobra wiadomość.

Oznaczało to, że rdzeń sklepu działa poprawnie, a problem dotyczy wyłącznie warstwy graficznej. Teraz mogłem przejść do odzyskiwania szablonu i sprawdzić, czy również nie kryje w sobie jakichś niespodzianek.

 

5. Odzyskiwanie szablonu ze starego sklepu

Przyszedł moment, którego obawiałem się od początku.

Musiałem wrócić do sklepu z dżumą i coś z niego zabrać.

Na szczęście nie cały sklep. Interesował mnie wyłącznie katalog z szablonem.

Już sama myśl o kopiowaniu czegokolwiek ze zhakowanego serwera powoduje, że kursor zaczyna lekko drżeć. Dlatego zanim jakikolwiek plik trafił do nowej instalacji, przeszedł małe śledztwo.

Na początek klasyczny skan ClamAV:

clamscan -r -i /var/www/html/em3/catalog/view/theme

Wynik:

Screen: skanowanie szablonu sklepu
Screen: skanowanie szablonu sklepu
----------- SCAN SUMMARY -----------
Known viruses: 3627875
Engine version: 1.4.4
Scanned directories: 68
Scanned files: 693
Infected files: 0

Czysto.

Problem w tym, że w sklepach z dżumą wirusy bardzo często nie wyglądają jak wirusy. Zwykle są to zwykłe pliki z zakodowanym lub sprytnie ukrytym kodem.

Dlatego sprawdzam dalej.

Najpierw szukam plików PHP. W szablonie sklepu praktycznie nie powinno ich być.

grep -rIl '<?php\|<?=' /var/www/html/em3/catalog/view/theme

Nic podejrzanego.

Następnie szukam popularnych technik obfuskacji JavaScript:

grep -rIlE 'eval\s*\(|String\.fromCharCode|atob\s*\(|fromCharCode' \
/var/www/html/em3/catalog/view/theme \
--include='*.js' --include='*.twig'

Również bez niespodzianek.

Kolejny krok to poszukiwanie plików o nazwach, które często pojawiają się przy włamaniach:

find /ścieżka/do/motyw -regextype posix-extended \
-regex '.*/(index|shell|upload|uploader|admin|config|wp-|backdoor).*'

Brak podejrzanych znalezisk.

Sprawdzam jeszcze, czy ktoś nie próbował ukryć kodu PHP w plikach graficznych:

find /ścieżka/do/motyw/image -type f \
\( -name '*.jpg' -o -name '*.png' -o -name '*.gif' \) \
-exec grep -lE '<?php|eval\(|base64_decode|gzinflate' {} \;

Również czysto.

Na tym etapie większość osób prawdopodobnie uznałaby temat za zamknięty. Ja lubię mieć jeszcze jedną opinię.

Odpalam więc Cursora i proszę AI o dodatkową analizę plików motywu. Nie dlatego, że sztuczna inteligencja znajdzie wszystko, ale dlatego, że czasem potrafi zwrócić uwagę na coś, co człowiek przeoczy po kilku godzinach patrzenia w kod.

Tym razem również nie znalazła niczego niepokojącego.

Po przejściu wszystkich testów mogłem wreszcie odetchnąć.

Szablon okazał się czysty i nadawał się do przeniesienia do nowej instalacji OpenCart.

Pierwszy element odzyskany ze sklepu z dżumą przeszedł kwarantannę pomyślnie.

 

6. Gdzie najczęściej siedzą infekcje w OpenCart?

Analizując na przestrzeni lat dziesiątki sklepów zauwazyłem, że złośliwy kod w OpenCart bardzo często pojawia się w tych samych miejscach:

system/storage/modification/*.php
vqmod/vqcache/*.php
catalog/controller/startup/*.php
catalog/controller/common/*.php
system/library/*.php

Do tego dochodzą jeszcze katalogi z obrazami, szczególnie gdy serwer lub formularz uploadu pozwalał kiedyś na przesyłanie plików PHP.

Nie oznacza to oczywiście, że infekcja zawsze będzie siedziała właśnie tam. Haker może ukryć kod praktycznie wszędzie. Są to jednak miejsca, które regularnie przewijają się podczas analizy przejętych sklepów.

Szczególną uwagę zwracam również na tabelę oc_modification w bazie danych. To właśnie tam mogą znajdować się instrukcje modyfikujące pliki OpenCart. Jeżeli zostały zainfekowane, wystarczy jedno odświeżenie modyfikacji, aby złośliwy kod ponownie trafił do wygenerowanych plików sklepu.

Właśnie dlatego nie kopiuję całej instalacji do nowego środowiska i nie analizuję kilku czy kilkunastu tysięcy plików jeden po drugim.

Znacznie szybciej i bezpieczniej jest pobrać czystego OpenCart, czyste moduły i odzyskać jedynie bazę danych, obrazy, szablon oraz pojedyncze pliki, które rzeczywiście są potrzebne.

Im mniej plików przenosimy ze sklepu z dżumą, tym mniejsze ryzyko, że razem z nimi przeniesiemy również pasażera na gapę.

 

7. Odzyskiwanie zdjęć produktów

Skoro szablon przeszedł kontrolę, przyszła pora na katalog ze zdjęciami produktów.

Kopiuję cały katalog image/catalog, zachowując oryginalną strukturę katalogów. Dzięki temu po przeniesieniu do nowej instalacji OpenCart wszystkie ścieżki do zdjęć pozostaną poprawne.

Zanim jednak cokolwiek trafi do nowego sklepu, sprawdzam zawartość katalogu.

Na początek szukam wszystkiego, co nie jest obrazem:

find /var/www/html/em3/image/catalog \
-type f \
! -iname "*.jpg" \
! -iname "*.jpeg" \
! -iname "*.png" \
! -iname "*.gif" \
! -iname "*.webp" \
! -iname "*.svg"

Najczęściej na liście pojawiają się pliki index.html. To normalne. Sprawdzam jedynie, czy są puste i nie zawierają żadnych niespodzianek.

ls -lah /var/www/html/sklep/image/catalog/index.html
ls -lah /var/www/html/sklep/image/catalog/demo/index.html

Następnie szukam kodu PHP ukrytego w katalogu z obrazami:

grep -RIl "<?php" /var/www/html/em3/image/catalog

I tutaj pojawiło się pierwsze trafienie.

W katalogu ze zdjęciami znalazłem plik PHP, który zdecydowanie nie miał tam prawa się znajdować.

Do jego analizy wrócę za chwilę.

Na koniec wykonuję jeszcze szybki skan antywirusem:

clamscan -r -i /var/www/html/em3/image/catalog

Wynik?

Czysto.

I właśnie dlatego nie ufam wyłącznie antywirusom. ClamAV nie znalazł niczego podejrzanego, a kilka minut wcześniej grep wskazał plik PHP ukryty pomiędzy zdjęciami produktów.

A ten plik okazał się znacznie ciekawszy, niż początkowo przypuszczałem.

 

8. Znalezisko: loader PHP w katalogu obrazów

Plik znaleziony podczas przeszukiwania katalogu image/catalog nazywał się:

NgasaL_Loader.php

Już sama nazwa wyglądała podejrzanie. Jeszcze ciekawiej zrobiło się po otwarciu pliku.

W pierwszych liniach znalazłem między innymi taki fragment:

$iBIjG = yJoIV($tRJ35);
file_put_contents($XiCuO, $iBIjG);
include $XiCuO;
unlink($XiCuO);

Nie trzeba było długo analizować kodu, żeby zrozumieć, co się tutaj dzieje.

Skrypt pobierał kod PHP z zewnętrznego serwera, zapisywał go do tymczasowego pliku, wykonywał przez include, a następnie usuwał ślady swojej działalności za pomocą unlink().

Innymi słowy, sam plik nie zawierał właściwego malware. Był jedynie loaderem pobierającym polecenia z zewnątrz.

Podczas dalszej analizy natrafiłem również na odwołania do zewnętrznej domeny:

$RjAc0 = "pastejet.xyz";

oraz funkcje odpowiedzialne za analizę adresów URL i komunikację z serwerem.

Wyglądało to jak typowy mechanizm zdalnego sterowania. Osoba posiadająca dostęp do odpowiedniego panelu mogła dostarczyć dowolny kod PHP, a serwer sklepu pobierał go i wykonywał z uprawnieniami sklepu internetowego.

Krótko mówiąc – pełna zdalna kontrola nad sklepem.

Najciekawsze jest jednak coś innego.

Kilka minut wcześniej wykonałem skan ClamAV i otrzymałem wynik „0 infected files”.

Antywirus nie znalazł niczego.

Dopiero ręczna analiza katalogu oraz zwykły grep po <?php doprowadziły do odnalezienia pliku.

Skaner antywirusowy jest świetnym dodatkiem, ale nie powinien być jedynym narzędziem podczas analizy włamania. Jeżeli coś wygląda podejrzanie, warto zajrzeć do środka i samodzielnie sprawdzić, co naprawdę robi dany plik.

W tym przypadku kilka minut ręcznej analizy ujawniło zagrożenie, którego automatyczne skanowanie w ogóle nie zauważyło.

 

9. Odtwarzanie modułów i funkcji sklepu

Po odzyskaniu bazy danych, szablonu i zdjęć mogłem przejść do składania sklepu z powrotem.

Na szczęście OpenCart przechowuje większość ustawień modułów w bazie danych. Oznacza to, że po wgraniu czystych plików rozszerzenia często od razu "przypominają sobie", jak były skonfigurowane wcześniej.

Oczywiście nie zawsze wszystko działa od pierwszego uruchomienia. Część modułów trzeba doinstalować ponownie, niektóre wymagają aktualizacji, a czasami trzeba ręcznie poprawić kilka ustawień.

Krok po kroku odtwarzam więc strukturę sklepu, instaluję brakujące rozszerzenia, konfiguruję metody płatności oraz metody wysyłki.

Gdy wszystko zaczyna wyglądać poprawnie, przechodzę do testów.

Sprawdzam działanie koszyka, składanie zamówień, proces checkout, wysyłkę wiadomości e-mail oraz najważniejsze funkcje sklepu. Na tym etapie lepiej znaleźć problem na localhost niż po uruchomieniu sklepu na produkcji.

Po kilku testowych zamówieniach sklep zaczyna przypominać ten, który działał przed infekcją. Różnica jest taka, że tym razem stoi na czystych plikach.

 

10. Czyszczenie kont i danych

Skoro sklep został przejęty, nie ma sensu ufać również użytkownikom znajdującym się w systemie.

Na początek usuwam stare konta administratorów i tworzę nowe. Dzięki temu mam pewność, że nie zostały po nich żadne stare hasła ani niepotrzebne uprawnienia.

Przy okazji sprawdzam wszystkich użytkowników panelu administracyjnego. Szukam kont, których właściciel nie potrafi zidentyfikować lub które zostały utworzone w podejrzanym czasie.

Przeglądam również bazę klientów. W wielu przejętych sklepach można znaleźć konta zakładane przez boty, testowe rejestracje lub zwykły spam. Takie rekordy usuwam.

Następnie sprawdzam adresy e-mail przypisane do kont administracyjnych, grupy uprawnień oraz ustawienia dostępu do sklepu.

Na końcu zmieniam wszystkie hasła, które tylko mogę zmienić.

Jeżeli sklep został przejęty, zakładam najgorszy scenariusz – że stare dane logowania mogły zostać poznane przez osobę niepowołaną. W takiej sytuacji bezpieczniej jest wygenerować nowe hasła niż zastanawiać się później, czy ktoś nadal ma dostęp do systemu.

 

11. Operacja na właściwym serwerze

Po zakończeniu prac na localhost przyszedł czas na właściwy serwer.

Usuwam wszystkie pliki starego sklepu. Dosłownie wszystkie. Nie zostawiam starych kontrolerów, bibliotek, modułów ani "na wszelki wypadek" jakiegoś katalogu z poprzedniej instalacji.

Następnie zmieniam hasło do bazy danych i importuję wcześniej oczyszczoną bazę.

Po chwili na serwer trafiają świeże pliki OpenCart 3.0.5.0, sprawdzony szablon oraz zweryfikowane zdjęcia produktów.

Na końcu konfiguruję katalog storage poza publicznym katalogiem strony. Dzięki temu użytkownik odwiedzający sklep nie ma bezpośredniego dostępu do plików sesji, cache, logów czy modyfikacji.

Po uruchomieniu sklepu wykonuję jeszcze ostatnią serię testów. Jeżeli wszystko działa poprawnie, sklep może wrócić do życia.

 

12. Klucze API, integracje i dostęp zewnętrzny

Odbudowa sklepu nie kończy się na plikach i bazie danych.

Jeżeli ktoś miał dostęp do serwera, trzeba założyć, że mógł również poznać różnego rodzaju klucze dostępowe.

Dlatego generuję nowe klucze API wszędzie tam, gdzie jest to możliwe.

Dotyczy to przede wszystkim integracji płatności, systemów kurierskich, narzędzi marketingowych oraz zewnętrznych aplikacji komunikujących się ze sklepem.

Sprawdzam również konfigurację SMTP, integracje z BaseLinkerem, Google Analytics, Google Merchant Center, Facebook Pixel oraz wszystkie pozostałe usługi podłączone do sklepu.

To często żmudna część pracy, ale znacznie łatwiej poświęcić na nią godzinę niż później zastanawiać się, czy ktoś nadal posiada dostęp do naszych danych.

Czemu generuje nowe klucze? Wyobraź sobie że masz w plikach albo w bazie klucz podany do np. API Google. Korzystasz np, translatora. Klucz nie jest ograniczony domeną. Haker go przejmuje i co?

Wyobraź sobie że za jego pomocą przetłumaczył Wikipedię w cenie $20 za każde 2 mln znaków 😰 - oczywiście hakerzy "prankowali" strony kiedyś, dzisiaj raczej wszystkie ataki są nastawione na korzyść biznesową hakera, a więc starałby się korzystać z klucza tak byś niczego nie podejrzewał. 

Warto przeczytać:

 

13. Dlaczego haker wróci?

Wiele osób zakłada, że po usunięciu wirusa problem znika.

Niestety najczęściej tak nie jest.

Przejęty sklep bardzo często trafia na listę wykorzystywaną przez automatyczne boty skanujące internet. Taki bot nie pamięta, że sklep został naprawiony. Co jakiś czas wraca i ponownie sprawdza, czy przypadkiem nie da się wejść tą samą drogą.

Dlatego po odbudowie sklepu w logach nadal można zobaczyć próby logowania, skanowanie katalogów, wyszukiwanie znanych luk czy próby uruchamiania starych backdoorów.

To normalne.

Samo usunięcie infekcji nie kończy więc pracy. Trzeba jeszcze zamknąć drogę, którą napastnik dostał się do środka i utrudnić mu kolejne próby.

W przeciwnym razie można za kilka tygodni wrócić dokładnie do tego samego problemu.

 

14. Wnioski z akcji ratunkowej

Po zakończeniu całej operacji można wyciągnąć kilka prostych wniosków.

Po pierwsze, ClamAV jest bardzo pomocnym narzędziem, ale nie powinien być jedynym źródłem informacji. W tym przypadku antywirus nie wykrył pliku, który dawał możliwość zdalnego wykonywania kodu.

Po drugie, największym problemem nie są klasyczne wirusy, ale zakodowany, nietypowy lub dobrze ukryty kod. To właśnie on najczęściej prześlizguje się przez automatyczne skanery.

Po trzecie, nie warto ufać plikom pochodzącym z przejętego sklepu. Nawet jeśli wyglądają całkowicie normalnie.

Znacznie bezpieczniej jest postawić czysty rdzeń OpenCart i odzyskać tylko te elementy, których rzeczywiście potrzebujemy.

Baza danych, obrazy oraz szablon również wymagają kontroli. Nie można zakładać, że skoro nie są częścią rdzenia sklepu, to są bezpieczne.

Najważniejszy wniosek jest jednak inny.

Sklep po infekcji należy traktować jak miejsce po włamaniu, a nie jak zwykłą awarię. Dopiero wtedy można podejść do problemu z odpowiednią ostrożnością.

Warto przeczytać: 

 

15. Jak doszło do ataku?

Po zakończeniu odbudowy sklepu zacząłem zastanawiać się nad jednym pytaniem.

Skąd właściwie haker dostał się na serwer?

Na tym samym hostingu działały dwa sklepy internetowe. Pierwszy oparty był o OpenCart 3.0.2.0, drugi o PrestaShop 1.4. Oba zostały przejęte przez tego samego napastnika.

Nie dysponuję logami z dnia włamania, więc nie jestem w stanie wskazać źródła ataku ze stuprocentową pewnością. Mogę jednak wskazać najbardziej prawdopodobny scenariusz.

PrestaShop 1.4 została wydana w 2010 roku. Oznacza to, że w momencie włamania była systemem mającym około 16 lat. Przez ten czas odkryto w niej wiele poważnych luk bezpieczeństwa.

Do najbardziej znanych należały między innymi:

  • incydent z 2011 roku, gdy po przejęciu infrastruktury PrestaShop złośliwy kod był rozsyłany do sklepów poprzez mechanizm aktualności w panelu administracyjnym,

  • krytyczne problemy związane z uwierzytelnianiem i bezpieczeństwem haseł, które wymagały publikacji specjalnych poprawek bezpieczeństwa,

  • liczne podatności XSS pozwalające na przejęcie sesji administratorów,

  • podatność CRLF Injection w panelu administracyjnym (CVE-2011-4545),

  • możliwość wykorzystania starych bibliotek i komponentów obecnych w historycznych instalacjach do zdalnego wykonania kodu i instalacji webshelli.

W praktyce oznacza to, że pozostawienie tak starego sklepu dostępnego publicznie jest ogromnym ryzykiem.

Najbardziej prawdopodobny scenariusz wygląda następująco.

Napastnik uzyskał dostęp do serwera przez podatną instalację PrestaShop 1.4 i pozostawił na niej webshell lub inny mechanizm zdalnego dostępu. Ponieważ oba sklepy działały na tym samym koncie hostingowym, mógł bez problemu przeglądać pozostałe katalogi.

Wystarczyło odczytać pliki config.php OpenCarta, poznać dane dostępowe do bazy danych i rozpocząć infekowanie drugiego sklepu.

To klasyczny przykład sytuacji, w której jedna podatna aplikacja staje się furtką do wszystkich pozostałych stron działających na tym samym koncie hostingowym.

Czy właśnie tak było?

Tego bez logów nie da się już udowodnić.

Patrząc jednak na wiek obu aplikacji, historię podatności PrestaShop 1.4 oraz fakt, że oba sklepy zostały przejęte jednocześnie, właśnie ten scenariusz wydaje się najbardziej prawdopodobny.

Dlatego podczas odbudowy serwera podjąłem prostą decyzję.

OpenCart został uratowany.

PrestaShop 1.4 została definitywnie usunięta.

 

16. Podsumowanie: metoda „spalić wszystko”

Po tej akcji po raz kolejny utwierdziłem się w przekonaniu, że najskuteczniejszą metodą ratowania przejętego sklepu jest ograniczenie zaufania do absolutnego minimum.

Nie próbuję analizować kilku czy kilkunastu tysięcy plików jeden po drugim. Nie próbuję zgadywać, czy znalazłem już wszystkie furtki pozostawione przez hakera.

Pobieram czystego OpenCart, odzyskuję tylko niezbędne dane, sprawdzam każdy element osobno i dopiero wtedy składam sklep z powrotem.

Może nie jest to najbardziej spektakularna metoda.

Za to pozwala spokojnie spać.

Bo nie naprawiamy zgniłych fundamentów. Budujemy nowe, a ze starego budynku zabieramy tylko to, co naprawdę nadaje się do ponownego wykorzystania.