张小白的渗透之路(五)——上传漏洞及解析漏洞详解

前言

web应用程序通常会有文件上传的功能,例如在BBS发布图片、在个人网站发布压缩包,只要web应用程序允许上传文件,就有可能存在文件上传漏洞。
上传漏洞与sql注射相比,风险更大,如果web应用程序存在上传漏洞,攻击者甚至可以直接上传一个webshell到服务器上。
那么如何确认web应用程序是否存在上传漏洞呢?比如,我的CSDN博客,由php编写,允许上传头像,但是文件上传时并没有对图片格式做验证,导致用户可以上传任意文件,那么这就是一个上传漏洞。

解析漏洞

攻击者在利用上传漏洞时,通常会与web容器的解析漏洞配合在一起。所以我们首先来了解一下解析漏洞,这样才能更深入地了解上传漏洞,并加以防范。
常见的web容器有IIS、Ngnix、Apache、Tomcat等,下面以Apache容器为例讲解。(IIS6.0也是解析漏洞比较经典的一个容器实例,大家可以自行学习,小白比较喜欢敲命令,不喜欢点来点去找,就没咋研究……)
Apache解析漏洞
在Apache 1.x 和Apache 2.x中存在解析漏洞,但他们与IIS解析漏洞不同。比如,一下就是典型的Apache解析漏洞。(别盯了,看url……)
解析漏洞
可以看到,上图的url中的文件名为1.php.rar,正常情况下,应该会弹出一个文件下载的提示框,但此时却没有,而是显示了phpinfo()的内容,这就是Apache的解析漏洞。1.php.rar的内容如下:

<?php
	phpinfo();
?>

Apache在解析文件时有一个原则:当碰上不认识的扩展名时,将会从后向前解析,直到碰到认识的扩展名为止,如果都不认识,则会暴露其源代码。比如:

1.php.rar.xs.aa

Apache首先会解析aa扩展名,如果不认识,将会解析xs扩展名,这样一直遍历到认识的扩展名为止,然后再将其进行解析。
ps:Apache支持的扩展名可以在Apache的安装目录“/conf/mime.types”文件中有详细的扩展名列表,如下图所示。
文件类型
有些程序开发人员在上传文件的设计时,要判断文件名是否是php、asp、aspx、asa、cer等脚本扩展名,如果是,则不允许上传,这时攻击者就有可能上传1.php.rar等扩展名来绕过程序检测,并配合解析漏洞,获取到webshell。

解析漏洞之PHP CGI解析漏洞
Nginx是一款高性能的web服务器,通常用来作为php的解析容器,Nginx也曾经被曝光过两个“解析漏洞”,比如访问

http://www.litbai.com/1.jpg/1.php

此时的1.php是不存在的,却可以看到1.jpg已经按照php脚本来解析了,问题就出现在这个“1.php”上。这就意味着攻击者可以上传合法的“图片”(图片木马),然后在URL后面加上“/xxx.php”,就可以获得网站的Webshell。
在2008年5月,国内著名的安全团队80SEC发现了此漏洞,,漏洞描述网址为: http://www.80sec.com/nginx-securit-securit.html
但是后来人们却发现,这不是Nginx特有的漏洞,在IIS7.0、IIS7.5、Lighttpd等Web容器中也经常会出现这样的解析漏洞。
后来人们慢慢发现,这种解析漏洞其实是PHP CGI的漏洞。在php的配置文件中有一个关键的选项:cgi.fi:x_pathinfo
这个选项在某些版本中默认是开启的,在开启时访问URL,比如:

http://www.litbai.com/x.txt/x.php

x.php是不存在的文件,所以php将会向前递归解析,于是造成了解析漏洞,可以说此漏洞与Nginx关系并不是很大,但由于Nginx与PHP配合很容易造成这种解析漏洞,所以PHP CGI漏洞经常被认为是Nginx解析漏洞。

绕过上传漏洞

程序员在开发web应用程序时,一般都会涉及文件上传,比如:上传文档并提供下载,上传图片增加客户体验。文件上传的基本流程相同,客户端使用Javascript验证,服务器端采用随机数来重命名文件,以防止文件重复。
程序员在防止上传漏洞时可以分为以下两种。

  • 客户端检测:客户端使用javascript检测,在文件未上传时,就对文件进行验证。
  • 服务器端检测:服务端脚本一般会检测文件的MIME类型,检测文件扩展名是否合法,甚至有些程序员检测文件中是否嵌入恶意代码。
    在研究上传漏洞之前,首先来看两个小工具:中国菜刀和一句话图片木马。
    中国菜刀
    这款软件是用来管理网站文件的,非常小巧灵活,他仅仅需要一段简短的代码就可以方便地管理网站。中国菜刀现已经成为安全研究者手中必备地利器,其官网网站为:http://www,maicaidao.com
    该软件提供地服务器端文件仅有一行代码。目前支持地服务器端脚本包括:PHP、ASP、ASP.NET、JSP等,并且支持HTTPS安全连接地网站。常见的代码如下:
ASP:        
<%eval request("Cknife")%>
 	
ASP.NET:    
<%@ Page Language="Jscript"%><%eval(Request.Item["Cknife"],"unsafe");%>

PHP:        
<?php @eval($_POST['Cknife']);?>

正因为代码短小精悍,所以被黑客称为一句话木马(一句话后门)
<?php @eval($_POST['Cknife']);?>保存为shell.php,上传至PHP主机空间中,配置菜刀进行连接。详情请参阅 https://blog.csdn.net/Litbai_zhang/article/details/82984795

一般对上传漏洞有两种方式:客户端检测和服务器端检测

客户端检测

很多程序员仅仅通过javascript来非法拒绝文件上传。这样验证对一些普通用户防止上传错误还可以,对专业的技术人员来说,这是非常低级的验证。攻击者可以通过非常多的方法来突破客户端验证。下面是一个非常简单的文件上传示例,使用javascript验证。
Upload.html页面使用javascript对文件扩展名验证,如果不是白名单中的扩展名,那么Form表单将不会提交至服务器,代码如下:

  <html>
    <head>
    <title>图片上传<title>
    <script type="text/javascript">
    function 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('文件不合法!!');
    	  		}
    	  	return flag;
    }
    </script>
    </head>
    <body>
    	<form action="upload.php" method="post" onsubmit="checkFile" enctype = "multipart/form-data">
    		<input type="file"  name="file" id="file" /><br/>
    		<input type="submit" value="提交" name="submit"/>
    	</form>
    </body>
</html>

Upload.php用来接受文件,在接收文件后,将文件重命名,然后放到本目录下,如下代码所示:

<?php
	if(isset($_POST["submit"]))
	{
		$name = $_FILES['file']['name'];                       //接收文件名
		$name = md5(data('Y-m-d h:m:s')).strrchr($name,".");   //文件重命名操作,保留原有扩展名
		$size = $_FILES['file']['size'];                       //接收文件大小
		$tmp = $_FILES['file']['tmp_name'];                    //临时路径
		move_uploaded_file($tmp,$name);                        //移动临时文件到当前文件目录
		echo "文件上传成功!path:".$name;
	}
?>

针对客户端验证有非常多的绕过方法(即前端绕过),小白比较喜欢(只会)用burpsuite来抓包实现“中间人攻击”(还有一种是通过调试工具例如Firebug(不过Firebug停更了就没去研究了)直接删除客户端的验证),burpsuit的实现原理是按照正常的流程通过javascript验证,然后在传输中的HTTP层做手脚。简单说一下实现思路,首先把木马文件扩展名改为一张正常图片的扩展名,比如JPG扩展名,在上传时使用Burpsuit拦截上传数据,再将其中的扩展名JPG修改为PHP,就可以绕过客户端验证。
这里需要注意一点:在HTTP协议中有请求头Content-Length,代表实体正文长度,如果此时的filename修改也就意味着实体正文长度增加或者减少了,这时就应该修改Content-Length请求头,如:Content-Length长度为200,把文件流中的filename="xxxxx.jpg"修改为filename=“1.php”。更改后,实体正文少了4个字符,所以需要把Content-Length长度修改为196.如果不修改上传可能会失败。
ps:
强调:任何客户端验证都是不安全的。客户端验证是防止用户输入错误,减少服务器的开销,而服务器端验证才可以真正防御攻击者。

服务器端检测

随着开发人员安全意识的提高,用前端验证攻击行为越来越少,一般放在服务器端做验证。而服务器端验证分为很多种,因为每个程序员的思路不一样,所以过滤的方式也不一样。但主要包含以下几点:白名单与黑名单扩展名过滤、文件类型检测、文件重命名等操作。这样看起来似乎无懈可击,但不要忘记一点,那就是解析漏洞。如果开发人员不考虑解析问题,上传漏洞配合解析漏洞,可以绕过大多数上传验证。
1.白名单与黑名单验证
在上传文件时,大多数程序员会对文件扩展名检测,验证文件扩展名通常有两种方式:白名单与黑名单。(那么简单的两个词就不解释啥意思了)

  1. 假设设置了黑名单,攻击者可以从黑名单中找到web开发人员忽略的扩展名,如:cer
  2. 在windows系统下,如果文件名以".“或者空格作为结尾,系统会自动去除”."与空格,利用此特性也可以绕过黑名单验证。例如上传“asp.”或者“asp_”(该处下划线为空格)扩展名程序,服务器端接收文件后接收文件名后在写文件操作,windows将会自动去除小数点和空格。
    上述例子不难看出,仅靠黑名单过滤是无法防御上传漏洞的,因为未知的风险太多,我们无法预测。
    3.然而白名单拥有比黑名单更好的防御机制。如:$WhiteList=array('rar','jpg','png','gif','mp4','doc');在获取到文件扩展名后对$WhiteList数组里的扩展名迭代判断,如果文件扩展名被命中,程序将认为文件是合法的,否则不允许上传。
    虽然采用白名单的过滤方式可以防御未知风险,但是不能完全依赖白名单,因为白名单并不能完全防御上传漏洞,例如IIS6.0,攻击者把木马文件名改为pentest.asp;1.jpg上传,此时文件为jpg格式,从而可以顺利通过认证,而IIS却会把pentest.asp;1.jpg当作ASP脚本程序来执行,最终攻击者可以绕过白名单的检测,并且执行木马程序。
    所以,白名单机制仅仅是防御上传漏洞的第一步。

2.MIME验证
MIME类型用来设定某种扩展名文件的打开方式,当具有扩展名的文件被访问时,浏览器会自动使用指定的应用程序来打开。如GIF图片MIME为image/gif,CSS文件的MIME类型为text/css。
通过抓包我们可以看到MIME类型一般在Content-Type这一属性中可以看到。

当上传一个php文档(MIME值为application/php)时,假设我们的服务器只允许image/jpeg类型的通过,那么直接上传肯定会失败,我们通过burpsuit将HTTP请求中的Content-Type更改为image/jpeg类型,这样即可通过程序验证。
3.目录验证
在文件上传时,程序通常允许用户将文件放到指定的目录中,然而有些web开发人员为了让代码更“健壮”,通常会做一个操作,如果指定的目录存在,就将文件写入目录中,不存在则先建立目录,然后写入。

文本编辑器上传漏洞

由于小白能力有限,文本编辑器种类又很多,例如CKEditor、Ewebeditor、UEditor、KindEditor、XHeditor等,暂时还没有一 一了解,简单的说一下,这类编辑器的功能是非常类似的,比如都有图片上传、视频上传、远程下载等功能,这类文本编辑器也成为富文本编辑器。使用此类编辑器减少了程序开发的时间,但是却增加了许多安全隐患,比如:使用CKEditor编辑器有10万个网站,如果CKEditor爆出一个Getshell漏洞,那么这10万个网站都因此受到牵连。

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值