Kā mēs 6 stundās notīrījām WordPress vietni no 90+ ļaunprogrammatūras artefaktiem

Vakar saņēmām e-pastu no klienta. Viņa vietne rādīja Indonēzijas kazino, nevis viņas loģistikas uzņēmuma lapu. Sekoja 6 stundas intensīva darba pret labi organizētu uzbrukuma sistēmu. Šis ir stāsts par to, ko atklājām, kā tīrījām un ko no tā mācījāmies.

Kas notika
Viena no mūsu klientu WordPress vietnēm tika kompromitēta 2026. gada 3. jūlijā. Uzbrucēji ielauzās caur automātisku skenētāju, kas ekspluatēja publiski zināmu ievainojamību (CVE-2026-63030) novecojušā WordPress versijā. Klients bija saņēmis mūsu atgādinājumus par nepieciešamo atjauninājumu, bet tie palika neatbildēti. Bet interesantākā daļa nav pati ielaušanās. Interesantākā daļa ir tas, ko viņi darīja pēc.
Nākamās 66 dienas uzbrucēji rūpīgi būvēja persistences infrastruktūru. Vairāki neatkarīgi aizmugures kanāli, izsmalcināta obfuscation, komandu un kontroles infrastruktūra caur GitLab un Telegram. Tikai tad, kad viss bija gatavs, viņi izvietoja galīgo payload: vietnes sākumlapa tika aizvietota ar Indonēzijas RUBY8000 kazino zīmola statisko klonu SEO manipulācijas nolūkos.
Kāpēc tas ir svarīgi
Ja Google būtu paguvis vietni indeksēt kazino stāvoklī pirms mēs to notīrījām, klienta SEO reputācija būtu bojāta uz mēnešiem. Google ātri iekļauj šādas vietnes melnajā sarakstā, un atgriešanās parastā rangā prasa ilgu laiku un manuālu Google Search Console iesniegumu.
Uzbrukuma anatomija
Kad sākām forensisko analīzi, sapratām, ka nav darīšana ar amatieru skriptu kiddie. Uzbrukumam bija 8 skaidri identificējamas fāzes, un katra no tām bija plānota kā rezerve iepriekšējai:
Fāze 1 - Sākuma foothold
PHP webshell augšupielāde caur ievainojamu punktu.
Fāze 2 - Privileģēta escalation
Izveidoti 22 WordPress administratora konti ar bulk-generated šabloniem (admin_wp2, wpadmin, root_admin...).
Fāze 3 - Persistence caur plugins
Iestrādāti 4 slēpti aizmugures plugins: core-helper-f6003adcd7, wp2shell_badba2c3, wp2shell-f38e02fa54f1, WP-Compact, plus falšs WebP optimizācijas plugin wtec-webp ar iebūvētu ALFA_TEAMSHELL čaulu.
Fāze 4 - Auto_prepend_file backdoor
.htaccess un .user.ini failos ievietots direktīvs, kas piespieda ielaides default.php izpildīsanu pirms katras PHP pieprasījuma apstrādes. Pat ja izdzēstu visus plugins, backdoor turpinātu strādāt.
Fāze 5 - Dziļi slēpti index.php
15+ index.php faili izvietoti dziļi WordPress struktūrā (piem. wp-includes/theme-compat/plugins/, wp-admin/network/pomo/) ar goto-based obfuscation un base64 evaluated payloads.
Fāze 6 - mu-plugins-old rezerve
Alternatīva mu-plugins direktorija ar l10n backdoor. Nosaukums izlikās par vecu rezerves kopiju.
Fāze 7 - C&C komunikācija
Trīs neatkarīgi komandu un kontroles kanāli: GitLab snippet dinamiskam payload lejupielādēšanai, Telegram bot notifikācijām, un tieša HTTP komunikācija ar operatora serveri.
Fāze 8 - Payload deploy
Vietnes index.php aizvietota ar index.html, kas satur pilnvērtīgu RUBY8000 kazino klonu.
Interesantākā tehniskā detaļa - whitespace obfuscation
Failā default.php (77 KB) atradām šo brīnumu:
$dispatcher = ' \t \t\t \t\t \t \t \t \t\t\t\t\t\t ...';
$binary = str_replace([' ', "\t"], ['0', '1'], $dispatcher);
// Katri 8 biti tiek pārveidoti par simbolu:
$decoded = '';
for ($i = 0; $i < strlen($binary); $i += 8) {
$decoded .= chr(bindec(substr($binary, $i, 8)));
}
eval($decoded); // Palaiž atkodēto PHP kodu
Uzbrucējs izmantoja atstarpes un tabulatorus kā binārus datus. Katra atstarpe ir 0, katrs tabs ir 1. Katri 8 simboli veido baitu. Šis ir gudrs risinājums, jo:
Automātiski antivirusa skaneri parasti skenē printable characters
Vizuāli fails izskatās kā tukši, formatēti komentāri
Grep pēc "eval" atrod tikai vienu vietu koda apakšā, nevis 77 KB obfuscated payload
Kā mēs tīrījām
Standarta pieeja būtu bijusi atjaunot no rezerves kopijas. Bet klientam pēdējā tīrā backup bija vecāka par 66 dienām, un pa to laiku vietne bija saņēmusi daudz leģitīmu satura atjauninājumu. Nevarējām vienkārši "atspoguļot atpakaļ" un zaudēt visu darbu.
Tāpēc izvēlējāmies ķirurģisko pieeju: precīzi identificēt un noņemt katru uzbrucēja artefaktu, saglabājot visu leģitīmo saturu. Trīs kārtas:
Kārta 1: Sākuma sanācija
Bash + wp-cli caur SSH. Deaktivizējām un dzēsām 4 aizmugures plugins, dzēsām default.php, .htaccess ar auto_prepend_file, .user.ini. Ar wp-cli dzēsām 22 admin kontus un pucinājām visus sesiju tokenus. Pirms jebkādām modifikācijām - pilna DB rezerves kopija kā drošības tīkls.
Kārta 2: Dziļuma skenēšana
Rekursīva PHP failu skenēšana visā WordPress instalācijā, meklējot signatūras un anomālijas. Piemēram: index.php fails vairāk par 20 KB WordPress dziļumā ir aizdomīgs. Atradām vēl 10 slēpti backdoor failus, kas nebija redzami pirmajā kārtā. Dzēsām arī ALFA_DATA direktoriju ar CGI wrappers un 15 uzbrucēja .htaccess failus.
Kārta 3: WordPress-native tīrīšana
Izmantojām Novamira MCP integrāciju tiešai WordPress API piekļuvei. Verificējām WordPress core failus pret oficiālajiem checksums (visi tīri). Notīrījām TranslatePress datubāzes ierakstus no RUBY8000 satura. Notīrījām Elementor un Varnish HTTP cache.
Servera cietināšana pēc tīrīšanas
Tīra vietne, kas paliek nemainīga, ir kā slēgtas durvis ar to pašu atslēgu, ko uzlauza. Tāpēc nostiprinājām konfigurāciju:
// wp-config.php papildinājumi
define('DISALLOW_FILE_EDIT', true); // Aizliedz plugin/tēmu labošanu no admin
define('AUTOMATIC_UPDATER_DISABLED', false);
define('WP_AUTO_UPDATE_CORE', 'minor'); // Auto-updates drošības patch
define('FORCE_SSL_ADMIN', true); // Piespiedu HTTPS wp-admin
Papildus rotējām visus WordPress AUTH_KEY, SECURE_AUTH_KEY, LOGGED_IN_KEY, NONCE_KEY salts (piespieda izrakstīties jebkuru vēl atlikušu uzbrucēja sesiju), bloķējām xmlrpc.php, aizsargājām wp-config.php no HTTP pieprasījumiem, un uzstādījām PHP izpildes bloķēšanu wp-content/uploads/ un wp-includes/ direktorijās.
4 mācības, ko no šī gadījuma paņēma līdzi
1. WordPress atjauninājumi nav "kad būs laiks", tie ir kritiski
Šī gadījuma sākotnējais cēlonis bija vienkāršs: novecojusi WordPress versija. Bijām nosūtījuši klientam atgādinājumus par nepieciešamo atjauninājumu, bet tie palika bez atbildes. Kad publiski tiek publicēta drošības ievainojamība kādā WordPress komponentā, automātiskie skenētāji sāk darboties dažu stundu laikā. Tāpēc atjauninājumi jāveic nedēļas, nevis mēnešu laikā.
Praktiska rekomendācija: parakstiet uzturēšanas līgumu ar savu WordPress partneri, kurā ir skaidri noteikts, ka tehniskais partneris pats veic atjauninājumus bez katras reizes apstiprināšanas. Tā jūs izvairāties no situācijas, kad e-pasts par kritisku atjauninājumu paliek neatvērts nedēļām ilgi.
2. Backup rotācija ir kritiska
Klientam bija backups, bet tie bija vecāki par uzbrukumu. 66 dienu latents periods nozīmēja, ka visos "svaigos" backup jau bija ielikts malware. Iesakām saglabāt vismaz 90 dienu backup vēsturi, ar off-site glabāšanu un neizmaināmām (immutable) rezerves kopijām.
3. Log rotācija 7 dienas ir par īsu
Precīzu sākuma piekļuves punktu 100% nevarējām identificēt, jo Nginx piekļuves logi glabājās tikai 7 dienas. Vismaz 180 dienu log retention būtu obligāts jebkurai vietnei, kas apstrādā personas datus.
4. WAF nav luksuss, tas ir minimums
Vietnei bija uzstādīts drošības plugin, bet daudzas tā funkcijas nebija aktivizētas. Reālā laika WAF (Web Application Firewall) ar aktīvām atjauninātām draudu signatūrām būtu, iespējams, apturējis sākuma skenētāju. Turklāt 2FA visiem admin kontiem ir obligāts minimums, nevis opcija.
Ko darīt, ja arī tevi skāra līdzīgs uzbrukums
Neatjauno no backup, ja neesi drošs, ka backup ir tīrs. Vispirms saglabā kopiju kompromitētajai vietnei kā pierādījumu.
Nemaini paroles no kompromitētas ierīces. Ja tavā datorā ir keylogger, jaunās paroles arī tiks pārtvertas.
Nomaini paroles no citas ierīces: WordPress admin, hosting kontrolpanelis, MySQL, FTP/SSH.
Nomet visas aktīvās sesijas un piespied 2FA visiem admin kontiem.
Sazinies ar drošības speciālistu. Manuāla tīrīšana bez zināšanām parasti atstāj daļu backdoor neaizskartu, un uzbrukums atgriežas 2-4 nedēļu laikā.
CERT.LV brīvprātīga ziņošana
Ja jūsu vietni skāris kiberincidents, varat brīvprātīgi ziņot CERT.LV ([email protected]). Tas nerada papildu pienākumus, un jūsu iesniegtie IoC var palīdzēt brīdināt citas Latvijas organizācijas par to pašu kampaņu.
Vai jūsu WordPress vietne ir aizsargāta?
EvoEX Drošības daļa piedāvā drošības auditu, 24/7 monitoringu un ārkārtas incidenta reaģēšanu. Proaktīva aizsardzība maksā aptuveni 10% no vienreizēja incidenta izmaksām.
ATCERIES!
Kiberuzbrukumu novēršana nav ātrs vai vienkāršs process - tā prasa dziļas tehniskās zināšanas, ārkārtas reakcijas laiku un dokumentāciju atbildīgajām iestādēm. Tāpēc iesakām izvēlēties sava WordPress izstrādātāja piedāvāto uzturēšanas pakalpojumu. Ja jums nav sava tehniskā partnera - sazinieties ar mums.

Saistītie pakalpojumi
Gatavs sākt savu projektu?
Aizpildi formu, pastāsti savu ideju, un mēs nosūtīsim mūsu tikšanās kalendāra linku. Izvēlies sev ērtu laiku un datumu, kurā satiksimies tiešsaistē un izrunāsim detaļas! Pēc tam izstrādāsim piedāvājumu!



