Kyberzápisník #90: SC WordPress malware, backdoor, který se po vyčištění sám obnoví

Bezpečnostní tým Sucuri popsal rodinu škodlivého kódu, kterou pojmenoval SC podle značek SC_ nalezených ve vložených blocích. SC WordPress malware není jeden soubor, ale síť vzájemně provázaných komponent, kde každá umí obnovit všechny ostatní. Při jejím zachycení se opakovala stejná situace: backdoor se vracel během několika sekund po každém odstranění, ať už byly viditelné soubory smazány jakkoli pečlivě. Smazání souborů tedy nestačí. Rozhoduje pořadí kroků.

Co je SC WordPress malware

Sucuri SC popisuje jako samoopravující se síť (self-healing mesh) loaderů, drop-inů a backdooru řízeného přes blockchain. Payload žije minimálně na osmi místech současně, rozprostřených mezi soubory, databází a sdílenou pamětí. Smazání pluginu vyvolá jeho opětovný zápis z drop-inu. Smazání drop-inu ho znovu vytvoří téma. Vyčištění všech souborů na disku skončí tím, že další načtení stránky obnoví celou sadu z databáze nebo ze segmentu sdílené paměti. Výsledkem je kruhový systém bez jediného bodu, jehož odstraněním by se infekce zastavila.

Všechny prozkoumané soubory sdílejí stejné obfuskační schéma. Chybí eval, nejnovější části nenesou žádné značky a názvy funkcí nejsou čitelné. Každý soubor obsahuje tabulku zakódovaných řetězců a malý dekodér, který číselný index převádí na skutečný název funkce pomocí substituční šifry.

Kde se SC WordPress backdoor ukrývá: osm míst najednou

#UmístěníRole
1.user.ini (případně php.ini, .htaccess)Direktiva auto_prepend_file spouští loader před každým PHP požadavkem v dané adresářové větvi, i u požadavků, které WordPress nikdy nedosáhnou. Hodnotu si PHP cachuje.
2wp-content/c1b12371.php (název se liší)Viditelný shim. Pokud vedle existuje skrytý soubor s tečkou, načte ho. Po jeho smazání tiše nedělá nic, takže web zůstane funkční a útočník získá čas.
3wp-content/.c1b12371.php (skrytý, název se liší)První skutečný loader. Obnovuje falešný plugin ve složce mu-plugins ze tří zdrojů: existující kopie v pluginech, zakódovaný stub v cache adresáři a ZIP záloha s náhodným hex názvem. Definuje konstantu SC_AUTO_PREPEND.
4wp-content/db.phpDrop-in načítaný velmi brzy při startu WordPressu. Nese celý payload jako blob gzip + base64 a při chybějícím nebo příliš malém pluginu ho zapíše zpět na disk.
5wp-content/advanced-cache.phpNejdříve načítaný a nejnebezpečnější drop-in (při zapnuté cache, konstanta WP_CACHE). Payload nenese, ale umí ho obnovit z pěti nezávislých zdrojů: z mu-pluginu, z běžného pluginu, ze sdílené paměti System V, ze ZIP balíčku a nakonec přímo z databáze.
6functions.php aktivního tématu (v ukázce téma khorshidi)Ohraničený blok kódu na konci jinak legitimního tématu. Je to tématová dvojnice db.php, která plugin přepíše, kdykoli zmizí.
7wp-content/mu-plugins/hyper-engine-kit.php (název se liší)Hlavní backdoor jako must-use plugin, načítaný automaticky a neviditelně.
8wp-content/plugins/hyper-engine-kit/hyper-engine-kit.phpIdentická kopie pro redundanci. Složka plugin obsahuje i falešnou stránku nastavení, shortcode a aktivační hook, takže na první pohled vypadá jako skutečný cache plugin. Obě kopie se navzájem synchronizují.

Perzistence SC WordPress malware mimo disk: databáze, sdílená paměť a cron

Nejdůležitější poučení z celého případu je, že perzistence se neomezuje na soubory. Sucuri našlo živé kopie payloadu ve třech místech mimo souborový systém, z nichž každé stačí k obnově celé sady při dalším požadavku.

  • Databáze. Celý payload leží v řádku tabulky wp_options s náhodným názvem, ve stejném formátu gzip + base64. Drop-in advanced-cache.php ho čte přes přímé databázové spojení s využitím přihlašovacích konstant webu. Proto selže i úplný a správný úklid souborů: následující načtení stránky vše obnoví z jediného řádku.
  • Sdílená paměť. Na serverech podporujících System V shared memory se payload zapisuje do segmentu s pevným číselným klíčem. Segment žije v RAM, přežije smazání souborů i vyčištění databáze a na sdíleném hostingu může patřit jinému účtu.
  • Naplánované úlohy. Infekce registruje cron hooky, včetně náhodně pojmenovaných vedle známého fetch hooku. Systémový cron spouští soubor WordPress cronu, nikoli návštěvnost, a podle plánu vyvolá opětovné nasazení.

K tomu se u příbuzných variant SC objevují databázové triggery, které při vložení řádku znovu vytvoří administrátorský účet. Trigger běží uvnitř databáze, takže přežije obnovu souborů i smazání účtu, který neustále obnovuje. Mazání uživatelů je tedy zbytečné, dokud trigger existuje.

Co SC WordPress backdoor umí

Payload je důvodem, proč celá síť existuje. Po spuštění provádí několik odlišných úloh.

  • Skrývá se. Filtruje seznam pluginů, transient aktualizací i pohledy na pluginy webu a sítě, takže se neobjeví v administraci ani v kontrole aktualizací. Jako záložní řešení vkládá admin JavaScript, který se z tabulky pluginů vymaže.
  • Komunikuje s C2 přes blockchain. Místo jednoho pevně zadaného serveru obsahuje seznam zhruba dvaceti veřejných Ethereum RPC bran a sadu selektorů metod smart kontraktů. Instrukce čte ze smart kontraktu, což je technika známá jako EtherHiding. Protože se zneužívají legitimní třetí strany, zablokování jediné brány, která byla zachycena v provozu, nestačí. Blokovat je nutné celou sadu.
  • Fingerprintuje web a stahuje payload. Sbírá URL a hostitele, verze WordPressu a pluginů, hashe cest, aktivní témata, seznam mu-pluginů i tokeny aktuálních relací administrátorů. Balík zašifruje a odešle na získaný endpoint. Odpověď může obsahovat front-endový JavaScript k vložení (na e-shopu to znamená skimmer na checkoutu), nové PHP k instalaci a seznamy bezpečnostních pluginů k deaktivaci a smazání. Při odstraňování bezpečnostního pluginu umí nejprve přeřadit nebo povýšit jiný účet.
  • Vytváří skrytého administrátora. Převezme existujícího skrytého admina nebo založí nového, v případě nedostupného API zapisuje přímo do tabulek users a usermeta. Oprávnění ukládá pod výchozí klíč capabilities a účet skrývá v seznamu uživatelů, počtech i přehledech rolí. Navíc umí padělat platné autentizační cookies, takže se operátor přihlásí bez hesla.
  • Nabízí živý beacon. Speciální parametr požadavku se zpracuje ještě před dokončením načtení WordPressu. Pokud je síť přítomna, vrátí běžnou odpověď a skončí.
  • Obnovuje celou síť. Zavěšuje velkou sadu akcí a filtrů, jejichž jediným účelem je zapsat zpět všechny ostatní komponenty: drop-iny, tématovou injekci, skrytý loader s direktivami v .htaccess a .user.ini, ZIP zálohu, segment sdílené paměti i databázovou kopii. Payload dokonce otevírá přímé databázové spojení a vkládá svůj řádek mimo WordPress API.

Indikátory kompromitace SC WordPress malware

Soubory a cesty (názvy se liší od webu k webu):

  • .user.ini, php.ini nebo .htaccess s direktivou auto_prepend_file mířící na skrytý PHP soubor začínající tečkou
  • viditelný shim a skrytý loader ve wp-content (v ukázce c1b12371.php a .c1b12371.php)
  • neočekávané PHP bloky ve wp-content/db.php a wp-content/advanced-cache.php s úvodním markerem ve stylu SC_ a ochrannou konstantou
  • ohraničený blok na konci functions.php aktivního tématu, někdy s duplikovaným úvodním markerem
  • falešný plugin současně v mu-plugins i plugins se shodným obsahem a věrohodnou stránkou nastavení (hyper-engine-kit)
  • ZIP záloha s náhodným hex názvem ve wp-content, wp-content/uploads nebo ve složce tématu

Markery v kódu a databázi:

  • konstanta SC_AUTO_PREPEND a značky SC_ na začátku bloků
  • řádek v wp_options s náhodným názvem a velkým blobem gzip + base64
  • kontrolní options a transients s prefixem sc_
  • plně privilegovaný administrátor, který se nemusí zobrazit v seznamu uživatelů, s oprávněními pod výchozím klíčem capabilities, případně osiřelá option odkazující na ID tohoto účtu po neúplném úklidu
  • škodlivé cron úlohy a případné databázové triggery

Mimo web:

  • segment sdílené paměti obsahující čitelný PHP kód začínající otevíracím tagem
  • odchozí požadavky z webového serveru na veřejné Ethereum RPC brány

Jak SC WordPress malware odhalit

Detekce vychází přímo z indikátorů. Příkazy níže slouží pouze k prohlídce, nic nemažou. Cesty a prefix tabulek je nutné upravit podle konkrétního webu.

bash

# direktiva auto_prepend_file v konfiguračních souborech
grep -rIn "auto_prepend_file" /cesta/k/webu --include=.user.ini --include=php.ini --include=.htaccess

# skryté PHP soubory s tečkou přímo ve wp-content a obsah kritických míst
find /cesta/k/webu/wp-content -maxdepth 1 -name ".*.php"
ls -la /cesta/k/webu/wp-content/db.php /cesta/k/webu/wp-content/advanced-cache.php /cesta/k/webu/wp-content/mu-plugins/

# markery SC_ v drop-inech
grep -n "SC_" /cesta/k/webu/wp-content/db.php /cesta/k/webu/wp-content/advanced-cache.php

# segmenty sdílené paměti System V (spouští se pod uživatelem webu i jako admin serveru)
ipcs -m

sql

-- největší řádky v options (kandidáti na zakódovaný payload)
SELECT option_name, LENGTH(option_value) AS velikost
FROM wp_options ORDER BY velikost DESC LIMIT 20;

-- administrátoři přímo z databáze (administrace i WP-CLI mohou skrytý účet filtrovat)
SELECT user_id FROM wp_usermeta
WHERE meta_key = 'wp_capabilities' AND meta_value LIKE '%administrator%';

-- databázové triggery
SELECT TRIGGER_NAME, EVENT_OBJECT_TABLE
FROM information_schema.TRIGGERS WHERE TRIGGER_SCHEMA = DATABASE();

Dotaz na administrátory je důležitý právě proto, že backdoor skrývá svůj účet pomocí filtrů nad seznamem uživatelů. Porovnání výsledku přímého SQL dotazu s tím, co zobrazuje administrace, odhalí rozdíl. Dále dává smysl sledovat odchozí provoz na Ethereum RPC brány, zapnout kontrolu integrity souborů (file integrity monitoring) a pravidelně procházet složku mu-plugins, kterou běžná správa pluginů vůbec neukazuje.

Správné pořadí čištění SC WordPress malware

Protože každá komponenta umí obnovit ostatní, pořadí kroků je důležitější než samotné mazání. Smazání souborů ve špatném pořadí jen spustí jejich opětovný zápis. Funguje postup: nejprve odříznout spouštění, potom vyčistit kopie mimo disk a až nakonec odstranit soubory, a to v jediném průchodu.

  1. Zneškodnit auto_prepend dříve, než se smaže jeho cíl. PHP hodnotu auto_prepend_file cachuje až 300 sekund. Cílový soubor se proto nejprve vyprázdní na neškodný stub, teprve potom se direktiva odstraní z .user.ini, php.ini a .htaccess. Smazání cíle při teplé cache shodí všechny PHP požadavky na účtu.
  2. Vyčistit kopie payloadu mimo disk. Odstranit řádek s payloadem z tabulky options, vyprázdnit segment sdílené paměti a smazat kontrolní options a transients. Pokud cokoli zůstane, další požadavek přes advanced-cache.php celou sadu zapíše zpět. Na sdíleném hostingu může segment sdílené paměti patřit jinému účtu, takže ho smaže jen ten účet nebo poskytovatel. Po odstranění drop-inů, které ho čtou, je segment neškodný.
  3. Odstranit naplánované úlohy a databázové triggery. Vyčistit škodlivé cron hooky, aby systémový cron nemohl nasadit infekci znovu, a zkontrolovat information_schema.TRIGGERS. Přeživší trigger obnoví přístup i po úplné obnově souborů.
  4. Smazat skrytého administrátora. Odstranit účet s oprávněními pod výchozím klíčem capabilities a uklidit osiřelou option odkazující na jeho ID.
  5. Vyčistit soubory v jednom průchodu. Odstranit samostatné loadery a shim, obě kopie falešného pluginu z mu-plugins i plugins, ZIP zálohu kdekoli ukrytou a infikované drop-iny. U db.php a advanced-cache.php jde o smazání škodlivých souborů. U functions.php tématu se odstraňuje pouze ohraničený blok mezi markery, aby legitimní kód tématu zůstal nedotčen.
  6. Znovu prohledat a sledovat znovuvytvoření souborů. Po dokončeném skenu následuje monitoring dotčených cest. Vrátí-li se kterákoli komponenta, přežil některý bod perzistence nebo je stále otevřená původní cesta průniku.

Úklid nekončí odstraněním malwaru. Je nutné uzavřít původní vstupní bod a rotovat všechny přístupové údaje, kterých se útočník mohl dotknout.

Prevence proti WordPress backdooru typu SC

  • Aktualizace. Většina kompromitací zneužívá známé a již opravené zranitelnosti v zastaralých komponentách. Rychlé aktualizace zkracují okno, které útočník má.
  • Web Application Firewall. Firewall může zastavit pokusy o zneužití dříve, než dosáhnou aplikace, zachytit parametr beaconu a pomoci omezit odchozí komunikaci s řídicím kanálem.
  • Pravidelný audit míst, kde se SC ukrývá. Tabulka options, naplánované úlohy, databázové triggery a uživatelské účty. Právě tam SC drží perzistenci, díky níž se vrací.
  • Každý návrat souboru je nedokončený úklid. Pokud se soubor objeví znovu, kopie payloadu stále existuje mimo disk nebo je stále aktivní naplánovaná úloha. Řešením je vrátit se ke zdrojům mimo disk, nikoli mazat stejný soubor podruhé.
  • Obecný hardening. Silná hesla a dvoufaktorové ověření pro všechny administrátory, omezení zápisových práv souborů pro proces webu, offline zálohy s ověřeně čistým obsahem a omezení nebo zákaz auto_prepend_file, pokud to hosting dovoluje.

Shrnutí: SC WordPress malware jako systém, ne soubor

SC ukazuje, že moderní infekce WordPressu může být celý systém. Identické kopie jednoho backdooru jsou rozmístěné v drop-inech, tématu, falešném pluginu na dvou místech, v databázi a ve sdílené paměti. Řídicí kanál se schovává v legitimní blockchainové infrastruktuře a po přeživší kopii se celá síť přepíše při dalším požadavku. Trvalé řešení vyžaduje vnímat soubory, databázi a sdílenou paměť jako jeden problém, vypnout spouštění před mazáním, odstranit perzistenci ve všech podobách, uzavřít vstupní bod a rotovat přístupy. Cokoli menšího nechá síť, aby se znovu postavila.

Zdroje

Leave a Reply

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *