The vulnerability exists in php-fpm because of missing bounds check in fpm_main.c. If the FastCGI variable PATH_INFO
is empty, the underflow happens when the code tries to calculate the value of the path_info
variable. An invalid pointer in path_info
leads to a single byte out-of-bounds write, which can be leveraged to code execution.
The php-fpm allows anyone who can connect to its’ port to execute code, so an RCE in php-fpm is not interesting by itself. However, this particular issue can be exploited even by a user who has access to the HTTP server (which is Nginx typically). In certain Nginx configurations, it is possible to make it send empty PATH_INFO
value by breaking regexp in fastcgi_split_pathinfo
directive using an encoded newline character (%0a
).
The issue was reported to PHP maintainers in the bug 78599 and assigned CVE-2019-11043. It was disclosed on October 22.
The exploit for the issue is available at https://github.com/neex/phuip-fpizdam/.
To reproduce the issue, follow the steps at the “Playground environment” section in the exploit’s README. The repo contains a Dockerfile, which builds the version of PHP just before the fix.
Exploit works only when Nginx config allows to trigger the bug (that is, to send empty PATH_INFO
FastCGI variable). The full list of preconditions can be found at the exploit repository. There are real world examples of big projects empoying such configuration, see e.g. https://twitter.com/chybeta/status/1187213401124036608 (this particular issue is already reported to the corresponding bug bounty program and they hardened the Nginx config).
As the vulnerability resides in php-fpm, not Nginx, there might be other ways to trigger the vulnerability when other HTTP server software is used. However, I’m not aware of any at this moment.
If the attack is successful, the attacker can execute code at the server that runs php-fpm with the privileges of the php-fpm process. Again, note that the attacker doesn’t have access to the php-fpm socket, she only makes HTTP requests to the nginx.