Aktuálna situácia: PHP2Shell. Dve kritické zraniteľnosti PHP (CVSS 9.2) umožňujú spustenie škodlivého kódu bez prihlásenia. Záplaty od 21. 10. 2026.Čo treba urobiť teraz →

Rozpoznanie zahmleného kódu PHP

Nečitateľný kód PHP s eval a base64_decode je klasickým znakom votrelého škodlivého kódu. Aké vzorce hľadať, ako ich nájsť bezpečne a kedy je zahmlenie legitímne.

Stav 5 min čítaniaDetekcia a forenzná analýza

Stručne: Zahmlený kód PHP je kód, ktorý bol zámerne urobený nečitateľným, zvyčajne kódovaním a kompresiou, ktoré sa rozlúštia až za behu. Typické vzorce na rozpoznanie sú eval spolu s base64_decode, gzinflate alebo str_rot13, veľmi dlhé riadky, hexadecimálne reťazce a názvy funkcií skladané z jednotlivých častí. Hľadajte neškodnými príkazmi grep, kód nikdy nespúšťajte a nálezy porovnajte s pôvodným balíkom.

Prečo útočníci svoj kód ukrývajú

Kto uloží na server webshell alebo zadné vrátka, chce, aby ostali dlho neodhalené. Čitateľný kód by bol nápadný každému adminovi, ktorý súbor otvorí, a každý skener by ho našiel. Útočníci preto svoj kód balia: kóduje sa, komprimuje a až pri zavolaní sa opäť poskladá a spustí.

Pre PHP2Shell neexistujú potvrdené indikátory kompromitácie (Indicators of Compromise). Zahmlený kód nie je znakom tejto zraniteľnosti, ale všeobecným znakom toho, že niekto votrel kód, bez ohľadu na cestu. Ako webshelly nájsť a odstrániť ako celok, opisuje Rozpoznanie a odstránenie webshellu. Tento článok sa sústreďuje na otázku, podľa čoho zahmlený kód spoznáte.

eval, base64 a spol.: typické stavebné prvky

Zahmlenie sa takmer vždy riadi rovnakým princípom: nečitateľný blok dát sa jednou alebo viacerými funkciami premení späť na kód, ktorý sa potom spustí. Nasledujúce stavebné prvky sa pritom stále objavujú.

Stavebný prvok Príklady Prečo upúta
Vykonanie eval, assert s reťazcom (do PHP 7.x), create_function (do PHP 7.x) vykoná text ako kód
Dekódovanie base64_decode, str_rot13, hex2bin, strrev, convert_uudecode robí dáta opäť čitateľnými
Dekompresia gzinflate, gzuncompress, gzdecode rozbalí vložený kód
Skladanie reťazce chr(), spájanie krátkych čiastkových reťazcov, úniky \x skrýva názvy funkcií
Dynamické volanie premenné ako názov funkcie, call_user_func, array_map s reťazcom volanie sa nikde neobjaví v čistom texte
Prístup k systému system, exec, shell_exec, passthru, proc_open, popen príkazy na serveri

Podľa príručky PHP assert() od PHP 8.0 už nevyhodnocuje reťazce ako kód a create_function() bola v PHP 8.0 odstránená. Na serveroch so staršími verziami PHP ostávajú oba relevantnými hľadanými pojmami.

Jednotlivý stavebný prvok je zriedka podozrivý, base64_decode používa legitímne mnoho aplikácií. Podozrivou sa stáva kombinácia: dekódovanie, ktorého výsledok ide priamo do vykonania.

Hľadať bezpečne: neškodné príkazy grep

Nasledujúce príkazy prehľadávajú súbory len ako text. Nespúšťajú žiadny kód PHP. Prispôsobte cestu.

# Vykonanie v kombinácii s dekódovaním alebo dekompresiou
grep -rlE "(eval|assert)\s*\(\s*(base64_decode|gzinflate|gzuncompress|str_rot13|hex2bin)" /var/www --include="*.php*"

# Veľmi dlhé riadky (často zabalený kód)
grep -rlE ".{2000,}" /var/www --include="*.php*"

# Veľa hexadecimálnych únikov alebo reťazcov chr() v jednom riadku
grep -rlE "(\\\\x[0-9a-fA-F]{2}){20,}" /var/www --include="*.php*"
grep -rlE "(chr\s*\(\s*[0-9]+\s*\)\s*\.\s*){8,}" /var/www --include="*.php*"

# Volanie funkcie cez premennú hneď po priradení z reťazcov
grep -rnE "\\\$[a-zA-Z_]+\s*=\s*['\"][a-z_]{4,}['\"]\s*;\s*\\\$[a-zA-Z_]+\s*\(" /var/www --include="*.php*" | head -50

Zásahy najprv skontrolujte pomocou ls -l a časovej pečiatky a potom ich otvorte len ako text, napríklad pomocou less. Podozrivé súbory nikdy nevolajte cez prehliadač, pretože by ich server vykonal.

Kde sa zahmlený kód typicky nachádza

Zahmlený kód zriedka stojí vo vlastnom nápadnom súbore. Častejšie sa vkladá do existujúcich súborov, celkom na začiatok alebo celkom na koniec, často za mnoho prázdnych riadkov, aby pri otvorení hneď nepadol do oka. Obľúbené sú súbory, ktoré sa načítavajú pri každom volaní: centrálny index.php, konfiguračné súbory a funkčné súbory témy.

Mimoriadne nenápadná cesta vedie cez konfiguráciu. Nastavením auto_prepend_file načíta PHP pred každým skriptom ďalší súbor. Ak je v .user.ini alebo .htaccess, ktorý vytvoril útočník, beží jeho kód pri každom zobrazení stránky, bez toho, aby sa zmenil jediný súbor aplikácie. Vložený súbor pritom rád nesie neškodnú príponu ako .ico alebo .png.

# Načítava sa pred alebo po každom skripte ďalší kód?
grep -rnE "auto_(prepend|append)_file" /var/www --include=".user.ini" --include=".htaccess" --include="*.conf" 2>/dev/null

# Kód PHP v súboroch s príponou obrázka alebo ikony
grep -rlE "<\?php" /var/www --include="*.ico" --include="*.png" --include="*.jpg" --include="*.gif" 2>/dev/null

Legitímne zahmlenie odlíšiť od škodlivého kódu

Nie každý nečitateľný kód je zlomyseľný. Často sa vyskytujú tri prípady:

  1. Komerčné enkódery: Niektorí výrobcovia pluginov a softvéru chránia svoj kód nástrojmi ako ionCube alebo SourceGuardian. Súbory sú nečitateľné, no typicky odkazujú na potrebný loader. Porovnajte ich s pôvodným balíkom.
  2. Minifikovaný alebo generovaný kód: Cache a šablónovacie nástroje vytvárajú dlhé riadky bez zalomení, avšak bez vykonávania dekódovaného textu.
  3. Vložené dáta: Obrázky alebo písma ako reťazec Base64 v súbore PHP sú neobvyklé, ale neškodné, kým sa výsledok nevykonáva.

Najspoľahlivejším testom je porovnanie so zdrojom: ak súbor pochádza nezmenený z balíka výrobcu, je legitímny. Ak sa nenachádza v žiadnom pôvodnom balíku alebo sa od neho odlišuje, patrí na vyšetrenie.

Dôležité

Nepokúšajte sa zahmlený kód rozlúštiť na produkčnom serveri, napríklad nahradením eval výpisom a zavolaním súboru. Už jedna chyba pritom spustí škodlivý kód. Analýza patrí do izolovaného prostredia.

Hranice vyhľadávania podľa vzorcov

Útočníci poznajú bežné hľadacie príkazy. Rozdeľujú názvy funkcií, skladajú ich za behu alebo skutočný kód vyčleňujú do databázy, do súborov obrázkov alebo do konfiguračných záznamov. Vyhľadávanie podľa vzorcov preto nájde veľa, ale nie všetko. Prečo narážajú na hranice aj skenery, vysvetľuje Skenery malvéru pre weby: čo nájdu a čo nie.

Nález je navyše zriedka jediný. Útočníci používajú vo viacerých súboroch často ten istý stavebný prvok, napríklad nápadné označenie premennej alebo výrazný reťazec znakov na začiatku kódovaného bloku. Po potvrdenom náleze preto cielene hľadajte presne tento reťazec v celom webovom adresári, aj v iných weboch na tom istom serveri. Tak nájdete súrodencov, ktorých nezachytilo žiadne všeobecné vyhľadávanie podľa vzorcov.

Vyhľadávanie doplňte o porovnanie s pôvodnými súbormi a o pohľad do databázy, pozri Kontrola databázy na votrelecký kód. Preventívne sa dajú zablokovať nepotrebné systémové funkcie, ako opisuje sprievodca Správne používanie disable_functions.

Ako konkrétne pomáha PHP SOS?

  • Hľadať: Prehľadáme súbory a databázu rozšírenými vzorcami a porovnáme s pôvodnými balíkmi.
  • Analyzovať: Podozrivý kód skúmame v izolovanom prostredí bez ohrozenia vášho systému.
  • Vyčistiť: Prostredníctvom odstránenia malvéru odstránime všetky súčasti a uzavrieme cestu vstupu.
  • Zabezpečiť: Obmedzíme funkcie PHP a práva zápisu a sledujeme nové alebo zmenené súbory.

Časté otázky

Je eval s base64_decode vždy škodlivý kód?

Nie vždy, ale veľmi často. Legitímny kód túto kombináciu takmer nepotrebuje. V súboroch, ktoré nepatria k vašej aplikácii ani k známemu pluginu, je to silný varovný signál.

Smiem zahmlený kód dekódovať na čítanie?

Len bez jeho spustenia a nie na produkčnom serveri. Už náhodné spustenie môže spôsobiť škodu. Analýzu nechajte v pochybnostiach odborníkom, ktorí pracujú s izolovanými prostrediami.

Prečo môj skener malvéru kód nenájde?

Skenery hľadajú známe vzorce. Útočníci svoj kód neustále menia, rozdeľujú názvy funkcií alebo ich skladajú za behu. Prázdny sken preto nie je dôkazom čistého servera.

Čo komerčne šifrované pluginy?

Niektorí výrobcovia chránia svoj kód enkódermi ako ionCube alebo SourceGuardian. Takéto súbory sú nečitateľné, ale legitímne, ak pochádzajú od výrobcu. Porovnajte ich s pôvodným balíkom.

Pomáha disable_functions proti zahmlenému kódu?

Čiastočne. Funkcie ako exec alebo system sa dajú zablokovať, eval však nie, pretože ide o jazykový konštrukt, nie o funkciu. Zablokovanie sťažuje útočníkom ďalší krok, no nezabráni každému škodlivému kódu.

Zdroje

Okamžitý kontakt

Každá hodina sa počíta. Napíšte nám hneď.

Stručne opíšte systém, verziu PHP a svoje pozorovanie. Ozveme sa, vyjasníme situáciu a budeme pracovať na diaľku, kým nebude incident uzavretý a zdokumentovaný.

Okamžitá pomoc