【information_schema】 数据库
在MySQL数据库的注入中,如果你有仔细看过SQL注入语句的话,你可能就会发现,在获取数据库名、表名和字段的时候,注入语句中information_schema这个数据库出现得很频繁,那么有没有想过为什么会需要用到这个数据库呢? 这个数据库又是什么?它里面保存了什么?
information_schema数据库是MySQL自带的,
MySQL 5以下没有这个数据库,它提供了访问数据库元数据的方式。
什么是【元数据】呢?
元数据是关于数据的数据,如数据库名或表名,列的数据类型,或访问权限等。
也就是说information_schema中保存着关于MySQL服务器所维护的所有其他数据库的信息。
如数据库名,数据库的表,表栏的数据类型与访问权限等。
在INFORMATION_SCHEMA中,有数个只读表
在phpmyadmin中相关命令:
查看表
可以执行如下SQL语句来查看该库中的所有表:
show tables
这上面显示的表,它们实际上是视图,而不是基本表,所以你在数据库的数据保存目录,会看不到这个数据库的实体文件
查找表所在目录
想要查看数据库的数据保存目录,可以执行
select @@datadir
SQL注入有关表
在SQL注入中,我们重点关注的表有如下几个,因为主要的时候主要利用这几个表来获取数据:
【SCHEMATA】:提供了当前mysql数据库中所有数据库的信息,
其中SCHEMA_NAME字段保存了所有的数据库名
show databases 的结果取自此表。
【TABLES】:提供了关于数据库中的表的信息,
详细表述了某个表属于哪个schema,表类型,表引擎,创建时间等信息,
其中table_name字段保存了所有列名信息,
show tables from schemaname 的结果取自此表。
【COLUMNS】:提供了表中的列信息。
详细表述了某张表的所有列以及每个列的信息,其中column_name保存了所有的字段信息。
show columns from schemaname.tablename 的结果取自此表。
SQL语句
进入information_schema 数据库
命令为:use information_schema;
注意:一定要注意后面记得加分号,分号表示一个语句结束,
如果没有检测到你输入分号,它会认为你一个语句还没结束,
直到碰到分号后,才开始执行语句。
查看所有的数据库
show databases;
select schema_name from schemata;
注意:他们的作用是一样的,都是列出所有数据库,
跟我们前面说的一样,SCHEMA_NAME字段保存了所有的数据库名。
在注入中,我们可以通过注入select schema_name from schemata 来查询的当前数据库中所有的数据库名
如果你去查看一些爆数据库名的注入语句,就会发现里面包含这么一句:select schema_name from information_schema.schemata limit 0,1
其原理就是通过查询information_schema.schemata中schema_name的结果,其中limit 0,1用来获取第一条记录,通过递增第一个参数,可以每次获取一条记录,也就是一次获取一个数据库名,直到出现错误为止,说明没有更多的错误。
通常在获取了数据库名后,就会选择感兴趣的数据库,然后来获取其中的数据,
首先需要获取感兴趣的数据库中的所有表名,
所以通过查询 **information_schema** 库中的TABLES表就可以获取表名。
在TABLES表中,它保存了所有数据库中的所有表名以及这个表所属的库,
意思是说,不管你在哪个数据库中的表,在这里都会有一条记录对应,
如果你在一个数据库中创建了一个表,相应地在这个表里,也会有一条记录对应你创建的那个表。
可以用来看表结构
desc (表名) ;
注意上图中标记的那2条记录,
每一条记录中,他们分别记录一个表名和一个这个表所属的库名。
其中TABLE_NAME保存的是表名,而TABLE_SCHEMA保存的是这个表名所在的数据库。
查询其中一条记录
select count(*) from tables;
注意:在查询前,先看看有多少条记录,避免记录太多查看不方便
说明当前所有数据库中的表数量为142。
查询任意一条记录查看
我这里选择最后一条记录,
SQL语句为:select * from tables limit 141,1\G
注意:由于在客户端中,默认查询结果显示不友好,
所以,可以把语句后面的分号改成\G,
他会让一条记录显示一行,看起来不那么乱。
\G只支持在客户端中用,在其他连接数据库的软件中,使用\G会报错。
可以看到,最后一条记录的TABLE_NAME是user,TABLE_SCHEMA为sqli。
查看sqli数据库中的表
SQL语句为:show tables from sqli;
可以看到确实存在user表。
既然information_schema的 TABLES 表中的 TABLE_SCHEMTA 字段是保存的数据库名,
而TABLE_NAME保存了表名,那么我们就可以使用TABLE_SCHEMTA字段作为查询条件,查询TABLE_NAME,即可得知所有指定数据库中的所有表名。
比如,我们想要通过information_schema数据库来查询sqli数据库中所有的表,那么就可以使用如下SQL语句:
select TABLE_NAME from information_schema.TABLES where TABLE_SCHEMA = 'sqli';
注意:如果当前库为information_schema,则可以省略不写,
否则跨库查询的时候,需要带上库名。
查询结果: