Threat Advisory: PHP-CGI At Your Command
For a long time, PHP has been the dominant server side framework for companies to write their web applications with. In fact, ~82% of all websites today are written in PHP. And while PHP’s power by numbers creates an appetite with security researchers to look for flaws leading to maturity, documentation, and security best practices– the numbers drive hackers to focus on it as well.
On October 2013, a public exploit in PHP was disclosed. The exploit uses a vulnerability found in May 2012 and was categorized as CVE-2012-1823. The exploit suggests that PHP, in conjunction with Apache, suffers from command injection vulnerability.
Soon after the exploit was released, Imperva honeypots detected web servers being attacked with this exploit in different flavors. In the three first weeks following the publication we were able to record as many as 30,000 attack campaigns using the exploit. As this was an interesting surge in attack activity, we decided to look deeper into the attack.
Later on, we picked up intelligence showing that different botnets have picked up the vulnerability per its effectiveness, and have also captured samples of bot clients that have embedded this vulnerability exploitation in them.
One of the interesting points is that despite the fact that this vulnerability is somewhat dated, cybercriminals are still using it, understanding that a major part of the install base of PHP does not update on a regular basis – thus creating the window of opportunity.
In this threat advisory, we will cover the following:
- The technical background and analysis of the vulnerability and exploitation techniques
- Samples of the attack vectors captured in the wild
- Industrialized cybercrime aspects of this vulnerability
- Mitigation techniques
A first look into the vulnerability
The vulnerability first appeared in the different vulnerability databases on 10-29-2013, and was identified with the CVE code 2012-1823. The exploitation code was soon available via different exploit websites
The vulnerability enables a remote attacker to execute arbitrary commands on a web server with PHP versions 5.4.x, 5.3.x before 5.4.2 or 5.3.12. These versions account for 16% of all public websites in the Internet.
The honeypot trail…
After having analyzed the attacks recorded by our honeypot, we learned few interesting facts:
- The overall count of attackers (different source IP) was 324 while the overall count of targeted web server was 272. Most of the attacks originated from the US (35%), France (21%) and Germany (15%).
- The most common URL used in the attacks was by far //cgi-bin/php (chart 1). Later on we will explain why the attack requires the exact location of the PHP CGI executable in order to succeed.
- The biggest attacks in terms of volume were carried out in half a day or a day period.
- The vast majority of the attackers (86 different attackers IPs) executed their attack in half a day or a one day period attacking a single target. As the attack period and the number of targets grew bigger, the number of attackers dropped significantly.
Technical Background and Analysis
The vulnerability official (and somewhat confusing) description is:
The simple, straightforward explanation is that an external attacker can set command line options for the PHP execution engine. Such command line options eventually allow the attacker to execute arbitrary PHP code on the server.
You might scratch your head and ask – haven’t we seen this before? The answer is YES! This vulnerability is not new and had previous public exploits published.
In previous cases, the attack relied on the server configuration to redirect all PHP files to PHP CGI and thus making it vulnerable to code leakage, code execution and more. The new attack however, tries to access the PHP CGI directly and hence must use the exact location of the PHP CGI executable.
Before we move on, it is essential to understand what PHP CGI is and how it works. Common Gateway Interface (CGI) is a standard method used to generate dynamic content on web pages and web applications. PHP CGI means using the PHP interpreter through CGI mode. The web server will pass the data from the request to PHP (an external program); its input is a PHP file (usually on the server) and its output is HTML code (usually rendered in the client’s browser). PHP CGI configuration is set via PHP INI directives files.
The vulnerability allows remote attackers to place PHP command line options in the query string, including the “-d” option. This option defines PHP INI directive before running the PHPinterpreter. In this attack, the “-d” option is used to manipulate PHP security settings in order to bypass security checks and allow remote code execution.
Looking at sapi/cgi/cgi_main.c file from the vulnerable PHP code tree, we can find out which directives are used for the security checks:
The code indicates two PHP CGI settings – cgi.force_redirect and cgi.redirect_status_env
PHP configuration directive cgi.force_redirect prevents anyone from calling PHP directly with a URL. Since PHP turns this directive on by default, a direct access to PHP via http://example.com/cgi-bin/php will produce HTTP error code and the following error message
The PHP CGI cannot be accessed directly. This PHP CGI binary was compiled with force-cgi-redirect enabled. This means that a page will only be served up if the REDIRECT_STATUS CGI variable is set, e.g. via an Apache Action directive.
Controlling cgi.force_redirectand cgi.redirect_status_env values enables the attacker to bypass PHP CGI security check.
Another crucial directive that is set using the “-d” option in the attack is auto_prepend_file.This directive specifies the name of a file that is automatically parsed before the main file; php://input isa read-only stream which in our case is the raw data from the request body.
By setting auto_prepend_file to php://input the payload of the attack (arbitrary PHP code) is introduced in the request body.
Attack vectors captured in the wild
Let’s take a look at an example attack vector that was captured in the wild
Which is translated to –
Not surprisingly, in the example attack vector above, the HTTP request body contained PHP code that downloaded and installed a botnet malware client –
We have managed to identify 43 different types of payload data in the attacks registered in our honeypot. The payloads appear to be botnet malware client constructed in the following pattern:
The PHP payload is designed to download a malware executable file from a remote server to an unsuspicious directory (/tmp, /dev/shm, /var/lock, /var/tmp), run it and hide it ever existed by removing it from the file system. The servers that host these files are usually legit, however compromised, servers and the file names are disguised as image files or text files.
The malware files are usually written in PHP, Python or C and vary from simple reverse shell backdoors, to IRC clients that connect to C&C servers. We also notice that some malwares have different functionality according to the kernel versions and the processor architecture of the infected server.
Our experience shows that this level of sophistication is linked with industrialized crime, also known as bot herding. The attackers in this case, scan for servers that are exposed to the vulnerability (using PHP CGI from vulnerable versions) to infect them with their bot clients, thus transforming them into zombies which receive commands from a C&C server under their control. These botnets are then sold or rented to the highest bidder.
A surprising fact is that even today, this vulnerability can be used successfully as companies don’t take the appropriate measures to secure their servers. Evidence to this fact can be found in active drop down sites that are still hosting the botnet clients, as shown in the following example:
Some of the botnets that we have been looking into are still active, some of them are relatively new and activity can be witnessed with commands being sent to their zombie servers that operate under their control.
It is a very intriguing point to show that cybercriminals understand the serious gap that exists between the time that a vulnerability is found in the wild, to the time it gets reported and patched (if third party software/framework is in the loop, such as PHP). Finally, there is a time lag until a company becomes aware of both the issues and the fix – and implements it. This creates a window of opportunity for hackers to act on, as they know that the window will be open for a long time.
PHP offers a patch (here) to mitigate the vulnerability. The code snippet below shows that PHP added a verification to ensure that the query string does not include command line options.
- Verify your PHP version is not vulnerable (i.e., PHP 5.3.12 and up, PHP 5.4.2 and up); if you still use a vulnerable PHP version, make sure it is patched
- If it is possible, do not use PHP in CGI mode
- Place your web application behind a web application security solution (such as a WAF) to protect it from web attacks such as this one