数据库元数据:
元数据(meta data)——“data about data” 关于数据的数据,一般是结构化数据(如存储在数据库里的数据,规定了字段的长度、类型等)。所以metadata就是描述数据的数据,在MySQL中就是描述database的数据。有哪些数据库、每个表有哪些表、表有多少字段、字段是什么类型等等,这样的数据就是数据库的元数据。
综上,我们可以称information_schema
是一个元数据库。它就像物业公司的信息库,对管理的每栋大厦有多少电梯、电梯型号、每个房间的长宽高等等了如指掌。
提供数据库信息,有哪些数据库,字符集是GBK还是UTF-8等等。
所有字段名:
其中某一条数据:
命令SHOW DATABASES;
的结果取自此表
提供表的信息,数据库有哪些表,是什么存储引擎等等。
所有字段名:
常用字段包含:
字段名 | 含义 | 备注 |
---|---|---|
TABLE_SCHEMA | 数据库名 | |
TABLE_NAME | 表名 | |
TABLE_TYPE | 表的类型 | |
ENGINE | 存储引擎 | |
CREATE_TIME | 建表时间 |
其中某几条记录:
命令SHOW TABLES;
的结果取自此表
提供字段的信息,有哪些字段字段类型是什么等等。
所有字段名:
常用字段名:
字段名 | 含义 | 备注 |
---|---|---|
SCHEMA_NAME | 数据库名 | |
TABLE_NAME | 表名 | |
COLUMN_NAME | 字段名 | |
COLUMN_TYPE | 字段类型 | 如int(10),varchar(250) |
其中某几条记录:
等同命令:SHOW COLUMNS
或者 desc learnSQL.customers
看emp表的具体字段。
这张表的单词是统计的意思,但是却是索引的信息。
所有字段名:
字段名 | 含义 | 备注 |
---|---|---|
SCHEMA_NAME | 数据库名 | |
TABLE_NAME | 表名 | |
INDEX_SCHEMA | 也是数据库名 | |
INDEX_NAME | 索引名 | |
COLUMN_NAME | 字段名 | |
INDEX_TYPE | 索引类型 | 一般是B-Tree |
其中几条记录:
等同于命令:SHOW INDEX;
提供约束情况,我们想看看表有哪些约束?约束指的是唯一性约束、主键约束、外键约束。
所有字段名:
常用字段名:
字段名 | 含义 | 备注 |
---|---|---|
CONSTRAINT_SCHEMA | 数据库名 | |
CONSTRAINT_NAME | 约束名 | |
TABLE_SCHEMA | 也是数据库名 | |
TABLE_NAME | 表名 | |
CONSTRAINT_TYPE | 约束类型 | UNIQUE、PRIMARY KEY、FOREIGN KEY |
其中几条记录:
唯一约束和主键约束,我们在前面的索引中一样可以查到
有STATISTICS和TABLE_CONSTRAINTS表,为什么还需要KEY_COLUMN_USAGE?
因为外键时没有指出参考的是哪张表的哪个字段!
所有字段:
常用字段:
字段名 | 含义 | 备注 |
---|---|---|
CONSTRAINT_SCHEMA | 数据库名 | |
CONSTRAINT_NAME | 约束名 | PRIMARY或列名或外键名 |
TABLE_SCHEMA | 也是数据库名 | |
TABLE_NAME | 表名 | |
COLUMN_NAME | 列名 | |
REFERENCED_TABLE_SCHEMA | 参考的数据库 | |
REFERENCED_TABLE_NAME | 参考的表 | |
REFERENCED_COLUMN_NAME | 参考的列 |
其中几条记录:
相比前面两个,KEY_COLUMN_USAGE这个表的信息是最全的。包括主键、外键、唯一约束。
查询数据库下所有的视图。
所有字段名:
常用字段名:
字段名 | 含义 | 备注 |
---|---|---|
TABLE_SCHEMA | 数据库名 | |
TABLE_NAME | 表名 | |
VIEW_DEFINITION | 视图定义语句 |
show ENGINES
show global variables
。除了global还有session。show PLUGINS
show full processlist
主要用于收集数据库服务器性能参数。并且库里表的存储引擎均为PERFORMANCE_SCHEMA,而用户是不能创建存储引擎为PERFORMANCE_SCHEMA的表。MySQL5.7默认是开启的。
mysql的核心数据库,类似于sql server中的master表,主要负责存储数据库的用户、权限设置、关键字等mysql自己需要使用的控制和管理信息。(常用的,在mysql.user表中修改root用户的密码)。
如何利用SQL语句查询库名、表名、字段名、内容以及当前用户等基本信息
- 查询库名:
SELECT schema_name FROM infomation_schema.schemata;
- 查询表名:
SELECT table_name FROM information_schema.tables WHERE table_schema='test'
;- 查询字段名:
SELECT column_name FROM information_schema.columns WHERE table_name='col'
;- 查询记录:
SELECT * FORM test.col;
查看文件
1 | mysql> system cat /etc/passwd |
执行命令
注意:
load_file()与load data file读取文件的原理都是一样的:新建一个表,读取文件为字符串形式插入表中后读取表中的数据。
使用load_file()和load data infile()函数时,需要满足以下条件:
secure_file_priv
不为 NULL,使用 select @@secure_file_priv
查看其值,值不为空字符串时,只能使用该目录进行文件的读写操作, 该值的设置见[附录](https://bingslient.github.io/2019/08/16/MySQL 数据库系统表的利用/#附录);FILE
权限,使用 show grants
查看;mysql
对该文件可读(要考虑系统的访问控制策略),在Ubuntu-18.04使用 MySQL 时默认的系统用户是 mysql
;max_allowed_packet
,使用 select @@max_allowed_packet
查看;如果上述任一条件不满足,函数返回 NULL
值。
查看secure_file_priv的值:
可以看到secure_file_priv的值为/var/lib/mysql-files
① secure_file_priv为NULL时,表示不允许导入导出;
② secure_file_priv指定文件夹时,表示mysql的导入导出只能发生在指定的文件夹;
③ secure_file_priv没有设置时,则表示没有任何限制
在不改变secure_file_priv值的情况下如何读文件:
可以新建一个表,或者直接把要读文件的内容into到已有的字符类型的表中。
1 | create table mytable(a VARCHAR(100), b VARCHAR(100), c VARCHAR(100), d VARCHAR(100), e VARCHAR(100), f VARCHAR(100), g VARCHAR(100)); |
使用load data infile读取文件:
1 | LOAD DATA LOCAL INFILE "/etc/passwd" INTO TABLE mytable; |
查看刚刚读入的文件:
在改变secure_file_priv值的情况下如何读文件:
修改MySQL配置文件etc/mysql/my.cnf
,在[mysqld]下添加如下内容:
1 | secure_file_priv="" |
再重启mysql服务:
1 | sudo service mysql restart |
在mysql命令行中查看secure_file_priv
的值:
修改成功!
使用load_file()读取文件:
在Ubuntu-18.04使用 MySQL 时默认的系统用户是
mysql
,所以必须把要读取的文件的所有者和用户组修改为mysql
SELECT INTO OUTFILE
和 LOAD DATA
这两条语句是完全互补的,一个写文件,一个读文件,语句的语法也很相似。
前提条件:
secure_file_priv
不为 NULL
,使用 select @@secure_file_priv
查看其值,值不为空字符串时,只能使用该目录进行文件的读写操作, 该值的设置见[附录](https://bingslient.github.io/2019/08/16/MySQL 数据库系统表的利用/#附录);FILE
权限,使用 show grants
查看;mysql
对该文件可写(要考虑系统的访问控制策略),在Ubuntu-18.04使用 MySQL 时默认的系统用户是 mysql
;max_allowed_packet
,使用 select @@max_allowed_packet
查看;将数据库中的某一个记录写入/tmp/customer.csv
文件中:
结果如下:
使用
SELECT INTO DUMPFILE
可将文件内容写成一行。
如果想把远程数据库的查询结果写到本地主机文件上, 可用:
1 >mysql -h hostname -P portnum -u username -p databsename -e "SELECT ..." > file_name
MySQL 用户的密码存储方式并非明文直接存储,而是经过 hash 函数加密进行存储的,从 mysql.user
中获取到 MySQL 用户密码的哈希值后,需要使用工具进行破解。
首先查询root
用户密码的Hash值:
工具:hashcat
hashcat 号称最快的高级密码恢复套机(密码破解工具),支持多系统(Linux,OS,Windows),多平台(GPU,CPU,DSP等),支持多达 200 多种的 Hash 类型,支持使用同一系统的不同设备,支持分布式系统资源等,重要的是开源啊!
使用:
1 | ./hashcat64.exe -m 300 -a 3 hashcode -o plaintxt --outfile-format=2 ?a?a?a?a?a?a |
参数解释:
-m 300
:hash 类型,300 选择的是 MySQL4/5 的hash
-a 3
:攻击模式,3代表爆破模式
软件一共支持5种破解模式,分别为:
0 Straight(字典破解)
1 Combination(组合破解)
3 Brute-force(掩码暴力破解)
6 Hybrid dict + mask(混合字典+掩码)
7 Hybrid mask + dict(混合掩码+字典)
-o pliantxt
:破解后输出到文件 plaintxt
--outfile-format=2
:输出文件格式,2表示只输出破解后的内容
?a?a?a?a?a?a
:这表示密码的掩码,所谓的掩码就是通过 ?[字符集代号]… 的格式表示密码的格式,包括密码的位数和每一位密码使用的字符集。?a 表示所有的键盘上可输入的字符,6个?a表示密码有6位。
hashcat 内置字符集如下:
?l = abcdefghijklmnopqrstuvwxyz
?u = ABCDEFGHIJKLMNOPQRSTUVWXYZ
?d = 0123456789
?h = 0123456789abcdef
?H = 0123456789ABCDEF
?s = !”#$%&’()*+,-./:;<=>?@[]^_`{
?a = ?l?u?d?s
?b = 0x00 - 0xff
如果要用掩码表示小写+数字怎么办呢?这就需要用到自定义字符集这个参数了。软件支持用户最多定义4组字符集,分别用
1 | --custom-charset1 [chars] |
比如说我要设置自定义字符集1为小写+数字,那么就加上:
1 | -- custom-charset1 ?l?d |
对于想要破解一些未知长度的密码,希望软件在一定长度范围内进行尝试的,可以使用–increment参数,并且使用–increment-min ?定义最短长度,使用–increment-max ?定义最大长度。比如要尝试6-8位小写字母,可以这样写:
1 | --increment --increment-min 6 --increment-max 8 ?l?l?l?l?l?l?l?l |
爆破结果:
最新版本的MySQL在配置密码规则是要求密码长度最小为8位,但是我这破电脑用hashcat爆破8位密码预计需要1年的时间,只能强行把密码最小长度改为6位,15分钟解决问题。