Encoding & Decoding PHP Code

[ Decoding PHP ] There are many ways to encode and decode PHP code. From the perspective of site security, there are three PHP functions — str_rot13(), base64_encode(), and gzinflate — that are frequently used to obfuscate malicious strings of PHP code. For those involved in the securing of websites, understanding how these functions are used to encode and decode encrypted chunks of PHP data is critical to accurate monitoring and expedient attack recovery.

For those already familiar with the concept, but could use a quick reference with examples, I put together a concise summary of this article. The article here is intended as a “behind-the-scenes” look at the decoding and encoding happening on the examples page. Here’s the quick-jump menu:

Encoding and decoding with str_rot13()

As explained in the PHP documentation, str_rot13() is a simple function used for rotating every letter “13 places in the alphabet” while ignoring non-alphanumeric characters. This type of encoding is called ROT13 encoding and it’s very straightforward using the str_rot13() function. Let’s look at an example..

Let’s say we want to ROT13-encode the following string:

<?php $string = 'Encoding and Decoding Encrypted PHP Code'; ?>

We run this string through str_rot13() and set it as a variable named $encoded like so:

<?php $encoded = str_rot13($string); ?>

Echoing the $encoded variable to the browser, we get this string of gibberish:

Rapbqvat naq Qrpbqvat Rapelcgrq CUC Pbqr

To decode a string encoded with str_rot13(), we simply run it back through the function to restore the original string. Here is an example that returns the original string to a variable named $decoded:

$decoded = str_rot13(str_rot13($string))

Echoing $decoded, we see the original string as expected:

Encoding and Decoding Encrypted PHP Code

Copy/paste example (try it for yourself):

<?php // str_rot13() example
$string  = 'Encoding and Decoding Encrypted PHP Code';
$encoded = str_rot13($string);
$decoded = str_rot13(str_rot13($string));
echo $encoded ."\n";
echo $decoded;
?>

Encode and decode with base64_encode() & base64_decode()

Also explained in the PHP documentation, the base64_encode() function “encodes the given data with base64.” Rather than get into the mechanics of encoding with base64, I’ll repeat the enigmatic haiku given in the docs:

This encoding is designed to make binary data survive transport through transport layers that are not 8-bit clean, such as mail bodies.

Ahh, I love taking stuff out of context, but I digress.. Let’s get back on track with a quick example showing how base64_encode() works its magic. Let’s say we want to encode the following string with base64:

<?php $string = 'Encoding and Decoding Encrypted PHP Code'; ?>

We run this string through base64_encode() and set it as a variable named $encoded like so:

<?php $encoded = base64_encode($string); ?>

Echoing the $encoded variable to the browser, we get this string of gibberish:

RW5jb2RpbmcgYW5kIERlY29kaW5nIEVuY3J5cHRlZCBQSFAgQ29kZQ==

As you may count, the base64-encoded string contains around 33% more data than the original. Now to decode a string encoded with base64_encode, we use the converse function, base64_decode. Here is an example that returns the original string to a variable named $decoded:

<?php $decoded = base64_decode(base64_encode($string)); ?>

Echoing $decoded, we see the original string as expected:

Encoding and Decoding Encrypted PHP Code

Copy/paste example (try for yourself):

<?php // base64_encode()/base64_decode() example
$string  = 'Encoding and Decoding Encrypted PHP Code';
$encoded = base64_decode($string);
$decoded = base64_decode(base64_encode($string));
echo $encoded ."\n";
echo $decoded;
?>

Deflate and inflate with gzdeflate() & gzinflate()

A third visit to the PHP docs gives us our third function, gzdeflate() is used to “compress the given string using the DEFLATE data format.” Again, not gonna veer off — let’s stay focused with a quick example.

Let’s say we want to “gzdeflate” the following string:

<?php $string = 'Encoding and Decoding Encrypted PHP Code'; ?>

We run this string through gzdeflate() and set it as a variable named $compressed:

<?php $compressed = gzdeflate($string); ?>

Echoing the $compressed variable to the browser, we get this bizarre-looking gibberish:

s�K�O��KWH�KQpI�r\���* JRS<��SR

To “decode” this alien-speak, we inflate it with the converse function, gzinflate(), to restore the original string. Here is an example that returns the original string to a variable named $uncompressed:

$uncompressed = gzinflate(gzdeflate($string));

Echoing $uncompressed, we see the original string as expected:

Encoding and Decoding Encrypted PHP Code

Copy/paste example:

<?php // gzinflate()/gzdeflate() example
$string       = 'Encoding and Decoding Encrypted PHP Code';
$compressed   = gzdeflate($string);
$uncompressed = gzinflate($compressed);
echo $compressed ."\n";
echo $uncompressed;
?>

Parameters

Also worth mentioning: whereas the first two functions — str_rot13() and base64_encode() — accept only one parameter (the input $string), the inflate/deflate functions accept two parameters. Perhaps surprisingly, these second parameters are different between the two functions:

  • gzdeflate()level = the level of compression (0 to 9)
  • gzinflate()length = the maximum length of data to decode

Returning to our example, let’s employ these second parameters to help visualize:

<?php // example using second parameters
$string       = 'Encoding and Decoding Encrypted PHP Code';
$compressed   = gzdeflate($string, 9); // compression level set to 9 = maximum
$uncompressed = gzinflate($compressed, strlen($string)); // length set to same as $string
echo $compressed ."\n";
echo $uncompressed;
?>

And the result as displayed in a browser:

s�K�O��KWH�KQpI�r\���* JRS<��SR
Encoding and Decoding Encrypted PHP Code

Combined example: gzinflate(str_rot13(base64_decode()))

Malicious scripts often combine multiple encoding methods to further obfuscate data strings. Using the numerous PHP encoding-type functions (and their various parameters), it’s possible to scramble data with many layers of obfuscation. For example, on common technique for encrypting malicious scripts combines all three of the functions described in this article. The structure of such technique looks like this:

$gibberish = eval(gzinflate(str_rot13(base64_decode($string))));

The concept is straightforward, however decoding the $gibberish can be tricky. The easiest way to decode such a string is to use an online decoding tool. And that’s my slick segue into the next section..

Online tools for decoding/encoding PHP code

To further contribute to the cause, I’ve created some online decoding tools to simplify the process. Here are some tools for encoding/decoding with some common PHP functions:

Additional resources

Into this decoding/ecoding stuff? You may also enjoy these fine functions..