PHP Remote Code Execution 0-Day Discovered in Real World CTF Exercise

We all know that Capture the Flag (CTF) tasks are synthetic. They are designed as games or puzzles for security professionals to solve in order to hone, demonstrate, and add skills.  It’s like merging chess, a maze, and a physically challenging 10K obstacle course, but for security aficionados.

“Computer security represents a challenge to education due to its interdisciplinary nature… Attack-oriented CTF competitions try to distill the essence of many aspects of professional computer security work into a single short exercise that is objectively measurable. The focus areas that CTF competitions tend to measure are vulnerability discovery, exploit creation, toolkit creation, and operational tradecraft.”

Trail of Bits on GitHub

Participating in CTF is often like playing jeopardy: it can be as much about getting into the mind of the puzzle’s creator as about the security issue itself. By going on the journey, you know something deeper about the terrain and reasoning of the cartographer. 

Luckily, security researchers who play CTF are not one of the contrived elements of CTF tasks. As a result, during many attempts to solve CTF exercises, researchers find security issues that are not at all a part of the original game, something never expected by authors—including 0days. Imagine a race where the contestant finds a better path than the course cartographer, navigating around a particularly nasty area of jungle, and finds a hidden trove of secret knowledge. 

Unpredicted PHP Vulnerability Found

Our story started at an hCorem Capture the Flag task, Realworld CTF, that took place from September 14th to 16th, 2019. Wallarm security researcher, Andrew Danau, stumbled upon an unusual PHP script behavior while solving a CTF task.

When Andrew Danau sent %0a (newline) byte in the URL, the server response was peculiar.  It returns back more data than should be there. And, the amount of extra data was related to the number of bytes after %0a inside the URL. Usually, that sort of response is related to memory corruption attacks and we expected to see an attack on the type of information disclosure. Information disclosure is bad enough as it can result in leaking sensitive or financial data. Even worse, from time to time, although quite rarely such behavior can indicate a remote code execution vulnerability.

Andrew had not found the solution to the CTF game designer planned. His original thinking allowed him to find a new course, that leads to unforeseen, valuable discoveries. Following the trail from the unusual behavior, Andrew’s  CTF fellow players, Emil and Omar, decided to drill down into the issue and exploit it. They were able to understand the reason for the unusual behavior, find an exploitation path, and make a relevant exploit to cause Remote Code Execution. 

Here are the resulting fixes in the PHP code.

The reason for this issue is under the hood of the Nginx+fastcgi bundle, in particular, in a fastcgi_split_path directive and a regexp tricks with newlines. Because of %0a character, Nginx will set an empty value to this variable, and fastcgi+PHP will not expect this. 

Because of some black magic spells with hash tables that Emil cast, it was possible to put arbitrary FastCGI variables, like PHP_VALUE. I wanna highly recommend you to educate yourself by learning how Emil did that (exploit is here: https://github.com/neex/phuip-fpizdam/) , just because this exploit as awesome. If you want, the entry point is here:

https://github.com/php/php-src/blob/master/sapi/fpm/fpm/fpm_main.c#L1142

What this all means is that it’s possible to call arbitrary PHP code—in this case of using “fastcgi_split_path” directive in the Nginx configuration file configured to process any user data, like URL. 

On further investigation, we found more than 6K these examples at GitHub: 

https://github.com/search?q=fastcgi_split_path&type=Code

Mitigation of PHP Issue

Andrew’s CTF discovery captured more than a flag. It captured a view of an unpredicted area of vulnerability that was outside the scope of the game designer. We were then able to test our own solutions, like Wallarm Cloud Native WAF, and confirmed that Wallarm automatically detects this issue. Good to know that Wallarm customers are already protected.

Wallarm’s 3rd generation detection approach works particularly well because of the binary nature of this issue. The specific RegExp approach discovered in the CTF exercise would yield a lot of false positives when detecting this issue.

That said, even if you are using an inexpensive solution, like ModSecurity, you can substantially mitigate the issue by filtering %0a/%0d bytes in URLs. A simple mod_security rule could look like this:

SecRule REQUEST_URI "@rx %0(a|d)" "id:1,phase:1,t:lowercase,deny"

However, if you have a legacy WAF and apply this rule, there will likely be a high false-positive level as a result. The high false-positive level is pretty common for the RegEx-expression based first generation WAFs.

Without patching, this issue may become a dangerous entry point into your web applications, most of which run on PHP infrastructure.  To check if your systems might be vulnerable, you can simply execute the following bash command. It can identify vulnerable FastCGI directive in your Nginx configs:

egrep -Rin --color 'fastcgi_split_path' /etc/nginx/

If you found similar lines, you need to apply virtual patch until an official PHP security update.

Conclusion

There is sometimes a huge positive that comes from thinking off-course, or rather being a pioneer of new courses for solving shared challenges. In this case, Wallarm’s Andrew Danau was able to contribute to the community; making the web applications space more secure, with an opportune accidental discovery of a PHP zero-day vulnerability that the CTF designer or anybody in the community knew nothing about. PHP powers many modern websites, including popular web platforms like WordPress and Drupal. While the team that maintains PHP is diligent, quickly patching newly found vulnerabilities such as this one and an earlier RCE, described in CVE-2019-13224, is important. For additional information on recent critical PHP vulnerabilities, see the earlier blog post.r DevOps engineers need to be diligent with regular updates and application-level protection.

Learn more in Recent Discoveries Reveal High-Risk PHP Vulnerabilities.

1 Response

Leave a Reply

Show Buttons
Hide Buttons