[强网杯 2019]随便注 1
作者:
斯柠
,
2022-03-15 16:12:25
,
所有人可见
,
阅读 146
菜狗的我对SQL注入一点都不熟悉(主要是对SQL语句的不熟悉),于是又拿这题来练SQL语句了
靶机界面进去以后,根据题目描述和界面显示的东西。盲猜sql注入
首先输入1' or '1'='1进行判断(最后1少一个'是因为在原本的语句构架里面有'进行闭合)
得到的结果是可以进行sql注入
我先试了试union联合注入,得到的结果emm看不懂,怀疑是对select进行过滤了
于是尝试叠堆注入(一次执行多个sql语句),得到的结果一样。试了使用大写select还是一样结果。更加确定了是对select过滤
![叠堆注入结果.png](https://cdn.acwing.com/media/article/image/2022/03/15/72609_70686735a4-20200926184051558.png)
显示结果没有对show过滤,于是使用show尝试输出表名
得到结果![表名.png](https://cdn.acwing.com/media/article/image/2022/03/15/72609_c02431c1a4-20200926185722755.png)
之后就是对这两个表的查询
发现flag在那个长串的数字表里。但是后台的语句是查询words表的id。
由于select呗过滤,我们不能直接输出flag。
于是有两个方案
方案一:我们将数字的表名改为words,如何将flag这个列名改为id
构建语句如下:
1';rename table `words` to words2;
rename table `1919810931114514` to `words`;
alter table words change flag id varchar(100);#
这些一定要一次输入,我就试过先执行1';rename table `words` to words2;#
结果表名是改成了,但是words表也没有了,后面再输入就提示没有words这个表了(我为此重启了靶机)
一次输入就可以成功改名,然后1' or '1'='1查询改名为id的flag即可
方案二:使用预编译语句
既然它过滤了select,但是没有过滤prepare
那我们就拿预编译语句prepare来过滤。
由于预编译语句还是要出现select,但是我们可以用concat拼接selct
于是构建如下语句:
-1';
set @sql=CONCAT('se','lect * from `1919810931114514`;');
prepare stmt from @sql;
execute stmt;
对如上语句进行解释:
SET; # 用于设置变量名和值
PREPARE stmt_name FROM preparable_stmt; # 用于预备一个语句,并赋予名称stmt_name,以后可以引用该语句
EXECUTE stmt_name; # 执行语句
得到结果是[OUTPUT]: strstr($inject, "set") && strstr($inject, "prepare")
也就是对set和prepare拦截
但是strstr对大小写敏感,于是把set和prepare大写,成功得到答案
嗯,确实是让我对sql注入熟悉了不少,之前只是看了很多的理论,动手还是烂的一塌糊涂。果然还是实际上手才最有用
之前知道预编译语句,只是知道合理利用它可以避免sql注入(避免的原理还是一知半解)。但是不知道可以这么玩
参考博客
https://www.cnblogs.com/chalan630/p/12583667.html