延时盲注+联合查询获得Mysql数据库数据

一、Mysql数据库结构及特性:

1)Mysql数据库结构

1
2
3
4
5
6
7
8
|数据库A——网站A
|--表
|----列(字段)
|------数据(值)

数据库B——网站B
......
数据库C——网站C

注入的不同攻击方式及手法由数据库类型造成!

2)版本特性

对于Mysql数据库,分为5.0以上和以下版本,区别在于有无information_schema数据库

  • Mysql5.0以上版本

    存在自带数据库information_schema

  • Mysql5.0以下版本

    不存在自带数据库information_schema

information_schema:记录有mysql所有数据库名,表明及列名信息的自带数据库,其中的两个重要的表

  • tables:记录数据库下的表名信息的表
  • columns:记录所有数据库下的列名信息的表

这两个表中有三个重要的字段:

  • Table_schema:数据库名
  • table_name:表名
  • Column_name:列名

3)用户权限特性

最高权限用户ROOT,有所有数据库的权限,并且可以利用Mysql调用执行命令,操作文件读写等。

二、Mysql延时盲注:

主要利用 if 语句和 sleep()函数。

  • if语句语法

    if(expr1,expr2,expr3),如果expr1真,则if返回expr2。为假则返回expr3。

  • sleep()特性

    其会导致查询的时间延迟

    1
    2
    3
    4
    5
    mysql> select * from news where id=1 and sleep(1);
    Empty set (1.00 sec)

    mysql> select * from news where id=1 and sleep(2);
    Empty set (2.00 sec)

结合 if 语句和 sleep()函数使用,我们就可以通过 if 语句的第一个参数的真假,来控制延迟的时间,而第一个参数的真假由我们构造的表达式来进行控制。

在这里我们先来理清一下从获取数据库名到获取数据库里的数据的思路

  1. 盲注获取数据库名长度
  2. 盲注获取数据库名每一位的值
  3. 联合查询获取表名
  4. 联合查询获取列名
  5. 联合查询获取指定数据

1)获取数据库名长度

http://127.0.0.1/test/sqlin.php?x=1 and sleep(if((select length(database())=6),5,0))

select length(database())就是求数据库名称长度

当数据库名长度为6时,这里应该延迟5秒(可以是任意值,只要能直观反映出区别就好)才返回结果,不为6时立即返回结果。因此我们通过逐一猜测长度(或通过二分法),当出现延迟时,说明我们的数据库名长度猜对了

2)获取数据库名称每一位的值

select * from news where id = 1 and sleep(if((select mid(database(),1,1)='x'),5,0))

select mid(database(),1,1)就是取数据库名称的第一位,select mid(database(),2,1)就是第二位,依次类推

我们从数据库名称第一位开始猜,其可用字符范围为:A-Z,a-z, 0-9 和_下划线(不排除有其它特殊字符,常规字符猜不到再考虑特殊字符)。当然,比较效率的方法是通过二分法比较ascii值

3)利用BurpSuite自动猜解长度和名称

  1. 火狐浏览器设置代理

  2. 开启BurpSuite抓包,然后右键发送到Intruder

  3. 设置Intruder,然后点击start attack即可

除此之外还可以在Options中设置线程等其它设置,在此不进行展开。猜解名称与猜解长度步骤大致相同,不再赘述。

三、联合查询

1)获取当前数据库中的表名

当我们得到数据库的名称之后,我们就可以通过联合查询,在information_schema数据库的tables表中查询我们当前所在的数据库(页面正常查询所使用的数据库,也即我们通过盲注猜出名称的数据库)中的表名

1.1)获取当前表字段个数

要使用联合查询,必须满足联合查询的限制条件,其基本语法:由多条select语句构成: 每一条select语句获取的字段数必须严格一致(但是字段类型无关),因此我们需要知道当前所在的表(页面正常查询所使用的表)的字段数目,通过添加额外的order by x(x代表字段数目),例如:

http://127.0.0.1/test/sqlin.php?x=1 order by 3

当猜对时,页面显示正常,否则不正常

1.2)联合查询爆出表名

猜测出字段数目之后,通过下面的句式就可以爆出表名,其中2,3占位用,无实际意义。union后的语义为:查询table_name,2,3字段的值从information_schema.tables这个表中当字段table_schema的值为xiaodi时

1
http://127.0.0.1/test/sqlin.php?x=1 union select table_name,2,3 from information_schema.tables where table_schema='xiaodi'

2)联合查询爆出列名

爆出表名之后,我们就可以进一步使用联合查询爆出的表下的列名,比如user表

1
http://127.0.0.1/test/sqlin.php?x=1 union select Column_name,2,3 from information_schema.columns where table_schema='xiaodi' and table_name='user'

3)联合查询得到数据

爆出字段名之后,我们就可以轻松获取到相应的数据了

http://127.0.0.1/test/sqlin.php?x=1 union select username,password,3 from user

由于我们测试数据库中只填写了一条记录,所以这里只爆出了一条用户名和密码,实际情况下,这一步可以爆出所有的数据

文章作者: TechOtaku
文章链接: http://techotaku.me/2018/04/25/延时盲注+联合查询获得Mysql数据库数据/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 徒然の博客