vlambda博客
学习文章列表

SQL注入-“错误”的语句为什么会得到“正确”的结果?


故事发生在前段时间准备内部CTF-SQL注入题目过程中。

前景提要

首先看下表的结构以及数据:

SQL注入-“错误”的语句为什么会得到“正确”的结果?

题目是要求实现一个查询,然后通过注入获取到admin的商品及其密码,再看下我的查询语句:

SQL注入-“错误”的语句为什么会得到“正确”的结果?

起因

我尝试在name字段进行SQL注入,过程中拼接出这样一个SQL语句:

SQL注入-“错误”的语句为什么会得到“正确”的结果?

这个语句的后半部分比较奇怪,但是它的查询结果是“正确”的,得到了我们需要的admin的商品及其密码:

SQL注入-“错误”的语句为什么会得到“正确”的结果?

那我们就需要研究一下这个语句为什么可以得到这样的结果了。

其一

首先我们先看一下后半条union select的语句:

SQL注入-“错误”的语句为什么会得到“正确”的结果?

执行发现输出了表中所有的password:

SQL注入-“错误”的语句为什么会得到“正确”的结果?

这条语句与常规语句的不同点在于等于号后面的值是在括号中的,那为什么会得到这个查询结果呢?我们一步一步来分析。

  • 首先,如果括号中是一个单独的字符串,那么和正常的结果没有区别

SQL注入-“错误”的语句为什么会得到“正确”的结果?
  • 如果括号中是一个条件语句,为true时无结果,为false时返回全部结果。

SQL注入-“错误”的语句为什么会得到“正确”的结果?
  • 为什么会是这样的结果呢?多次尝试之后得到了答案。我们的两个name均为字符串,而字符串默认为false,所以name=flase时会查询出所有name为字符串的password。

    “字符串默认为false,整数默认为true”

SQL注入-“错误”的语句为什么会得到“正确”的结果?
  • 所以这就可以解释为什么最开始的where name =('admin' and password='123')可以把两个password都输出出来,因为在条件语句中,and前面的'admin'相当于false,所以这个条件语句的结果最后肯定是false。

  • 既然我们已经知道了原因,那么再来一个这样的语句看看结果:

SQL注入-“错误”的语句为什么会得到“正确”的结果?
  • 首先针对admin/admin123这一条数据来说,password='admin123'结果为true,where name=true,但是name是admin是一个字符串,是flase,所以就不会输出了。针对wangyibo/orange这一条数据来说,password='admin123'结果为false,name=false就会输出这一条的password;

SQL注入-“错误”的语句为什么会得到“正确”的结果?

其二

根据上述分析我们可以看到union后面的查询语句,实际上是会查询出两个password的,那为什么整条语句查询的时候会只查询出一个password呢?

这个问题其实比较好猜测,第一时间就想到了去重问题,我们的product和password都有一个orange,那么是不是查询结果自动去重了呢?更改password之后发现果然如此:

SQL注入-“错误”的语句为什么会得到“正确”的结果?

但是要知道select是不会自动去重的,那么问题就出现在了union这儿:

SQL注入-“错误”的语句为什么会得到“正确”的结果?

使用union all就可以得到不去重的结果:

SQL注入-“错误”的语句为什么会得到“正确”的结果?





🔍
作者介绍
SQL注入-“错误”的语句为什么会得到“正确”的结果?
🕵️‍♀️
ABOUT US
有 趣 灵 魂 集 结 地
思 路 总 结 大 本 营

SCAN AND FOLLOW US NOW
@BUG侦探