0x01:前言

HTTP请求行区别:
Http定义了与服务器交互的不同方法,最基本的方法有4种,分别是GET,POST,PUT,DELETE。

对应HTTP中的GET,POST,PUT,DELETE就对应着对这个资源的查,改,增,删4个操作。

现在用的比较多的是POST和GET
方式,一般情况下,如果不说明请求方式,例如地址栏输入网址请求、
超链接请求等都是GET请求,只有在form表单请求时可以设置method方式为POST。

GET请求方式请求数据显示在url后面,POST方式显示在请求体中,空白行下面。

GET方式请求数据有限制,最大为1k,而POST方式理论上没有限制。

在绕WAF中 GET包 与 POST包在处理上是有区别的,先看GET与POST的区别

image1.png
image2.png

Content-Type: 实体报头域用语指明发送给接收者的实体正文的媒体类型
现在市场上大部分的WAF会解析这行 Content-Type 去识别是否是POST注入,因为要防止方法污染。所以我们就可以根据这个特性来设置不同的Content-Type利用尝试绕过WAF

0x02:请求方式差异规则松懈性绕过

GET——> POST
有些WAF同时接收GET方法和POST的方法,但只在GET方法中增加了过滤规则,可通过发送POST方法进行绕过。
(一)、基于HTTP协议的绕过 - 图3

0x03:异常Method绕过

有些WAF只检测GET,POST方法,可通过使用异常方法进行绕过。
增加了过滤规则的代码:
(一)、基于HTTP协议的绕过 - 图4

正常payload:

  1. GET/xxx/?id=1+and+sleep(3) HTTP/1.1

绕过payload:

  1. DigApis /xxx/?id=1+and+sleep(3) HTTP/1.1


0x04:利用pipline绕过

原理:
http协议是由tcp协议封装而来,当浏览器发起一个http请求时,浏览器先和服务器建立起连接tcp连接,然后发送http数据包(即我们用burpsuite截获的数据),其中包含了一个Connection字段,一般值为close,apache等容器根据这个字段决定是保持该tcp连接或是断开。当发送的内容太大,超过一个http包容量,需要分多次发送时,值会变成keep-alive,即本次发起的http请求所建立的tcp连接不断开,直到所发送内容结束Connection为close为止。

当请求中的Connection字段值为keep-alive,则代表本次发起的请求所建立的tcp连接不断开,直到所发送内容结束Connection为close为止。部分WAF可能只对第一次传输过来的请求进行过滤处理。

利用pipline进行绕过:
1.关闭burp的Repeater的Content-Length自动更新,如图四所示,点击红圈的Repeater在下拉选项中取消update Content-Length选中。这一步至关重要!!!image.png2.burp 拦截数据包,修改Connection字段值为keep-alive,注意更改数据包的Content-Length的值(对应POST传递值得长度),将带有攻击语句的数据请求附加到正常请求后面再发送一遍。

0x05:利用HTTPS和HTTP绕过

如果目标网站对HTTP和HTTPS同时开放服务,没有做HTTP到HTTPS的强制跳转,导致HTTPS有WAF防护,HTTP没有防护,直接访问HTTP站点绕过防护。

0x06:协议未覆盖绕过WAF

原理:
POST 请求常用有2种参数提交方式:
Content-Type: application/x-www-form-urlencoded;
Content-Type: multipart/form-data;

WAF未能覆盖Content-Type: multipart/form-data从而导致被绕过。或者WAF会认为它是文件上传请求,从而只检测文件上传,导致被绕过。

首先将数据包转换为文件上传包格式,使用bp工具change body encoding
image.png

image.png
绕过:
1.添加参数filename,filename =1.jpg,等于号前需要加个空格

image.png

2.加双引号绕过
image.png

3.边界混淆绕过
这是原始的边界
image.png
进行混淆后
image.png
或者有
image.png

0x07:利用分块编码传输

原理:
在头部加入 Transfer-Encoding: chunked 之后,就代表这个报文采用了分块编码。这时,post请求报文中的数据部分需要改为用一系列分块来传输。每个分块包含十六进制的长度值和数据,长度值独占一行,长度不包括它结尾的,也不包括分块数据结尾的,且最后需要用0独占一行表示结束。

在burp中关闭自动补全,删掉Content-Length: 37,添加Tranfer-Enconding: chunked就代表是分块传输了,将数据部分id=1 and 1=1进行分块编码(注意长度值必须为十六进制数),每一块里长度值独占一行,数据占一行如图所示

image.png

将上面的数据包 id=1 and 1=1 改为 id=1 and 1=2
image.png
没有回显,说明payload生效
注意:分块编码传输需要将关键字and,or,select ,union等关键字拆开编码,不然仍然会被waf拦截。编码过程中长度需包括空格的长度。最后用0表示编码结束,并在0后空两行表示数据包结束,不然点击提交按钮后会看到一直处于waiting状态。

如果这样依旧被拦截可以在每分块后面加上;注释,尝试绕过

  1. 2;CESHI
  2. id
  3. 2;CESHI
  4. =1
  5. 5;CESHI
  6. order
  7. 2;CESHI
  8. by
  9. 1;CESHI
  10. 4


0x08:分块编码+协议未覆盖组合绕过

在协议未覆盖的数据包中加入Transfer-Encoding: chunked ,然后将数据部分全部进行分块编码
image.png

最后用0表示编码结束,并在0后空两行表示数据包结束,不然点击提交按钮后会看到一直处于waiting状态。

0x09:Content-type编码绕过

利用特殊编码对payload进行转义,从而绕过WAF对特殊关键词的过滤
image.png

0x10:http头格式的绕过

  • TAB
  • 空格
  • 回车
  • x00
  • 等等

示例:
Host字段回车加TAB
image.png
混乱特殊字符绕过
image.png

image.png

注意:只能位于chunked字符之前加入字符
image.png

加入双::号
image.png

0x11:参数污染绕过:

在这种情况下,例如网站的参数是id=1,我们可以再后面再加上一个参数,形成id=1&id=1然后尝试在第二个参数来进行注入。,部分WAF在处理的过程中可能只处理前面提交的参数值(id=1),而后端程序在处理的时候可能取的是最后面的值。
正常payload:

  1. ?id=1+and+sleep(3)

绕过payload:

  1. ?id=1&id=2+and+sleep(3)

将攻击语句赋予最后一个id参数,可绕过WAF检测直接进入后端服务器。

0x12::脏数据绕过:

有的waf能检测的数据是有限的比如只能检查10w个字符,20w个字符,30w个字符。但如果我们的将命令复制40w次,可能前面的命令还是会被过滤,但是后面的,超过了waf检测上限的命令就可以正常执行了。有的waf的长期执行对系统的占用率很好,所有有的waf可能会设置只检测和拦截4m的数据,超过4m就不会被拦截。
无waf

例子1:?id=1 and (select 1)=(Select 0xA1000)+UnIoN+SeLeCT+1,2,version(),4,5,database(),user(),8,9
PS:0xA
1000指0xA后面”A”重复1000次,一般来说对应用软件构成缓冲区溢出都需要较大的测试长度,这里1000只做参考也许在有些情况下可能不需要这么长也能溢出。

正常payload:

  1. ?id=1+and+sleep(3)

绕过payload:

  1. ?id=1+and+sleep(3)+and+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111=111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111

添加无用字符,使内容大小超过WAF检测能检测到的最大内容。