前言
打了些比赛后发现sql注入还有很多姿势没有学会,这篇博客专门对新见到的sql注入进行补充说明。
模糊查询注入
这是从unctf的一道题目学习到的。
关于模糊查询
模糊查询的语句格式一般如下:SELECT 字段(一般用*) FROM 表 WHERE 某字段 Like 条件
在mysql中,模糊查询有四种用法:
匹配任意个数与类型的字符
1
2
3%a%:把某字段中含有a的数据全部搜索出来
where username like %a% and username like %d%:把username字段中含有a与d的数据全部搜索出来
%a%d%:把某字段中含有a和d的数据全部搜索出来,并且a在d的前面匹配任意单个字符
1
2
3_a_:把某字段中三个字的且中间为a的数据全部搜索出来
__a:把某字段中三个字的且最后为a的数据全部搜索出来
等等指定一个范围
1
[abc]1:搜索a1、b1与c1,如果中括号内为连续的数字或字母,可以简写为[1-5]或者[a-e]
指定一个范围排除之
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后,不能用双引号来引用字符串,因为它被解释为识别符