实战篇——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:单引号闭合

image-20240701150916173

Less-2:数字型

image-20240701151023493

Less-3:单引号加括号闭合

image-20240701151116572

Less-4:双引号加括号闭合

image-20240701151205476

(2) 无报错信息,但语法错误和语法正确可区分

首先尝试:
?id=1'
?id=1"
都报错就是数字型。

单引号报错,双引号不报错:
继续尝试:
?id=1'#
不报错就是单引号闭合,报错就是单引号加括号闭合。

单引号不报错,双引号报错:
继续尝试:
?id=1"#
不报错就是双引号闭合,报错就是双引号加括号闭合。

事实上语法正确又可以分为两类——查询结果非空和查询结果为空,上述判断方法针对的是语法错误和查询结果非空可区分的情形,而针对语法错误和查询结果为空可区分的情形只需将1改为-1即可。

image-20240701152614539

image-20240701152633622

单引号报错,双引号不报错

image-20240701152741587

单引号加注释符不报错,判断为单引号闭合。

(3) 无报错信息,语法错误和语法正确不可区分

也就是回显内容和输入内容无关(时间盲注),这种情况可以通过and sleep(5)#这样的方式根据响应时间判断。

正常情况:

image-20240701153612955

延时响应:

image-20240701153703721

据此判断为单引号闭合。

SQL注入的利用:

(1) 联合注入

有显示位首选联合注入

1.通过order by判断字段数为3

image-20240701154108311

image-20240701154146216

2.通过union select 1,2,3判断显示位为2和3

image-20240701154311972

3.爆库(group_concat)

image-20240701154606674

4.爆表(group_concat)

image-20240701154849680

5.爆字段(group_concat)

image-20240701155057453

6.爆数据(group_concat+concat_ws)

image-20240701155518086

(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(),'~'))#

image-20240701161614870

具体的爆库爆表爆字段爆数据的过程和联合注入没啥区别,唯一需要注意的是报错回显的内容最多只有32位,因此当字符串过长时需要使用substr、mid等截取函数

image-20240701161845929

image-20240701162442167

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函数没啥区别

image-20240701163220663

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)#

image-20240701164515424

需要注意的是利用floor进行报错注入不能使用group_concat函数(原因我也不清楚),只能使用limit子句一个一个查询

image-20240701165018208

image-20240701165156637

(3) 布尔盲注

如果既没有显示位也没有报错信息,但查询结果非空和查询结果为空可区分,那么可以使用布尔盲注。

?id=1' and boolean_expression#
?id=-1' or boolean_expression#

手工盲注过程比较繁琐,可以考虑使用相关工具,下面利用Burpsuite进行布尔盲注。

先判断库的数量为9

image-20240701170705734

image-20240701170734458

再判断每个库名的长度(非手工盲注不需要这一步)

image-20240701171147451

image-20240701171549262

最后判断每个库的名称

image-20240701172013236

image-20240701173650584

可见第一个库的名称是information_schema......

后续爆表爆字段爆数据的过程就不再演示了,和爆库的过程基本一致。

(4) 时间盲注

如果既没有显示位也没有报错信息,甚至连查询结果非空和查询结果为空都不可区分,那就只好用时间盲注了。

?id=1' and if(boolean_expression,sleep(5),1)#

image-20240701174905773

image-20240701174825788

根据响应时间,判断库的数量为9。

利用时间盲注爆库爆表爆字段爆数据的过程就不再演示了,和布尔盲注基本一致。

posted @ 2024-07-01 18:01  yaoguyuan  阅读(19)  评论(0编辑  收藏  举报