PHP-FPM/Nginx Vulnerability – CVE-2019-11043

Reading Time: 3 minutes

A new vulnerability in PHP-FPM has been noted which could lead to remote code execution on nginx. An earlier message on Twitter exposed the CVE-2019-11043 bug:

Freshly patched RCE in PHP-FPM
Exploit
Many nginx+PHP configurations vulnerable, watch out!— BECHED (@ahack_ru) October 22, 2019

According to Tenable:

CVE-2019-11043 is an env_path_info underflow flaw in PHP-FPM’s fpm_main.c. The vulnerability was first reported to the PHP bug-tracker by security researcher Emil Lerner on September 26, 2019.

On October 24, PHP 7.3.11 (current stable) and PHP 7.2.24 (old stable) were released to address this vulnerability along with other scheduled bug fixes. Those using nginx with PHP-FPM are encouraged to upgrade to a patched version as soon as possible.

According to Lerner, under certain configurations where a web server is using nginx and PHP-FPM, the vulnerability can be exploited to gain remote code execution. These configurations require a certain set of preconditions in order for it to be exploitable.

These preconditions include:
* The nginx location directive forwards requests to PHP-FPM
* The fastcgi_split_path_info directive is present and includes a regular expression beginning with a ‘^’ symbol and ending with a ‘$’ symbol
* The fastcgi_param directive is used to assign the PATH_INFO variable

There are no checks in place to determine whether or not a file exists (e.g., using try_files or an if statement) but it appears such configurations and preconditions are not uncommon.

https://lqwb.us/33ZvifR

It was also pointed out that on line 1140 in the file sapi/fpm/fpm/fpm_main.c contained pointer arithmetic that assumed that env_path_info has a prefix equal to the path to the php script. However, the code does not check to see if this assumption is satisfied. The absence of this check can lead to an invalid pointer in the "path_info" variable. Such conditions can be achieved in a standard Nginx configuration. If there is an Nginx config setup like this:

```
   location ~ [^/]\.php(/|$) {
        fastcgi_split_path_info ^(.+?\.php)(/.*)$;
        fastcgi_param PATH_INFO       $fastcgi_path_info;
        fastcgi_pass   php:9000;
        ...
  }
}
```

The regexp in the

fastcgi_split_path_info
directive can be broken using the newline character (in encoded form, %0a). This broken regexp leads to an empty PATH_INFO, setting which triggers the bug. This issue leads to the remote code execution.

Later in the code, the value of path_info[0] is set to zero; then FCGI_PUTENV is called.

Using a carefully chosen length in the URL path and query string, an attacker can make path_info point precisely to the first byte of the _fcgi_data_seg structure.

Putting a zero into it moves the

char* pos
field backward, and following FCGI_PUTENV overwrites some data (including other fast cgi variables) with the script path. Using this technique, a researcher could create a fake PHP_VALUE FCGI variable and then use a chain of carefully chosen config values to get code execution.

Test Script

To reproduce the issue, take the following steps:

  1. Build php with --enable-fpm and ASAN enabled.
  2. Download the file https://www.dropbox.com/s/eio9zikkg1juuj7/reproducer.tar.xz?dl=0. (The following steps assume you're in the reproducerdirectory from the archive.)
  3. Run nginx using sudo /usr/sbin/nginx -p $PWD -c nginx.conf
  4. Run php-fpm using path/to/php-fpm -y ./php-fpm.conf -F
  5. Visit a (pretty long) link from the crash_link.txt using another tool, like curl $(cat crash_link.txt).

Expected Result

No crash should happen.

Actual Result

You will get a crash. Here is the output error:

==6629==ERROR: AddressSanitizer: SEGV on unknown address 0x620000005203 (pc 0x7efd1341a47f bp 0x7ffe980574e0 sp 0x7ffe98056c98 T0)
==6629==The signal is caused by a WRITE memory access.
    #0 0x7efd1341a47e in memcpy /build/glibc-OTsEL5/glibc-2.27/string/../sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S:140
    #1 0x4b7c57 in __asan_memcpy /home/emil/llvm/projects/compiler-rt/lib/asan/asan_interceptors_memintrinsics.cpp:22:3
    #2 0x13a88df in fcgi_hash_strndup /home/emil/php-src/main/fastcgi.c:322:2
    #3 0x13a88df in fcgi_hash_set /home/emil/php-src/main/fastcgi.c:359:11
    #4 0x13c4121 in init_request_info /home/emil/php-src/sapi/fpm/fpm/fpm_main.c:1154:12
    #5 0x13c4121 in main /home/emil/php-src/sapi/fpm/fpm/fpm_main.c:1864:4
    #6 0x7efd13380b96 in __libc_start_main /build/glibc-OTsEL5/glibc-2.27/csu/../csu/libc-start.c:310
    #7 0x440219 in _start (/home/emil/php-src/builded/sbin/php-fpm+0x440219)
AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /build/glibc-OTsEL5/glibc-2.27/string/../sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S:140 in memcpy

Patch/Fix

Current Stable PHP 7.3.11 & Old Stable PHP 7.2.24 have been released to address this issue. Please update PHP as soon as possible. For further information, please visit this link.

Learn More!

Having a patched system is a priority when trying to upgrade to the latest version of PHP or nginx, especially when issues like this occur. Still have questions, concerns or issues with upgrading? Allow our Level 3 system administrators to assist in resolving this issue for you.

Avatar for David Singer

About the Author: David Singer

I am a g33k, Linux blogger, developer, student, and former Tech Writer for Liquidweb.com. My passion for all things tech drives my hunt for all the coolz. I often need a vacation after I get back from vacation....

Latest Articles

Blocking IP or whitelisting IP addresses with UFW

Read Article

CentOS Linux 7 end of life migrations

Read Article

Use ChatGPT to diagnose and resolve server issues

Read Article

What is SDDC VMware?

Read Article

Best authentication practices for email senders

Read Article