码迷,mamicode.com
首页 > Web开发 > 详细

owasp文件上传漏洞简析

时间:2015-07-21 01:02:16      阅读:336      评论:0      收藏:0      [点我收藏+]

标签:

0x01:

文件上传漏洞起因于,上传程序没有对上传文件格式进行正确判断,导致可执行程序上传到网站目录。

常见的验证上传文件有两种:1.js本地验证,通过js获取上传文件后缀名,并和白名单比较,匹配则上传成功。由于js代码是本地验证,存在绕过风险(去除js代码,构造表单数据,直接绕过)。

2.后端程序验证,通过post数据到file_upload()函数,$_FILES[‘file‘][‘type‘]判断上传程序后缀名.

function file_upload(){

  $file_name = $_FILES[‘file‘][‘name‘];

  $file_type = $_FILES[‘file‘][‘type‘];

  $file_tmp = $_FILES[‘file‘][‘tmp_name‘]; //临时文件存放位置

  //判断文件后缀

 问题1. if($file_type === ‘image/jpg‘ || $file_type === ‘image/jpeg‘){ //jpg和jpeg类型,详见wiki  

 问题2.     $file_new_type = ‘.jpg‘;

    }

 问题4.      $file_name = substr(md5(time()),0,10);

   move_uploaded_file($file_tmp,$file_name.$file_type) ;

}

关于PHP处理文件流,详见w3chool php file

问题1.$file_type获取文件后缀名,正常上传jpg时,$file_type =‘image/jpg‘ 文件格式,上传php文件时,$file_type =‘application/octet-stream‘(任意二进制流)。这里的image/jpg,application/octet-stream属于MIME(Multipurpose Internet Mail Extensions),在浏览器里上传抓包时,有个content-type:image/jpg,值得就是header里MIME类型(问题3).

通过获取$file_type里的值,和白名单(image/jpg,image/jpeg)比较,如果值相同,说明后缀名是jpg(不考虑问题3)。

问题3(MIME头欺骗).既然获取MIME里的文件类型和白名单比较,通过修改数据包中Content-type:image/jpg(修改MIME类型),上传文件。

上传a.php,burpsuite截断数据包,修改content-type:application/octet-stream => image/jpg,然后转发。这时,$file_type=‘image/jpg‘,本来上传的php文件,获取的文件类型为二进制流,现在修改MIME后变成image/jpg。如果直接用$file_type作为文件的后缀名,就会造成a.php文件直接存储到网站目录中,造成getshell。

问题2.获取MIME类型为image/jpg,并不代表无法解决MIME欺骗问题,这里采用文件重命名,$file_type = jpg,那么$file_new_type = ‘.jpg‘;通过拼接文件名,即使上传的php文件,最后存储到网站目录里的也是jpg文件类型。

0x02:

文件上传漏洞产生来源于过滤不严,很多人采用strpos($str,‘.‘)这种方式截取文件后缀名,然后就出现了xx.php;.jpg之类的畸形文件名(问题4)。最简单防护方式就是直接重命名文件名(全部),可能有人觉得问题2里,写多个判断语句会很麻烦,代码能安全一点,多写点不费事。

swicth($file_type){

  case ‘image/jpg‘:

  $file_new_type =‘.jpg‘;break;

  case ‘image/jpeg‘:

  $file_new_type =‘.jpeg‘;break;

  ....

  default:

  $file_new_type = false;  

}

这里获取文件后缀名之后,重命名文件,有人担心,含有一句话代码的图片存储到网站里,不用考虑上传的是什么文件,当程序判断文件属于白名单里的后缀时,直接使用白名单里后缀写法,这样即使这个文件含有一句话,但服务器会把它当作图片处理,并不会执行里的代码(问题5)

文件名重命名一般采用:upload/时间/时间种子的MD5.后缀名

具体代码:

$file_save_directory = ‘upload‘.date(‘Y-m-d‘,time()); //命名存储文件夹名

if(!file_exists($file_save_directory)){

  mkdir($file_save_directory); //如果不存在 创建文件夹

}

$file_new_name = substr(md5(time()),0,10).$file_new_type; //重命名文件名字

$result = move_uploaded_file($file_tmp,$file_save_directory.‘/‘.$file_new_name);

if($result){echo "upload success"} 

0x03

php上传文件漏洞已经有很多年历史了,大牛前几天发出了个CVE-2006-7243的php空字符处理问题(webshell.cc),由于php处理a.php\x00.jpg时,会保存成a.php文件,导致畸形文件名的php文件能上传成功,有兴趣的可以搭环境测试下。

文件上传的同时伴随着文件名解析漏洞。IIS/Apache/Nginx,对畸形文件名处理错误,导致a.php;jpg/a.php .jpg(0x00截断)上传成功并解析

参考:wooyun php安全编码 

 http://zone.wooyun.org/content/1910 php上传缺陷

 

owasp文件上传漏洞简析

标签:

原文地址:http://www.cnblogs.com/developd/p/4662992.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!