(一)Js客户端认证绕过
Jvascript演示脚本实例
1 <?php 2 /** 3 * Created by 中国联通信息安全中心 4 * Date: 2015-4-18 5 * Name: upload1.php 6 */
7 //文件上传漏洞演示脚本之js验证
8 $uploaddir = 'uploads/'; 9 if (isset($_POST['submit'])) { 10 if (file_exists($uploaddir)) { 11 if (move_uploaded_file($_FILES['upfile']['tmp_name'], $uploaddir . '/' . $_FILES['upfile']['name'])) { 12 echo '文件上传成功,保存于:' . $uploaddir . $_FILES['upfile']['name'] . "\n"; 13 } 14 } else { 15 exit($uploaddir . '文件夹不存在,请手工创建!'); 16 } 17 //print_r($_FILES);
18 } 19 ?>
1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 2 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3 <html xmlns="http://www.w3.org/1999/xhtml">
4 <head>
5 <meta http-equiv="Content-Type" content="text/html;charset=gbk"/>
6 <meta http-equiv="content-language" content="zh-CN"/>
7 <title>文件上传漏洞演示脚本--JS验证实例</title>
8 <script type="text/javascript">
9 function checkFile() { 10 var file = document.getElementsByName('upfile')[0].value; 11 if (file == null || file == "") { 12 alert("你还没有选择任何文件,不能上传!"); 13 return false; 14 } 15 //定义允许上传的文件类型
16 var allow_ext = ".jpg|.jpeg|.png|.gif|.bmp|"; 17 //提取上传文件的类型
18 var ext_name = file.substring(file.lastIndexOf(".")); 19 //alert(ext_name);
20 //alert(ext_name + "|");
21 //判断上传文件类型是否允许上传
22 if (allow_ext.indexOf(ext_name + "|") == -1) { 23 var errMsg = "该文件不允许上传,请上传" + allow_ext + "类型的文件,当前文件类型为:" + ext_name; 24 alert(errMsg); 25 return false; 26 } 27 } 28 </script>
29 <body>
30 <h3>文件上传漏洞演示脚本--JS验证实例</h3>
31
32 <form action="" method="post" enctype="multipart/form-data" name="upload" onsubmit="return checkFile()">
33 <input type="hidden" name="MAX_FILE_SIZE" value="204800"/>
34 请选择要上传的文件:<input type="file" name="upfile"/>
35 <input type="submit" name="submit" value="上传"/>
36 </form>
37 </body>
38 </html>
红色部分主要是来验证客户端文件扩展名认证,一般允许上传的文件名如下
var allow_ext = ".jpg|.jpeg|.png|.gif|.bmp|"。
①实例演示绕过方法
这个是我们上传页面,当我们选择好上传文件以后,比如我们上传一个后缀名为php时,如果是js前端认证的话,没有点上传,会立刻给我们弹出一个alert文本框,图示如下
对于这样的js前段认证,总结方法如下
第一种删除return checkFile()认证函数。
首先用火狐浏览器打开网址,然后打开火狐的工具firebug,把onsubmit验证的函数删除,就可绕过js认证。认证截图如下
菜刀链接路径:localhost:8080/uploads/redBull.php
第二种修改文件上传的扩展名
认证方式如下
修改checkFile函数里面的允许的上传类型,我们修改成我们希望上传的类型,比如我修改成后缀为php后缀的木马文件
文件上传成功。
第三种验证上传表单验证
认证方式如下
这个时候是自己构造的表单,然后把onsubmit删除掉,就可以上传。认证图如下
第四种方式burp修改扩展名绕过
Burp绕过认证方式如下
(二)服务器MINE认证
①MINE认证主要是content-type函数,验证主要是image/jpeg,只有我们对应image/jpeg才会上传成功。
认证代码如下
1 <?php 2 if($_FILES[‘userfile’][‘type’]!=”image/gif”) 3 $uploaddir=’uploads/’; 4 $uploadfile=$uploaddir.basename($_FILES[‘userfile’][‘name’]); 5 If(move_uploaded_file($_FILES[‘userfile’][‘name’]); 6 Echo “文件成功上传\n”; 7 }else{ 8 Echo “文件上传失败\n”; 9 } 10 ?>
在这里修改content-type的参数的修改,原为content-type:t e x t / p l a i n ,这里我们改为content-type:image/gif,然后把filename的后缀值改为php木马类型。
服务器验证方法:①黑名单验证方式②白名单验证方式
黑名单验证方式:大小写绕过方式,例如后缀可以是,pHP,Asp;名单列表绕过,如后缀为asa,cer等等这些;特殊文件名绕过方式,如后缀后面加上横线和点等,如后缀为xx.asp_,xx.asp.等等这样的后缀;0x00截断绕过,不过这种方式目前只适合于asp的网站;最后涉及的就是解析漏洞,解析漏洞就是根据不同类型的操作系统而言,如window系统iis6.0服务器,网站的解析漏洞就为xx.asp;.jpg可以轻松绕过,linux的apache服务器为xxx.php.xxx,为不正常的后缀名,就可以轻松绕过。
白名单验证方式:同黑名单绕过方式。
安全狗认证绕过方法
认证代码
<?php if ($_FILES["file"]["error"] > 0) { echo "Return Code: " . $_FILES["file"]["error"] . "<br />"; } else { echo "Upload: " . $_FILES["file"]["name"] . "<br />"; echo "Type: " . $_FILES["file"]["type"] . "<br />"; echo "Size: " . ($_FILES["file"]["size"] / 1024) . " Kb<br />"; echo "Temp file: " . $_FILES["file"]["tmp_name"] . "<br />"; if (file_exists("upload/" . $_FILES["file"]["name"])) { echo $_FILES["file"]["name"] . " already exists. "; } else { move_uploaded_file($_FILES["file"]["tmp_name"],
"upload/" . $_FILES["file"]["name"]); echo "Stored in: " . "upload/" . $_FILES["file"]["name"]; } } ?>
<html>
<body>
<form action="upload.php" method="post" enctype="multipart/form-data">
<label for="file">Filename:</label>
<input type="file" name="file" id="file" />
<br />
<input type="submit" name="submit" value="Submit" />
</form>
</body>
</html>
我们通过burp把上传的HTTP包抓下来,然后自己进行一下修改POST数据。经过了一些实验,直接说结果吧,当增加一处文件名和内容,让两个文件名不一致的时候,成功绕过了安全狗的防护,上传了php文件。原因是安全狗进行文件名匹配时候用的是第一个文件名test.jpg,是复合安全要求的,但是webserver在保存文件的时候却保存了第二个文件名test.php,也就是if(security_check(a)){do(b);},导致安全检查没有用,php文件已经成功上传了
SQL注入绕过测试
代码认证
<?php if(isset($_GET['Submit'])){ // Retrieve data
$id = $_GET['id']; $getid = "SELECT first_name, last_name FROM users WHERE user_id = '$id'"; $result = mysql_query($getid) or die('<pre>' . mysql_error() . '</pre>' ); $num = mysql_numrows($result); $i = 0; while ($i < $num) { $first = mysql_result($result,$i,"first_name"); $last = mysql_result($result,$i,"last_name"); $html .= '<pre>'; $html .= 'ID: ' . $id . '<br>First name: ' . $first . '<br>Surname: ' . $last; $html .= '</pre>'; $i++; } } ?>
但是我们加上安全狗以后,就会阻挡一些我们测试的语句。
成功绕过安全狗,利用/*!union*/这样的方式。
参考文章:
http://www.freebuf.com/articles/web/54686.html
http://drops.wooyun.org/tips/132
http://drops.wooyun.org/tips/4322