[CTF-writeup] BUUCTF:SUCTF2019_EasySQL

概要

类型:Web-SQL注入

来源:BUUCTF

知识点:堆叠注入;MySQL系统变量;逻辑运算符;

思路

首先能看到页面中提供了一个比较简单的查询,查看页面源代码,没有发现有效的其他信息。

很明显这个查询框就是唯一的注入点。先随意输入一些东西提交查询,发现当输入任何的非零数字时,页面总是回显一个相同的查询结果。

但是当我们输入的是0,或其他的字母、字符时,页面没有任何的回显。

再尝试输入一些MySQL中的关键字,如union、sleep,发现页面都会回显“Nonono”,大概是这些关键字被过滤了,也就是说盲注、联合查询在这里用不到了。

分析一下该注入点的闭合方式,发现不论是单引号还是双引号都没能引起语法层面的错误,结合前面发现的只有查询数字才有回显,可以判断就是数字型注入了。

在这里可以试试堆叠注入,我们可以先查询一下当前的表名:

1;show tables#

现在我们知道当前数据库下只有一个叫作为“Flag”的表了,我们想要的flag或许就在其中的某一条记录中。

回忆一下MySQL中是如何对表“Flag”进行查询的:

select * from Flag where unknown=xxx;

其中,unknown是Flag的某个字段,并且它的数据类型是整型。但我们无法使用“show columns from…”来获取这个表的任何字段名,因为我们发现“flag”这个字符串也被后端过滤了。

那么是否能换一种思路,有没有可能后端在查询时本就没有带任何的条件?

select xxx from Flag;

但这又难以解释为什么“xxx”为字符、字母、0时无回显,而为任意非零数时有回显。

因此我们认为后端一定对“xxx”做了变换。不知道0、1能不能让您想起什么,在一般的逻辑运算中,0代表假值,1代表真值。而在MySQL中,0被视为假值,非零数被视为真值。输入0时无回显,输入非零数时有回显,那么很可能存在一个或运算符“OR”,让我们的输入和一个假值进行了一次或运算。因此,可以猜测查询的语句如下:

select xxx OR false from Flag;

当然,这个假值,可以是0(false),也可以是这个表的某个字段名,因为在MySQL中,字符串在进行逻辑运算时,不能被正确地转换了类型,一般会被视为假值0。

根据我们猜测的查询语句,有以下两种方法可以获得flag。

法一

在select中,可以使用逗号来连接待查询的字段,即:

select name1,name2 from Flag;

我们的目的是消除或运算符的影响。利用这一点,可以构造出一种查询语句如下(方法不唯一):

select *,0 OR false from Flag;

根据逻辑运算符,该语句等价于:

select *,0 from Flag;

这里的0,实际上是在查询结果中增加了一列,该列的名称是“0”,每条记录在该字段的值也都是0,这一列并不属于表Flag,只是将查询的结果进行了拼接。

这样就能获取该表的所有记录了。

法二

该方法建立在已知Flag表的字段名为“flag”,且后端所使用的逻辑运算符为“||”的情况。

事实上,在MySQL中,管道符“||“也可以作为逻辑运算符,因此后端不一定用的就是”OR“。在这种情况下,MySQL有一种机制可以切换”||“的作用:

sql_mode=pipes_as_concat;

该语句通过系统变量sql_mode,赋予“||”以CONCAT()函数的作用,将查询结果按字段连接成一个字符串,而不再用于逻辑或运算。这就能破坏后端查询语句的语义。对此,可以构造以下语句获取flag(方法不唯一):

select 0;set sql_mode=pipes_as_concat;select 0||flag from Flag;

这等价于分别执行了三条语句:

select 0;

set sql_mode=pipes_as_concat;

select concat(0,flag) from Flag;

第一句并不重要;第二句则是切换了“||”的功能;最后一句对Flag表进行查询,将每条记录中flag字段的值和0进行拼接后再返回,因此如下图中flag前面会有一个“0”字符。

总结

这道SQL注入主要考验猜测、分析后端查询代码结构的能力。笔者在看其他作者对于这道题的WP时,发现大部分文章对猜测“select xxx||flag from Flag”的分析过程,都没有讲解得很清楚,往往都是一笔带过,用”显然可能应该是这样“等等,来搪塞读者,使人理解起来非常困难。事实上如何猜测得出这个查询语句,是关键所在。因此,我希望我自己浅薄的思考、分析的过程,能够帮助各位更好地来进行理解,理解“为什么能这样猜”。

在本题中,法二对大家也有一定的启示,有时我们可以修改MySQL的系统变量以达成一些目的。

  • 22
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值