CVE-2012-1172:PHP Corrupted $_FILES indices lead to security concern


发布人:admin分类:网络安全浏览量:874发布时间:2017-12-12

by flyh4t@hotmail.com

前几天提到CVE-2012-1172这个漏洞,今天来把分析过程写下。
其实PHP在处理文件上传的时候,曾经发生过多个类似的漏洞,我们先列举几个:

2004年:PHP处理RFC1867 MIME格式导致数组错误漏洞
http://www.nsfocus.net/index.php?act=ma … w&mid=2368

2009年:PHP Bug #49683:$_FILES overwrite
https://bugs.php.net/bug.php?id=49683

2011年:File path injection in PHP  5.3.6 file upload (CVE 2011-2202)
http://blog.kotowicz.net/2011/06/file-p … -file.html

CVE-2012-1172实际上和上面的漏洞比较相似,我们先看poc

 
 

我们同时上传一个jpg文件和一个txt文件,返回结果如下:

Array
 (
 [file] => Array
 (
 [name] => Array
 (
 [[type] => text/plain
 [[name] => test.txt
 [[tmp_name] => C:\Windows\Temp\phpAFF2.tmp
 [[error] => 0
 [[size] => 5231
 )

[type] => Array
 (
 [[type] => image/jpeg
 )

[tmp_name] => Array
 (
 [[type] => C:\Windows\Temp\phpAFE1.tmp
 )

[error] => Array
 (
 [[type] => 0
 )

[size] => Array
 (
 [[type] => 5145
 )

明显的处理异常发生了变量覆盖的情况,因为如果是正常的文件上传,应该是返回类似如下结果的数组

Array
 (
 [file] => Array
 (
 [name] => Array
 (
 [type] => 11.jpg
 [name] => test.txt
 )

[type] => Array
 (
 [type] => image/jpeg
 [name] => text/plain
 )

[tmp_name] => Array
 (
 [type] => C:\Windows\Temp\phpD4C7.tmp
 [name] => C:\Windows\Temp\phpD4C8.tmp
 )

[error] => Array
 (
 [type] => 0
 [name] => 0
 )

[size] => Array
 (
 [type] => 5145
 [name] => 5231
 )

)

)

下面我们来分析下漏洞是怎么产生的。查看文件 rfc1867.c中对于是否为合法上传的判断:

992 if (!skip_upload) {
 993 char *tmp = param;
 994 long c = 0;
 995
 996 while (*tmp) {
 997 if (*tmp == ‘[') {
 998 c++;
 999 } else if (*tmp == ']‘) {
 1000 c–;
 1001 if (tmp[1] && tmp[1] != ‘[') {
 1002 skip_upload = 1;
 1003 break;
 1004 }
 1005 }
 1006 if (c < 0) {
 1007 skip_upload = 1;
 1008 break;
 1009 }
 1010 tmp++;
 1011 }
 1012 }

这地方没有考虑到c>0的可能,也就是说我们提交的变量名称中允许出现[比]数量多的情况,比如可以为file[[type]或者file[name][的形式。正是由于这两种格式的变量处理不当才导致了变量覆盖的问题。继续看代码:

1146 /* is_arr_upload is true when name of file upload field
    1147 * ends in [.*]
    1148 * start_arr is set to point to 1st [ */
    1149 is_arr_upload = (start_arr = strchr(param,'[')) && (param[strlen(param)-1] == ‘]’);

这个地方判断是否为批量上传的比较关键,需要以]结尾的才认为是批量上传,具体来说file[[type]可以使is_arr_upload为1而 file[name][则使is_arr_upload为0,之后处理的方式完全不同

   1151 if (is_arr_upload) {
    1152 array_len = strlen(start_arr);
    1153 if (array_index) {
    1154 efree(array_index);
    1155 }
    1156 array_index = estrndup(start_arr + 1, array_len - 2);
    1157 }
 ……

1225 /* Add $foo[name] */
    1226 if (is_arr_upload) {
    1227 snprintf(lbuf, llen, “%s[name][%s]“, abuf, array_index);
    1228 } else {
    1229 snprintf(lbuf, llen, “%s[name]“, param);
    1230 }

……

1260 /* Add $foo[type] */
    1261 if (is_arr_upload) {
    1262 snprintf(lbuf, llen, “%s[type][%s]“, abuf, array_index);
    1263 } else {
    1264 snprintf(lbuf, llen, “%s[type]“, param);
    1265 }

file[[type]按照is_arr_upload为1的方式处理,产生的变量依次为file[name][[type]和
file[type][[type]。

file[name][按照is_arr_upload为0的方式处理,产生的变量依次为 file[name][[name]和
file[name][[type]。

按照注册的顺序,后者会覆盖前者产生的相同的变量。

漏洞分析就到这里,具体在实战中的运用还要看应用的代码,在一定条件下是可以下载文件或者上传非法文件的。

官方修复的方式也比较简单

— main/rfc1867.c 2012/01/01 23:51:21 321663
 +++ main/rfc1867.c 2012/01/01 23:54:25 321664
 @@ -942,6 +942,10 @@
 }
 tmp++;
 }
 +    /* Brackets should always be closed */
 +    if(c != 0) {
 +     skip_upload = 1;
 +    }
 }

参考:

https://nealpoole.com/blog/2011/10/dire … e-uploads/

http://lxr.php.net/opengrok/xref/PHP_5_2/main/rfc1867.c

转自:http://bbs.wolvez.org/viewtopic.php?id=267


被黑站点统计 - 文章版权1、本主题所有言论和图片纯属会员个人意见,与本文章立场无关
2、本站所有主题由该文章作者发表,该文章作者与被黑站点统计享有文章相关版权
3、其他单位或个人使用、转载或引用本文时必须同时征得该文章作者和被黑站点统计的同意
4、文章作者须承担一切因本文发表而直接或间接导致的民事或刑事法律责任
5、本帖部分内容转载自其它媒体,但并不代表本站赞同其观点和对其真实性负责
6、如本帖侵犯到任何版权问题,请立即告知本站,本站将及时予与删除并致以最深的歉意
7、被黑站点统计管理员有权不事先通知发贴者而删除本文

免责声明

本站主要通过网络搜集国内被黑网站信息,统计分析数据,为部署安全型网络提供强有力的依据.本站所有工作人员均不参与黑站,挂马或赢利性行为,所有数据均为网民提供,提交者不一定是黑站人,所有提交采取不记名,先提交先审核的方式,如有任何疑问请及时与我们联系.

admin  的文章


微信公众号

微信公众号


Copyright © 2012-2022被黑网站统计系统All Rights Reserved
页面总访问量:17061361(PV) 页面执行时间:59.947(MS)