关于sql注入方法的补充

前言

打了些比赛后发现sql注入还有很多姿势没有学会,这篇博客专门对新见到的sql注入进行补充说明。

模糊查询注入

这是从unctf的一道题目学习到的。

关于模糊查询

模糊查询的语句格式一般如下:
SELECT 字段(一般用*) FROM 表 WHERE 某字段 Like 条件

在mysql中,模糊查询有四种用法:

  1. 匹配任意个数与类型的字符

    1
    2
    3
    %a%:把某字段中含有a的数据全部搜索出来
    where username like %a% and username like %d%:把username字段中含有a与d的数据全部搜索出来
    %a%d%:把某字段中含有a和d的数据全部搜索出来,并且a在d的前面
  2. 匹配任意单个字符

    1
    2
    3
    _a_:把某字段中三个字的且中间为a的数据全部搜索出来
    __a:把某字段中三个字的且最后为a的数据全部搜索出来
    等等
  3. 指定一个范围

    1
    [abc]1:搜索a1、b1与c1,如果中括号内为连续的数字或字母,可以简写为[1-5]或者[a-e]
  4. 指定一个范围排除之

    1
    [^abc]1:搜索除a1、b1与c1外_1的结果,如果中括号内为连续的数字或字母,可以简写为[^1-5]或者[^a-e]

使用条件

在登录时要登录admin但是被限制登录(例如限制ip)时可以使用模糊查询,也就是已知要查询的数据名时可以使用。

慢查询日志

这是深育杯中的ezsql题目,用到了慢查询日志来进行sql注入。

关于慢查询日志

MySQL的慢查询日志用来记录在MySQL中响应时间超过阀值的语句,具体指运行时间超过long_query_time值的SQL语句,会被记录到慢查询日志中。long_query_time的默认值为10。默认情况下,Mysql数据库并不启动慢查询日志,需要我们手动来设置这个参数。

使用方法

首先使用setglobal slow_query_log=1;开启慢查询日志,接着用setglobal slow_query_log_file='';设置慢查询日志的位置。这里可以直接使用sleep()设置执行时间,如果sleep被过滤了,我们可以修改慢查询日志的时间值:setglobal long_query_time=0.000001;,然后再查询webshell访问就可以了。

猜测后端payload

这是buu中的[SUCTF 2019]EasySQL这道题目,有两种解题方法,这里都介绍下。

跑一下fuzz发现能过滤的基本都过滤了,所以联合、报错、盲注等方法都不能使用。

这题要我们对后端语句进行猜测,这是这题最难的地方,通过输入非零数字得到的回显1和输入其余字符得不到回显来判断出内部的查询语句可能存在有||,也就是select 输入的数据||内置的一个列名 from 表名。接着使用堆叠注入验证,得出payload大概为:

1
sql="select".sql="select".post[‘query’]."||flag from Flag";

方法一

输入*,1,使语句变为:

1
select *,1||flag from Flag

此时1||flag计算为1,因此payload最终被识别为:

1
select *,1 from Flag

方法二

使用堆叠注入写入select @@global.sql_mode查看,发现PIPES_AS_CONCAT,因此我们可以进行利用。

输入1;set sql_mode=pipes_as_concat;select 1,这里使用到了pipes_as_concat使||变为连接操作符,这样就绕过了原本应有的判断导致语句无返回值。

这里对常见的sql_mode值进行补充:

ONLY_FULL_GROUP_BY:出现在select语句、HAVING条件和ORDER BY语句中的列,必须是GROUP BY的列或者依赖于GROUP BY列的函数列。
NO_ZERO_IN_DATE:这个模式影响了是否允许日期中的月份和日包含0。

ERROR_FOR_DIVISION_BY_ZERO:在INSERT或UPDATE过程中,如果数据被零除,则产生错误而非警告。如果未给出该模式,那么数据被零除时MySQL返回NULL

NO_ENGINE_SUBSTITUTION:如果需要的存储引擎被禁用或未编译,那么抛出错误。不设置此值时,用默认的存储引擎替代,并抛出一个异常

PIPES_AS_CONCAT:将”||”视为字符串的连接操作符而非或运算符,这和Oracle数据库是一样的,也和字符串的拼接函数Concat相类似

ANSI_QUOTES:启用ANSI_QUOTES后,不能用双引号来引用字符串,因为它被解释为识别符