【Web安全】之文件上传漏洞

一、文件上传漏洞介绍

Web应用程序通常带有文件上传的功能,比如在博客园发表文章需要上传图片等行为,这其中就可能存在文件上传漏洞。

如果Web应用程序存在上传漏洞,攻击者可以直接上传WebShell(以asp、php或者jsp等网页文件形式存在的一种命令执行环境,也可以将其称做为一种网页后门)到服务器上。

二、解析漏洞

攻击者在利用上传漏洞时,通常会与Web容器的解析漏洞配合在一起。

常见的Web容器有IIS、Nginx、Apache、Tomcat。

1. IIS解析漏洞(基于IIS6.0环境)

(1)当建立*.asa*.asp格式的文件夹时,其目录下的任意文件都将被IIS当做asp文件来解析。

测试案例:建立文件夹parsing.asp,在文件夹内新建内容为<%=NOW()%>的文本文件test.txt,然后在浏览器里访问。

测试结论:NOW()是ASP获取当前时间的函数。正常而言,IIS是不会去解析文本文档格式而是直接显示内容。而在parsing.asp文件夹内,却被当做ASP脚本来解析。

(2)当文件为*.asp;1.jpg时,IIS同样会以ASP脚本执行。

测试案例:创建文件名为test.asp;1.jpg,其内容为<%=NOW()%>

(3)WebDav漏洞

WebDav是一种基于HTTP1.1协议的通信协议。在GET、POST、HEAD等HTTP标准方法之外扩展了新方法。

攻击者可以通过PUT方法向服务器上传危险脚本。

2. Apache解析漏洞(基于Apache 1.xApache 2.x环境)

(1)Apache漏洞介绍:

我们在Apache环境中设置文件内容为<?php phpinfo(); ?>1.php.aa文件,在正常情况下,应该会提示下载该文件,但是在此情况下却显示了phpinfo()的内容。

(2)Apache在解析文件名的原理:

当遇到不认识的扩展名,将会从后向前解析,直到碰到认识的扩展名。例如文件名为1.php.aa,首先解析aa扩展名,发现不认识继续向前面遍历。

(3)Apache可识别扩展名(在/conf/mime.types文件中有详细列表)

(4)对于Apache解析漏洞的防范:

在开发设计上传文件程序时,应设置判断是否为PHP、ASP、ASPX以及在(3)中提到的扩展名的函数,如果函数返回Fasle则禁止上传。

3. PHP CGI(Nginx)解析漏洞

(1)漏洞介绍

我们在Nginx环境下布置一个1.jpg文件,并用文本编辑器写入<?php echo "hello world"; ?>。通常情况而言,我们打开URL:http://127.0.0.1:80/1.jpg 显示为一张无法识别的图片,但是利用Nginx解析漏洞,我们打开URL:http://127.0.0.1:80/1.jpg/1.php (1.php是虚构、不存在的文件)时,却将文件1.jpg识别为一个php文件。


(2)漏洞解析

在PHP的配置文件中有一个选项:cgi.fix_pathinfo=True,在访问URL时,当Nginx服务器遇到1.php是不存在的文件时,便会向前遍历解析。

如下图在php7.3.4版本中,cgi.fix_pathinfo默认是开启的。

三、绕过上传漏洞

使用Web应用中,很多场景都要使用文件上传。文件上传的流程为客户端使用JavaScript验证与服务器端采用随机数命名文件。因此在客户端利用JavaScript在文件未上传的时候就对文件进行验证,服务器端检测上传文件的MIME类型、检测文件扩展名是否合法、是否嵌入恶意代码。

任何客户端验证都是不安全的。客户端验证是防止用户错误输入,减少服务器开销而已。

1. 客户端检测

下面通过对Upload.html中JavaScript源代码分析来突破客户端验证。

<html>
<head>
  <title>Pic Upload</title>
  <script type="text.javascript">
  		funtion checkFile(){
  			var flag=false;
  			var str=document.getElementById("file").value;
  			str=str.substring(str.lastIndexOf('.')+1);
  			var arr=new Array('png','bmp','gif','jpg'); 
  			for(var i=0;i<arr.length;i++){
  				if(str=arr[i]){
  					flag=true;
  				}
  			}
  			if(!flag)
  				alert('file invalid');
  			}
  			return flag;
  		}
  </script>
  </head>
  <body>
    <form action="upload.php" method="post" onsubmit=“ checkFile ”
          enctype="multpart/form-data">
      		<input type="file" name="file" id="file" /><br/>
     			<input type="submit" value="Submit" name="submit" />     
    </form>
  </body>
</html>

由源代码得知客户端JavaScript仅针对png,bmp,gif,jpg四种进行文件上传,那么攻击者就可以将文件名伪装成这些类型上传。

(1)使用Firebug

Firebug介绍:

  1. 是网页浏览器 Mozilla Firefox 下的一款开发类扩展,它集HTML查看和编辑、Javascript控制台、网络状况监视器于一体,是开发JavaScript、CSS、HTML和Ajax的得力助手。

  2. Firebug从各个不同的角度剖析Web页面内部的细节层面,给Web开发者带来很大的便利。

  3. Firebug也是一个除错工具。用户可以利用它除错、编辑、甚至删改任何网站的 CSS、HTMLDOM 以及JavaScript 代码。

Firebug安装

在Upload.html中单击Submit按钮,Form表单将会触发onsubmit时间从而调用checkFile()函数,通过检验扩展名是否合法从而允许文件是否可以上传至服务器。Firebug将onsubmit事件删除,因此所有类型的文件扩展名都可以绕过JavaScript函数checkfile()验证。

(2)中间人攻击

机制与(1)中的Firebug完全不同,中间人攻击在传输中的HTTP层做手脚。可以简单地理解为上传1.jpg文件通过JavaScript函数的验证,再使用抓包工具(Burp Suite)将文件名修改后缀为php。

注意:HTTP请求头部Content-Length参数(实体正文长度),需要根据文件名长度的改动进行相应的修改。

2. 服务器端检测

服务器端验证主要包含白名单与黑名单扩展名过滤、文件类型检测、文件重命名等操作。如果将上传漏洞配合解析漏洞就可以绕过大多数上传验证。

(1)白名单与黑名单验证

黑名单过滤:定义一系列不安全的扩展名,在服务器端收到文件后匹对扩展名。

<?php
	$Blacklist = array('asp','php','jsp','php5','asa','aspx');#危险函数黑名单
	if(isset($_POST["submit"])){
		$name = $_FILES['file']['name'];
		$extension = substr(strrchr($name, "."), 1);
		$boo = false;
		foreach($Blacklist as $key => $value) {
			if ($value==$extension){
				$boo = true;
				break;
			}
		}
		if($boo){
			echo "file invalid";
		}
	}
?>

黑名单过滤的缺点:

  1. 攻击者可以从黑名单中找到Web开发者忽略的扩展名
  2. 没有进行大小写转换,诸如.PHP扩展名不在黑名单里,依旧会被服务器接收
  3. windows系统下,如果文件名以"."或空格结尾会自动取出。asp.转化为asp

白名单过滤:

与黑名单过滤相反,白名单只允许已定义过的扩展名,比黑名单有更好的防御机制。

<?php
	$Whitelist = array('jpg','jpge','bmp','gif','png');#白名单允许函数
	if(isset($_POST["submit"])){
		$name = $_FILES['file']['name'];
		$extension = substr(strrchr($name, "."), 1);
		$boo = true;
		foreach($Blacklist as $key => $value) {
			if ($value==$extension){
				$boo = false;
				break;
			}
		}
		if(!$boo){
			echo "file invalid";
		}
	}
?>

白名单过滤的缺点:

白名单并不能完全防御上传漏洞。在IIS解析漏洞章节中,我们介绍过当文件名为*.asp;1.jpg时,白名单过滤机制识别文件扩展名为.jpg,即验证通过可以上传。但是在IIS解析漏洞中,此文件会被当做asp脚本程序来执行。

(2)MIME验证

MIMIE类型用来设定某种扩展名文件的打开方式。

if($_FILES['file']['type']==" image/jpeg"){
	$imageTempName=$_FILES['file']['tmp_name'];
	$imageName=$_FILES['file']['name'];
	$last=substr($imageName, strrpos($imageName,"."));
	if(!is_dir("uploadFile")){
		mkdir("uploadFile");
	}
	$imageName=md5($imageName).$last;
	move_uploaded_file($imageName, "./uploadFile/".$imageName;
	echo("Success");
}else{
	echo("Fail");
	exit();
}

上传php文件时,我们使用抓包工具(Burp Suite)查看其MIME类型,可以发现php文件的MIME类型为application/php,无法通过验证。因此可以将Content-Type修改成image/jpeg类型,即可通过验证。

(3)目录验证

简介:在文件上传时,允许用户将文件放到指定的目录中,如果不存在指定目录,就会先创建目录再将文件放入。

攻击手段:HTML代码中有一个隐藏标签<input type="hidden" name="Extension" value="up"/>,这是文件上传默认的文件夹,我们可以将参数value的值就可以达到目的。结合IIS解析漏洞(当建立*.asa*.asp格式的文件夹时,其目录下的任意文件都将被IIS当做asp文件来解析),就可以将恶意代码写入。

(4)截断上传攻击

此方法通常适用于ASP程序。

//ASP代码
<%
username = request("username")
Response.write username
%>
//将请求输入的username输出

截断上传攻击指的是%00将后面的字符都截断,当我们上传文件名为1.asp x.jpg时,然后将空格的十六进制数20改成00,因此文件名为1.asp%00x.jpg,即符合截断上传攻击原型,最终将上传1.asp文件。

四、文件编辑器上传漏洞

(1)敏感信息暴露

部分文本编辑器的文件目录存在一些敏感文件,将敏感信息直接暴露在攻击者前。

(2)黑名单策略错误

部分文本编辑器采用的是黑名单机制,基于上述黑名单策略的缺点,攻击者仍可以找到另外的危险脚本。

(3)任意文件上传漏洞

五、修复上传漏洞的策略

文件上传漏洞产生的原因主要是:

  1. 目录过滤不严,攻击者可能建立畸形目录
  2. 文件未重命名,攻击者可能利用Web容器解析漏洞

经过学习,设计如下代码可预防上述攻击。

<?php
  if(!isset($_POST['submit'])){
    exit();
  }
  $arr = Array('jpg','gif','jpeg','png','rar','zip','doc'); //设置白名单
  $imageTempName=$_FILES['file']['temp_name'] //将文件放在临时路径,防止解析漏洞发生
  $imageName=$_FILES['file']['name'];
  $last=strtolower(substr($imageName, strrpos($imageName,'.')+1)); //获取文件扩展名并全部转换成小写
  if(!in_array($last,$arr)){
    exit('extension name invalid .$last ...'); //当扩展名不在白名单内,立即退出程序。
  }
	$Extension=$_POST['Extension']; //确认扩展名安全方可获取文件上传目录
  $imageName = md5($imageName).".".$last; //对文件重命名,防止利用解析漏洞
  move_uploaded_file($imageTempName, "./$Extension/".$imageName);
  echo("Success!");
}
  1. 接收文件将其存放在文件临时路径,即便存在解析漏洞也不能获取有效信息。
  2. 将扩展名与白名单对照,不符合的情况下直接退出程序。
  3. 对文件重命名方式诸如test.asp;1.jpg文件名绕过白名单却利用解析漏洞实施攻击。
posted @ 2020-03-01 21:06  imPlanck  阅读(2391)  评论(0编辑  收藏  举报