PHP not properly checking Params
This is a summary of [Iwaniuk 2011]
PHP 5.3.6 (source) uses two slightly different datastructures to handle metadata on a file upload/multifile upload [RFC 1867]. PHP gates which of these codepaths and datastructures to use based on user controlled input, and it is possible to mangle the datastructure by forcing PHP to shove multifile upload metadata into the datastructure/codepath meant for single file metadata.
(Most of the following occurs in the function:
SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler).)
In rfc1867.c:1177 we have the core of the problem which are calls to snprintf with user controlled data that is given in param (lines 4 and 6 below):
{% highlight c %}
if (is_arr_upload) {
if (abuf) efree(abuf);
abuf = estrndup(param, strlen(param)-array_len);
snprintf(lbuf, llen, "%s_name[%s]", abuf, array_index);
} else {
snprintf(lbuf, llen, "%s_name", param);
}
{% endhighlight %}
In rfc1867.c:1157 PHP does a check which chooses what datastructure and codepath to use for the metadata, based on the user controlled input in param. If param ends with a "]" (ie. "file[]") then PHP selects the codepath for the multifile upload; otherwise PHP treats the upload as a single file upload.
{% highlight c %}
is_arr_upload = (start_arr = strchr(param,'[')) && (param[strlen(param)-1] == ']');
{% endhighlight %}
Here's the PHP code that showcases the vulnerability, slightly modified from the original to help understand what is going on:
{% highlight php %}
copy($_FILES["file"]["tmp_name"]['.$key."],''.rand().'.txt'
"); $src = $_FILES["file"]["tmp_name"][$key]; $dst = ''.rand().'.txt'; print("