前言
经过几个月的不懈奋战(,终于把靶场前三页全部刷完了,第四页都是挑战题,检验这个靶场的学习成果。最后也会总结sql注入的过程及方法。
ps.整理了关于sqli-labs靶场的博客,将分散的几篇整合了起来。
less38-45
关于堆叠注入
sql注入的又一块拼图补上了,这块拼图就是堆叠注入。首先我们截取关键源码看一下:
1 | $sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1"; |
我们注意到,源码使用了一个叫做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 | ?sort=1 and extractvalue(1,concat(0x7e,database(),0x7e)) |
之前提到的报错注入方式全都是可以使用的
第二种方法是通过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注入的难度都是相当大的,需要大量的实战经验来进行积累。接下来还有很多新东西在前面,让我们进入下个靶场继续磨炼。