# Apmaskota PHP koda atpazīšana

> eval, base64_decode un citi: pēc kā atpazīt apmaskotu PHP kodu, kā to droši meklēt un kā atšķirt likumīgus kodētājus no ļaunprātīga koda.

Avots: https://phpsos.de/lv/blog/verschleierter-php-code/  
Aktuāls uz: 25.10.2026  
Pakalpojuma sniedzējs: PHP SOS, PHP ārkārtas palīdzība un serveru drošība. Tūlītēja palīdzība pa WhatsApp: https://wa.me/491736494914?text=Sveiki%2C%20PHP%20SOS%2C%20mums%20nepiecie%C5%A1ama%20pal%C4%ABdz%C4%ABba%20ar%20m%C5%ABsu%20PHP%20serveri.%20Uz%C5%86%C4%93mums%3A%20%E2%80%A6%20Vietne%3A%20%E2%80%A6

**Īsi sakot:** Apmaskots PHP kods ir kods, kas apzināti padarīts nelasāms, parasti ar kodēšanu un kompresiju, ko atrisina tikai izpildes laikā. Tipiski atpazīšanas modeļi ir `eval` kopā ar `base64_decode`, `gzinflate` vai `str_rot13`, ļoti garas rindas, heksadecimālas rakstzīmju virknes un funkciju nosaukumi, kas saliekti no atsevišķām daļām. Meklējiet ar nekaitīgām grep komandām, kodu nekad neizpildiet un atradumus salīdziniet ar oriģinālo pakotni.

## Kāpēc uzbrucēji savu kodu slēpj

Kas serverī novieto webshell vai slēpto piekļuvi, grib, lai tā ilgi paliktu neatklāta. Lasāms kods uzkristu acīs katram administratoram, kas failu atver, un katrs skeneris to atrastu. Tāpēc uzbrucēji savu kodu iepako: tas tiek kodēts, saspiests un atkal saliekts un izpildīts tikai izsaukuma brīdī.

PHP2Shell nav apstiprinātu Indicators of Compromise. Apmaskots kods nav šīs ievainojamības raksturīga pazīme, bet vispārēja zīme, ka kāds ir ievadījis kodu, neatkarīgi no ceļa. Kā webshell kopumā atrast un noņemt, apraksta [Webshell atpazīšana un noņemšana](https://phpsos.de/lv/ratgeber/webshell-erkennen/). Šis raksts koncentrējas uz jautājumu, pēc kā atpazīt apmaskotu kodu.

## eval, base64 un citi: tipiskie būvelementi

Apmaskošana gandrīz vienmēr seko vienam principam: nelasāms datu bloks ar vienu vai vairākām funkcijām tiek pārvērsts atpakaļ kodā, ko pēc tam izpilda. Šie būvelementi parādās atkal un atkal.

| Būvelements | Piemēri | Kāpēc tas uzkrīt |
|---|---|---|
| Izpilde | `eval`, `assert` ar rakstzīmju virkni (līdz PHP 7.x), `create_function` (līdz PHP 7.x) | izpilda tekstu kā kodu |
| Dekodēšana | `base64_decode`, `str_rot13`, `hex2bin`, `strrev`, `convert_uudecode` | atkal padara datus lasāmus |
| Dekompresija | `gzinflate`, `gzuncompress`, `gzdecode` | izpako iegultu kodu |
| Salikšana | `chr()` ķēdes, īsu daļu savienošana, `\x` escape | slēpj funkciju nosaukumus |
| Dinamisks izsaukums | mainīgie kā funkcijas nosaukums, `call_user_func`, `array_map` ar rakstzīmju virkni | izsaukums nekur neparādās atklātā tekstā |
| Piekļuve sistēmai | `system`, `exec`, `shell_exec`, `passthru`, `proc_open`, `popen` | komandas serverī |

Saskaņā ar PHP rokasgrāmatu `assert()` kopš PHP 8.0 rakstzīmju virknes vairs neizvērtē kā kodu, un `create_function()` PHP 8.0 tika noņemta. Serveros ar vecākām PHP versijām abi paliek nozīmīgi meklēšanas jēdzieni.

Atsevišķs būvelements reti ir aizdomīgs, `base64_decode`, piemēram, likumīgi izmanto daudzas lietojumprogrammas. Aizdomīga kļūst kombinācija: dekodēšana, kuras rezultāts tieši nonāk izpildē.

## Droši meklēt: nekaitīgas grep komandas

Šīs komandas failus pārmeklē tikai kā tekstu. Tās neizpilda nekādu PHP kodu. Pielāgojiet ceļu.

```bash
# Izpilde, kombinēta ar dekodēšanu vai dekompresiju
grep -rlE "(eval|assert)\s*\(\s*(base64_decode|gzinflate|gzuncompress|str_rot13|hex2bin)" /var/www --include="*.php*"

# Ļoti garas rindas (bieži iepakots kods)
grep -rlE ".{2000,}" /var/www --include="*.php*"

# Daudz heksadecimālu escape vai chr() ķēžu vienā rindā
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*"

# Funkcijas izsaukums caur mainīgo uzreiz pēc piešķiršanas no rakstzīmju virknēm
grep -rnE "\\\$[a-zA-Z_]+\s*=\s*['\"][a-z_]{4,}['\"]\s*;\s*\\\$[a-zA-Z_]+\s*\(" /var/www --include="*.php*" | head -50
```

Trāpījumus vispirms pārbaudiet ar `ls -l` un laika zīmogu un tikai tad atveriet kā tekstu, piemēram, ar `less`. Aizdomīgus failus nekad neizsauciet caur pārlūkprogrammu, jo tad serveris tos izpildītu.

## Kur apmaskots kods tipiski atrodas

Apmaskots kods reti atrodas savā uzkrītošā failā. Biežāk tas tiek ievietots esošos failos, pašā sākumā vai pašās beigās, bieži pēc daudzām tukšām rindām, lai atverot uzreiz neiekristu acīs. Iecienīti ir faili, kas tiek ielādēti pie katra izsaukuma: centrālais `index.php`, konfigurācijas faili un motīva funkciju faili.

Īpaši neuzkrītošs ceļš ir caur konfigurāciju. Ar iestatījumu `auto_prepend_file` PHP pirms katra skripta ielādē papildu failu. Ja tas ir uzbrucēja izveidotā `.user.ini` vai `.htaccess`, viņa kods darbojas pie katra lapas izsaukuma, nemainot nevienu lietojumprogrammas failu. Iekļautajam failam labprāt dod nekaitīgu paplašinājumu, piemēram, `.ico` vai `.png`.

```bash
# Vai pirms vai pēc katra skripta tiek ielādēts papildu kods?
grep -rnE "auto_(prepend|append)_file" /var/www --include=".user.ini" --include=".htaccess" --include="*.conf" 2>/dev/null

# PHP kods failos ar attēla vai ikonas paplašinājumu
grep -rlE "<\?php" /var/www --include="*.ico" --include="*.png" --include="*.jpg" --include="*.gif" 2>/dev/null
```

## Likumīgu apmaskošanu atšķirt no ļaunprātīga koda

Ne katrs nelasāms kods ir ļaunprātīgs. Bieži sastopami trīs gadījumi:

1. **Komerciāli kodētāji:** daži spraudņu un programmatūras ražotāji savu kodu aizsargā ar rīkiem, piemēram, ionCube vai SourceGuardian. Faili ir nelasāmi, bet tipiski norāda uz nepieciešamo loader. Salīdziniet tos ar oriģinālo pakotni.
2. **Minificēts vai ģenerēts kods:** kešatmiņas un veidņu dzinēji rada garas rindas bez pārtraukumiem, taču bez dekodēta teksta izpildes.
3. **Iegulti dati:** attēli vai fonti kā Base64 virkne PHP failā ir neparasti, bet nekaitīgi, kamēr rezultāts netiek izpildīts.

Uzticamākā pārbaude ir salīdzinājums ar avotu: ja fails nemainīts nāk no ražotāja pakotnes, tas ir likumīgs. Ja tas nav nevienā oriģinālajā pakotnē vai no tās atšķiras, tas pelna izmeklēšanu.

> **Svarīgi:**
> Nemēģiniet apmaskotu kodu atšifrēt produkcijas serverī, piemēram, aizstājot `eval` ar izvadi un izsaucot failu. Jau viena kļūda tad izpilda ļaunprātīgo kodu. Analīzei jānotiek izolētā vidē.

## Modeļu meklēšanas robežas

Uzbrucēji pazīst izplatītākās meklēšanas komandas. Viņi sadala funkciju nosaukumus, saliek tos izpildes laikā vai izceļ pašu kodu datubāzē, attēlu failos vai konfigurācijas ierakstos. Modeļu meklēšana tāpēc atrod daudz, bet ne visu. Kāpēc arī skeneri šeit sastopas ar robežām, izskaidro [Vietņu ļaunprogrammatūras skeneri: ko tie atrod un ko ne](https://phpsos.de/lv/blog/grenzen-von-malware-scannern/).

Atradums turklāt reti ir vienīgais. Uzbrucēji vairākos failos bieži izmanto vienu un to pašu būvelementu, piemēram, uzkrītošu mainīgā apzīmējumu vai raksturīgu rakstzīmju virkni kodētā bloka sākumā. Pēc apstiprināta atraduma tāpēc mērķtiecīgi meklējiet tieši šo rakstzīmju virkni visā tīmekļa direktorijā, arī citās tajā pašā serverī esošās vietnēs. Tā atradīsit brāļus, ko neviena vispārīgā modeļu meklēšana nav aptvērusi.

Meklēšanu papildiniet ar salīdzinājumu ar oriģinālajiem failiem un skatienu datubāzē, skatiet [Datubāzes pārbaude uz ievadītu kodu](https://phpsos.de/lv/blog/datenbank-auf-schadcode-pruefen/). Profilaktiski nevajadzīgās sistēmas funkcijas var bloķēt, kā aprakstīts ceļvedī [disable_functions pareiza lietošana](https://phpsos.de/lv/ratgeber/disable-functions/).

## Kā PHP SOS palīdz konkrēti?

- **Meklēt:** Mēs pārmeklējam failus un datubāzi ar paplašinātiem modeļiem un salīdzinām ar oriģinālajām pakotnēm.
- **Analizēt:** Mēs aizdomīgu kodu izmeklējam izolētā vidē, neapdraudot jūsu sistēmu.
- **Attīrīt:** Ar [ļaunprogrammatūras noņemšanu](https://phpsos.de/lv/leistungen/malware-entfernung/) mēs noņemam visas sastāvdaļas un aizveram ieejas ceļu.
- **Aizsargāt:** Mēs ierobežojam PHP funkcijas un rakstīšanas tiesības un uzraugām jaunus vai mainītus failus.


## Biežāk uzdotie jautājumi

**Vai eval ar base64_decode vienmēr ir ļaunprātīgs kods?**  
Ne vienmēr, bet ļoti bieži. Likumīgam kodam šī kombinācija gandrīz nav vajadzīga. Failos, kas nepieder jūsu lietojumprogrammai vai zināmam spraudnim, tā ir spēcīga brīdinājuma pazīme.

**Vai apmaskotu kodu lasīšanai drīkstu dekodēt?**  
Tikai to neizpildot un ne produkcijas serverī. Jau nejauša izpilde var nodarīt kaitējumu. Šaubu gadījumā analīzi atstājiet speciālistiem, kas strādā izolētās vidēs.

**Kāpēc mans ļaunprogrammatūras skeneris kodu neatrod?**  
Skeneri meklē zināmus modeļus. Uzbrucēji savu kodu nemitīgi maina, sadala funkciju nosaukumus vai saliek tos izpildes laikā. Tukša skenēšana tāpēc nav pierādījums tīram serverim.

**Kā ir ar komerciāli šifrētiem spraudņiem?**  
Daži ražotāji savu kodu aizsargā ar kodētājiem, piemēram, ionCube vai SourceGuardian. Šādi faili ir nelasāmi, bet likumīgi, ja nāk no ražotāja. Salīdziniet tos ar oriģinālo pakotni.

**Vai disable_functions palīdz pret apmaskotu kodu?**  
Daļēji. Funkcijas, piemēram, exec vai system, var bloķēt, eval turpretī nevar, jo tā ir valodas konstrukcija, nevis funkcija. Bloķēšana uzbrucējiem apgrūtina nākamo soli, bet nenovērš katru ļaunprātīgo kodu.

## Avoti

- [PHP rokasgrāmata: assert()](https://www.php.net/manual/de/function.assert.php)
- [PHP rokasgrāmata: create_function()](https://www.php.net/manual/de/function.create-function.php)
- [OWASP Cheat Sheet Series](https://cheatsheetseries.owasp.org/)
