PHP Obfuscation techniques

Obfuscation is being used to prevent code from being easily readable, though it still can be executed. Often these techniques are being used in copy-protected or evil scripts.

Ddecode.com is a site where you can upload (partial) script to try to automatically de-obfuscate the script. Often this will succeed, other cases it will fail.

An example of an obfuscated script:

eval(gzinflate(base64_decode(strrev(str_rot13('=RDe1Za8XXAI1A9vlESqYAcHlB5FXFIqmeVI1RwNzYoIC78FEmZmA9ZFlEwZZyplZ3RYgbRHIO7IBalH')))));  

This script is using strrot13 to rotate the characters by 13, reverse the whole string, base64decode and followed by gzinflate. Next it will be evaluated by eval.

$so = "XXX@gmail.com";
mail($so,$subject,$msg,$from);  

Some of the techniques are used multiple times, the eval will eval another obfuscated script.

De-obfuscation can be done on several ways:

  • parsing and interpreting the script using a library, for example using parser the python php parser: https://github.com/ramen/phply
  • altering the php executable so that dangerous functions will be harmless, then you can safely eval the code. You need to be very certain that he the php executable is safe to execute. Don't forget these scripts are often evil.
  • using online script decoders like ddecode.com

The following techniques are frequently being used for executing obfuscated scripts.

From the PHP documentation:

mixed eval ( string $code ) Evaluates the given code as PHP.

string gzinflate ( string $data [, int $length = 0 ] ) This function inflates a deflated string.

string base64_decode ( string $data [, bool $strict = false ] ) Decodes a base64 encoded data.

string strrev ( string $string ) Returns string, reversed.

string str_rot13 ( string $str ) Performs the ROT13 encoding on the str argument and returns the resulting string.

The ROT13 encoding simply shifts every letter by 13 places in the alphabet while leaving non-alpha characters untouched. Encoding and decoding are done by the same function, passing an encoded string as argument will return the original version.

string rawurldecode ( string $str ) Returns a string in which the sequences with percent (%) signs followed by two hex digits have been replaced with literal characters.

mixed preg_replace ( mixed $pattern , mixed $replacement , mixed $subject [, int $limit = -1 [, int &$count ]] ) Searches subject for matches to pattern and replaces them with replacement.

string gzdecode ( string $data [, int $length ] ) This function returns a decoded version of the input data.

string gzuncompress ( string $data [, int $length = 0 ] )This function uncompress a compressed string.

string zlibdecode ( string $data [, string $maxdecoded_len ] ) Uncompress any raw/gzip/zlib encoded data.


References
http://ddecode.com/phpdecoder/
http://nl3.php.net/manual/en/function.gzrewind.php