目录

  • 1 前端JS检测与绕过
  • 2 实验简介
  • 2.1 实验目的
  • 2.2 实验环境
  • 2.3 实验前准备
  • 3 实验过程
  • 3.1 方法一:删除JS直接上传
  • 3.2 方法二:绕过JS后修改数据
  • 3 总结


1 前端JS检测与绕过

  1. 概述:JS 检测绕过上传漏洞常见于用户选择文件上传的场景,如果上传文件的后缀不被允许,则会弹框告知,此时上传文件的数据包并没有发送到服务端,只是在客户端浏览器使用JavaScript对数据包进行检测。
  2. 绕过方法:
  • 方法一:JS代码是在前端浏览器上执行的,如果页面JS代码被删除,则无法起到检测功能。
  • 方法二:首先把需要上传文件的后缀改成允许上传的,如jpg、 png等, 绕过JS的检测后再抓包 ,把后缀名改成可执行文件的后缀即可上传成功。

2 实验简介

2.1 实验目的

掌握两种绕过JS检测的方法,验证文件上传漏洞的存在。

2.2 实验环境

  1. 靶场:基于WAMP环境的upload-labs靶场,搭建过程可参考文章《基于WAMP环境的upload-labs漏洞测试平台搭建过程》。
  2. 攻击机:安装BurpSuite软件。

2.3 实验前准备

  1. 准备好一个文件,该文件可能是木马,也可能是其他任意文件,本实验以php探针作为测试文件,来验证是否存在文件上传漏洞以及绕过漏洞检测的方法。
  2. 文件名为:info.php,文件内容:<?php phpinfo();?>

3 实验过程

3.1 方法一:删除JS直接上传

  1. 在客户端打开浏览器,输入网址访问靶场,进入第一关。点击浏览选择刚刚准备得探针文件。
  2. 当我们点击上传时,弹出错误提示说文件类型不对。
  3. 检测有可能发生在前端到后端服务器的整个流程中,此处我们先查看一波网页源代码。我们发现在52~56行是我们提交文件数据的表单,其中有个以onsubmit事件,其值为checkFile(),这是一个自定义函数,定义内容位于83~101行。该函数定义了一个后缀名的白名单,满足白名单后缀名的文件即可通过。
<html>
<head>
	<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
	<link rel="icon" type="image/x-icon" href="/upload-labs/img/favicon.png" />  
	<title>upload-labs</title>
</head>
<link rel="stylesheet" type="text/css" href="/upload-labs/css/index.css">
<link rel="stylesheet" type="text/css" href="/upload-labs/css/prism.css">
<body>
	<div id="head">
		<a href="/upload-labs/"><img src="/upload-labs/img/logo.png"/></a>
		<div id="head_menu">
			<a id="handle_code" href="javascript:show_code()">显示源码</a>
			<a href="javascript:get_prompt()">查看提示</a>
			<a href="javascript:clean_upload_file()">清空上传文件</a>
		</div>
	</div>
	<div id="main"><div id="menu">     
	<ul id="menulist">         
		<li><a id="Pass-01" href="/upload-labs/Pass-01/index.php">Pass-01</a></li> 
		<li><a id="Pass-02" href="/upload-labs/Pass-02/index.php">Pass-02</a></li> 
		<li><a id="Pass-03" href="/upload-labs/Pass-03/index.php">Pass-03</a></li> 
		<li><a id="Pass-04" href="/upload-labs/Pass-04/index.php">Pass-04</a></li> 
		<li><a id="Pass-05" href="/upload-labs/Pass-05/index.php">Pass-05</a></li> 
		<li><a id="Pass-06" href="/upload-labs/Pass-06/index.php">Pass-06</a></li> 
		<li><a id="Pass-07" href="/upload-labs/Pass-07/index.php">Pass-07</a></li> 
		<li><a id="Pass-08" href="/upload-labs/Pass-08/index.php">Pass-08</a></li> 
		<li><a id="Pass-09" href="/upload-labs/Pass-09/index.php">Pass-09</a></li> 
		<li><a id="Pass-10" href="/upload-labs/Pass-10/index.php">Pass-10</a></li> 
		<li><a id="Pass-11" href="/upload-labs/Pass-11/index.php">Pass-11</a></li> 
		<li><a id="Pass-12" href="/upload-labs/Pass-12/index.php">Pass-12</a></li> 
		<li><a id="Pass-13" href="/upload-labs/Pass-13/index.php">Pass-13</a></li> 
		<li><a id="Pass-14" href="/upload-labs/Pass-14/index.php">Pass-14</a></li> 
		<li><a id="Pass-15" href="/upload-labs/Pass-15/index.php">Pass-15</a></li> 
		<li><a id="Pass-16" href="/upload-labs/Pass-16/index.php">Pass-16</a></li> 
		<li><a id="Pass-17" href="/upload-labs/Pass-17/index.php">Pass-17</a></li> 
		<li><a id="Pass-18" href="/upload-labs/Pass-18/index.php">Pass-18</a></li> 
		<li><a id="Pass-19" href="/upload-labs/Pass-19/index.php">Pass-19</a></li>
		<li><a id="Pass-20" href="/upload-labs/Pass-20/index.php">Pass-20</a></li>
        <li><a id="Pass-21" href="/upload-labs/Pass-21/index.php">Pass-21</a></li>
	</ul> 
</div>

<div id="upload_panel">
    <ol>
        <li>
            <h3>任务</h3>
            <p>上传一个<code>webshell</code>到服务器。</p>
        </li>
        <li>
            <h3>上传区</h3>
            <form enctype="multipart/form-data" method="post" onsubmit="return checkFile()">
                <p>请选择要上传的图片:<p>
                <input class="input_file" type="file" name="upload_file"/>
                <input class="button" type="submit" name="submit" value="上传"/>
            </form>
            <div id="msg">
                            </div>
            <div id="img">
                            </div>
        </li>
	    	</ol>
</div>

</div>
		<div id="footer">
			<center>Copyright @ <span id="copyright_time"></span> by <a href="http://gv7.me" target="_bank">c0ny1</a></center>
		</div>
		<div class="mask"></div>
		<div class="dialog">
		    <div class="dialog-title">提 示<a href="javascript:void(0)" class="close" title="关闭">关闭</a></div>
		    <div class="dialog-content"></div>
		</div>		
</body>
<script type="text/javascript" src="/upload-labs/js/jquery.min.js"></script>
<script type="text/javascript" src="/upload-labs/js/prism.js"></script>
<script type="text/javascript" src="/upload-labs/js/prism-line-numbers.min.js"></script>
<script type="text/javascript" src="/upload-labs/js/prism-php.min.js"></script>
<script type="text/javascript" src="/upload-labs/js/index.js"></script>
</html>


<script type="text/javascript">
    function checkFile() {
        var file = document.getElementsByName('upload_file')[0].value;
        if (file == null || file == "") {
            alert("请选择要上传的文件!");
            return false;
        }
        //定义允许上传的文件类型
        var allow_ext = ".jpg|.png|.gif";
        //提取上传文件的类型
        var ext_name = file.substring(file.lastIndexOf("."));
        //判断上传文件类型是否允许上传
        if (allow_ext.indexOf(ext_name) == -1) {
            var errMsg = "该文件不允许上传,请上传" + allow_ext + "类型的文件,当前文件类型为:" + ext_name;
            alert(errMsg);
            return false;
        }
    }
</script>
  1. 对此,我们可以在网页前端将表单中的事件删掉,直接让页面没有检测功能。按下F12,查看元素后将事件代码删去。
  2. 删去代码后再次点击上传按钮,可以看到成功上传文件,只是该文件并不是图片格式,无法正常显示。
  3. 鼠标右键上图中红框位置(本该是显示图片的位置),点击“新建标签页打开”,可以看到在新的页面成功执行该文件,并返回探针信息内容。如果是其他页面语句,也将成功执行。
  4. 方法一演示结束,点击页面右上角“清空上传文件”按钮,方便下次实验。

3.2 方法二:绕过JS后修改数据

  1. 相比于方法一,方法二显得步骤繁琐一些。
  2. 打开BurpSuite,打开其自带浏览器,访问第一关的网页。将我们上传的文件名后缀修改为png以绕过前端JS检测。
  3. 开启代理拦截功能,并在页面点击上传按钮。在BurpSuite界面我们看到成功拦截到请求,在请求中我们看到上传的文件信息如下图,其中有文件名信息,将其修改为info.php,点击forward,后续请求也点击forward。
  4. 看到页面内容如下,已经成功绕过前端JS检查,将文件上传到服务器。后续验证步骤如方法一,可以看到探针信息。

3 总结

  1. 了解前端JS检测的方法。该方法能让普通用户更早发现自己上传文件是否出错,但是对于攻击者无法起到任何阻碍作用。
  2. 掌握前端JS检测的两种绕过方法。