SQL注入

SQL注入

概述

SQL注入就是指Web应用程序对用户输入数据的合法性没有判断,前端传入后端的参数是攻击者可控的,并且参数带入数据库查询,攻击者可以构造不同的SQL语句实现对数据库的任意操作

这里以PHP代码为例:

1
$sql = ''SELECT \* FROM users WHERE id = $_GET [ 'id' ]'';

比如这里的参数 id 是可控的,还是带入了数据库查询,所以非法用户可以任意拼接SQL语句来进行攻击。

1.原理

SQL注入的原理:

​ SQL注入漏洞的产生需要满足以下两个条件

  1. 参数用户可控:前端传给后端的参数内容是用户可以控制的。

  2. 参数带入数据库查询:传入的参数拼接到SQL语句,且带入数据库查询。

2.本质

SQL注入攻击的本质:

SQL注入攻击其实就是:

  • 攻击语句全都是由前端的输入传入后端

  • 通过浏览器的网址传入到后台数据库进行查询

  • 通过数据库返回的值判断你所得到的数据

这就是SQL注入的本质。

数据库 information_schema

在学习SQL注入漏洞之前,先学习一个相关的知识点。

​ 在MySQL 5.0版本之后,MySQL默认在数据库中存放一个“information_schema”的数据库,在该库中,需要记住三个表名,分别是:

  • schemata
  • tables
  • columns

schemata表

schemata表存储该用户创建的所有数据库的库名。

其中记录数据库库名的字段名为:

1
schemata_name

tables表

tables表存储该用户创建的所有数据库的库名表名

​ 其中记录数据库库名和表名的字段名分别是:

  • tables_schema
    
    1
    2
    3

    - `````
    table_name

column表

columns表存储该用户创建的所有数据库的库名表名字段名

​ 其中记录数据库库名表名字段名的字段名分别是

  • table_schema
    
    1
    2
    3

    - ````
    table_name
  • column_name
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57

    ----------

    - **information_schema.tables**:**数据库的表名**

    - **information_schema.columns**:**数据库的列名**

    --------

    ![img](SQL注入/wps1.jpg)

    ### **判断流程**

    **SQL注入的具体判断流程**:

    - 注入点测试:也就是先需要测试交互方式,判断浏览器提交数据和web浏览器的交互方式。
    - **判断字符的类型**:**整数型**还是**字符型**
    - **构造闭合**:<u>***字符型需要***</u>,<u>***整型不需要***</u>
    - **查询字段数**:在构造SQL语句并判断数据库表的**行数**
    - **判断回显位**:通过构造SQL语句,找到数据库回显的位置
    - **查询**数据库的**基本信息**:数据库名字、版本
    - **爆数据库的敏感信息**:数据库**表名**、字段名(**列名**)、字符中的数据



    ### SQL语句

    在学习SQL注入之前,需要学习了解SQL语句,这里就重点记一些基础的**SQL语句**:

    #### 基础语句

    ##### 查询语句select

    - 在表tables_name中查询字段column_name

    ```
    select column_name from tables_name
    ```

    -----

    - 在已知的条件下,在表tables_name中查询字段column_name

    `````
    select column_name from tables_name where···
    `````

    ------------

    ##### 分页查询limit

    **limit**子句是用于限制查询结果返回的数量,常用于**分页查询**。

    - 也就是SQL查询出来的结果集,按照**升序**排列,有小到大排列。

    **语法:**

    limit m,n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30

    **参数:**

    - m:是指记录开始的位置,从0开始,表示第一条记录

    - n:是指取n条记录

    例如:limit 0,1 的含义说就是表示从第一条记录开始,表示取最上面0到1之间的记录,即为第一条记录,取一条记录。

    #### 注释符

    在MySQL中,常见注释符的表达方式:

    ```
    #······
    ```

    - #号后面的都会被注释

    ----

    `````
    --······
    `````

    - **--**号后面的都会被注释
    - 注意:在 **--** 的**前后**都需要**加空格再加数据**!!!

    -----

    /*······*/
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11

    - 内联注释,内联注释可以用于整个SQL语句中,用来执行SQL语句。

    例如:index?id=-10 /*!union*/ /*!select*/ 1,2,3

    --------

    #### 常见命令查询

    - 查表名

    id=1 union select 1,2,group_concat(table_name) form information_schema.tables where table_schema='数据库名称'
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25

    -----------

    - 查字段名(列名)

    ```
    id=1 union select 1,2,group_concat(column_name) from information_schema.columns where table_name='表名'
    ```

    ------

    - 查详细信息

    ```
    id=1 union select 1,group_concat('字段名'),group_concat('字段名') form '表名'
    ```

    ------

    #### 常用函数

    #### union

    **语法**:

    select column_name from table_name1 union select column_name from table_name2
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48

    **注意:**

    - union内部的select语句必须拥有相同数量的列。
    - 列也必须拥有相似的数据类型。
    - 同时,每条select语句中的列的顺序必须是相同的。

    ![img](SQL注入/wps2.jpg) ![img](SQL注入/wps3.jpg)

    #### order by

    ​ **order by**关键字用于<u>对结果集按照一个列或者多个列进行排序,默认升序</u>。

    **语法**:

    ```
    order bu column_name
    ```

    注意:

    - order by语句是默认按照升序对记录进行排序

    - 也可以使用desc关键字进行降序排序
    - (**order by**被正则过滤掉的话,是可以用**desc**来进行判断字段)

    **用处:判断字段数**

    例如:

    order by 1或者order by 2中

    - 1表示第一个栏位,2表示第二个栏位。
    - 如果当表中只有两个字段列时,order by 3就会报错
    - 因此就可以通过这种方式来判断字段数。

    ![img](SQL注入/wps4.jpg) ![img](SQL注入/wps5.jpg)

    - 即如果**order by**后面的列数大于实际的列数就会报错:

    ![img](SQL注入/wps6.jpg)

    #### concat

    **concat**:**将多个字符串连接成一个字符串**

    **语法**:

    concat(str1,str2)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29

    注意:

    返回结果为连接参数产生的字符串,如果有任何一个参数为null,则返回值为**null**。

    ![img](SQL注入/wps7.jpg)

    ![img](SQL注入/wps8.jpg) ![img](SQL注入/wps9.jpg)

    #### group by

    **group by**语句:用于结合合计函数,根据一个或多个列队结果集进行分组。

    ```
    gourp by x
    ```

    ​ 会根据x的规则队数据进行分组,而分组的时候,MySQL会建立一个临时空表来进行分组。

    #### group_concat()函数

    group_concat()函数:该函数返回带有来自一个组的连接的非NULL值的**字符串**结果。

    **功能:**

    ​ 将group by产生的同一个分组中的值连接起来,返回一个字符串的结果。

    **语法:**

    group_concat( [distinct] 要连接的字段 [order by 排序字段 asc/desc] [separator ‘分隔符’])
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15

    **说明:**

    - distinct可以排除重复值
    - order by子句可以对结果中的值进行排序
    - separator是一个字符串值



    #### substr()函数

    substr()函数:用来截取数据库某个字段中的一部分。

    **语法**:

    substr(string,star,length)

**参数:**

- string:必选,数据库中需要截取的字段
- start:必选。
- - 正数,从字符串指定位置开始截取;
- - 负数,从字符串结尾指定位置开始截取;
- - 0,在字符串中第一个位置开始截取。
- length:可选,需要截取的长度。缺省。即截取到结束位置

####  ascii()函数

ascii()函数:返回字符串str的**最左边的数值**。

**语法:**

1
ascii(str)
![img](SQL注入/wps12.jpg) ![img](SQL注入/wps13.jpg) 此外还有一些其他常用的SQL注入函数,后续再记录 ***\*·二、SQL注入漏洞种类\**** ***\*@1.1 union注入(整型和字符型)\**** \>这里先介绍整数型注入和字符型注入。 #