HTTP协议bypass WAF(狗/盾)

2018-12-22 21:57:01 35 7083 14

HTTP协议bypass WAF


0x00 前言

1.最近在整理并总结bypass WAF的一些方法,大概几个板块:注入绕过、漏洞exp绕过、上传绕过以及HTTP协议绕过。期间通过学习
  很多国内外好的资源收获了不少,也给大家分享些方法。
2.这里仅以HTTP协议其中一部分来bypass WAF来测试并编写sqlmap 的Tamper 发文当天仅测试了安全狗、D盾其他没有测试。

总结的手段大概如下(截图):

0x01 HTTP协议

  1. 协议版本。首先HTTP协议从开始的HTTP0.9版本-->1.0--->1.1-->逐步到现在的2.0。不断的在完善,也不断的有特性的改变,所以在进行bypass WAF的时候也可以利用版本的不用同来对WAF进行测试,利用WAF可能没有完全包含全HTTP协议版本的特性点进行fuzz.
  2. HTTP 头部参数。http头参数平时并没有很仔细研究,在阅读相关资料后,你会发现每个头部甚至参数都还有其他特性用法。过WAF的时候也是利用其特性来绕过,常规的样式WAF早就记录,但是可能遗漏很多其他特性。

常见的HTP请求头(如图):

这个是最普通的头部字段,其中还有很多没有字段没有体现,有些字段稍微的变化甚至会影响整个payload的样貌,具体更多HTTP头部的介绍可以参考官网的文档:RFC2068、RFC2616、RFC7230、RFC7540等等。

这里举例过WAF的用的是2个HTTP的头参数:Transfer-Encoding、Content-Type等


0x02 Transfer-Encoding

分块传输编码(Chunked transfer encoding)是超文本传输协议(HTTP)中的一种数据传输机制,允许HTTP由网页服务器(客户端)发送给客户端的数据可以分成多个部分。利用点就是把我们攻击代码进行分块传输,WAF不能直接规则匹配到。数据到服务端后会自动根据http头获知是chunked的会自动组合来进行后续的资源响应。

类似于(如图):


0x03 Content-Type

这个参数平时查看HTTP头部的时候 肯定都看到多。其实在这个头部的参数里还有个参数:charset 。这个值平时我们看到是没有后面的值,默认是utf-8,没有显示的。其实它还有很多很多的编码。这个参数的含义是给内容进行编码。试想下你客户端提交的数据是不常用的编码且服务端的容器是支持的话,WAF可能不会包含所有的编码还自动解码在判断在编码发给服务端的。这样就达到一个绕过WAF的一种手段。

如图():

由于本次测试的环境是:2008+IIS7 IIS支持的编码有:IBM037, IBM500, IBM870, cp875, IBM1026, IBM01047, IBM01140, IBM01141, IBM01142, IBM01143, IBM01144, IBM01145, IBM01146, IBM01147, IBM01148, IBM01149, utf-16, unicodeFFFE, utf-32, utf-32BE, IBM273, IBM277, IBM278, IBM280, IBM284, IBM285, IBM290, IBM297, IBM420,IBM423, IBM424, xEBCDIC-KoreanExtended, IBM-Thai, IBM871, IBM880, IBM905, IBM00924, cp1025

脚本编写选择用的编码是:ibm037


0x04 编写sqlmap tamper过WAF脚本

1.首先是编写chunked 分块传输的编码,根据协议的标准,把数据进行每行分块的传输,我这里设置分块的大小是2。即2个字符就分块。

如图:

2 然后就是charset自动编码的代码。功能简单,就是把payload全部进行指定的编码进行编码。 如图:

3.sqlmap tamper的修改。因为修改了2个HTTP头部参数,需要在tamper中制定头部中添加一个分块传输,以及指定编码。

如图:

这里最折腾我就是我明明代码指明了要分快传输头部chunked, 但是实际发包却没有。。。一直没有找到原因。如果哪位老哥知道我错在哪里,请教我一招。。3q

我的解决办法就是直接执行sqlmap的时候强制加上头部:--headers="Transfer-Encoding: chunked"。然后坑又来了,我加上头部后使用proxy=http://127.0.0.1:8080 发现发包不出去,没有数据通讯(折腾了好久。。)主要是通过BP来看看数据包,这样比较直观数据发送是否正常、样貌方便各位看的明白舒服。后来就只能使用wireshark来跟数据给大家展示。

0x05 动态效果

动态图中参数增加了: --data "*" --dbms mssql --dbs --headers="Transfer-Encoding: chunked" --tamper 666666.py --skip-urlencode(不要url编码) 由于代码功底差,代码很乱。一般代码功能实现了,就懒得去优化了。不贴上来丢人了。原理就是这样,大佬们可造最优脚本。

首先是撸安全狗的动态图:

然后是D盾的动态图:

0x06 总结

欠缺的还有很多,需要更加学习和实战

TCV : 0

关于作者

J0k3r20篇文章385篇回复

评论35次

要评论?请先  登录  或  注册
  • TOP1
    2018-12-22 22:04

    老哥,你这些一大堆方法都必须post形式对不对?如果get可以转post的直接用sqlmap跑。如果转不了怎么办?,年初的时候一直手工用这种方法,但是很多站get不支持post方法。一直没有想到解决方法。

  • 35楼
  • 34楼
    2019-5-31 00:00

    Failed parsing or buffering the chunk-encoded client body.

  • 33楼
    2019-4-30 18:59
    00ff00ff

    老哥,你这些一大堆方法都必须post形式对不对?如果get可以转post的直接用sqlmap跑。如果转不了怎么办?,年初的时候一直手工用这种方法,但是很多站get不支持post方法。一直没有想到解决方法。

    1

    很简单不能转,你换成换行字符就ok.了

  • 32楼
    2019-4-29 10:26

    大部分方法貌似不行

  • 31楼
    2019-4-28 16:38

    这个测试了 不过现在的成本高的waf是做了拦截的。

  • 30楼
    2019-3-10 11:40
    算命縖子

    def tamper(payload, **kwargs): #添加head信息 headers = kwargs.get("headers", {}) headers = "Chunked" headers = "application/x-www-form-urlencoded"headers = "Chunked" 楼主 你怎么获取到payload前面的参数的? 怎么在参数前面添加内容?

    1
    J0k3r

    定位好注入点,把整个数据post的数据都当做payload

    2
    Solo_LD

    我好像明白了,,老哥原来是把--data设置为*

    3

    就是这样的,直接把整个当成payload,具体参数直接在tamper里面设定好

  • 29楼
    2019-3-10 00:09
    算命縖子

    def tamper(payload, **kwargs): #添加head信息 headers = kwargs.get("headers", {}) headers = "Chunked" headers = "application/x-www-form-urlencoded"headers = "Chunked" 楼主 你怎么获取到payload前面的参数的? 怎么在参数前面添加内容?

    1
    J0k3r

    定位好注入点,把整个数据post的数据都当做payload

    2

    我好像明白了,,老哥原来是把--data设置为*

  • 28楼
    2019-3-10 00:05
    算命縖子

    def tamper(payload, **kwargs): #添加head信息 headers = kwargs.get("headers", {}) headers = "Chunked" headers = "application/x-www-form-urlencoded"headers = "Chunked" 楼主 你怎么获取到payload前面的参数的? 怎么在参数前面添加内容?

    1
    J0k3r

    定位好注入点,把整个数据post的数据都当做payload

    2

    请问老哥具体怎么弄?需要改源码吗?tamper脚本里的post参数试了好久都改不成功。

  • 27楼
    2019-3-9 09:18
    算命縖子

    def tamper(payload, **kwargs): #添加head信息 headers = kwargs.get("headers", {}) headers = "Chunked" headers = "application/x-www-form-urlencoded"headers = "Chunked" 楼主 你怎么获取到payload前面的参数的? 怎么在参数前面添加内容?

    1

    定位好注入点,把整个数据post的数据都当做payload

  • 26楼
    2019-3-8 21:16

    def tamper(payload, **kwargs):     #添加head信息     headers = kwargs.get("headers", {})     headers["Transfer-Encoding "] = "Chunked"     headers["Content-Type"] = "application/x-www-form-urlencoded"
    headers["Transfer-Encoding空格"] = "Chunked" 楼主 你怎么获取到payload前面的参数的? 怎么在参数前面添加内容?

  • 25楼
    2019-1-31 12:45

    楼主能不能把参考的文章博客的链接发出来学xi一下啊??

  • 24楼
    2019-1-31 09:15

    这个是分块传输绕过的那个方法吗?

  • 23楼
    2019-1-23 21:47

    看到链接 回来复xi的 总结的真的不错!

  • 22楼
    2019-1-23 18:49

    脚本能发出来吗 不会写Py啊

  • 21楼
    2018-12-29 11:16

    我好像在好多论坛都看过

  • 20楼
    2018-12-29 10:51

    分块之前测试没成功,参考楼主有空再试试,

  • 19楼
    2018-12-29 10:50
    阿乾

    Content-Type 这个可以绕过iis的主动防御,甚至在github上有burp关于这方面的插件

    1
  • 18楼
    2018-12-29 10:35

    Content-Type 这个可以绕过iis的主动防御,甚至在github上有burp关于这方面的插件

  • 17楼
    2018-12-29 09:43

    Content-Type知道一点点,分块传输那个没见过,开眼界了

  • 16楼
    2018-12-26 18:03

    好思路,想到应用到菜刀上应该能过一批检测菜刀流量的防御。