procedura usuwania wirusów ze strony opartej o system CMS WordPress [Update]
Oczywiście scenariusz wykonywania naprawy może być inny. Przedstawiamy naszą propozycję na oczyszczenie instalacji WP z infekcji przy pomocy komend Linuksa. Na upartego wystarczy nam do tego sama konsola Linux. Np. przy pomocy serwera VPS.
Przeraża Cię ta procedura ? 🙂 Skorzystaj z pomocy specjalisty !
Zawartość artykułu
1. Porównanie wersji z kopii bezpieczeństwa z aktualną wersją plików
Jeśli dysponujemy kopią bezpieczeństwa najlepiej jest dodać ją do repozytorium SVN celem prześledzenia zmian w plikach.
a) Tworzymy repozytorium SVN oraz kopię roboczą:
cd ~ mkdir repozytoria cd repozytoria svnadmin create backup-wordpress cd ~ mkdir workspace cd workspace svn co file:///home/user/repozytoria/backup-wordpress wordpress-infekcja
(gdzie user – nazwa Twojego użytkownika)
b) Wgrywamy następnie do folderu
~/workspace/wordpress-infekcja
Pliki z kopii bezpieczeństwa.
Duże pliki binarne (mp3, mp4, jpg, png, zip, tar) nie są potrzebne do synchronizacji. Najlepiej je usunąć aby przyśpieszyć sobie pracę.
Znajdujemy takie pliki (o wielkości powyżej 500kb)
find . -type f -size +500k
i je usuwamy:
rm /sciezka/do/pliku
Czytaj jak kopiować i wklejać tekst w konsoli Linux.
Jeśli plik jest to niezbędny plik .js albo .php – zostawiamy go.
Dodajemy wszystkie pliki do kontroli wersji i komitujemy:
svn status | grep "^\?" | sed -e 's/? *//' | sed -e 's/ /\\ /g' | xargs svn add svn ci -m 'wgranie plików z kopii bezpieczeństwa (lub inny dowolny komentarz)'
c) Pobieramy pliki z zainfekowanej strony do osobnego folderu (tutaj utworzony poniżej folder: wordpress-infekcja), który uprzednio tworzymy:
cd ~ mkdir pliki-stron cd ~/pliki-stron mkdir wordpress-infekcja cd wordpress-infekcja
d) Gdy już pliki zostaną pobrane dokonujemy synchronizacji:
rsync -r -t --progress --delete -s --exclude '.svn' ~/pliki-stron/wordpress-infekcja ~/workspace/
Nastepnie przeglądamy listę zmian w plikach:
cd ~/workspace/wordpress-infekcja svn st
Listę dostępnych statusów odnośnie zmienionych plików znaleźć można tutaj : https://linuxporady.pl/lista-statusow-svn-subversion-eng/
Wykonane zmiany w plikach możemy sprawdzić poprzez komendę:
svn diff /sciezka/do/pliku
Jednak bardziej pomocne mogą okazać się programy typu Eclipse lub Netbeans z odp. wtyczkami SVN.
Następnie:
Usuwamy złośliwe pliki:
rm /sciezka/do/pliku
Leczymy złośliwie zmienione pliki
svn revert /sciezka/do/pliku
Przywracamy niezbędne dla działania systemu pliki usunięte (symbol „!” po komendzie svn st) przez hakera:
svn revert /sciezka/do/pliku
Po skrupulatnym wykonaniu powyższych czynności nowo powstałe pliki dodajemy do repozytorium:
svn status | grep "^\?" | sed -e 's/? *//' | sed -e 's/ /\\ /g' | xargs svn add
Usunięte – wykluczamy z repozytorium:
svn status | grep "^\?" | sed -e 's/? *//' | sed -e 's/ /\\ /g' | xargs rm -R
Całość zmian komitujemy:
svn ci -m 'Nowa kopia robocza (lub inny dowolny komentarz)'
2. Znalezienie rozmaitych podejrzanych wystąpień w plikach
Każde takie odkrycie badamy z osobna pod kątem czy jest to istotnie zawartość skryptu WP albo modułu, czy fragment złośliwego kodu.
Automatycznie znaleziska są składowane w pliku „zmiany”, który za każdą komendą jest nadpisywany.
a) znalezienie plików które nie mają rozszerzenia PHP a mają znacznik php:
find -not -iname "*.php" -type f -exec grep -q ' zmiany
b) wystąpienia wieloelementowej tablicy _Global:
find -type f -exec grep -q '\$GLOBAL\S\[$GLOBALS' {} \; -print > zmiany
c) znalezienie wystąpień tłumionego include. Używamy kilku wariantów wyszukiwania:
find -type f -exec grep -q '@include "' {} \; -print > zmiany
find -type f -exec grep -q '\@include\ \"' {} \; -print > zmiany
d) znalezienie wystąpień hexowego wpisywania znaków w PHP:
find -type f -iname "*.php" -exec grep -q 'chr\(109\)' {} \; -print > zmiany
tu zamiast 109 możemy użyć innych cyfr
e) znalezienie podejrzanych operacji na zmiennej tablicowej _FILE i funkcji haszującej:
find -type f -iname "*.php" -exec grep -q '\$_FILES\[base64_decode' {} \; -print > zmiany
find -type f -iname "*.php" -exec grep -q 'gzinflate\(' {} \; -print > zmiany
f) komendy wyodrębniające podejrzane pod kątem exploitów pliki PHP:
grep '((eval.*(base64_decode|gzinflate|\$_))|\$[0O]{4,}|FilesMan|JGF1dGhfc|IIIl|die\(PHP_OS|posix_getpwuid|Array\(base64_decode|document\.write\("\\u00|sh(3(ll|11)))' . -lroE --include=*.php* > mozliwe_exploity.txt
cd . sploitpattern='r0nin|m0rtix|upl0ad|r57shell|cFaTaLisTiCz_Fx|Tukulesto|99shell|shellbot|phpshell|void.ru|phpremoteview|directmail|bash_history|.ru/|brute *force|multiviews|cwings|vandal|bitchx|eggdrop|guardservices|psybnc|dalnet|undernet|vulnscan|spymeta|raslan58|Webshell' find . -name "*.php" -print0 | xargs -0 egrep -il "$sploitpattern" | sort > mozliwe_exploity.txt
grep '((eval.*(base64_decode|gzinflate|\$_))|\$[0O]{4,}|FilesMan|GLOBALS.*exit|JGF1dGhfc|IIIl|die\(PHP_OS|posix_getpwuid|Array\(base64_decode|document\.write\("\\u00|sh(3(ll|11)))' . -lroE --include=*.php*
g) znalezienie wystąpień includowanego kodu który jest zazwyczaj widoczny w ukrytych (zaczynających się od kropki) plikach PHP udających ikony (rozszerzenie .ico)
find -type f -exec grep -q 'basename\/\*' {} \; -print > zmiany
h) znalezienie podejrzanych skrytów o 8-literowej nazwie plików
W niektórych infekcjach – haker umieszcza na serwerze w losowych miejscach pliki o losowej nazwie (to istotne – nazwy są generowane automatycznie i nie mają sensu – to po prostu 8-literowy ciąg znaków). Zazwyczaj są one 8-literowe. Najlepiej wylistować wszystkie takie pliki i znaleźć takie podejrzane wystąpienia:
find . \( -name "????????.php" \)
Dla przykładu plik o nazwie typu:
vecqmdgn.php gtyxodmt.php
może wymagać wglądu – czy rzeczywiście jest częścią webserwisu. Jeśli nie i posiada podejrzany kod. Należy go skasować.
Oczywiście 8-literowy ciąg to nie standard. Jeśli pojawia się dużo plików np. 6-literowych należy odp. zmienić kryteria wyszukiwania.
i) znajdowanie zainfekowanych plików JavaScript wykonujących przekierowanie – brak możliwości zalogowania się do admina albo oglądania strony
więcej na ten temat: https://blog.sucuri.net/2019/11/vulnerable-versions-of-adminer-as-a-universal-infection-vector.html )
find -type f -name "*.js" -exec grep -q 'document.currentScript.parentNode.insertBefore(s, document.currentScript);' {} \; -print
Oczywiście ta lista możliwych podejrzanych zmian w plikach nie jest wyczerpująca.
Wszystkie ew. zmiany w plikach musimy zakomitować, aby mieć pewność że dysponujemy aktualną i oczyszczoną kopią roboczą:
svn ci -m 'Nowa kopia robocza (lub inny dowolny komentarz)'
j) Wyszukanie plików PHP w folderze ze zdjęciami i próba znalezienia złośliwych skryptów.
Jeśli na serwerze mamy folder ze zdjeciami (np. systemy PrestaShop: /img) a w nim niezliczoną liczbę plików PHP tym prostym zapytniem posortujemy pliki wg rozmiarów i zapiszemy wynik do pliku tekstowego:
find . -type f -name "*.php" -exec du -h {} \; | sort -h > pliki-php.txt
W ten sposób plik PHP ze stosunkowo dużym rozmiarem (kilka-kilkanaście kb wielkości) może być potencjalnym plikiem z którego może być przeprowadzony atak.
Dla przykładu, jeśli posiadamy folder ze zdjęciami i w każdym podfolderze jest plik zaślepkowy index.php kierujący do glownej, mozemy łatwo sprwadzic czy któryś z nich nie jest podejrzanie duży i np. w nim znajduje się exploit.
k) znalezienie plików, które były edytowane w przeciągu ostatniego tygodnia:
find . -type f -name '*.php' -mtime -7
Oczywiście zamieniająć cyfrę 7 na np. 14 – wylistujemy pliki z przed 2 tyg. itd.
Analogicznie możemy znaleźć tak pliki ZIP w których czasem hakerzy umieszczają archiwum do wypakowania:
find . -type f -iname '*.zip' -mtime -7
flaga iname nie zwraca uwagi na wielkość liter 😛
3. Aktualizacja i weryfikacja modułów
Należy zaktualizować możliwe najwięcej komponentów w WP. Zatem:
- jądro WordPress
- motywy
- wtyczki
Musimy się także zastanowić czy wszystkie zainstalowane wtyczki są niezbędne do funkcjonowania strony. Niepotrzebne lub podejrzane komponenty należy usunąć.
Po dokonaniu aktualizacji należy uwzględnić zmiany w kopii bezpieczeństwa w SVN. Powtarzamy tutaj proces z pkt. 1 tego artykułu.
4. Ustawienie prawidłowych uprawnień na plikach i folderach.
Następnie całość plików powinna być wgrana przez FTP na serwer docelowy uprzednio po usunięciu zawartości:
find . -type f -exec chmod 644 {} \;
find . -type d -exec chmod 755 {} \;
5. Zmiana haseł powiązanych ze stroną
a) Zmiana wszystkich dostępów FTP (skomplikowane hasło).
Najlepiej jest usunąć wszystkie konta FTP zostawiając tylko jedno, które ma trudne i unikalne hasło.
b) Zmiana wszystkich dostępów CMS.
W dziale użytkownicy w WP należy dokonać przeglądu którzy administratorzy są potrzebni, a którzy nie.
c) Zmiana hasła do bazy danych (skomplikowane, unikalne hasło)
Następnie należy je wprowadzić w pliku
wp-config.php
w katalogu głównym
6. Asekuracyjnie. Porównajmy naszą zaktualizowaną wersję strony opartej o WordPress z bazową wersją tego CMS.
Analogicznie jak w pkt. 1:
Upewniamy się, że mamy aktualną wersję kopii roboczej opartej o kopię bezpieczeństwa z SVN:
~/workspace/wordpress-infekcja svn st svn up
Do osobnego folderu wgrywamy aktualną wersję CMS WordPress ze strony: https://pl.wordpress.org/
Tworzymy go w folderze pliki-stron:
cd ~/pliki-stron mkdir wordpress-base/wordpress-infekcja -p
Następnie synchronizujemy pliki z naszą kopią bezpieczeństwa sprawdzamy zmiany:
rsync -r -t --progress --delete -s --exclude '.svn' ~/pliki-stron/wordpress-base/wordpress-infekcja ~/workspace/ svn st
Większość wtyczek, motywów itp. będzie usunięta (symbol wykrzyknika). Zapewne nie zawierają się one w podstawowej wersji CMS. Najbardziej kluczowe mogą być podejrzane zmiany w plikach jądra CMS, albo usunięcie plików, które mają łudząco podobną nazwę do składowych plików CMS. Należy przeglądnąć ich zawartość.
7. Dodatkowe zabezpieczenia
Blokowanie wywołań plików php i ukrytych plików php.
W folderze:
wp-content/uploads
Umieść plik o nazwie:
.htaccess
I zawartości:
Order allow,deny Deny from all
Dodatkowo, zgodnie z informacjami zawartymi na stronie: https://perishablepress.com/protect-post-requests/ możemy zupełnie uniemożliwić requesty POST. Czyli jeśli nasza strona nie posiada formularza kontaktowego itp. możemy dodać taką regułę do .htaccess. Jednak uwaga – może to uniemożliwić logowanie do CMS. W takim wypadku na czas logowania należy ją zakomentować:
# deny all POST requestsRewriteCond %{REQUEST_METHOD} POST RewriteRule .* - [F,L]
Widok zakomentowanej reguły:
# deny all POST requests ## RewriteCond %{REQUEST_METHOD} POST # RewriteRule .* - [F,L] #
8. Sprawdzenie podejrzanych użytkowników bazie danych.
Niekiedy hakerzy przejmują kontrolę nad systemem CMS i za jego pośrednictwem dokonują swoich działań.
Aby się upewnić, że w CMS nie ma takiego backdoora zaloguj się do bazy danych przez program PhpMyAdmin. Dane do zalogowania znajdziesz w pliku:
wp-config.php
następnie zaznacz tabelę:
wp_users
Jeśli w jej obrębie znajdują się podejrzane konta użytkowników
a) Usuń je – notując ich numery ID
b) Wywołaj komendę:
DELETE FROM `wp_usermeta` WHERE `user_id` = 2
Gdzie 2 – to zanotowany numer ID.
c) zmień hasło do bazy danych i zaktualizuj je w pliku php:
wp-config.php
Możesz też wywołać poniższą komendę w SQL (np. w phpmyadmin):
SELECT * FROM `wp_usermeta` WHERE `meta_key` = 'wp_capabilities' AND `meta_value` LIKE "%administrator%"
Wskaże ona ID użytkowników w randze admina. Jeśli haker założył dodatkowe konta z takimi użtkownikami – przegladnij je i wykasuj podejrzane konta.
9. Sprawdzenie sytuacji po paru dniach
Należy następnie sprawdzić sytuację na witrynie po paru dniach / tygodniach. Najlepiej dla szybkości pobrać jedynie pliki narażone na atak. Następnie prześledzić ich zmiany przez SVN na identycznej zasadzie jak w pkt. 1 albo 6 niniejszego artykułu:
find -iregex '.*\.\(ico\|php\)$' > pliki tar -czvf pliki.tar.gz -T pliki
Ewentualnie jak bazujemy na hostingu opartym o Direct Admin dodajmy takie komenty do crona:
find ~/domains -iregex '.*\.\(ico\|php\)$' > ~/domains/pliki tar -czvf ~/domains/pliki.tar.gz -T ~/domains/pliki
10. Dodanie do CRON polecenia automatycznie usuwającego plik o określonej nazwie
Jeśli plik z exploitem pojawia się zawsze pod specyficzną nazwą np. jest to plik php:
SHELLcmd.php
I nie ma na serwerze innego pliku pod tą nazwą. Można po prostu dodatkowo zabezpieczyć się poprzez dodania do CRON automatycznego znalezienia tego pliku i unięcia.
Komenda:
find -name "SHELLcmd.php" | xargs rm
CRON ustawiamy aby uruchamiał się co 1 minutę. Np. w Direct Admin wpisujemy w polu minuta:
*/1
11. Popularne dziury w innych systemach CMS.
Jeśli na Twoim serwerze są inne popularne skrypty CMS jak np. Joomla albo PrestaShop przepatrz te strony pod kątem zagrożeń. Dla Joomla wykonaj aktualizację do najnowszej wersji + porównanie plików z plikami z demo tej samej wersji. Dla PrestaShop – podobnie.
Dość popularną dziurą w PrestaShop ostatnimi czasy (szczególnie dla wersji 1.6.x) była często wykorzystywana podatność w module: jmsslider
Więcej informacji znajdziesz tutaj: https://www.joommasters.com/index.php/blog/tutorials-and-case-studies/how-to-fix-security-bug-of-slider-security-breach-of-theme.html

