SQL注入
SQL注入
MooSeSQL注入
概述
SQL注入就是指Web应用程序对用户输入数据的合法性没有判断,前端传入后端的参数是攻击者可控的,并且参数带入数据库查询,攻击者可以构造不同的SQL语句来实现对数据库的任意操作。
这里以PHP代码为例:
1 | $sql = ''SELECT \* FROM users WHERE id = $_GET [ 'id' ]''; |
比如这里的参数 id 是可控的,还是带入了数据库查询,所以非法用户可以任意拼接SQL语句来进行攻击。
1.原理
SQL注入的原理:
SQL注入漏洞的产生需要满足以下两个条件:
参数用户可控:前端传给后端的参数内容是用户可以控制的。
参数带入数据库查询:传入的参数拼接到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_namecolumn_name
limit m,n1
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查询出来的结果集,按照**升序**排列,有小到大排列。
**语法:**/*······*/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中,常见注释符的表达方式:
```
#······
```
- #号后面的都会被注释
----
`````
--······
`````
- **--**号后面的都会被注释
- 注意:在 **--** 的**前后**都需要**加空格再加数据**!!!
-----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
- 内联注释,内联注释可以用于整个SQL语句中,用来执行SQL语句。
例如:index?id=-10 /*!union*/ /*!select*/ 1,2,3
--------
#### 常见命令查询
- 查表名select column_name from table_name1 union select column_name from table_name21
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
**语法**: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
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**:**将多个字符串连接成一个字符串**
**语法**:group_concat( [distinct] 要连接的字段 [order by 排序字段 asc/desc] [separator ‘分隔符’])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产生的同一个分组中的值连接起来,返回一个字符串的结果。
**语法:**substr(string,star,length)1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
**说明:**
- distinct可以排除重复值
- order by子句可以对结果中的值进行排序
- separator是一个字符串值
#### substr()函数
substr()函数:用来截取数据库某个字段中的一部分。
**语法**:
**参数:**
- string:必选,数据库中需要截取的字段
- start:必选。
- - 正数,从字符串指定位置开始截取;
- - 负数,从字符串结尾指定位置开始截取;
- - 0,在字符串中第一个位置开始截取。
- length:可选,需要截取的长度。缺省。即截取到结束位置
#### ascii()函数
ascii()函数:返回字符串str的**最左边的数值**。
**语法:**
1
ascii(str)
![img](SQL注入/wps12.jpg) ![img](SQL注入/wps13.jpg)
此外还有一些其他常用的SQL注入函数,后续再记录
***\*·二、SQL注入漏洞种类\****
***\*@1.1 union注入(整型和字符型)\****
\>这里先介绍整数型注入和字符型注入。
#