SQL注入information_schema的作用
在MySQL数据库的注入中,如果你有仔细看过SQL注入语句的话,你可能就会发现,在获取数据库名、表名和字段的时候,注入语句中information_schema这个数据库出现得很频繁,那么有没有想过为什么会需要用到这个数据库呢? 这个数据库又是什么?它里面保存了什么?
因为它保存着有关MYSQL服务器维护得所有其它数据库的信息,它确切的说是信息数据库
information_schema
在MySQL中,把 information_schema 看作是一个数据库,确切说是信息数据库。其中保存着关于MySQL服务器所维护的所有其他数据库的信息。如数据库名,数据库的表,表栏的数据类型与访问权 限等。
在INFORMATION_SCHEMA中,有数个只读表。它们实际上是视图,而不是基本表,因此,你将无法看到与之相关的任何文件。
information_schema数据库表说明:
SCHEMATA表:提供了当前mysql实例中所有数据库的信息。是show databases的结果取之此表。
TABLES表:提供了关于数据库中的表的信息(包括视图)。详细表述了某个表属于哪个schema,表类型,表引擎,创建时间等信息。是show tables from schemaname的结果取之此表。
COLUMNS表:提供了表中的列信息。详细表述了某张表的所有列以及每个列的信息。是show columns from schemaname.tablename的结果取之此表。
STATISTICS表:提供了关于表索引的信息。是show index from schemaname.tablename的结果取之此表。
USER_PRIVILEGES(用户权限)表:给出了关于全程权限的信息。该信息源自mysql.user授权表。是非标准表。
SCHEMA_PRIVILEGES(方案权限)表:给出了关于方案(数据库)权限的信息。该信息来自mysql.db授权表。是非标准表。
TABLE_PRIVILEGES(表权限)表:给出了关于表权限的信息。该信息源自mysql.tables_priv授权表。是非标准表。
COLUMN_PRIVILEGES(列权限)表:给出了关于列权限的信息。该信息源自mysql.columns_priv授权表。是非标准表。
CHARACTER_SETS(字符集)表:提供了mysql实例可用字符集的信息。是SHOW CHARACTER SET结果集取之此表。
原文链接:https://blog.csdn.net/xianjie0318/article/details/80857568
PhpMyAdmin
phpMyAdmin 是一个以PHP为基础,以Web-Base方式架构在网站主机上的MySQL的数据库管理工具,让管理者可用Web接口管理MySQL数据库。借由此Web接口可以成为一个简易方式输入繁杂SQL语法的较佳途径,尤其要处理大量资料的汇入及汇出更为方便。
优势:
远端管理MySQL数据库,方便的建立、修改、删除数据库及资料表。也可借由phpMyAdmin建立常用的php语法,方便编写网页时所需要的sql语法正确性。
WampServer
WampServer就是Windows Apache Mysql PHP集成安装环境,即在Windows操作系统下的apache、php和mysql的服务器软件。
实验目的
通过本次实验,掌握SQL注入中,通过information_schema这个数据库爆库名、表名以及字段名的原理。
实验环境
windows 7、安装wamp环境。
实验
查看数据库下的所有表
红圈1:输入localhost/phpmyadmin
红圈2:点击information_schema数据库。
红圈3:SQL语句
红圈4:输入SQL语句:
show tables(显示在information_schema数据库下所有的表)
这上面显示的表,它们实际上是视图,而不是基本表
所以你在数据库的数据保存目录,会看不到这个数据库的实体文件。数据库的数据保存在 C:\wamp\bin\mysql\mysql5.6.17\data 目录,在这个目录下一共有如下4个目录:
它们是:
mysql
performance_schma
sqli
test
SQL语句查看数据库的数据保存目录
select @@datadir
每一个目录对应数据库中的一个数据库
查看数据库
show databases;
少了information_schema这个数据库
在SQL注入中,我们重点关注的表有如下几个,因为主要的时候主要利用这几个表来获取数据:
SCHEMATA:提供了当前mysql数据库中所有数据库的信息,其中SCHEMA_NAME字段保存了所有的数据库名。show databases的结果取自此表。
TABLES:提供了关于数据库中的表的信息,详细表述了某个表属于哪个schema,表类型,表引擎,创建时间等信息,其中table_name字段保存了所有列名信息,show tables from schemaname的结果取自此表。
COLUMNS:提供了表中的列信息。详细表述了某张表的所有列以及每个列的信息,其中column_name保存了所有的字段信息。show columns from schemaname.tablename的结果取自此表。
打开mysql终端:
点击MySQL后点击MySQL 控制台(M)
密码为空的话输入空格即可
进入information_schema 数据库,
命令为:use information_schema;
注:和C语言一样,一个语句的结束由分号标志
查看所有的数据库
show databases;
或者
select schema_name from schemata;
可以看到SCHEMA_NAME字段保存了所有的数据库名。
所以,在注入中,我们可以通过注入select schema_name from schemata 来查询的当前数据库中所有的数据库名
通过查询information_schema.schemata中schema_name的结果,其中limit 0,1用来获取第一条记录,通过递增第一个参数,可以每次获取一条记录,也就是一次获取一个数据库名,直到出现错误为止,说明没有更多的错误。
select schema_name from information_schema.schemata limit 0,1
在TABLES表中,它保存了所有数据库中的所有表名以及这个表所属的库,意思是说,不管你在哪个数据库中的表,在这里都会有一条记录对应,如果你在一个数据库中创建了一个表,相应地在这个表里,也会有一条记录对应你创建的那个表。
查看tables的表结构
desc tables;
TABLE_NAME保存的是表名
TABLE_SCHEMA保存的是这个表名所在的数据库
查看tables有多少条数据
select count(*) from tables;
筛选来看
select * from tables limit 141,1\G
select * from table limit 3, 7; // 返回4-11行
select * from table limit 3,1; // 返回第4行
select * from table limit 3; // 返回前3行
可以看到,最后一条记录的TABLE_NAME是user,TABLE_SCHEMA为sqli。
查看sqli数据库中的表
show tables from sqli;
通过information_schema数据库来查询sqli数据库中所有的表
select TABLE_NAME from information_schema.TABLES where TABLE_SCHEMA = 'sqli';
(如果当前库为information_schema,则可以省略不写,否则跨库查询的时候,需要带上库名)
可以看到确实存在user表。
通过修改TABLE_SCHEMA 的限制,可以查询任意数据库中的所有表名,网上的通过注入爆表名便是这个原理。
知道了表名,那么如何获取表中的字段呢?要知道我们没有表名的话,会把所有的数据查询出来,而如果注入没有回显,不能进行union查询,那么想要获取我们的标目数据,无疑效率极低。
幸运的是,在information_schema数据库中,同样存在一个表,它保存了整个数据中,所有的列名,这个表就是COLUMNS。同样先查看该表结构。
查看COLUMNS的表结构
desc COLUMNS;
TABLE_SCHEMA保存了这条记录保存的字段所属的数据库名
TABLE_NAME保存的是该字段所属表名
COLUMN_NAME则是一个列名记录
确定该表有多少条记录
select count(*) from columns;
获取最后一条记录
lect * from columns limit 1661,1\G
其中COLUMNS_NAME为ip,TABLE_NAME为user,TABLE_SCHEMA为sqli
这说明,在sqli这个数据中,user表存在一个ip的列,也就是我们常说的ip字段。
查看sqli的user表是否存在该字段
show columns from sqli.user;
可以看到确实存在该字段。
通过information_schema数据库的columns表查询sqli数据库中new表中所有的字段
select column_name from information_schema.columns where TABLE_SCHEMA='sqli' and TABLE_NAME='new';
show columns from sqli.user;
作业:
为什么网上的SQL注入语句中,数据库名都是用的字符的16进制值?
因为数据库名的命名规范:正式数据库名使用小写英文以及下划线组成