小迪-day12(SQL注入简要概述)

1、相关sql函数、语句

1.1 count()

1.1.1 count(column_name)

​ count(column_name)是计算数据库表中指定列有多少行,

​ 例:

SELECT COUNT(column_name) FROM table_name

1.1.2 count(*)

可以计算表中有多少行(有多少条数据)表中记录数

1.2 sum()

返回数值列的总和(只能运用于数值列)

1.3 exists()

exists()用于判断查询字句是否有记录,如果有一条或多条记录,则返回True,没有记录则返回False

EXISTS 语法

SELECT column_name(s)
FROM table_name
WHERE EXISTS
(SELECT column_name FROM table_name WHERE condition);

1.4 order by

ORDER BY 语句用于根据指定的  列  对结果集进行排序。

ORDER BY 语句默认按照升序对记录进行排序。

如果您希望按照降序对记录进行排序,可以使用 DESC 关键字。

order by 根据来进行排序,后面跟上 列名 asc(升序,默认)/desc(降序)

例如:

SELECT Company, OrderNumber FROM Orders ORDER BY Company

如果order by 后面的列数,大于表的列数,就会报错。

可以在order by 后面写数字,代表一个临时的列(详见标题2),如果数字数大于表的列数就会报错

例如:

此时有1,2,3,4四个数字代表四个临时列,由于表只有三个列,所以报错

1.5 union

union 联合查询,将多条查询语句的结果集放在一个表中

UNION 操作符用于合并两个或多个 SELECT 语句的结果集。

请注意,UNION 内部的每个 SELECT 语句必须拥有相同数量的列。列也必须拥有相似的数据类型。同时,每个 SELECT 语句中的列的顺序必须相同。

SQL UNION 语法

SELECT column_name(s) FROM table1
UNION
SELECT column_name(s) FROM table2;

**注释:**默认地,UNION 操作符选取不同的值(结果集中没有重复的)。

​ 如果允许重复的值,请使用 UNION ALL

SQL UNION ALL 语法

SELECT *column_name(s)* FROM *table1*
UNION ALL
SELECT *column_name(s)* FROM *table2*;

**注释:**UNION 结果集中的列名总是等于 UNION 中第一个 SELECT 语句中的列名。

1.6 group_concat()

group_concat()函数可以将组中的字符串连接成为具有各种选项的单个字符串。

最简单用法,可以把多个结果用逗号分开,形成一个字符串

2、语句 select 1 from 是什么?

select 1 from ...   与 select anycol(目的表集合中的任意一行)from ...  
与 select * from ...  都可以用来查询数据是否有记录

select 1 from 中的1是一常量(可以为任意数值),查到的所有行的值都是它,但从效率上来说,1>anycol>*,因为不用查字典表

测试场景:

kc表是一个数据表,假设表的行数为10行。

小迪-day12(SQL注入简要概述)_第1张图片

1:select 1 from kc 增加临时列,每行的列值是写在select后的数,这条sql语句中是1

2:select count(1) from kc 不管count(a)的a值如何变化,得出的值总是kc表的行数

3:select sum(1) from kc 计算临时列的和

在MySQL中用 1 测试了一下,发现结果如下:

1:测试结果,得出一个行数和kc表行数一样的临时列(暂且这么叫,我也不知道该叫什么),每行的列值是1;

2:得出一个数,该数是kc表的行数;

3:得出一个数,该数是kc表的行数;

然后我又用“2”测试,结果如下:

1:得出一个行数和kc表行数一样的临时列,每行的列值是2;

2:得出一个数,该数是kc表的行数;

3:得出一个数,该数是kc表的行数×2的数

然后我又用更大的数测试:

1:得出一个行数和kc表行数一样的临时列,每行的列值是我写在select后的数;

2:还是得出一个数,该数是kc表的行数;

3:得出一个数,该数是table表的行数×写在select后的数

结果图:


注意观察下面的两幅图的区别。

**
**

**

**

综上所述:

第一种的写法是增加临时列,每行的列值是写在select后的数;第二种是不管count(a)的a值如何变化,得出的值总是table表的行数;第三种是计算临时列的和

​ 当不需要知道结果是什么,只需要知道有没有结果的时候,可以使用select 1 作为子查询结果是否存在判断,这样可以提高性能。

3、SQL注入

1.1 前言

​ SQL注入漏洞将是重点部分,其中SQL注入又非常复杂,区分各种数据库类型,提交方法,数据类型等注入,我们需要按部就班的学习,才能学会相关SQL注入的核心。同样此类漏洞是WEB安全中严重的安全漏洞,学习如何利用,挖掘,修复也是很重要的。

小迪-day12(SQL注入简要概述)_第2张图片

​ SQL注入简单的说就是,通过添加一些sql语句在一些原有sql语句中可注入的地方,达到改写sql语句功能的目的,从而获取到数据库相关信息(高危)

1.2 MySQL注入

小迪-day12(SQL注入简要概述)_第3张图片

1.3 sqlilabs靶场搭建

下载文件放进phpstudy的www文件下,然后该配置文件,更改数据库用户名,密码,

然后进入靶场初始化数据库

实例:less-2

小迪-day12(SQL注入简要概述)_第4张图片

查看源码:

发现源码中$id变量接受后没有做任何限制,为恶意sql注入创造了条件。

查询数据库security可知,该数据库有4张表。

查询users表:

查询emails表:

小迪-day12(SQL注入简要概述)_第5张图片

在数据库中执行如下语句:

select * from users where id=-1 union select 1,email_id,3 from emails limit 0,1;

可得:

*** 如果执行如下语句:

 select 1,email_id,3 from emails union select * from users;

则表结构为:

说明:如果使用union联合查询,产生表的列名为第一条select语句查询表的列名
解释:
(limit 只显示第一条)
此处令id = -1 目的是使前一条select语句查询不到结果,然后显示出后面的select语句

语句:select 1,email_id,3 from emails 
1:代表临时产生的一列,放在结果集的第一列,列中的值为1
email_id: 放在第二列
3:代表临时产生的一列,放在结果集的第一列,列中的值为3

将上述代码放在url中执行:可以将email查询到用户名中。

image-20221108191426881

注: url中 %20 代表空格

1.4 测试题:

参数x有注入,以下那个注入测试正确? a,b,c

a. www.xiaodi8.com/news.php?y=1 and 1=1&x=2

b. www.xiaodi8.com/news.php?y=1&x=2 and 1=1

c. www .xiaodi8.com/news.php?y=1 and 1=1&x=2 and 1=1

d. www .xiaodi8.com/news.php?xx=1 and 1=1&xxx=2 and 1=1

**总结:**可控变量,带入数据库查询,变量未存在过滤或过滤不严谨。

1.5 判断是否存在注入点?

1、逻辑值
    and 1 = 1		页面正常
    and 1 = 2		页面异常
    则可能存在注入点
(在url中加入)


2order by
		通过order by 判断注入的字段数
	
	order by 1,2,3,4 如果123不报错,1234报错,说明该表中只有三列,存在sql注入
    

1.6 信息收集

sql获得相关信息
数据库版本:version()
数据库名字:database()
数据库用户:user()
操作系统:@@version_compile_os   		没有括号!

直接在sql语句中写

1.7 MySQL 5.0+版本探测

在mysql5.0以后的版本

存在一个information_schema数据库、里面有 所有存储记录数据库名表名列名的数据库
相当于可以通过information_schema这个数据库获取到数据库下面的表名和列名。

1.7.1 获取相关信息

可以使用 . 来调用子类

information_schema.tables			#information_schema下面的所有表名
information_schema.columns			#information_schema下面所有的列名
table_name										#表名
column_name										#列名
table_schema									#数据库名

1、查询security数据库下的所有表

2、查询users表下的所有列名

1.8 墨者学院例题

点进去发现里面有个公告

?id=1 疑似sql注入点

判断是否有sql注入:

?id=1 and 1=1	正常
?id=1 and 1=2 	异常

说明存在sql注入

然后判断该表的字段数

?id=1 order by 1		...		?id=1 order by 4

当by后面的数字为5时,页面不正常,说明字段数为4

然后判断回显的字段是哪几个?

使用union联合查询,注意此时让id=-1 查询不到前面的数据,则会把后半段select语句显示出来
此处说明第二列和第三列会被显示

信息搜集:

version() 查询mysql版本号,5.0+说明此处可以使用数据库 information_schema.tables/columns

database() 查询此数据库名称

小迪-day12(SQL注入简要概述)_第6张图片

user() 查询数据库用户名

@@version_compile_os 查询操作系统名称

查询该数据库下的所有表,

table_name 代表	表   table_schema代表数据库,
information_schema.tables	存储了所有表信息(5.0+)

查询该表下的所有字段(列)

image-20221109191553480

column_name 代表列名
information_schema.columns	存储了所有列信息(5.0+)

group_concat(列名) 把所有结果拼接

1.9 链接

1.9.1sqlilabs靶场相关解答

https://www.yuque.com/office/yuque/0/2022/pdf/2476579/1647239035090-84752d34-43a3-4d21-953e-612760a5e4d7.pdf?from=https%3A%2F%2Fwww.yuque.com%2Fweiker%2Fxiaodi%2Fgeg7au

e=“zoom:25%;” />

查询该数据库下的所有表,

table_name 代表	表   table_schema代表数据库,
information_schema.tables	存储了所有表信息(5.0+)

查询该表下的所有字段(列)

[外链图片转存中…(img-If0PYi1y-1670312423010)]

column_name 代表列名
information_schema.columns	存储了所有列信息(5.0+)

group_concat(列名) 把所有结果拼接

1.9 链接

1.9.1sqlilabs靶场相关解答

https://www.yuque.com/office/yuque/0/2022/pdf/2476579/1647239035090-84752d34-43a3-4d21-953e-612760a5e4d7.pdf?from=https%3A%2F%2Fwww.yuque.com%2Fweiker%2Fxiaodi%2Fgeg7au

你可能感兴趣的:(CTF,sql,数据库)