我们学习 SQL 注入漏洞之前,我们必须要理解什么是数据库? 什么是SQL 、一些常见的数据库操作(增删查改),因为我们常听说的SQL注入,居于数据库,基于SQL发生的漏洞。
一、什么是数据库:
数据库,简单的来说就是电子方式的文件柜,存储数据,用户可以根据自己的需求来进行增删改查的操作。数据库也可以看作成图书馆,数据库中的 table 就是图书馆中的书架,数据库中的字段相当于图书馆中书架上的图书,数据库中的内容就是书中的信息。
数据库管理系统(Database Management System, DBMS) ,简言而知,就是为管理数据库而设计的软件操作系统。比如我们常说的:Mysql、Oracle、Microsoft SQL Server 。PostgreSQL等等。
在WEB中,一定会用到数据库,那么它在哪个位置呢? 我们来看看下面这个图
看到这张图中,显而易见的看到整个数据库在整个Web请求中,处在什么位置,提供了什么。我们知道,浏览网页,都是有各种数据集合而成,这些数据存放在数据库中,在请求某个信息时,也是由数据库来提供。
大致的网页的流程是:我们从前端请求数据,来到WEB服务器处,由相关的脚本语言代码来处理请求信息,上图中,我们想要查询7089bAt,这时候就是将这个数据带入到数据中查询,并将查询的相应信息经过相关的脚本语言代码处理后返回呈现在前端,我们的浏览器中。
在上述的例子中,我们用到了数据库查询操作,当然还有增加、修改、删除操作,既然有这些操作,那必然有一套规范语法,去使用这些语法来操作数据库。
二、什么是SQL
SQL (Structured Query Language:结构化查询语言),也有相关的资料说到SQL,就是单独的一个单词,SQL(涩儿Q,我这幽默而有趣的中文标 注,嘿嘿)。不管是哪种,我们只需要理解一个概念,SQL就是用来访问和操作数据库的一套规范化的计算机语言。
我们常见的很多数据库管理系统,访问和操作的方式,都是基于SQL规范语法来拓展的,基础大致相同,但又有一些细微的差别。
三、MySQL 介绍
1、什么是MySQL :
MYSQL 是一个中、小型关系数据库管理系统,由瑞典 MySQL DB 公司开发,目前属于Oracle 公司。 Mysql 是一种关联数据库管理系统,关联数据库将数据保存在不同的表中,而不是将所有数据放在一个仓库内,增加了速度和灵活性。MySQL 软件采用 GPL (GNU 用用公共许可证),由于体积小、速度快、成本低、开放源码这一特点,一般中小型网站的开发都选择MySQL 作为网站的数据库。
MySQL分为:商业版(MySQL Enterprise Edition 和 MySQL Cluster CGE) 和GPL版本(MySQL Community Edition)。
2、Mysql 数据库结构
存储引擎层:
SQL层:
1.接收上层的命令
2.语法检测
3.语义(SQL类型),权限
SQL类型:DDL数据定义语言 DCL数据控制语言 DML数据操作语言 DQL数据查询
4.专用解析器解析SQL,解析成多种执行计划
5.优化器:帮我们选择一个代价最低的执行计划(cpu,IO,MEM)
6.执行器:按照优化器的选择,执行SQL语句,得出获取数据方法
7.查询缓存:默认是关闭的. 一般会使用redis产品替代 Tair
8.记录日志:二进制日志
连接层:
1.通信协议:定义数据库如何与web进行通信
2. 线程:连接数量的管理
3. 验证:验证用户输入的用户名和密码,来连接数据库
SQL层的功能:
1. 判断语法、语句、语义
2. 数据库对象授权情况判断,授权失败不继续
3. 解析(解析器):将 sql 语句解析成执行计划,运行执行计划
4. 优化(优化器) :运行执行计划,基于算法,从执行计划中 选择最小代价的交给执行器
5. 执行(执行器):运行执行计划,最终生产如何去磁盘找数据方式
6. 将取数据的方式,交由下层(存储引擎层)进行处理
7. 最终将取出的数据抽象成管理员或用户能看懂的方式(表),展现在用户面前
8. 查询缓存:缓存之前查询的数据
3、MySQL 内置库 ( > = 5.7) :
- mysql :保存账户信息,权限信息,存储过程,event,时区等信息。
- sys: 包含了 一系列的存储过程,自定义函数以及试图来帮助我们快速了解系统的元数据信息(元数据: 关于数据的数据,如数据库名,表名,列的数据类型,或访问的权限等)
- performance_schema : 用于收集数据库服务器性能参数
- information_schema:提供了访问数据库元数据的方式,其中保存着关于MySQL服务器所维护的所有其他数据库的信息,如数据库名,数据库的表,表的数据类型等等。
在使用MySQL学习SQL语法之前,我们要先安装MySQL。 这节课MySQL安装,我们将使用的PHPstudy,它集成了WEB服务器所需要的软件,作为基础学习很是好用,一键安装,全套使用。作为基础学习,我 们应当把注意点放在知识点上,避免了调试报错一些列苦恼的事情,来影响自己。
4、安装PhpStudy
PHPstudy的安装 在之前也闹过PHPstudy后门的事件,官方也说明了,现在在官方网站下载的,是不会出现问题的,人外有人,天外有天,我们拿来学习就好了, 不必想这么多,有特殊情况的朋友,可以在虚拟机下学习使用。
如何将MySQL添加到环境变量中,便于 命令行中启动MySQL。
首先,找到PHPstudy的安装路径,打开Extensions文件,在这个文件下有MySQL文件夹,以为的为例,将下面路径复制:
现在已经将MySQL的环境变量添加进去了,现在试试是否成功添加,首先要确保在PHPstudy中启动了MySQL,然后打开CMD命令行,输 入mysql -u root -p,回车,然后输入密码root,回车,出现下图这种状态,即是添加成功:
备注:PHPstudy下的MySQL初始化密码是root,大家可以自行在主界面中的数据库选项栏下,修改密码。
我们上面安装调试使用CMD命令行连接访问MySQL数据库,当然还有基于图形化的MySQL数据库管理系统工具 —- Navicat。 大家常听说的phpmyadmin是基于WEB页面的本地MySQL数据库管理系统工具。
5、 mysql中几个关键表
关于MySQL下的information_schema数据库 在MySQL 5.0 版本以上都会自带一个默认的information_schema数据库。 MySQL 5.0版本以下是没有的,如果想要获取表名,只能暴力跑表名。
information_schema数据库有大量数据表,各个数据表中都存放着不同的描述信息,关于MySQL所在服务器上的一些元数据。
我们只需要关注上图中的三个表即可,因为我们在渗透测试中,经常使用到三个表进行一些SQL注入。
(1)SCHEMATA表:提供了当前MySQL中所有数据库的信息,就是show databases;所展示的结果。我们可以通过
select schema_name from information_schema.schemata; schema_name 的内容是数据库的名称。我们可以查询网站共有多少个数据库,
(2)TABLES表:提供了关于数据库中的表的信息(包括视图),详细表述了某个表的信息。发现table_schema的内容是数据库,而table_name 是数据库中对于的表
我们可以 通过这条语句select table_name from information_schema.tables where table_schema=’hack’; 去查询出指定数据库中对应的表。
(3) COLUMNS表:提供了每个表中的列的信息,详细表述了某个表中列的信息。
select column_name from information_schema.columns where table_schema=’hack’ and table_name=’hack’;
我们可以通过这条语句去查询出指定数据库中指定表中有哪些字段。在SQL注入中很常用
select table_name from (select * from information_schema.tables where table_schema='lingchen' order by table_schema limit 0,1) t limit 0,1;
这段代码的意思是:
1. 括号里面的就是查询lingchen 数据中所有的内容,这里只查第一个,使用order by 进行排序,
2 . 给括号内的查询起了一个t 的别名
3 继续过滤出来表名
对这三个简言之,就是,SCHEMATA表存放着所有数据库的名字,TABLES表存放着各个数据库下数据表的名字,COLUMNS表 存放着各个数据库下数据表下的列的名字。
在上面我们提到了,MySQL是管理数据库的软件,简言之,它将所有数据库集合到了一起来操作,那说了半天数据库到底是什么呢?
我继续做一个类比,我把MySQL比作一个小区,就叫小白帽小区吧,小白帽小区里有一栋又一栋高楼,每栋高楼又有1单元,2单元,3单元…每个单元 下又有1层,2层,3,4层。
在上面的类比中,我将高楼等同于数据库,每个单元比作数据表,单元下的每一层,可以比作数据表中的具体数据,有行,有列。这是一个类比的概 念,有了这个概念更方便理解操作数据库中的数据,就好比,你想回家,必定先回自己的小区,找到自己住的那一栋,再进自己的单元,回到自己的 楼层,打开自己的家门。操作数据库也有自己的流程。
下面我们正式进入数据库操作的阶段了。 以下例子,我全部都是用的命令行来操作的。 练习前一定不要忘了打开MySQL哦。
四、MySQL之数据库操作 :
注意:SQL语句对大小写不敏感。MySQL每句话都要以 ;结束,一定要是英文的分号。
0、链接数据库
首先,我们要使用命令行来连接数据库
mysql -u root -p (回车)
输入密码 (回车)
1、查看当前数据库
查看当前数据库,可显示出当前有多少数据库
SHOW DATABASES;
2、创建数据库
现在,我们创建一个数据库,用于此次练习
CREATE DATABASE lingchen;
3、指定操作的数据库
我们新建了lingchen数据库,我们要在这个数据库下操作练习,那么们要先选中/使用这个数据库:
use lingchen;
4、删除数据库
五、MySQL之数据表操作
在进行了数据库的操作后,我们现在进入数据表的操作。 数据库中可以包含大量的数据表,每张表中都包含着我们特定的数据。
1、创建数据表
CREATE TABLE test( id int(10) not null primary key auto_increment, name char(20) not null, age int(8) not null, sex char(20) not null );
首先,我们使用CREATE TABLE test创建了一个名为test的数据表,下面的语句即是这个表的简单规则,其中,将id设置为了这个数据表的主键键值 primary key,并且是自增长 - auto_increment,它的数据类型为 - int,not null代表数据不能为空,然后下面还设置了name,age,sex信息,其 中char为字符数据类型。
2、查看当下数据表
SHOW TABLES;
3.向数据表中插入数据
insert into 表名 set 字段1=值1,字段2=值2...;
insert into 表名(字段1,字段2,字段3...) values(值1,值2,值3...), (值1,值2,值3...), (值1,值2,值3...);
INSERT INTO test(name,age,sex) VALUES('7089bAt','99','F&M');
4、查询数据表中的数据:
SELECT FROM test;
(星号)代表所有的数据。
我们进一步看看什么是数据表,存在了哪些信息:
下图是刚才操作,并且插入数据后的数据表:
这是一个数据表,每个数据表都会涵盖这些信息,或者更多其他信息。
六、MySQL之数据操作
如果之前输入的数据不对怎么办呢?我们可以更改这条数据,或者 删除掉这条数据。
1. 更改数据
更改数据,我们使用UPDATE 这条语句
update test set name=’hack’ where id =2;
我们使用UPDATA关键字来修改数据,我们要更改的是test数据表下name的值,具体是id=1的那条数据,使用了WHERE来进行条件判断,id=1的数据是 哪条就删除那条
2. 删除数据:
delete from test where id=1;
delete from test where name='haha';
第二个语句,如果是相同的两个name 值,会删除两个同样name值的数据
七、MySQL 之数据查询操作
1. WHERE 子句,条件限制语句
select * 或其他 from 数据表(可以是多个) where 需要满足的条件
对数据还可以进行AND和OR限制。 AND代表两个条件都要满足。 OR代表满足其中一个条件即可。and 优先级是大于OR的,所以and会先执行。
2、ORDER BY 子句
ORDER BY 子句,排序语句:
select * 或其他 from 数据表(可以是多个) ORDER BY 字段 ASC/DESC
ASC是升序排序,DESC是降序排序。
我们可以使用数字来进行判断列长度,当使用 UNION 注入时,使用ORDER BY 判断字段数。因为当使用 ORDER BY 判断字段数时,当不存在的字段数排序时,就会报错,就可以判断出字段数是多少。
3、UNION 子句,联合查询
所谓联合查询,就是查询不同的两个表,将要查询的信息合并显示。
联合查询有两个子句:
UNION 子句: 查询后不会显示重复数据
UNION ALL 子句:查询后会显示重复数据
请注意,UNION 内部的 SELECT 语句必须拥有相同数量的列。列也必须拥有相似的数据类型。
SELECT 或其他 FROM 数据表1 UNION SELECT 或其他 FROM 数据表2;
我创建了个test2 数据表,插入了相同的数据,来对 UNION 子句和 UNION ALL 子句来进行一个比较
可以发现使用 union 子句时,就是查询后不显示重复的数据UNION ALL 子句:查询后会显示重复数据
八、MySQL 数据库外连的权限配置
Mysql5.7及之前版本的直接授权的方法
grant all privileges on _. _ to ‘root’@’%’ identified by ‘root’;
刷新数据库命令设置:flush privileges;
Mysql8.0
- 1)创建用户和授权 在mysql8.0创建用户和授权和之前不太一样了,其实严格上来讲,也不能说是不一样, 只能说是更严格, mysql8.0需要先创建用户(创建用户时要带@并指定地址, 则grant授权时的地址就是这个@后面指定的!, 否则grant授权就会报错!)和设置密码,然后才能授权。 ``` mysql> create user ‘kevin’@’%’ identified by ‘123456’; Query OK, 0 rows affected (0.04 sec)
mysql> grant all privileges on . to ‘kevin’@’%’ with grant option;
Query OK, 0 rows affected (0.04 sec)
- 2)Mysql8.0默认是不能使用root账号进行远程登录的! root账号只能本地登录!
如果想要远程登录, 则需要进行update更新下root账号的权限
mysql> update mysql.user set host=’%’ where user=”root”; Query OK, 1 row affected (0.10 sec) Rows matched: 1 Changed: 1 Warnings: 0
mysql> flush privileges; Query OK, 0 rows affected (0.14 sec)
修改root账号权限, 允许root账号远程登录后, 用navicat进行mysql的远程连接时,出现了弹窗报错:<br />![image.png](https://cdn.nlark.com/yuque/0/2021/png/1442084/1614491484174-295ebc2c-5867-47d6-8c44-901fae8dbd8b.png#align=left&display=inline&height=99&margin=%5Bobject%20Object%5D&name=image.png&originHeight=132&originWidth=658&size=19919&status=done&style=none&width=494)<br />出现这个原因是mysql8 之前的版本中加密规则是mysql_native_password, 而在mysql8之后,加密规则是caching_sha2_password, 解决问题方法有两种:
1. 一种是升级navicat驱动;
1. 一种是把mysql用户登录密码加密规则还原成mysql_native_password;
这里选择第二种方法来解决:
修改加密规则
mysql> ALTER USER ‘root’@’%’ IDENTIFIED BY ‘123456’ PASSWORD EXPIRE NEVER;
Query OK, 0 rows affected (0.16 sec)
更新一下用户的密码
mysql> ALTER USER ‘root’@’%’ IDENTIFIED WITH mysql_native_password BY ‘123456’; Query OK, 0 rows affected (0.08 sec)
刷新权限
mysql> FLUSH PRIVILEGES; Query OK, 0 rows affected (0.03 sec)
<br />
<a name="xKY1u"></a>
## 九、查询起别名
语法规则:select username a from 表名 where 条件; 其中a就是username的别名
<a name="rGB2V"></a>
## 十 、 备份数据库:
mysqldump -u 用户名 -p —default-character-set=latinl 数据库名 > 导出的文件名 (数据库默认的编码是 latinl) mysqldump -u root -p mysql > mysqlbackup20201025.sql
导出一个表: mysqldump -u root -p 数据库表名 > 导出的文件名 mysqldump -u root -p mysql users > mysql_users.sql
导出一个数据库结构: mysqldump -u root -p -d —add-drop-table antian365_member > d:\antian_db.sql
-d 没有数据, —add-drop-table 在每个create 语句之前增加一个drop table。
<a name="D17Ji"></a>
## 十一、恢复数据库:
常使用 source 命令 use antic; source antian365_db.sql
使用mysqlduump 命令: mysqldump -u username -p dbname < filename.sql
使用 mysql 命令; mysql -u usernmae -p -D dbname < filename.sql
<a name="YQnfX"></a>
## 十二、 显示具体的表结构:
(1) describe security.users;
(2) show columns from security.users;
(3) desc security.users; ```