SQL注入漏洞

1.原理:

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

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

2.基础SQL语句:

select column_name from tables_name

在表tables_name中查询字段column_name

select column_name from tables_name where 已知字段名=已知的条件

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

3.information_schema

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

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

数据库库名的字段名为schemata_name

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

数据库库名表名的字段名分别是tables_schematable_name

3.columns表存储该用户创建的所有数据库的库名、表名和字段名。

数据库库名、表名和字段名的字段名分别是tables_schematable_namecolumn_name

information_schema.tables:数据库的表名

information_schema.columns:数据库的列名

4.limit的用法

limit子句是用于限制查询结果返回的数量,常用于分页查询。也就是SQL查询出来的结果集,按照升序排列,由小到大排列。

语法:limit m,n

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

​ n:是指取n条记录

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

5.注释符:

# …… :#号后面的都会被注释

– …… :–号后面的都会被注释,不过在 – 的前后都需要加空格再加数据

/* … */ :内联注释,内联注释可以用于整个SQL语句中,用来执行SQL语句。

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

6.SQL注入常规命令查询:

id=1 union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=’数据库名称’ //查表名

id=1 union select 1,2,group_concat(column_name) from information_schema.columns where table_name=’表名称’ //查字段名(列名)

id=1 union select 1,2,字段名 from 表名 //查详细信息

7.SQL注入中常用的函数及命令:

1.union:union操作符用于合并两个或者多个select语句的结果集。

如:sql1: N行,sql2: M行,sql1 union sql2 —> N+M行

语法:select column_name from table_name1 union select column_name from table_name2

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

1、能否从2张表查询再union呢?

可以,union 合并的是”结果集”,不区分在自于哪一张表.

2、取自于2张表,通过”别名”让2个结果集的列一致。那么,如果取出的结果集,列名字不一样,还能否union.

可以,而且取出的最终列名,以第1条sql为准

3、union满足什么条件就可以用了?

只要结果集中的列数一致就可以.(如都是2列或者N列)

4、union后结果集,可否再排序呢?

可以的。Sql1 union sql2 order by 字段

注意: order by 是针对合并后的结果集排的序.

5、如果Union后的结果有重复(即某2行,或N行,所有的列,值都一样),怎么办?

这种情况是比较常见的,默认会去重.

6、如果不想去重怎么办?

union all

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
1、 union会去掉重复的行
SELECT id,num FROM num_a UNION SELECT id, num FROM num_b

2、order by对union后的结果集排序
SELECT id,num FROM num_a UNION SELECT id, num FROM num_b ORDER BY num DESC

3、UNION ALL不会过滤重复的行
SELECT id,num FROM num_a UNION ALL SELECT id, num FROM num_b

4、把num_a和num_b不同的索引结果保留, 相同的索引结果相加 然后输出:
SELECT a.id, ( a.num + b.num ) AS num FROM num_a AS a INNER JOIN num_b AS b ON a.id = b.id
UNION ALL
SELECT * FROM num_a AS a WHERE NOT EXISTS( SELECT * FROM num_b AS b WHERE a.id = b.id )
UNION ALL
SELECT * FROM num_b AS b WHERE NOT EXISTS( SELECT * FROM num_a AS a WHERE a.id = b.id )
ORDER BY id ASC

5、第二种方法用子查询分组统计,也可以达到同样的效果
SELECT id, SUM( num ) AS num FROM ( SELECT * FROM num_a a UNION ALL SELECT * FROM num_b b ) tmp
GROUP BY id;

2.order by:order by关键字用于对结果集按照一个列或者多个列进行排序,默认升序。

语法:order by column_name

注意:order by语句是默认按照升序对记录进行排序,如果希望按照降序对记录进行排序,也可以使用desc关键字(order by被正则过滤掉的话,是可以用desc来进行判断字段)

例如:order by 1或者order by 2中其实1表示第一个栏位,2表示第二个栏位。如果当表中只有两个字段列时,order by 3就会报错,就是通过这种方式来判断字段数。

3.concat:将多个字符串连接成一个字符串。

语法:concat(str1,str2)

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

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

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

语法:group_concat( [distinct] 要连接的字段 [order by 排序字段 asc/desc] [separator ‘分隔符’])

说明:distinct可以排除重复值,order by子句可以对结果中的值进行跑徐,separator是一个字符串值,缺省为一个逗号。

(以id分组,把name字段的值打印在一行。)

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

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

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

语法:substr(string,start,length)

参数:string:必选,数据库中需要截取的字段

​ start:必选。正数,从字符串指定位置开始截取;负数,从字符串结尾指定位置开始 截取;0,在字符串中第一个位置开始截取。

​ length:可选,需要截取的长度。即截取到结束位置

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

语法:ascii(str)

7.database():当前使用的数据库。