Napadnutá stránka WordPress: zastaraný plugin a webový shell

Zastaraný plugin umožnil nahrať webový shell, stránka presmerúvala návštevníkov a Google ju označil. Čistá obnova, aktualizácia, obmena tajomstiev a spevnenie.

Firma
Malá firma s prezentačným webom, 10 ľudí
Web
WordPress s viacerými pluginmi a kontaktným formulárom
Správa
Web občas spravuje externý človek, aktualizácie nikto nesleduje
Hosting
Jeden VPS, Nginx a PHP-FPM, MySQL

01Východiskový stav

Web beží na WordPresse s niekoľkými pluginmi. Jeden z nich, wp-file-manager, je vo verzii spred vydania opravy. Prihlásenie do administrácie je verejne dostupné, v administrácii je zapnutá úprava súborov a databázový účet WordPressu má plné práva.

Zálohy existujú, ale nikto ich neskúšal obnoviť, a integrita súborov sa nesleduje.

  1. Internet
  2. Nginx / PHP-FPM
  3. WordPress (zastaraný plugin)
  4. MySQL

02Problém

Zákazníci hlásili, že sa im web na mobile presmeruje na pochybnú stránku. Google Search Console web označil za škodlivý a organická návštevnosť klesla.

Príčinou bola zraniteľnosť CVE-2020-25213 v plugine wp-file-manager pred verziou 6.9. Plugin sprístupňoval súbor, cez ktorý sa dal bez prihlásenia nahrať a spustiť PHP kód, teda vzdialené spustenie kódu. Útočník takto nahral webový shell, malý PHP súbor na ovládanie servera, a do stránky vložil podmienené presmerovanie (na mobiloch a z výsledkov vyhľadávania) spolu so spamovým obsahom pre vyhľadávače.

Predpoklad útoku: stačí, že je zraniteľný plugin dostupný z internetu. Ide o verejne známu a masovo zneužívanú zraniteľnosť z roku 2020, nie o nič, čo by sme tu odhaľovali.

Napadnutie webu znamená, že server bol pod kontrolou útočníka. Preto sa k nemu pristupovalo tak, že dôveryhodné už nie je nič, čo na ňom je.

03Technická príčina

Hlavná príčina je zastaraný plugin so známou zraniteľnosťou. Bez sledovania aktualizácií ostala otvorená mesiace po vydaní opravy.

Dopad zväčšili nastavenia: zapnutá úprava súborov v administrácii a databázový účet s plnými právami rozšírili, čo sa dá po prvom prieniku spraviť. PHP sa navyše dalo spustiť aj z priečinka s nahranými súbormi, kam shell pristál.

To, že zálohy nikto neskúšal obnoviť a integrita sa nesledovala, znamenalo, že napadnutie sa prejavilo až sťažnosťami zákazníkov, nie skôr.

04Vyšetrenie

Časy zmien súborov ukázali neznáme PHP súbory v priečinku s nahranými súbormi a upravené súbory šablóny. V databáze bol vložený kód v nastaveniach a v obsahu stránok.

Prístupové logy Nginx ukázali požiadavky na súbor pluginu zo zahraničných adries v čase, keď sa objavili neznáme súbory.

Search Console ukázala, ktoré adresy Google označil a čo návštevníkom zobrazoval.

Rozsah sa overil porovnaním s čistou inštaláciou WordPressu a pluginov z oficiálnych zdrojov, aby bolo jasné, čo na serveri nemá čo hľadať.

05Náprava

Web sa odstavil do režimu údržby. Shell sa len tak nezmazal: po napadnutí sa nedá spoľahlivo dokázať, že útočník nenechal ďalšie zadné vrátka, preto sa web postavil nanovo.

Jadro WordPressu, pluginy aj šablóna sa nahradili z oficiálnych zdrojov. Obsah sa obnovil z overene čistej zálohy, prípadne sa databáza vyčistila od vloženého kódu. Plugin wp-file-manager sa odstránil, keďže ho web nepotreboval.

Obmenili sa všetky tajomstvá: heslá administrátorov, heslo databázy, bezpečnostné kľúče vo wp-config.php (čím sa zneplatnia všetky prihlásenia) a prístupy k hostingu.

wp-config.php
// turn off the built-in file editor in wp-admin: no code changes from the browser
define('DISALLOW_FILE_EDIT', true);

// rotate ALL of these after a compromise, with fresh values from the
// WordPress secret-key API; it invalidates every existing login cookie
define('AUTH_KEY',         '...'); // also SECURE_AUTH_KEY, LOGGED_IN_KEY, NONCE_KEY
define('AUTH_SALT',        '...'); // also SECURE_AUTH_SALT, LOGGED_IN_SALT, NONCE_SALT

Spustenie PHP z priečinka s nahranými súbormi sa zakázalo, takže prípadný ďalší shell tam ostane neúčinný.

nginx: server block
# never run PHP from the uploads directory: a web shell dropped there stays inert
location ~* /wp-content/uploads/.*\.php$ {
    deny all;
}

Web sa spevnil: vypnutá úprava súborov v administrácii, databázový účet len s potrebnými právami, automatické aktualizácie pluginov, druhý faktor a obmedzenie pokusov pri prihlásení do administrácie, a sledovanie integrity súborov.

V Search Console firma požiadala o opätovné posúdenie, aby Google označenie odstránil.

06Prečo oprava funguje

Odstránenie pluginu zavrie cestu, ktorou sa shell nahral. Aktualizácia by ju zavrela tiež, no plugin nebol potrebný.

Postavenie webu nanovo z oficiálnych zdrojov odstráni aj zadné vrátka, ktoré by sa pri ručnom čistení dali prehliadnuť.

Obmena bezpečnostných kľúčov vo wp-config.php zneplatní všetky prihlasovacie cookies, takže útočník sa cez staré prihlásenie nevráti.

Zákaz spúšťania PHP z priečinka s nahranými súbormi znamená, že aj keby tam ďalší shell pristál, server ho nespustí.

Vypnutá úprava súborov a databázový účet s minimom práv zmenšujú, čo sa dá po budúcej chybe spraviť.

Čo to nerieši: zraniteľnosť v plugine, ktorý si ponecháte, ani chybu v hostingu zdieľanom s cudzími webmi. Preto sú dôležité aktualizácie a minimum pluginov.

07Overenie

  • Súbor pluginu už na nahranie neodpovedá, plugin je odstránený.
  • V priečinku s nahranými súbormi nie je žiadne neznáme PHP a pokus o jeho spustenie server odmietne.
  • Vložený kód zmizol z databázy aj zo šablóny, web sa už na mobile nepresmeruje.
  • Google po posúdení označenie odstránil a integrita súborov sa odvtedy sleduje voči základnému stavu.

08Výsledky

Opravené

  • Cesta, ktorou sa dal nahrať kód, je zavretá a shell odstránený.
  • Vložené presmerovanie a spam sú preč a Google web už neoznačuje.

Znížené riziko

  • PHP sa nedá spustiť z priečinka s nahranými súbormi.
  • Úprava súborov je vypnutá a databázový účet má len potrebné práva.
  • Pluginy sa aktualizujú automaticky a integrita súborov sa sleduje.

Ostáva otvorené

  • Za obdobie pred obnovou sa nedá preukázať, čo všetko útočník so serverom robil.
  • Kým web stojí na pluginoch tretích strán, každý z nich je možná ďalšia cesta.

09Obmedzenia

  • Bezpečnosť webu je len taká dobrá ako najslabší plugin. Každý ponechaný plugin treba aktualizovať.
  • Sledovanie integrity odhalí zmenu, len ak si niekto všimne upozornenie a zareaguje.
  • Na zdieľanom hostingu môže web ohroziť aj napadnutý sused. Tento web beží na vlastnom VPS, čo to obmedzuje, ale nevylučuje chybu v prostredí hostingu.

10Poučenia

  • Napadnutý web znamená napadnutý server. Zmazať shell nestačí, treba postaviť nanovo z čistých zdrojov.
  • Zastaraný plugin so známou zraniteľnosťou je najčastejšia cesta do webu na WordPresse. Aktualizujte, alebo plugin odstráňte.
  • Po napadnutí obmeňte všetky tajomstvá vrátane bezpečnostných kľúčov, inak sa útočník vráti cez staré prihlásenie.
  • V priečinku s nahranými súbormi nemá čo bežať PHP. Zakážte to.
  • Menej pluginov znamená menšiu plochu na útok. Čo web nepotrebuje, nech tam nie je.
  • Zálohu, ktorú ste neskúšali obnoviť, nemáte overenú, a napadnutie odhalíte neskoro, ak integritu nesledujete.

11Ďalšie kroky pre malú firmu

  1. 1.Zapnúť automatické aktualizácie a pravidelne prejsť, ktoré pluginy sú naozaj potrebné.
  2. 2.Druhý faktor pre prihlásenie do administrácie a obmedzenie pokusov o prihlásenie.
  3. 3.Predradiť webu ochrannú vrstvu (napríklad Cloudflare) a sledovať integritu súborov.
  4. 4.Overiť obnovu zo zálohy, aby bola pri ďalšom probléme istá.
Ozvite sa

Spoznávate v tom svoju firmu?

Napíšte nám, čoho sa to týka. Ozveme sa do jedného pracovného dňa a povieme, či je to práca pre nás, aj keď odpoveď bude nie.