Egy fertőzött WordPress oldal megtisztítása

[Ezt a cikket 20 perc elolvasni.]

Egy fertőzött WordPress oldal kitakarítása és helyreállítása koránt sem egyszerű feladat. A folyamat több lépcsős, rengeteg a buktató és könnyű elsiklani az esetlegesen rejtve maradó biztonsági rések és gondosan eldugott malware kódrészletek között. Nincs két egyforma fertőzés, ezért minden oldal megtisztítása egy teljesen új kihívás és pontosan ebben rejlik a dolog izgalma is.

Nemrégiben felkértek egy fertőzött WordPress weblap kitakarítására, azonban itt a szokottnál is trükkösebb volt a fertőzés elhelyezésének a módja, így elhatároztam, hogy dokumentálom az esetet, ezzel rávilágítva arra is, hogy miért nincs értelme komolyabb technikai háttérismeret nélkül belevágni a takarításba.

Az eset részletes ismertetése előtt viszont fontos megjegyezni, hogy ha egy weboldal megfertőződik, akkor sosem elég csak magát a malware-t eltávolítani, hiszen tudvalevő, hogy az nem magától került oda, hanem nagy valószínűséggel egy meglévő biztonsági résen keresztül jutott be. Tehát minden esetben legalább annyira fontos befoltozni magát a biztonsági rést, mint eltávolítani a malware-t. Az egyik feladat a másik végrehajtása nélkül teljesen haszontalan, mondhatni szélmalomharc. Ha nem tömöd be a biztonsági rést, akkor a fertőzés rövidesen újra megjelenik majd, ugyanakkor hiába tömöd be a biztonsági rést, ha a fertőzést nem távolítottad el rendesen. Elég lehet egy darab megtisztítatlan, kártékony kódot tartalmazó PHP fájl ahhoz, hogy az egész fájlrendszert újrafertőzze a malware.

Na de mi is lehet biztonsági rés? Nos, szinte bármi.

  • Elavult (nem frissített) WordPress verzió
  • Elavult (nem frissített) bővítmények vagy sablonok
  • Gyenge vagy könnyen kitalálható jelszavak (WordPress admin, FTP, tárhely admin felület, stb.)
  • Fertőzött (vagy nyilvános) számítógép, amin keresztül bejelentkeztél a weboldaladra (igen, ez is megtörténhet, elég hozzá egy keylogger (egy háttérben futó aprócska kis program, ami naplózza és akár el is küldi az összes leütött billentyűt a hackernek vagy rosszakarónak.))
  • Nem megfelelően bebiztosított tárhely vagy éppen szerver (találkoztam már olyan tárhellyel, ahol elég volt egyetlen weboldalon keresztül bejutni ahhoz, hogy az összes többi ott hosztolt weblap fájlrendszeréhez is hozzá lehessen férni. Mondanom sem kell, hogy ez mekkora biztonsági kockázatot jelent. Ez az egyik ok, amiért nem éri meg a tárhellyel (sem) spórolni.)
  • Internetről letöltött “nulled” sablonok és témák (ezeket előszeretettel pakolják tele backdoorokkal (úgynevezett hátsó bejárat), amiken keresztül könnyedén ki-be járhat a weboldalunkon a hacker. De temérdek változatosan csomagolt egyéb malware-el is találkoztam már kétes oldalakról letöltött prémium sablonok esetében (a manapság igen népszerű “WP-VCD” malware is ezeken keresztül jut be.)

Összegezve tehát az alapok, amiket minden weboldal tulajdonosnak meg kell(ene) fogadnia: Mindig frissíts WordPress core-t, plugineket, sablonokat, használj erős jelszavakat, bérelj megbízható tárhelyet/szervert és csak általad vásárolt prémium sablonokat használj (vagy válassz az ingyenesek közül a WordPress.org gyűjteményéből).

A fentiek betartása mellett nagyságrendekkel csökken egy esetleges feltörés valószínűsége, de természetesen ezek csak a lecsupaszított kötelező alaplépések és önmagukban nem garantálják a teljes védettséget (mert ilyen sajnos nem is létezik korunk digitális világában).

Sajnálatos módon bárkivel megtörténhet az, ami a mai cikk témájával kapcsolatos weboldal tulajdonosával is: Az oldalát egyik napról a másikra feltörték. Tegnap még hibátlanul futott, ma viszont első megtekintéskor minden esetben átirányítja a látogatót változatos egyéb domainekre, amik főként reklámokat tartalmaznak. A problémát fokozza, hogy egyes átirányított domainekre a vírusirtó is bejelez, még tovább rontva a weboldal megbízhatóságát. Mondanom sem kell, hogy ez roppant mód kellemetlen, főleg abban az esetben, ha a honlap egy üzleti modell része és esetlegesen bevételt is termel. Személyes vagy hobbi projekt oldalak esetében is kínos, de egy vállalkozás egész egyszerűen nem engedheti ezt meg magának, mert minden bizalmát vesztett felhasználó egyben bevétel kiesést is jelent.

Az első kétségbeesés után a tulajdonos szinte mindig felkeresi a tárhelyszolgáltatót, aki általános tapasztalataim szerint a leggyakrabban annyit javasol, hogy kerüljön visszaállításra egy korábbi biztonsági mentés arra az állapotra, amikor a weboldal még hibátlanul üzemelt. Ez tűzoltásnak megfelelő lehet akkor, ha létezik egyáltalán korábbi mentés, mert sajnos sok esetben a szolgáltató nem készít ilyet alapértelmezetten, így ha a tulajdonos sem gondoskodott róla, akkor ez nem is lesz opció. Ezzel csak annyi a bökkenő, hogy hiába áll vissza a weboldal egy korábbi (még tiszta) állapotra, a biztonsági rés továbbra is befoltozatlan marad, így csak idő kérdése, amíg újra rá nem talál egy bot vagy éppen hacker.

Sok esetben a szolgáltató is észleli a támadást és ez legtöbbször automatikusan történik a szerveren futó malware szkenner alkalmazásokon keresztül. A korrektebb hozzáállás ilyenkor a tulajdonos azonnali értesítése az észlelt támadás és az érintett fájlok megjelölésével, de sajnos nagyon gyakori az is, hogy az egész tárhely/weboldal rögtön letiltásra is kerül, így egy az egyben el is tűnik a netről, ami szintén megengedhetetlen egy vállalkozás számára. Érdemes tehát nagy hangsúlyt fektetni a biztonságra és mindent megtenni azért, hogy ne jussunk el idáig, mivel a tisztítás sem egy gyors és könnyű feladat.

A szóban forgó weboldal tulajdonos is értesítette a szolgáltatót, akik ezután szintén egy korábbi biztonsági mentést állítottak vissza, de ez sem hozott eredményt, mert a fertőzés már akkor is jelen volt. Próbáltak még segíteni egy szerver szintű malware ellenőrzés futtatásával is, de ez nem adott találatot, így részükről le is zárták a közreműködést. Ezután kerestek meg engem, hogy valahogyan találjam meg és távolítsam el a malware-t, majd foltozzam be a biztonsági rést és tegyek meg minden szükséges lépést azért, hogy a weboldaluk a lehető legbiztonságosabb lehessen.

Sokan sokféleképpen látnának neki ennek a feladatnak, de az évek alatt szerzett tapasztalatok már bebizonyították, hogy ezt csak alaposan és mindenre kiterjedően érdemes végrehajtani. Az első lépés tehát mindig a tárhely teljes biztonsági mentése (komplett fájlrendszer + adatbázis(ok)), majd az egész átköltöztetése a saját szerveremre, ahol az ellenőrzés/malware eltávolítás/patchelés/frissítés fog zajlani. Nem véletlenül írtam tárhelyet a weblap helyett, ugyanis egy fertőzés esetén szinte minden esetben a teljes tárhely is érintett, tehát hiába beszélünk csak egy fertőzött domainről, mégis szükséges az összes többi ugyanott hosztolt weblap ellenőrzése és mentése is, ugyanis ez is úgy működik, mint az influenza. Az egyik weboldal “elkapja” és borítékolható, hogy ez rövidesen át fog terjedni a többire is, ha egy “légtérben” tartózkodnak, azaz nincsenek elszeparálva egymástól (tehát a PHP folyamatok képesek “belátni” az egyéb domainek fájlrendszerébe is).

Gyakori kérdés, hogy miért is szükséges az egész tárhely költöztetése, miért is nem lehet rögtön az éles tárhelyen dolgozni? Erre nagyon egyszerű a válasz: Az éles tárhely elérhető a webről, ezáltal folyamatos megtekintéseknek van kitéve (hétköznapi látogatók, keresőrobotok, sebezhetőség után kutató botok, crawlerek, hackerek, stb.). Minden megtekintés temérdek PHP folyamatot indít el és ha ezek között található kártékony kód is, akkor önmagunk ellen dolgozunk, ugyanis lehet, hogy kitörlünk néhány fertőzött kódrészletet vagy fájlt, de ha eközben érkezik egy megtekintés, akkor a munkánk hiábavaló volt, mert a kód képes reprodukálni önmagát, tehát rövidesen ismét újrafertőzi magát a fájlrendszer. Manapság roppant mód kifinomult és összetett kódok íródnak és találkoztam már olyan esettel is, ahol kívülről percenként meghívásra került egy újrafertőzésért felelős elrejtett PHP fájl, így amíg ez érintetlen maradt, addig teljesen mindegy is volt, hogy a többi (százas nagyságrendű) malware fájl törlésre kerül-e vagy sem. Viszont ha átköltözteted az oldalt/oldalakat egy kívülről elérhetetlen szerverre, akkor kizárod a külső behatásokat, nem érkezhet rajtad kívül megtekintés és nem fog futni egy automatikus PHP kódrészlet sem.

Dolgomat megkönnyítendő mindig készítek egy bejegyzést a saját szerveremre költöztetett domainekről a helyi hosts fájlba, így nem szükséges az adatbázisban a domain csere és el tudom érni a weblapot a böngészőmben az eredeti domainen keresztül. Erről a kis trükkről EBBEN a cikkben írtam részletesen. Természetesen ez nem kötelező lépés, de sokat gyorsíthat a folyamaton, mert a takarítás elvégeztével rögtön mehet is vissza minden az eredeti tárhelyre és nem szükséges az ismételt domaincsere a visszaköltözés előtt.

Minden adott tehát a munka elkezdéséhez, a weboldalakat átköltöztettem a saját szerveremre, az adatbázisokat importáltam, a hosts fájlba pedig beírtam a szerverem IP címét és a domaineket.

A malware ellenőrzésnek mindig van egy manuális és egy automatikus része. Mindkettő szükséges ahhoz, hogy az összes kártevő felderítésre kerüljön és itt kiemelten fontos az alaposság. Egyre több és egyre pontosabb automatikus malware ellenőrző alkalmazás létezik, de ezek önmagukban sajnos még mindig kevésnek bizonyulnak, ezért fontos, hogy a teljes fájlrendszert kézileg is ellenőrizzük.

Minden WordPress oldal esetében jelen vannak a core könyvtárak és fájlok, ezeket a felhasználó sosem módosítja, így ezeket felesleges is ellenőrizni, rögtön törlöm is őket (wp-admin, wp-includes könyvtár, wp-login.php és az egyéb fájlok a gyökérkönyvtárban). Egyedül a wp-content mappát, a .htaccess és a wp-config.php fájlt hagyom meg. A törlés után letöltöm a legfrissebb WordPress zip csomagot és ebből pótolom az eltávolított core könyvtárakat és fájlokat. A .htaccess ellenőrzése mindig kézileg történik, itt elengedhetetlen egy kis szakmai ismeret, ugyanis tudni kell olvasni a sorok között és tudni kell megállapítani, hogy melyik szabály az, ami futhat és melyik az, ami esetlegesen kártékony. Ide előszeretettel pakolnak a hackerek átirányításért felelős kódokat, amelyek bizonyos feltételek teljesülése esetén kerülnek végrehajtásra. Akkor sincs gond azonban, ha ez ismeretlen terep, ilyen esetben legtöbbször törölhető a fájl tartalma és elég lehet beilleszteni az alap WordPress rewrite szabályokat, amik a keresőbarát URL-ek működéséért felelősek. A wp-config.php ellenőrzése is kézileg történik, itt is találtam már kártékony kódot számtalan alkalommal. Természetesen ez a fájl is helyreállítható az alap wp-config-sample.php felhasználásával (az adatbázis adatokat kell beilleszteni az eredeti fájlból és új saltokat kell generáltatni).

Ha ez a két fontos fájl tiszta, akkor következik a wp-content könyvtár ellenőrzése. A themes könyvtárban szinte mindig több (felesleges) sablon található, ezért rögtön törlöm is az összeset az aktív sablonon kívül. Ha meggyőződtem róla, hogy a megmaradt aktív sablon nem tartalmaz egyéni módosítást, akkor egy az egyben törlöm és feltöltöm helyette a frissen letöltött és elérhető legfrissebb változatot. Ha van belőle származtatott child theme a módosításoknak, akkor itt kézi ellenőrzést végzek az összes benne található PHP fájl esetében és összehasonlítom a szülő sablon fájljaival is.

A plugins mappánál is könnyű dolgom van, ugyanis ezek többsége ingyenesen elérhető a WordPress bővítménytárában, tehát törlöm is az összeset, amit tudok pótolni. A töröltek helyére feltöltöm az elérhető legfrissebb változatokat, az esetleges megvásárolt prémium plugineket pedig elkérem a tulajdonostól és ezeket is kicserélem. Ha van egyénileg fejlesztett plugin, akkor itt is a kézi ellenőrzés marad az egyedüli opció. A végén garantáltan tiszta és malware mentes az összes bővítményünk.

Az uploads mappában találhatóak a feltöltéseink (javarészt képek, videók, PDF fájlok és egyéb dokumentumok). Amik viszont nem lehetnek itt, azok a PHP fájlok. Indítok tehát egy keresést az uploads mappában és listázom az összes PHP fájlt. Ha van találat, akkor ezeket megnyitom, ellenőrzöm őket, majd törlöm is mindet, mert az esetek 99 százalékában az összes kártékony kódot tartalmaz.

Az egyéb wp-content-ben szereplő könyvtárakat kézzel ellenőrzöm (upgrade, cache, mu-plugins, languages, egyes bővítmények egyéni könyvtárai, stb.) és ha bármi gyanúsat találok, akkor azt eltávolítom.

Ezután jöhet az automatikus ellenőrzés, amelyre több bevált módszer is létezik. Ezekről a korábbi “WordPress biztonsági kalauz” cikkemben írtam. Érdemes futtatni egy teljes WordFence ellenőrzést, de egyénileg konfigurált módon (keressen a WordPress szülő könyvtáron túl is, ellenőrizze a sablonokat és a plugineket is). Ezek az opciók nem engedélyezettek alapértelmezetten, nekünk kell bekapcsolni őket a scanner modul beállításaiban. Futtatok még egy “Anti-Malware Security” ellenőrzést is, mert van olyan fertőzés, amit csak az egyik szúr ki és van olyan, amit csak a másik. Szerencsére az esetek többségében szinte mindent sikerül eltávolítani a kézi ellenőrzés/helyreállítás során, de volt már rá példa, hogy egyes fertőzések felett sikerült átsiklanom. Ilyenkor jelenthetnek nagy segítséget a fenti eszközök.

Természetesen a fájlrendszer kitakarítása csak az első lépés, ugyanis az adatbázis ugyanúgy tartalmazhat kártékony kódot. Ennek az ellenőrzése előtt azonban mindig megnézem az adminisztrátor felhasználókat, ugyanis számtalan fertőzés ad hozzá a készítője számára új admin felhasználót változatos nevekkel. Ha találok ilyet, akkor azonnal törlöm is.

A következő a sablon és egyes pluginek “Custom JS” azaz egyéni JavaScript kódrészlet szekciója. Ez egy mező, ahova a weboldal tulajdonos beírhatja a saját kis egyéni JavaScript kódrészletét és ez is olyan szakasz, ahová előszeretettel illesztenek be kártékony kódot. Sokan elsiklanak felette, pedig nagyon fontos, hogy ezeket is ellenőrizzük.

Sajnos ezután sincs vége, mert sok esetben magukba a bejegyzésekbe/oldalakba is beágyazásra kerül a kártékony kód. Ez különösen izgalmas akkor, amikor ezt automatikusan hajtja végre a támadó és több ezer bejegyzés megfertőzése esetén lehetetlenné válik a kézi eltávolítás. A felderítéshez szükséges, hogy a szerkesztő “HTML” nézetbe legyen kapcsolva, ugyanis “Vizuális” módban nem fognak megjelenni a hozzáadott kódok. Legtöbbször a bejegyzés alján találhatóak bizonyos script részletek, de találkoztam már titkosított kóddal a bejegyzés tartalmi részében is. A titkosítás piszok kellemetlen húzás, ugyanis így hiába is futtatsz automatikus keresést az adatbázisban vagy a fájlrendszerben a vírusirtód vagy a külső ellenőrző alkalmazás által kidobott fertőzött URL-re vagy részletre, nem fogsz találatot kapni, mivel abban a formában nem is jelenik meg ott. Csak megtekintéskor fordítja át a böngésző “emészthető” formátumra. Ha tehát nem találod meg kézzel a titkosított kódot, akkor nem is fogod tudni izolálni a fertőzést. Kis szerencsével viszont megtalálhatsz egyet egy bejegyzésben és akkor törölhető az összes megegyező kód az adatbázisból egy “Search & Replace” eszköz használatával.

Az átköltöztetett weboldal esetében is végrehajtottam a fenti lépéseket, azonban sem a manuális, sem az automatikus ellenőrzés nem adott találatot, de ez várható is volt, hiszen a tárhelyszolgáltató által használt eszköz sem jelzett fertőzött fájlt. Az adatbázisban sem volt hozzáadott adminisztrátor felhasználó és a sablon “Custom JS” szekciója is üresen állt. A bejegyzések és oldalak alapos ellenőrzése sem vezetett eredményre, tehát itt sem volt beágyazott kártékony kódrészlet. A feladatot nehezítette, hogy az átirányítás mindig más domainre történt, tehát értelme sem lett volna rákeresni bármelyikre is, mert borítékolható ilyen esetben, hogy ezeket egy teljesen más kód generálja vagy tölti be.

Maradt tehát a forráskód elemzése és meg is akadt a szemem egy gyanús script behíváson a <head> szekció végén. Ez általában a sablon header.php fájljában található, de ez garantáltan tiszta volt jelen esetben, mert a teljes sablont felülírtam a legfrissebb verzióval. Mivel a fájlrendszert egy az egyben helyreállítottam biztos lehettem benne, hogy az adatbázisban kell keresni a fertőzést. Kis kutakodás után rá is leltem a gondosan elrejtett titkosított kódra, mégpedig egy meglévő HTML widget tetején. Más módszerrel szinte lehetetlen lett volna a kód megtalálása, ezt nyilvánvalóvá teszi a formátuma.

Számok. Sem URL, sem bármi egyéb, amire rá lehetne szűrni és ami rögtön gyanús lehetne. Természetesen ez egy kódolt script, amit a böngésző fordít át futtatható és általunk is értelmezhető formátumra. Minden egyes szám egy karakternek felel meg, a “fromCharCode” JavaScript metódus cseréli ki őket.

Kíváncsi voltam mi is történik, ezért kibogoztam a titkosítást.

Alakul, de nem is lenne igazi fertőzés, ha nem lenne titkosítva maga a titkosítás is. 🙂 Bogozzuk hát ki azt is, hogy mit is húz be kívülről a script.

És igen! Megérkezett az átirányításokért felelős JavaScript fájl is, amit kiszúrtam a forráskód <head> részében.

Lényegében annyi történik, hogy ez a gondosan elkészített kis fertőzés létrehoz egy új <script> szekciót az oldal fejrészében, ott pedig betölti a fenti képen szereplő külső JavaScript fájlt, ami pedig végrehajtja az átirányításokat, de csak akkor, ha teljesülnek az ehhez szükséges feltételek (csak első látogatás esetén, csak megadott user-agent esetén, bizonyos referrer (hivatkozó, tehát például Google találatok) esetén stb.)

A kód törlése után azonnal megszűntek az átirányítások, az oldal pedig friss WordPress core, friss pluginek és sablonok mellett mehetett vissza az eredeti tárhelyére. A biztonsági rést itt is az elavult és nem frissített verziók kreálták (WordPress core, sablonok, pluginek). Az adminisztrátorok jelszavait erősre cseréltük, az oldalnak pedig adtam egy extra biztonsági réteget a WordFence WAF engedélyezésével és az iThemes Security manuális konfigurációjával.

Ez egy rendhagyó fertőzés, ugyanis felettébb ritka, hogy a fájlrendszer érintetlenül marad és nem kerül feltöltésre vagy beágyazásra kártékony kód. Ebből kifolyólag a felderítése is jóval komplikáltabb és nem is annyira magától értetődő, mint a legtöbb esetben.

Bízom benne, hogy ez a kis esetleírás hasznosnak bizonyult és talán arra is sikerült rávilágítanom, hogy mennyire fontos is az, hogy minden esetben szakértő végezze el a malware eltávolítását. Elég egyetlen kihagyott PHP fájl vagy benn hagyott kártékony kódrészlet és az összes addigi munkánk kárba is veszett. Nem is beszélve a bevételkiesésről, amit egy ilyen fertőzés okozhat.

Nem lehet és nem is szükséges, hogy minden weboldal tulajdonos malware szakértő legyen, azonban manapság már elengedhetetlen egy alapvető biztonságtudatosság az oldalunk üzemeltetéséhez. Feltörhetetlen rendszer nem létezik, de mindent meg kell tennünk azért, hogy a lehető legjobban megnehezítsük a hackerek dolgát, hisz a védelem első lépcsője mi magunk vagyunk. Használjunk erős (és minden oldal/alkalmazás esetén különböző) jelszavakat, mindent tartsunk naprakészen, ügyeljünk a személyi számítógépeink biztonságára és ne használjunk kétes helyről letöltött vagy éppen feltört alkalmazásokat vagy bővítményeket.

Ha tetszik, mutasd meg másoknak is: