zoukankan      html  css  js  c++  java
  • sql注入学习笔记 详解篇

    sql注入的原理以及怎么预防sql注入(请参考上一篇文章)  

      https://www.cnblogs.com/KHZ521/p/12128364.html

    (本章主要针对MySQL数据库进行注入)

    sql注入的分类:

      根据注入类型分类:

        1.union联合注入  

        2.报错注入

        3.盲注

          布尔类型盲注

          延时盲注

      根据注入位置分类

        get注入

        post注入

        请求头注入

      根据sql语句不同分类

        数字型注入

        字符型注入

    sql 注入的步骤:

      1.寻找注入点

        哪些地方可能存在注入点(所有与数据库交互的地方都有可能存在注入点)

        一般get请求注入点判断的方式,例:假设参数为?id=1在携带参数的后面使用?id=1',(请注意单引号,如果单引号被数据库查询)

     ?id=1'            
    //使用单引号使数据库报错,引发数据库异常(有时候使用双引号闭合的时候,单引号是不会报错的 在可能存在注入点的地方多尝试就好了)假如提交了?id=1'
    //和id=1时候出现出现明显不一样的页面,就表示可能存在注入点,当然,也有可能是被waf拦截了
    //假设php中查询的sql语句为 
    sql = "select * from user where id='$id' limit 0,1";
    如果id正常为1是可以查询成功的,加上单引号(?id=1')报错是因为使sql语句变成了
    select * from user where id='1'' limit 0,1 所以会出现sql异常

      2.判断字符型注入还是数字型

        常用的类型判断方式(%23为url编码中的# , 表示sql中的注释,以下出现%23都表示#) :判断 1'and 1=1%23 与 1' and 1=2%23的区别

        

    //假设php中查询的sql语句为 
    sql = "select * from user where id='$id' limit 0,1";
    假设当前id的值为1'and 1=1%23当前的sql语句为
    select * from user where id='1' and 1=1#' limit 0,1
    id值为1' and 1=2%23的sql语句为
    select * from user where id='1' and 1=2#' limit 0,1
    因为and 1=1 恒定为真 和 and 1=2 恒定为假的区别进行比较判断字符型的闭合类型

    注意:如果select * from user where id="1' and 1=1#" limit 0,1 只判断一次是无法进行判断闭合符号的 这样和直接查询id=1的结果是一样的
    注意2:数字型的判断也可以通过and 1=1和and 1=2进行判断的 只不过不需要闭合单引号和添加后面的注释
    例:sql="select * from user where id=$id limit 0,1";将传递来的id设置为1 and 1=1和1 and 1=2 就可以根据页面结果的不同判断是否为数字型(因为不存在多余的闭合符号所以不需要添加注释)
    小知识:字符型sql是可以不加注释来验证的 我们可以构造特殊的参数让其正常显示:id=1' and '1'='1
    这样实际的sql语句就是select * from user where id='1' and '1'='1' limit 0,1 也可以正常使用哦,适用于注释被屏蔽的情况下使用

      获取数据:

       union联合注入:

        什么是union联合注入:通过使用union联合查询查询数据库中的数据

        特点:简单,有数据的回显位置,效率高

        union的使用条件:两条查询语句必须具有相同的列,所以想要使用union,必须先判断本次查询的列数是多少

         

         如果不相同,就会出现错误

          

         假设我们不确定当前sql语句查询的列数是多少,我们可以通过使用order by判断当前查询

         如果指定的列数小于等于当前列数,语句正常,

        

        语句大于当前使用的列数就会出现数据库异常,可以根据order by 指定第几列判断当前查询的字段是多少

        

        具体操作步骤:

         1.查找注入点  单引号报错,证明存在注入点

         

         2.判断字符闭合类型:

          (1)尝试数字型

           id=1 and 1=1

           

           id=1 and 1=2

            

             与id=1 and 1=1 比较,页面结果相同,如果and 1=2被数据库执行,页面结果一定与id=1 and 1=1不同 所以肯定不是数字型注入

           (1)单引号尝试

             id=1' and 1=1--+  

            

             id=1' and 1=2%23

             

             证明闭合符号为单引号

         3.使用order by判断字段数:

          id=1' order by 4%23页面不是正常结果,字段数不为4

          

          id=1‘ order by 3%23结果正常,表名字段数为3

          

         4.判断数据回显位置

          id=-1' union select 1,2,3%23   在这里解释以下为什么使用-1,当我们正常使用id=1查询数据的时候,会正常查询到数据库中的内容,使用-1是为了使第一个查询语句查询到的结果为空,当第一个查询语句查询结果为空的时候,我们给定的1,2,3才会在页面中显示出来,有时候,可以使用id=1' and 1=2来使查询到的结果为空

          

          由此可知2,3位置可以显示数据

         5.查询数据内容:

          (1)查询数据库名和版本信息

          ?id=-1' union select 1,database(),version()%23

          

          (2)查询数据表名(可以通过limit控制查询第几个表)

          

          查询到的表分别是1.emails 2.referers 3.uagents 4.users(账号密码信息可能存放在users表中)

          (3)查询数据字段名

          

           字段名分别为:1.id 2.username 3.password

          (4)查询数据表内容

           拿到了表名,字段名就可以直接在表中查询数据了。(也可以通过limit控制显示的行数)

           

    报错注入的特点:(有的人会将报错注入分类到盲注里面)

      学习报错注入之前,让我们先来学习几个sql函数

        concat

        updatexml 和 ExtractValue

        效率增加函数:group_concat

    报错注入的原理:

      当sql语句拥有语法错误的时候,我们可以使用指定的错误的显示结果为我们向要的显示结果

        只要页面的出现了详细的错误信息(明显不是服务器提供的专门的错误页面,而是打印出来的sql具体语法错误

    )就可以尝试使用报错注入 例如:

        

       构造注入语句:

        将报错的语句指定为我们的xml语法错误(是因为xml解析的时候存在了xml没有的特殊字符0x7e(0x7e是16进制~的表示),当然,也可以直接使用xml解析中不存在的字符串,注意别忘了加引号哦)

           不要问为什么这个报错可以把数据库的名字显示出来  你这就好像在问为什么select能够查找到数据一样

        

    盲注:

      先来学习一下我们需要用到的函数  

        left(字符串, 字符个数):截取字符串 返回从左往右数几个字符

        substr(字符串,第几个字符,截取几个):截取字符串

        mid() 同substr

        ascii(字符) 将字符串转换为ASCII码(区别大小写)

        ord() 同ascii函数

        length() 返回字符串的长度

        count() 返回字段数

      盲注一般都会采用工具进行注入(太麻烦),但是盲注的原理大家还是了解的 (有时候工具不行,但是就是存在注入点,没办法,只能使用手工了)

    get注入

    post注入

    请求头注入

    数字型注入

    字符型注入

        

        

      

  • 相关阅读:
    395. Coins in a Line II
    394. Coins in a Line
    221. Maximal Square
    64. Minimum Path Sum
    [LeetCode] 129. Sum Root to Leaf Numbers Java
    [LeetCode] 117. Populating Next Right Pointers in Each Node II Java
    [LeetCode] 116. Populating Next Right Pointers in Each Node Java
    [LeetCode] 114. Flatten Binary Tree to Linked List Java
    [LeetCode] 113. Path Sum II Java
    [LeetCode] 112. Path Sum Java
  • 原文地址:https://www.cnblogs.com/KHZ521/p/12129283.html
Copyright © 2011-2022 走看看