# Elrejtett PHP-kód felismerése

> eval, base64_decode és társaik: miről ismeri fel az elrejtett PHP-kódot, hogyan keres veszélytelenül, és hogyan különbözteti meg a jogos kódolókat a kártékony kódtól.

Forrás: https://phpsos.de/hu/blog/verschleierter-php-code/  
Állapot: 2026. 10. 25.  
Szolgáltató: PHP SOS, PHP-vészhelyzeti segítség és szerverbiztonság. Azonnali segítség WhatsAppon: https://wa.me/491736494914?text=%C3%9Cdv%C3%B6zl%C3%B6m%2C%20PHP%20SOS%21%20Seg%C3%ADts%C3%A9gre%20van%20sz%C3%BCks%C3%A9g%C3%BCnk%20a%20PHP-szerver%C3%BCnkkel.%20C%C3%A9g%3A%20%E2%80%A6%20Weboldal%3A%20%E2%80%A6

**Röviden:** Az elrejtett PHP-kód olyan kód, amelyet szándékosan olvashatatlanná tettek, többnyire kódolással és tömörítéssel, amelyet csak futásidőben bontanak fel. Tipikus felismerési minták: az `eval` a `base64_decode`, a `gzinflate` vagy a `str_rot13` mellett, nagyon hosszú sorok, hexadecimális karakterláncok és a részekből összeállított függvénynevek. Ártalmatlan grep-parancsokkal keressen, a kódot soha ne hajtsa végre, és a leleteket vesse össze az eredeti csomaggal.

## Miért rejtik el a támadók a kódjukat

Aki webshellt vagy hátsó kaput helyez el egy szerveren, azt szeretné, hogy sokáig észrevétlen maradjon. Az olvasható kód minden adminnak feltűnne, aki megnyitja a fájlt, és minden szkenner megtalálná. Ezért a támadók becsomagolják a kódjukat: kódolják, tömörítik, és csak meghíváskor állítják össze újra és hajtják végre.

A PHP2Shellre nincsenek megerősített Indicators of Compromise. Az elrejtett kód nem ennek a résnek a jellemzője, hanem általános jele annak, hogy valaki kódot csempészett be, bármilyen úton is. Hogyan talál meg és távolít el webshelleket általában, azt a [Webshell felismerése és eltávolítása](https://phpsos.de/hu/ratgeber/webshell-erkennen/) írja le. Ez a cikk arra a kérdésre összpontosít, miről ismeri fel az elrejtett kódot.

## eval, base64 és társaik: a tipikus építőelemek

Az elrejtés szinte mindig ugyanazt az elvet követi: egy olvashatatlan adatblokkot egy vagy több függvény visszaalakít kóddá, amelyet azután végrehajtanak. Az alábbi építőelemek újra és újra előbukkannak.

| Építőelem | Példák | Miért tűnik fel |
|---|---|---|
| Végrehajtás | `eval`, `assert` karakterlánccal (PHP 7.x-ig), `create_function` (PHP 7.x-ig) | szöveget hajt végre kódként |
| Dekódolás | `base64_decode`, `str_rot13`, `hex2bin`, `strrev`, `convert_uudecode` | újra olvashatóvá teszi az adatokat |
| Kitömörítés | `gzinflate`, `gzuncompress`, `gzdecode` | kicsomagolja a beágyazott kódot |
| Összeállítás | `chr()`-láncok, rövid részek összefűzése, `\x`-escape-ek | elrejti a függvényneveket |
| Dinamikus hívás | változók függvénynévként, `call_user_func`, `array_map` karakterlánccal | a hívás sehol sem jelenik meg egyszerű szövegként |
| Rendszerhozzáférés | `system`, `exec`, `shell_exec`, `passthru`, `proc_open`, `popen` | parancsok a szerveren |

A PHP-kézikönyv szerint az `assert()` a PHP 8.0 óta már nem értékel ki karakterláncokat kódként, a `create_function()` pedig a PHP 8.0-ban megszűnt. A régebbi PHP-verziójú szervereken mindkettő releváns keresési kifejezés marad.

Egyetlen építőelem ritkán gyanús, a `base64_decode`-ot például sok alkalmazás jogosan használja. A kombináció gyanús: dekódolás, amelynek eredménye közvetlenül egy végrehajtásba folyik.

## Veszélytelen keresés: ártalmatlan grep-parancsok

A következő parancsok a fájlokat csak szövegként vizsgálják át. Nem hajtanak végre PHP-kódot. Igazítsa az útvonalat.

```bash
# Végrehajtás dekódolással vagy kitömörítéssel kombinálva
grep -rlE "(eval|assert)\s*\(\s*(base64_decode|gzinflate|gzuncompress|str_rot13|hex2bin)" /var/www --include="*.php*"

# Nagyon hosszú sorok (gyakran tömörített kód)
grep -rlE ".{2000,}" /var/www --include="*.php*"

# Sok hexadecimális escape vagy chr()-lánc egy sorban
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*"

# Függvényhívás változón keresztül, közvetlenül egy karakterláncokból álló értékadás után
grep -rnE "\\\$[a-zA-Z_]+\s*=\s*['\"][a-z_]{4,}['\"]\s*;\s*\\\$[a-zA-Z_]+\s*\(" /var/www --include="*.php*" | head -50
```

A találatokat először az `ls -l` paranccsal és az időbélyeggel ellenőrizze, azután csak szövegként nyissa meg, például a `less` paranccsal. A gyanús fájlokat soha ne hívja meg a böngészőn keresztül, mert ezzel a szerver végrehajtaná őket.

## Hol található tipikusan az elrejtett kód

Az elrejtett kód ritkán áll saját, feltűnő fájlban. Gyakrabban meglévő fájlokba szúrják be, egészen az elejére vagy a végére, gyakran sok üres sor után, hogy megnyitáskor ne essen rögtön szembe. Népszerűek azok a fájlok, amelyeket minden meghíváskor betöltenek: a központi `index.php`, a konfigurációs fájlok és egy téma függvényfájljai.

Különösen feltűnésmentes út a konfiguráción át vezet. Az `auto_prepend_file` beállítással a PHP minden szkript előtt betölt egy további fájlt. Ha ez egy, a támadó által létrehozott `.user.ini` vagy `.htaccess` fájlban áll, a kódja minden oldalmeghíváskor együtt fut, anélkül hogy egyetlen alkalmazásfájlt módosítottak volna. A beágyazott fájl szívesen visel ártalmatlan végződést, például `.ico` vagy `.png`.

```bash
# Betöltődik további kód minden szkript előtt vagy után?
grep -rnE "auto_(prepend|append)_file" /var/www --include=".user.ini" --include=".htaccess" --include="*.conf" 2>/dev/null

# PHP-kód kép- vagy ikonvégződésű fájlokban
grep -rlE "<\?php" /var/www --include="*.ico" --include="*.png" --include="*.jpg" --include="*.gif" 2>/dev/null
```

## A jogos elrejtés megkülönböztetése a kártékony kódtól

Nem minden olvashatatlan kód rosszindulatú. Három eset gyakori:

1. **Kereskedelmi kódolók:** Egyes plugin- és szoftvergyártók az ionCube vagy a SourceGuardian típusú eszközökkel védik a kódjukat. A fájlok olvashatatlanok, de tipikusan a szükséges loaderre hivatkoznak. Vesse össze őket az eredeti csomaggal.
2. **Minifikált vagy generált kód:** A gyorsítótárak és a sablonmotorok sortörés nélküli hosszú sorokat hoznak létre, de dekódolt szöveg végrehajtása nélkül.
3. **Beágyazott adatok:** Képek vagy betűtípusok Base64-karakterláncként egy PHP-fájlban szokatlanok, de ártalmatlanok, amíg az eredményt nem hajtják végre.

A legmegbízhatóbb teszt az összevetés a forrással: ha a fájl változatlanul a gyártó csomagjából származik, jogos. Ha egyetlen eredeti csomagban sincs meg, vagy eltér tőle, meg kell vizsgálni.

> **Fontos:**
> Ne próbálja meg az elrejtett kódot az éles szerveren megfejteni, például úgy, hogy az `eval` helyére kimenetet tesz, és meghívja a fájlt. Már egy hiba is végrehajtja a kártékony kódot. Az elemzés egy izolált környezetbe tartozik.

## A mintakeresés korlátai

A támadók ismerik az elterjedt keresési parancsokat. Felosztják a függvényneveket, futásidőben állítják össze őket, vagy magát a kódot az adatbázisba, képfájlokba vagy konfigurációs bejegyzésekbe szervezik ki. A mintakeresés ezért sokat, de nem mindent talál meg. Hogy a szkennerek miért ütköznek itt korlátokba, azt a [Kártevő-szkennerek weboldalakhoz: mit találnak meg és mit nem](https://phpsos.de/hu/blog/grenzen-von-malware-scannern/) magyarázza.

A lelet ráadásul ritkán az egyetlen. A támadók több fájlban gyakran ugyanazt az építőelemet használják, például egy feltűnő változónevet vagy egy jellegzetes karaktersort a kódolt blokk elején. Egy megerősített lelet után ezért célzottan keresse éppen ezt a karaktersort a teljes webkönyvtárban, a ugyanazon a szerveren lévő más weboldalakban is. Így megtalálja azokat a testvéreket, amelyeket az általános mintakeresések nem fogtak meg.

Egészítse ki a keresést az eredeti fájlokkal való összevetéssel és egy pillantással az adatbázisba, lásd [Az adatbázis ellenőrzése beszúrt kódra](https://phpsos.de/hu/blog/datenbank-auf-schadcode-pruefen/). Megelőzésként a nem szükséges rendszerfüggvények zárolhatók, ahogyan a [A disable_functions helyes használata](https://phpsos.de/hu/ratgeber/disable-functions/) útmutató leírja.

## Hogyan segít konkrétan a PHP SOS?

- **Keresés:** Kiterjesztett mintákkal átvizsgáljuk a fájlokat és az adatbázist, és összevetjük az eredeti csomagokkal.
- **Elemzés:** A gyanús kódot izolált környezetben vizsgáljuk, a rendszere veszélyeztetése nélkül.
- **Tisztítás:** A [kártevő-eltávolítással](https://phpsos.de/hu/leistungen/malware-entfernung/) eltávolítjuk az összes összetevőt, és lezárjuk a behatolási utat.
- **Védelem:** Korlátozzuk a PHP-függvényeket és az írási jogokat, és figyeljük az új vagy módosított fájlokat.


## Gyakori kérdések

**Az eval base64_decode-dal mindig kártékony kód?**  
Nem mindig, de nagyon gyakran. A jogos kódnak alig van szüksége erre a kombinációra. Azokban a fájlokban, amelyek nem tartoznak az Ön alkalmazásához vagy egy ismert pluginhoz, erős figyelmeztető jel.

**Dekódolhatom az elrejtett kódot olvasás céljából?**  
Csak a végrehajtása nélkül és nem az éles szerveren. Már egy véletlen végrehajtás is kárt okozhat. Kétség esetén bízza az elemzést szakemberekre, akik izolált környezetekkel dolgoznak.

**Miért nem találja meg a kártevő-szkennerem a kódot?**  
A szkennerek ismert mintákat keresnek. A támadók folyamatosan módosítják a kódjukat, felosztják a függvényneveket, vagy futásidőben állítják össze őket. Az üres vizsgálat ezért nem bizonyítja, hogy a szerver tiszta.

**Mi a helyzet a kereskedelmi forgalomban titkosított pluginokkal?**  
Egyes gyártók az ionCube vagy a SourceGuardian típusú kódolókkal védik a kódjukat. Az ilyen fájlok olvashatatlanok, de jogosak, ha a gyártótól származnak. Vesse össze őket az eredeti csomaggal.

**Segít a disable_functions az elrejtett kód ellen?**  
Részben. Az olyan függvények, mint az exec vagy a system, zárolhatók, az eval viszont nem, mert nyelvi szerkezet, nem függvény. A zárolás megnehezíti a támadók következő lépését, de nem akadályoz meg minden kártékony kódot.

## Források

- [PHP-kézikönyv: assert()](https://www.php.net/manual/de/function.assert.php)
- [PHP-kézikönyv: create_function()](https://www.php.net/manual/de/function.create-function.php)
- [OWASP Cheat Sheet Series](https://cheatsheetseries.owasp.org/)
