[SUCTF 2019]EasySQL-WP

一、知识前置

堆叠注入:堆叠注入的存在,是因为在 SQL 中,分号代表着一条 SQL 语句的结束。如果我们在有限的空间里在上一条语句结束后继续构造下一条 SQL 语句,那么是否是一起执行的。正是因为这个想法,所以产生了堆叠注入。

堆叠注入与联合注入的不同点:我们都知道联合注入是将两条语句合并起来,似乎也是一起执行。这其中的差别就在于联合注入只能用于查询(SELECT)类语句,堆叠注入的语句可以是任何语句。堆叠注入是比联合注入更加强大的。

堆叠注入的局限性

  1. 堆叠注入也不像我们想象的那么美好,对环境的要求比较高。比如权限不足,后端 API 或者数据库引擎不支持多语句执行,这些都使我们无法修改数据。
  2. 因为一般来说,我们的后端只返回一个结果时,那么外面在页面上是看不到第二条语句的执行结果。
  3. 堆叠注入需要更多的条件:数据库名,表名,字段名等等。(可以尝试 show 来查看)。

|| 的作用:|| 在 SQL 语句中,相当于 or,如果前一个数据为真,那么就不看后面的数据。

二、解题过程

进入题目,我会根据之前打过的题,踩过的坑,也进行一个习惯性遍历。

1. 先对题目进行扫描,用 dirsearch 扫一扫,没扫到不吃亏,扫到就是赚到 233,这题没扫到啥,一片紫,就不放图片了。

2. 进到题目后,打开网络,看看里面的消息头有没有啥信息,看看源代码有没有啥信息。

QQ图片20220513164613.png

这题没有像有道题,是给了一个假页面的注入,最后真页面藏在最初页面的消息头里。

3. 该题是 SQL 类题型,只给了一个框,输入 1 有回显数据,输入 1’,1”,1)这些都没有回显数据。

2.png
1.png

4. 然后输入 1 order by 1 #,1’ and 1=1 -- - 时,回显了 NONONO,判断应该是有过滤的。

3.png

5. 用 burp 跑个字典看看过滤了哪些大宝贝。

字典跑完之后,过滤了 union,or,and,order,information_schema 等挺多重要的东西的。

首先过滤了 information_schema,order,union,updatexml 这些,那么联合和报错注入应该是无法注入的。

又过滤了 length,ascii,sleep,ord,大概率盲注也是失效的。

没有过滤的有 show,database,table,select 这些,

翻阅笔记后,堆叠注入可以在规则内使用。

6. 那么首先先查看数据库,表这些.

5.png

6.png

7. 查到表为 Flag 后,尝试直接查询全部字段,发现回显 nonono,经检验后,发现 Flag,flag 被过滤了。

图片.png

8. 到这一步 = =,就有点摸不着了,查看多个 WP 之后,从输入多个数字回显的数据一样,但是一输入字母后便不回显数据来推测出 SQL 语句存在 || 结构。

这里判断的依据,我自建环境摸索过后可能是这个原因,就是如果||为真就是1,,就相当于select 1 from Flag,那么回显出来的就是这个数据1.

也就是可能存在这样一个结构:select 输入的数据 || 原来存在的列名 from Flag;

第一种解法:

存在这样一个结构,我们就可以通过 select 在查询时,列出的列名是通过,区分的。

所以我们在框中输入 *,数字。

因为数字为真,在这里输入字母之类,会报错不存在该字母的列名。前端也就无法显示出数据。

图片.png

输入过后,回显出两个数据,我们这个时候的 SQL 语句是 select *,2||flag from Flag;

回显出得第一个数据其实就相当于是 select * from Flag。

第二个数据是 select 1 from Flag。

第二种解法:

第二种解法是我没注意到有这样一种设置可以将 || 的功能转换为拼接的功能,相当是开阔视野了。

因为在 mysql 中缺省不支持,需要将 mysql 的 sql_mode 调整成 pipes_as_concat 来实现关于 oracle 的功能。

但是在 oracle 中,就可以通过 || 来实现字符串拼接的功能。

通过在框中输入:1;set sql_mode=pipes_as_concat;select 1

相当于是 select 1;set sql_mode=PIPES_AS_CONCAT;select 1||flag from Flag;

同时实现三个语句。

图片.png