实战篇——SQL注入sqli-labs-master靶场实战一
实战篇——SQL注入sqli-labs-master靶场实战(1)
SQL注入的原理
没有对用户的输入进行合法性判断或过滤,而是直接将其拼接至SQL查询语句当中作为命令执行,从而导致非法操作。
SQL注入的检测
也就是闭合方式的判断,根据报错信息的不同情况可以分为3类——(1)有报错信息 (2)无报错信息,但语法错误和语法正确可区分 (3)无报错信息,语法错误和语法正确不可区分。
(此处参考了https://blog.csdn.net/weixin_46634468/article/details/120480080?spm=1001.2014.3001.5506)
(1) 有报错信息
这是最理想的情况,直接跟上转义字符\即可。
当闭合字符遇到转义字符时,会被转义,那么缺少闭合字符的语句就不完整了,就会报错。
因此转义字符后面跟着的字符就是闭合字符,如果没有就是数字型。
Less-1:单引号闭合
Less-2:数字型
Less-3:单引号加括号闭合
Less-4:双引号加括号闭合
(2) 无报错信息,但语法错误和语法正确可区分
首先尝试:
?id=1'
?id=1"
都报错就是数字型。单引号报错,双引号不报错:
继续尝试:
?id=1'#
不报错就是单引号闭合,报错就是单引号加括号闭合。单引号不报错,双引号报错:
继续尝试:
?id=1"#
不报错就是双引号闭合,报错就是双引号加括号闭合。
事实上语法正确又可以分为两类——查询结果非空和查询结果为空,上述判断方法针对的是语法错误和查询结果非空可区分的情形,而针对语法错误和查询结果为空可区分的情形只需将1改为-1即可。
单引号报错,双引号不报错
单引号加注释符不报错,判断为单引号闭合。
(3) 无报错信息,语法错误和语法正确不可区分
也就是回显内容和输入内容无关(时间盲注),这种情况可以通过and sleep(5)#这样的方式根据响应时间判断。
正常情况:
延时响应:
据此判断为单引号闭合。
SQL注入的利用:
(1) 联合注入
有显示位首选联合注入。
1.通过order by判断字段数为3
2.通过union select 1,2,3判断显示位为2和3
3.爆库(group_concat)
4.爆表(group_concat)
5.爆字段(group_concat)
6.爆数据(group_concat+concat_ws)
(2) 报错注入
无显示位但有报错信息首选报错注入。
报错注入一般需要使用特定的函数,下面介绍三个可用于报错注入的函数。
(此处参考了https://blog.csdn.net/l2872253606/article/details/124423275)
1. extractvalue
EXTRACTVALUE (XML_document, XPath_string);
第一个参数:XML_document是String格式,为XML文档对象的名称;
第二个参数:XPath_string (Xpath格式的字符串);返回内容:若Xpath正确则返回目标XML查询的结果,否则返回Xpath错误内容
在Xpath中,插入~和^等特殊字符是非法的,会报错,利用concat函数可以解析SQL语句。
?id=1' and extractvalue('a',concat('~',database(),'~'))#
具体的爆库爆表爆字段爆数据的过程和联合注入没啥区别,唯一需要注意的是报错回显的内容最多只有32位,因此当字符串过长时需要使用substr、mid等截取函数。
2. updatexml
UPDATEXML (XML_document, XPath_string, new_value);
第一个参数:XML_document是String格式,为XML文档对象的名称;
第二个参数:XPath_string (Xpath格式的字符串);
第三个参数:new_value,String格式,替换查找到的符合条件的数据;
返回内容:若Xpath正确则返回更改对象名称,否则返回Xpath错误内容
?id=1' and updatexml('a',concat('~',database(),'~'),'a')#
其实和extractvalue函数没啥区别
3. floor
当group by与rand一起使用时,如果临时表中没有该主键,rand会再计算一次并将第二次计算结果插入临时表,导致主键重复报错
?id=1' and (select 1 from (select count(*),concat(database(),floor(rand(0)*2))x from information_schema.schemata group by x)a limit 0,1)#
需要注意的是利用floor进行报错注入不能使用group_concat函数(原因我也不清楚),只能使用limit子句一个一个查询。
(3) 布尔盲注
如果既没有显示位也没有报错信息,但查询结果非空和查询结果为空可区分,那么可以使用布尔盲注。
?id=1' and boolean_expression#
?id=-1' or boolean_expression#
手工盲注过程比较繁琐,可以考虑使用相关工具,下面利用Burpsuite进行布尔盲注。
先判断库的数量为9
再判断每个库名的长度(非手工盲注不需要这一步)
最后判断每个库的名称
可见第一个库的名称是information_schema......
后续爆表爆字段爆数据的过程就不再演示了,和爆库的过程基本一致。
(4) 时间盲注
如果既没有显示位也没有报错信息,甚至连查询结果非空和查询结果为空都不可区分,那就只好用时间盲注了。
?id=1' and if(boolean_expression,sleep(5),1)#
根据响应时间,判断库的数量为9。
利用时间盲注爆库爆表爆字段爆数据的过程就不再演示了,和布尔盲注基本一致。