Web安全-文件上传漏洞与WAF绕过 1

举报
ruogu994 发表于 2024/01/18 20:41:03 2024/01/18
【摘要】 概述文件上传漏洞是指网络攻击者上传了一个可执行的文件到服务器并执行。这里上传的文件可以是木马,病毒,恶意脚本或者 WebShell 等。这种攻击方式是最为直接和有效的,部分文件上传漏洞的利用技术门槛非常的低,对于攻击者来说很容易实施。文件上传漏洞本身就是一个危害巨大的漏洞,WebShell 更是将这种漏洞的利用无限扩大。大多数的上传漏洞被利用后攻击者都会留下 WebShell 以方便后续进...

概述

文件上传漏洞是指网络攻击者上传了一个可执行的文件到服务器并执行。这里上传的文件可以是木马,病毒,恶意脚本或者 WebShell 等。这种攻击方式是最为直接和有效的,部分文件上传漏洞的利用技术门槛非常的低,对于攻击者来说很容易实施。

文件上传漏洞本身就是一个危害巨大的漏洞,WebShell 更是将这种漏洞的利用无限扩大。大多数的上传漏洞被利用后攻击者都会留下 WebShell 以方便后续进入系统。攻击者在受影响系统放置或者插入 WebShell 后,可通过该 WebShell更 轻松,更隐蔽的在服务中为所欲为。这里需要特别说明的是上传漏洞的利用经常会使用 WebShell,而 WebShell 的植入远不止文件上传这一种方式。

Webshell简述

WebShell 就是以 asp、php、jsp 或者 cgi 等网页文件形式存在的一种命令执行环境,也可以将其称之为一种网页后门。攻击者在入侵了一个网站后,通常会将这些 asp 或 php 后门文件与网站服务器 web 目录下正常的网页文件混在一起,然后使用浏览器来访问这些后门,得到一个命令执行环境,以达到控制网站服务器的目的(可以上传下载或者修改文件,操作数据库,执行任意命令等)。

WebShell 后门隐蔽较性高,可以轻松穿越防火墙,访问 WebShell 时不会留下系统日志,只会在网站的 web 日志中留下一些数据提交记录,没有经验的管理员不容易发现入侵痕迹。攻击者可以将 WebShell 隐藏在正常文件中并修改文件时间增强隐蔽性,也可以采用一些函数对 WebShell 进行编码或者拼接以规避检测。除此之外,通过一句话木马的小马来提交功能更强大的大马可以更容易通过应用本身的检测,<?php eval($_POST[a]); ?>就是一个最常见最原始的小马。

上传漏洞原理

大部分的网站和应用系统都有上传功能,一些文件上传功能实现代码没有严格限制用户上传的文件后缀以及文件类型,导致允许攻击者向某个可通过 Web 访问的目录上传任意 PHP 文件,并能够将这些文件传递给 PHP 解释器,就可以在远程服务器上执行任意PHP脚本。

当系统存在文件上传漏洞时攻击者可以将病毒,木马,WebShell,其他恶意脚本或者是包含了脚本的图片上传到服务器,这些文件将对攻击者后续攻击提供便利。根据具体漏洞的差异,此处上传的脚本可以是正常后缀的 PHP,ASP以及JSP 脚本,也可以是篡改后缀后的这几类脚本。

上传文件是病毒或者木马时,主要用于诱骗用户或者管理员下载执行或者直接自动运行;

  1. 上传文件是WebShell时,攻击者可通过这些网页后门执行命令并控制服务器;
  2. 上传文件是其他恶意脚本时,攻击者可直接执行脚本进行攻击;
  3. 上传文件是恶意图片时,图片中可能包含了脚本,加载或者点击这些图片时脚本会悄无声息的执行;

上传文件是伪装成正常后缀的恶意脚本时,攻击者可借助本地文件包含漏洞 (Local File Include) 执行该文件。如将 bad.php 文件改名为 bad.doc 上传到服务器,再通过 PHP 的 include,include_once,require,require_once 等函数包含执行。

此处造成恶意文件上传的原因主要有三种:

1、文件上传时检查不严
没有进行文件格式检查。
一些应用仅仅在客户端进行了检查,而在专业的攻击者眼里几乎所有的客户端检查都等于没有检查,攻击者可以通过NC,Fiddler等断点上传工具轻松绕过客户端的检查;
一些应用虽然在服务器端进行了黑名单检查,但是却可能忽略了大小写,如将.php改为.Php即可绕过检查;
一些应用虽然在服务器端进行了白名单检查却忽略了%00截断符,如应用本来只允许上传jpg图片,那么可以构造文件名为xxx.php%00.jpg,其中%00为十六进制的0x00字符,.jpg骗过了应用的上传文件类型检测,但对于服务器来说,因为%00字符截断的关系,最终上传的文件变成了xxx.php。
2、文件上传后修改文件名时处理不当
一些应用在服务器端进行了完整的黑名单和白名单过滤,在修改已上传文件文件名时却百密一疏,允许用户修改文件后缀。如应用只能上传.doc文件时攻击者可以先将.php文件后缀修改为.doc,成功上传后在修改文件名时将后缀改回.php。
3、使用第三方插件时引入
好多应用都引用了带有文件上传功能的第三方插件,这些插件的文件上传功能实现上可能有漏洞,攻击者可通过这些漏洞进行文件上传攻击。如著名的博客平台 WordPress 就有丰富的插件,而这些插件中每年都会被挖掘出大量的文件上传漏洞。

上传漏洞绕过

程序员在防止上传漏洞时可以分为两种:

  1. 客户端检测: 客户端使用JavaScript检测,在文件未上传时,就对文件进行验证。
  2. 服务器端检测: 服务端脚本一般会检测文件的MIME类型,检测文件扩展名是否合法,甚至是否嵌入恶意代码等。

"中国菜刀":仅需要一段简短的代码便可以管理网站。目前支持的服务器端脚本包括: php、ASP、ASP.NET、JSP等,并且支持HTPTPS安全连接的网站。

PHP: <?php @eval($_POST['mima']);?>
ASP: <%eval request("mima")%>
ASP.NET <%@ Page Language="Jscript"%><%eval(Request.Item["mima"],"unsafe");%>

"图片一句话" 是将一句话插入在图片里面。例如: Edjpgcom 这个软件只需要将图片拖入程序中,在填写一句话,就可以制作图片一句话木马。

解析漏洞

解析漏洞: 攻击者利用上传漏洞时,通常与web容器的解析漏洞配合在一起。常见的 web 容器有 IIS、Nginx、Apache、Tomcat 等。

IIS 6.0解析漏洞

IIS 6.0在解析文件时存在以下两个解析漏洞:

  • 当建立*.asa,*.asp格式的文件夹,其目录下的任意文件都将被IIS当作asp文件解析。例如,建立文件夹parsing.asp,在里面新建一个test.txt。其内容为 <%=NOW()%>。其内容被IIS当作asp脚本来解析。

  • 当文件为*.asp;1.jpg时。同样会以asp脚本执行。原理:服务器默认不解析;号后面的内容,因此xx.asp;.jpg便被解析成asp文件了。

IIS 6.0 默认的可执行文件除了asp还包含这三种 :

  • /test.asa
  • /test.cer
  • /test.cdx

Apache解析漏洞

(1)漏洞原理

Apache 解析文件的规则:从右到左开始判断解析,如果后缀名为不可识别文件解析,就再往左判断,直到碰到认识的扩展名为止。如果都不认识,会暴漏源码。

比如test.php.qwe.asd 中 “.qwe”和”.asd” 这两种后缀是apache不可识别解析,apache就会把wooyun.php.qwe.asd解析成php。

(2)漏洞形式
www.xxxx.xxx.com/test.php.php123
再例如:www.xxser.com/1.php.rar(文件内容为下列代码)
<?php phpinfo();?>
上述的文件名为1.php.rar,本应弹出下载文件的提示,但却显示了phpinfo()的内容。这就是apache的解析漏洞。

(3)其余配置问题导致漏洞

1.如果在 Apache 的 conf 里有这样一行配置 AddHandler php5-script .php
这时只要文件名里包含.php 即使文件名是 test2.php.jpg 也会以 php 来执行。
2.如果在 Apache 的 conf 里有这样一行配置 AddType application/x-httpd-php .jpg
即使扩展名是 jpg,一样能以php 方式执行。

Nginx解析漏洞

Nginx是一款高性能的Web服务器,通常作为PHP的解析容器它,曾被爆出两个解析漏洞。
http://www.xxser.com/1.jpg/1.php
此时的 1.jpg 会被当作PHP脚本来解析。此时的 1.php 是不存在的,但 1.jpg 却按照 php 脚本解析了。问题就在这个 “1.php” 中( 1.php 不是特定的,可以随意命名),这就意味着攻击者可以上传图片木马,然后在url加上/xxx.php 就可以获得网站的 Webshell。

Windows文件命名

上传不符合 Windows 文件命名规则的文件名:

  • test.asp.
  • test.asp(空格)
  • test.php:1.jpg
  • test.php:: $DATA

客户端检测绕过

很多程序员仅通过JavaScript拒绝非法上传,是十分低级的验证。例如下列代码对文件扩展名进行验证,如果不是白名单中的扩展名将不会提交到服务器。

<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>
 
		<from 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['files']['size'];                       //接收文件大小
		$tmp=$_FILES['file']['tmp_name'];                     //临时路径
		move_upload_file($tmp,$name);                         //移动临时文件到当前文件目录
		echo "文件上传成功 path:".$name;
	}	
?>

针对客户端验证有非常多的绕过方式:

更改前端JS代码

1、修改脚本JS,将自定义的文件类型后缀添加进去:

  • 这里不知道为什么图片上传不了

2 、—删除对js验证脚本的调用,使其不能对上传的文件类型做检测,从而达到绕过。同样的通过审查元素,查看到form表单的内容,form的开始标签为<form enctype="multipart/form-data" method="post" onsubmit="return checkFile()">,其中的onsubmit="return checkFile()"的作用就是当点击上传按钮的时候,就会触发js验证脚本,所以将这一部分删除,就可以成功绕过检测:

Burp中间人攻击

这种方式与FireBug完全不同,它是使用Burp按照正常的流程通过JavaScript验证,然后在传输中的HTTP层做手脚。首先把木马文件扩展名改为一张正常的图片的扩展名。在上传时使用Burp拦截数据,将其中的扩展名改为php,就可以绕过客户端验证。
这里需要注意: 在HTTP协议中有请求头 Content-Length,代表实体正文长度,而修改filename意为着实体长度的改变。如: Content-Length长度为200.把文件中的 filename=“xxser.jpg” 修改为 “1.php”,实体正文少了4个字符。所以需要把 Content-Length 改为196。

今天先更这么点,下期继续,不早了,各位师傅晚安

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。