Aktuellt läge: PHP2Shell. Två kritiska PHP-sårbarheter (CVSS 9,2) tillåter skadlig kod utan inloggning. Patchar sedan den 21 oktober 2026.Vad som bör göras nu →

Känn igen förvrängd PHP-kod

Oläslig PHP-kod med eval och base64_decode är ett klassiskt tecken på insmugglad skadlig kod. Vilka mönster ni söker, hur ni hittar dem riskfritt och när förvrängning är legitim.

Aktualitet 5 min läsningUpptäckt och forensik

Kort sagt: Förvrängd PHP-kod är kod som avsiktligt har gjorts oläslig, oftast genom kodning och komprimering som först löses upp under körning. Typiska igenkänningsmönster är eval tillsammans med base64_decode, gzinflate eller str_rot13, mycket långa rader, hex-teckensträngar och funktionsnamn som sätts ihop av delar. Sök med ofarliga grep-kommandon, kör aldrig koden och stäm av fynd mot originalpaketet.

Varför angripare gömmer sin kod

Den som lägger en webbshell eller bakdörr på en server vill att den ska förbli oupptäckt länge. Läsbar kod skulle sticka ut för varje administratör som öppnar filen, och varje skanner skulle hitta den. Därför förpackar angripare sin kod: den kodas, komprimeras och sätts först vid anropet ihop igen och körs.

För PHP2Shell finns inga bekräftade Indicators of Compromise. Förvrängd kod är inget kännetecken för just den här sårbarheten, utan ett allmänt tecken på att någon har smugglat in kod, oavsett på vilken väg. Hur ni överhuvudtaget hittar och tar bort webbshells beskrivs i Känn igen och ta bort webbshells. Det här inlägget koncentrerar sig på frågan hur ni känner igen förvrängd kod.

eval, base64 och liknande: de typiska byggstenarna

Förvrängning följer nästan alltid samma princip: ett oläsligt datablock förvandlas av en eller flera funktioner tillbaka till kod som sedan körs. Byggstenarna nedan dyker upp om och om igen.

Byggsten Exempel Varför den sticker ut
Körning eval, assert med teckensträng (till PHP 7.x), create_function (till PHP 7.x) kör text som kod
Avkodning base64_decode, str_rot13, hex2bin, strrev, convert_uudecode gör data läsbar igen
Dekomprimering gzinflate, gzuncompress, gzdecode packar upp inbäddad kod
Sammansättning chr()-kedjor, sammanfogning av korta delar, \x-escapes döljer funktionsnamn
Dynamiskt anrop variabler som funktionsnamn, call_user_func, array_map med teckensträng anropet syns ingenstans i klartext
Systemåtkomst system, exec, shell_exec, passthru, proc_open, popen kommandon på servern

Enligt PHP-manualen utvärderar assert() sedan PHP 8.0 inte längre teckensträngar som kod, och create_function() togs bort i PHP 8.0. På servrar med äldre PHP-versioner förblir båda relevanta sökbegrepp.

En enskild byggsten är sällan misstänkt, base64_decode använder till exempel många applikationer legitimt. Misstänkt blir kombinationen: en avkodning vars resultat flyter direkt in i en körning.

Sök riskfritt: ofarliga grep-kommandon

Kommandona nedan genomsöker filer bara som text. De kör ingen PHP-kod. Anpassa sökvägen.

# Körning kombinerad med avkodning eller dekomprimering
grep -rlE "(eval|assert)\s*\(\s*(base64_decode|gzinflate|gzuncompress|str_rot13|hex2bin)" /var/www --include="*.php*"

# Mycket långa rader (ofta packad kod)
grep -rlE ".{2000,}" /var/www --include="*.php*"

# Många hex-escapes eller chr()-kedjor på en rad
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*"

# Funktionsanrop via en variabel direkt efter en tilldelning av teckensträngar
grep -rnE "\\\$[a-zA-Z_]+\s*=\s*['\"][a-z_]{4,}['\"]\s*;\s*\\\$[a-zA-Z_]+\s*\(" /var/www --include="*.php*" | head -50

Kontrollera träffar först med ls -l och tidsstämpeln och öppna dem sedan bara som text, till exempel med less. Anropa aldrig misstänkta filer via webbläsaren, för då skulle servern köra dem.

Var förvrängd kod typiskt sitter

Förvrängd kod står sällan i en egen, uppseendeväckande fil. Oftare förs den in i befintliga filer, allra först eller allra sist, ofta efter många tomma rader så att den inte genast fångar blicken vid öppnandet. Omtyckta är filer som laddas vid varje anrop: den centrala index.php, konfigurationsfiler och ett temas funktionsfiler.

En särskilt anonym väg går via konfigurationen. Med inställningen auto_prepend_file laddar PHP en extra fil före varje skript. Står den i en .user.ini eller .htaccess som en angripare har skapat körs hans kod vid varje sidanrop, utan att en enda applikationsfil har ändrats. Den inbundna filen bär gärna en harmlös ändelse som .ico eller .png.

# Laddas extra kod före eller efter varje skript?
grep -rnE "auto_(prepend|append)_file" /var/www --include=".user.ini" --include=".htaccess" --include="*.conf" 2>/dev/null

# PHP-kod i filer med bild- eller ikonändelse
grep -rlE "<\?php" /var/www --include="*.ico" --include="*.png" --include="*.jpg" --include="*.gif" 2>/dev/null

Skilj legitim förvrängning från skadlig kod

Inte all oläslig kod är illasinnad. Tre fall förekommer ofta:

  1. Kommersiella kodare: Vissa plugin- och programtillverkare skyddar sin kod med verktyg som ionCube eller SourceGuardian. Filerna är oläsliga men hänvisar typiskt till den nödvändiga loadern. Stäm av dem mot originalpaketet.
  2. Minifierad eller genererad kod: Cacher och mallmotorer skapar långa rader utan radbrytningar, dock utan att köra avkodad text.
  3. Inbäddade data: Bilder eller typsnitt som Base64-teckensträng i en PHP-fil är ovanligt men ofarligt, så länge resultatet inte körs.

Det mest tillförlitliga testet är avstämningen mot källan: kommer filen oförändrad ur tillverkarens paket är den legitim. Ligger den i inget originalpaket eller avviker från det, hör den hemma i en undersökning.

Viktigt

Försök inte avkoda förvrängd kod på produktionsservern, till exempel genom att byta ut eval mot en utskrift och anropa filen. Redan ett fel därvid kör den skadliga koden. Analysen hör hemma i en isolerad miljö.

Mönstersökningens gränser

Angripare känner till de vanliga sökkommandona. De delar upp funktionsnamn, sätter ihop dem under körning eller flyttar den egentliga koden till databasen, till bildfiler eller till konfigurationsposter. En mönstersökning hittar därför mycket, men inte allt. Varför även skannrar stöter på gränser här förklaras i Skadeprogramsskannrar för webbplatser: vad de hittar och vad de inte hittar.

Ett fynd är dessutom sällan det enda. Angripare använder ofta samma byggsten i flera filer, till exempel en iögonfallande variabelbeteckning eller en framträdande teckenföljd i början av det kodade blocket. Sök därför efter ett bekräftat fynd målinriktat efter just den teckenföljden i hela webbkatalogen, även i andra webbplatser på samma server. Så hittar ni syskon som ingen av de allmänna mönstersökningarna fångade.

Komplettera sökningen med avstämning mot originalfiler och en titt i databasen, se Kontrollera databasen efter insmugglad kod. Förebyggande kan systemfunktioner som inte behövs spärras, som beskrivs i guiden Använd disable_functions rätt.

Hur hjälper PHP SOS konkret?

  • Söka: Vi genomsöker filer och databas med utökade mönster och stämmer av mot originalpaket.
  • Analysera: Vi undersöker misstänkt kod i en isolerad miljö utan att riskera ert system.
  • Sanera: Med skadeprogramborttagningen tar vi bort alla delar och stänger ingångsvägen.
  • Säkra: Vi begränsar PHP-funktioner och skrivrättigheter och övervakar nya eller förändrade filer.

Vanliga frågor

Är eval med base64_decode alltid skadlig kod?

Inte alltid, men mycket ofta. Legitim kod behöver knappast den kombinationen. I filer som inte hör till er applikation eller ett känt plugin är den en stark varningssignal.

Får jag avkoda förvrängd kod för att läsa den?

Bara utan att köra den och inte på produktionsservern. Redan en oavsiktlig körning kan orsaka skada. Låt vid tvivel analysen göras av experter som arbetar med isolerade miljöer.

Varför hittar min skadeprogramsskanner inte koden?

Skannrar söker efter kända mönster. Angripare ändrar hela tiden sin kod, delar upp funktionsnamn eller sätter ihop dem under körning. En tom skanning är därför inget bevis på en ren server.

Hur är det med kommersiellt krypterade plugins?

Vissa tillverkare skyddar sin kod med kodare som ionCube eller SourceGuardian. Sådana filer är oläsliga men legitima om de kommer från tillverkaren. Stäm av dem mot originalpaketet.

Hjälper disable_functions mot förvrängd kod?

Delvis. Funktioner som exec eller system kan spärras, eval däremot inte, eftersom det är en språkkonstruktion och ingen funktion. Spärren försvårar angriparens nästa steg, men förhindrar inte all skadlig kod.

Källor

Direktkontakt

Varje timme räknas. Skriv till oss nu.

Beskriv kort system, PHP-version och observation. Vi hör av oss, klarlägger läget och arbetar på distans tills incidenten är avslutad och dokumenterad.

Direkthjälp