进入题目环境,有输入框与注入参数,推测类型为SQL注入:
测试--注入类型为数字型还是字符型,构造payload:?inject=1 or 1=2 并提交:
发现页面依然正常,说明注入类型为字符型,则继续检查闭合方式,首先尝试单引号闭合,构造payload: ?inject=1' --+
证实了闭合方式为单引号,继续测试字段数目(order by / group by ),经测试,字段数目为2。接着开始注数据库名,表名等关键信息:
首先尝试Union联合注入---构造payload: ?inject=1' union select database(),提交页面如下:
页面回显提示我们后端代码对注入点inject提交的内容进行了过滤,将 select、where等一系列关键字进行了过滤,并无视大小写,阻止了 大小写绕过 等绕过方法。所以Union联合注入不可行。
同时,观察到 show、from 等一些堆叠注入关键词没有被过滤,故尝试堆叠注入,构造payload:?inject=1';show databases; --+ ,提交页面如下:
发现回显数据库信息,证实堆叠注入可行。继续注表名,构造payload:?inject=1';show tables' --+,提交页面如下:
发现两张表,分别查看这两张表中的列名,构造payload:?inject=1';show columns from 表名; --+,提交页面如下:
首先查看表 words,发现列名分别为 id 和 data,猜测表words可能为默认查询的表,构造payload:?inject=1'or 1=1 #进行验证:
观察到回显内容格式均为 id + data 的格式,证实表 words 为默认查询的表。
继续查询 表1919810931114514中的列,构造相同payload:?inject=1';show columns from `1919810931114514`; #,提交查询页面如下:
发现 flag 存储在这张表中,于是尝试获取flag。
表名是纯数字时,要用反引号框住,否则查询无效:
这是因为在标准 SQL 中,表名以纯数字开头时会被解释为数字,而不是作为表名。在 MySQL 中,反引号用于将标识符括起来,以允许使用特殊字符或保留字作为标识符,同时避免歧义。
我们有两种方法来获取flag:
方法一:
已知表 words 为查询的默认表,则可以利用 rename 关键字将 表word改名为words,并将表 1919810931114514改名为 word,这样默认查询的表就变成了原先的 表1919810931114514,并将列 flag 改为 id,这样进行查询则可得到 flag 的值:
payload: ?inject=1';rename `words` to `words1`;rename `1919810931114514` to `words`;alter table `words` change `flag` `id` varchar(100); #
提交页面如下:
使用 payload : ?inject=1' or 1=1 # 查询默认的表,查询到flag值。