Nasty bug with very simple exploit hits PHP just in time for the weekend


One example, WatchTowr noted, occurs when queries are parsed and sent through a command line. The result: a harmless request such as http://host/cgi.php?foo=bar could be converted into php.exe cgi.php foo=bar, a command that would be executed by the main PHP engine.

No escape

Like many other languages, PHP converts certain types of user input to prevent it from being interpreted as a command for execution. This is a process known as escaping. For example, in HTML, the < and > characters are often escaped by converting them into their unicode hex value equivalents < and > to prevent them from being interpreted as HTML tags by a browser.

The WatchTowr researchers demonstrate how Best Fit fails to escape characters such as a soft hyphen (with unicode value 0xAD) and instead converts it to an unescaped regular hyphen (0x2D), a character that’s instrumental in many code syntaxes.

The researchers went on to explain:

It turns out that, as part of unicode processing, PHP will apply what’s known as a ‘best fit’ mapping, and helpfully assume that, when the user entered a soft hyphen, they actually intended to type a real hyphen, and interpret it as such. Herein lies our vulnerability—if we supply a CGI handler with a soft hyphen (0xAD), the CGI handler won’t feel the need to escape it, and will pass it to PHP. PHP, however, will interpret it as if it were a real hyphen, which allows an attacker to sneak extra command line arguments, which begin with hyphens, into the PHP process.

This is remarkably similar to an older PHP bug (when in CGI mode), CVE-2012-1823, and so we can borrow some exploitation techniques developed for this older bug and adapt them to work with our new bug. A helpful writeup advises that, to translate our injection into RCE, we should aim to inject the following arguments:

-d allow_url_include=1 -d auto_prepend_file=php://input

This will accept input from our HTTP request body, and process it using PHP. Straightforward enough – let’s try a version of this equipped with our 0xAD ‘soft hyphen’ instead of the usual hyphen. Maybe it’s enough to slip through the escaping?

POST /test.php?%ADd+allow_url_include%3d1+%ADd+auto_prepend_file%3dphp://input HTTP/1.1
Host: {{host}}
User-Agent: curl/8.3.0
Accept: */*
Content-Length: 23
Content-Type: application/x-www-form-urlencoded
Connection: keep-alive


 

Oh joy—we’re rewarded with a phpinfo page, showing us we have indeed achieved RCE.

The vulnerability was discovered by Devcore researcher Orange Tsai, who said: “The bug is incredibly simple, but that’s also what makes it interesting.”

Scroll to Top