Since the thing went public before new PHP version has been released, I present full details of the latest PHP vulnerability I reported - together with some sweet demo exploit. The issue was found with fuzzing being part of my recent file upload research. And I still have some more to show in the future :)
My thanks go to Paweł Goleń who helped analyze the vulnerability.
The PHP Part
The whole issue is tracked as PHP bug #54939, but the website is now down. The exemplary exploit is at pastebin. The nature of the bug is simple. PHP claims to remove the path component from HTTP file upload forms (transferred as MIME multipart/form-data requests), leaving only the file name given by the user agent. This is both for security, and to fix MSIE incompatibility (IE used to send full path like this: c:\WINDOWS\WHATEVER\My_file.txt).
However, in 2008 PHP developers made a off-by-one error, and, as a result, if a name starts with \ or / and has no other (back)slashes, it's left as-is. So, this allows for:
- /autorun.inf (/ will map to C:\ in WINDOWS - the drive where your PHP is run from)
and other interesting file "names" to pass through.
The application part
Of course, what this means is simply that $_FILES[$input_field_name]['name'] will contain unsanitized file path - and that's not enough to complete an exploit. PHP script would need to use that filename as a destination for file writing. Unfortunately, at least a few applications do. I've found some pretty interesting examples. Among them is this AjaxFileUpload plugin. There are more applications with the same approach - just go on looking! AjaxFileUpload simply passes the given file "name" to move_uploaded_file(), which would try to create/overwrite a file in a root directory...
The set up part
And that will most likely fail, because of insufficient permissions. Who on Earth would allow PHP to write to root? Well, default Apache installation on Windows systems is run as a SYSTEM user (a.k.a root). Also, for some shared hostings PHP is run in a chroot-ed environment, and / is the document root of a website (which allows for an easy site defacement). It's tricky, I agree, that's why this bug is v. difficult to exploit in the wild (luckily).
But it's possible!
- WAMP server, newest version (PHP 5.3.5), default install
- PHP <= 5.3.6, (5.3.5 in the demo)
- Windows XP
- AjaxFileUpload - A jQuery plugin that simulates asynchronous file uploads.
In the exploit I simply show that (thanks to vulnerable set up) I can overwrite c:\boot.ini and make the system unbootable. There are more advanced scenarios that could be done (essentially I can supply a boot record file to use on next boot), but it's not my area of expertise. To upload a file, the HTML5 arbitrary file upload technique was used.
So, patch your PHPs and bye!