文章归档

置顶文章

Web安全

Web安全基础

PHP相关

Writeups

靶机系列

HackTheBox

VulnHub

代码审计

PHP代码审计

流量分析

机器学习

基础学习

Python

Python编程

Java

Java编程

算法

Leetcode

随笔

经验

技术

 2019-09-17   1k

web安全学习之SQL注入——双查询报错注入及其原理

如果是SQL报错注入的话,经常会看到一个报错函数floor,虽然有现成的公式给你套用,但我还是觉得有必要弄清楚里面的原理。

payload形成

双注入payload需要用到四个函数和一个group by语句:

  1. group by:分组语句;
  2. rand():随机生成函数;
  3. floor():取整函数;
  4. concat():字符串连接函数;
  5. count():统计函数。

用sqli-labs中的数据库为示例:

concat函数

1
mysql> SELECT concat("test:",(SELECT database()))as a;

执行查询操作时,子查询先开始,所以SELECT database()先执行,然后查询到当前数据库名称”security“,并将其传给concat函数,concat函数在对字符进行连接,于是显示出图上的结果。

rand函数

rand()函数,其作用是生成一个大于0小于1的随机浮点数,如下:

floor函数

floor()函数的作用是对传入的参数取整,这里将rand()生成的随机数做处理进行取整,由于rand()生成的值取整结果只能为0,所以我们这里做一点处理,使其生成一个大于0小于2的随机值,并对其取整:

1
mysql> SELECT floor(rand()*2);

结果要么为0要么为1:

接下来结合子查询,显示出数据库信息:

1
mysql> SELECT concat((SELECT database()), floor(rand()*2)) from users;

users表有多少条数据就会返回多少条信息:

在注入中,我们不知道库名表名,往往借助information_schema这个库进行猜解

其中information_schema.schemata中包含了mysql的所有库名,information_schema.tables中包含了所有的表名,information_schema.columns中包含了所有的列名。

group by语句

现在加上group by语句对返回的数据进行分组处理:

1
SELECT concat((SELECT database()), floor(rand()*2))as a from information_schema.schemata group by a;

count函数

这里增加一个聚合函数count,构造的语句如下:

1
SELECT count(*),concat((SELECT database()), floor(rand()*2))as a from information_schema.schemata group by a;

当我们加上count(*)函数时,操作过程为:查看虚拟表是否存在该主键值,不存在则插入新记录,存在则count(*)字段直接加1。

这里利用count(*)对前面的返回数据进行统计,由于group by 和随机数的原因,有可能会出现重复的键值,当键值重复时就会触发错误,然后报错,由于子查询在错误发生之前就已经完成,所以子查询的内容会随着报错信息一起显示出来:

payload原理

直接把这一篇文章搬运过来吧,写得非常好,在此就做个小的总结:

通过floor报错的方法来爆数据的本质是group by语句的报错。group by语句报错的原因是floor(random(0)*2)的不确定性,即可能为0也可能为1,(group by key的原理是循环读取数据的每一行,将结果保存于临时表中。读取每一行的key时,如果key存在于临时表中,则不在临时表中更新临时表中的数据;如果该key不存在于临时表中,则在临时表中插入key所在行的数据。group by floor(random(0)*2)出错的原因是key是个随机数,检测临时表中key是否存在时计算了一下floor(random(0)*2)可能为0,如果此时临时表只有key为1的行和不存在key为0的行,那么数据库要将该条记录插入临时表,由于是随机数,插时又要计算一下随机值,此时floor(random(0)*2)结果可能为1,就会导致插入时冲突而报错。即检测时和插入时两次计算了随机数的值。

结论是:当与临时表里面的值进行比较,如果不同,就插入,但是插入的时候又计算了一次,所以如果插入时计算的值与直接比较的值不一样,则报错

Copyright © ca01h 2019-2020 | 本站总访问量