In the first part of this article series we showed you a simple form of php malware: the base64 encoded eval. Today we'll have a look at some other form of malicious piece of PHP code.
Escaped characters (hex codes etc.)
In PHP you have different possibilities of assigning strings to a variable. The simplest and obviously most harmless form is $var = "My simple string";
.
It wouldn't be hard finding something like $var = "base64_decode('xxxxxx')"; eval($var);
would it?
But what about this:
$var = "b\141s".chr(101)."6\x34".chr(95)."de\x63o".chr(100)."e('xxxxxx')"; $var2 = "e\166a".chr(108); $var2($var);
It does exactly the same thing: executing the base64_encoded string 'xxxxxx'. To explain this a bit further, we have to look into the way PHP interprets code inside double quotes. The \ character introduces a special character, so \x tells PHP that a hex code will follow (\x63 is the character with hex code 63, i. e. "c"). Same applies for numeric (octal) character codes like \141 (i. e. "a"). This way you can obfuscate strings making it harder to recognize malicious content at first sight.
Real world malware madness
Let's have a look at an excerpt of a sample file:
<?php $GLOBALS['j4a274a2d'];global$j4a274a2d;$j4a274a2d=$GLOBALS;$j4a274a2d['m3b8d95']="\x73\x24\x42\x69\x9\x4c\xa\x2b\x63\x6f\x2a\x48\x55\x21\x25\x70\x68\x62\x65\x74\x3b\x45\x54\x79\x60\x47\x27\x20\x37\x43\x7c\x4d\x2c\x5f\xd\x4e\x6d\x66\x6e\x51\x75\x26\x7d\x6a\x40\x49\x2d\x72\x57\x67\x5a\x76\x3e\x29\x38\x3c\x32\x64\x56\x78\x59\x7b\x34\x53\x2e\x6c\x23\x4b\x4f\x33\x77\x52\x6b\x2f\x3a\x28\x3f\x31\x36\x41\x50\x3d\x7e\x46\x22\x5e\x4a\x61\x7a\x35\x5b\x71\x44\x58\x30\x5c\x39\x5d";$j4a274a2d[$j4a274a2d['m3b8d95'][59].$j4a274a2d['m3b8d95'][96].$j4a274a2d['m3b8d95'][57].$j4a274a2d['m3b8d95'][54].$j4a274a2d['m3b8d95'][87]]=$j4a274a2d['m3b8d95'][8].$j4a274a2d['m3b8d95'][16].$j4a274a2d['m3b8d95'][47];$j4a274a2d[$j4a274a2d['m3b8d95'][16].$j4a274a2d['m3b8d95'][28].$j4a274a2d['m3b8d95'][18].$j4a274a2d['m3b8d95'][57].$j4a274a2d['m3b8d95'][78].$j4a274a2d['m3b8d95'][8].$j4a274a2d['m3b8d95'][37]]=$j4a274a2d['m3b8d95'][9].$j4a274a2d['m3b8d95'][47]. … … …
Looks really suspicious, right? And here's what it does. The hex codes that are stored in the random variable $j4a274a2d['m3b8d95'] equals the following string:
s$Bi L
NmfnQu&}j@I-rWgZv>)8<2dVxY{4S.l#KO3wRk/:(?16AP=~F"^Jaz5[qDX0\9]
So what? Now the script constructs it's contents from the characters of this string:
$j4a274a2d[$j4a274a2d['m3b8d95'][59].$j4a274a2d['m3b8d95'][96].$j4a274a2d['m3b8d95'][57].$j4a274a2d['m3b8d95'][54].$j4a274a2d['m3b8d95'][87]]=$j4a274a2d['m3b8d95'][8].$j4a274a2d['m3b8d95'][16].$j4a274a2d['m3b8d95'][47];
Once decoded, this wound be:
$j4a274a2d['x9d8a'] = 'chr';
Get the point? The script constructs several new variables containing 'chr', 'base64_decode', 'eval', 'str_rot13' etc. from the string and combines them afterwards to execute any code it likes to.
Watch out for PHP code containing lots of escaped characters!
Marius Burkard has been working as a software developer for 20 years and has several years of experience as a server administrator. As one of the lead developers of the ISPConfig control panel and technical contact for several hundred web hosting customers, he has extensive experience with malware, hacked websites and the analysis of vulnerabilities.