1.SQL注入提权后创建一个账户
在mysql中,假如提权成功,在sql注入中,如何创建账号,应该在那个表中插入记录,这个表所在的数据库,还有那些敏感的信息表可以利用呢
即使我们在提权的过程中,在盲注的过程中,假如,我们想要获得数据库的相关信息,比如数据库、数据库名,数据库表,以及一个重要表中的字段名,我们应该去那里寻找这种信息呢
这里就要用到mysql中的字典元数据信息,所以,我们这篇文章就来探讨常用的字典元数据信息与注入的应用是怎么样的
数据库提权成功,登录数据库后,如何创建一个普通的账号、如何创建一个超级的账号
接下来,我们将通过实际的操作给大家演示一下,是如何进行的
我们先打开mysql命令配置界面,输入mysql -uroot -proot
我们打开mysql数据库,这个数据库名就叫mysql,use mysql;
我们看一下当前有什么表,show tables;
其中有个表叫user表
我们先看一下,这个表的结构是怎么样的,show create table user;
我们看到这个表有很多的字段
在mysql中,用户名的验证,它是基于主机,用户名和密码的验证,如果主机,用户名和密码都通过,那就意味着我们可以登录数据库
所以,最基本的权限必须插入三个字段的信息,我们来试试
我们在user表中插入一条记录,insert into user,一个是主机,一个是用户,一个是密码,我们插入的时候,希望在任何地方都可以登录,用通配符,百分号,用户名,假如admin3,密码,我们用password加密一下,它的原文密码是abc,回车,insert into user(host,user,password) values(’%’,‘admin3’,password(‘abc’));
这样,就创建了一个账户,他只有普通的权限,我们看到有3个warnings,我们先不用理会他
我们看到除了3个字段外,下面还有,我们看到所有字段中,这个用户应该具有什么权限,比如select权限,插入权限,update权限和删除权限,等等,它们都是以priv结尾的这个字段名,默认值是N,也就是NO
NO是没有这个权限的,所以我们刚刚创建的账户,这些权限应该都是没有,但是可以登录
我们看到到划红线为止,都是权限
插入之后,我们可以还通过select 查找出来,select host,user,password from mysql.user;
验证一下,我们看到先添加的admin3,已经添加成功
我们刷新一下权限,flush privileges;
然后,我们在开一个验证一下,这边验证的时候,我们通过mysql -uadmin3 -pabc,回车
我们发现可以登录,我们用show databases;看一下
我们看到,他只能看到这两个数据库,也就是说,它只有登录权限,并且其它权限都没有,其它权限相对,也很受限
显然,这样插入的项目,过于普通,也不一定满足注入者,注入攻击的需要
接下来,我们要创建一个超级账户,超级账户如果在提权成功,具有数据库权限的情况下,创建一个超级账户并不难,也就是我们使用,acl语言所授权的那样,这是一种办法
同时,我们还可以通过拷贝的方法,比如,我们先创建一个表,create table ,这是临时表,创建临时表的目的,是拷贝一条和root权限一样,具有高级权限的一条记录,然后再插入进去,from mysql.user where,user应该是root账号,我们只需要一条,使用limit 1,create table tmp select * from mysql.user where user=‘root’ limit 1;
这样呢,我们就得到了一条记录,select * from tmp;
这个记录中,实际上是localhost中的root账户
拷贝这个账号的目的,是为了,把它插进去,我们看到user表结构中,它是host、user作为主键的
所以我们拷贝这个记录后,需要对tmp表进行更新,host,我们希望它从任何地方都可以登录,user,我们改一下,我们把它改成admin4,密码改成password等于abc,这样,我们就把这条记录成功的更新,但是它的权限跟root账户是一样高的,update tmp set host=’%’,user=‘admin4’,password=password(‘abc’);
我们暂时先看一下,select * from tmp;
这样就完成了一个admin4账户的创建,它的权限跟root保持一致
那我们就把这条记录插入到user表中,insert into mysql.user表中,回车,insert into mysql.user select * from tmp;
我们在刷新一下权限,flush privileges;
我们甚至可以通过host、user、password往mysql.user,我们可以验证一下,select host,user,password from mysql.user;
这个账户已经创建成功,然后我们通过另外一个端口验证一下,回车,mysql -uadmin4 -pabc
我们show databases;
我们看到所有的数据库,都是可以看到的
甚至,我们可以把test数据库,删除掉,我们可以验证一下,它的权限是有多高,drop database test;
show databases;
我们看到数据库被删除掉了,已经不存在了
好,我们概括一下
数据库提权成功,登录数据库后
1.数据库普通账户:Insert into mysql.user(user,host,password) values(‘admin’,’%’,password(’abc’))
一个是创建数据库普通的账号,叫Insert into mysql.user,这只是我们要充分利用mysql中的user数据表,来进行插入数据的
另外一种,如果我们需要跟root一样高的权限,那我们就采取拷贝用户的办法,进行更新user,host,password三个字段,就能够实现
mysql是个字典库,这个字典库除了user表之外,还保存了些敏感信息表
2.字典库mysql主要保存了哪些敏感信息表?
我们通过实际的操作,给大家看一下
我们打开mysql数据库,use mysql;
我们show tables;看一下
user表,它保存了用户名、密码和主机,以及权限,相关的所有信息,因此,在这个数据库中,最重要的,也是最敏感的一个表,就是user表
第二个表,我们看到这里的db表,db是数据库级别的权限信息,我们可以看一下这个表的字段信息,show create table db;
我们看到主机、所在的DB、用户名,那么这些也是对用户权限的验证
对这个DB的权限,基本跟user所具有的权限保持一致,但是因为,它是数据库层级的,有自己特别的权限,我们看到这些基本上保持一致,这些都是权限,以priv结尾的,这是DB的表
这个DB表之外,还有一个我们相对比较重要的表,叫columns_priv,这个是所有字段,相关的权限信息,也就是字段级别的权限信息,我们还可以看一下,这个表的表结构,show create table columns_priv;
我们看到这里有个主机,所在的DB,用户名,表名,字段名,字段所具有的权限是什么,这权限它是个集合,可以是下边集合中的一种和多种,通常字段的权限,我们用的比较少,我们发挥的最有余地的就是user表和DB表
我们概括一下
用户表:user 保存了主机,用户名和密码和权限等重要信息
这是我们用的最多,也是最重要的表
数据库权限:db 保存了对数据库级别的权限信息
字段权限表:columns_priv 保存了字段的详细权限分配信息
当然,我们用的最多的是第一个,其它的在注入攻击中,用的相对比较少,但是如果数据库的用户名得不到最高的权限,或者限制在一定的db范围内,那我们可能要了解其它的权限信息是怎么样的
3.如何获取当前实例所有数据库名
如果我们得到这些权限信息之后,我们就要去获得当前实例所有的数据库名
我们接下来演示一下,这是如何实现的
我们先show databases;看一下
这个命令,就可以得到所有的数据库名,当然,它只是一个命令,而不是一个字典
接下来,我们将从字典中得到所有数据库名的信息呢,因为只有查询,在注入攻击中,才会有充分发挥的余地,
数据库名,我们可以通过查询来实现,select schema_name from information_schema.schemata;
我们看到show databases,实际上是下面这条查询,所得到的,它们的意义是一样的
除了这种办法,还有另外一种办法,上面那个是schemata表,还有另外一个表
我们可以通过distinct的办法,distinct是去重的意思,select distinct table_schema from information_schema.tables;
我们看到这个结果,跟上面的结果,是一致的,它们都是通过查询的办法查询出来的,而这种查询的办法,往往,在注入攻击中,发挥的灵活,也有发挥的余地
而类似show databases在查询中,经常是比较少发挥的,灵活性也欠缺
现在,我们概括一下,如何获取当前实例的所有数据库名
select distinct table_schema from Information_schema.tables;
一种是通过查Information_schema下的tables来查询
select SCHEMA_NAME from Information_schema .SCHEMATA;
另外一种,我们可以直接查询SCHEMATA这个数据库表
我们看到这种数据库的所有信息,表的所有信息,所在的数据库是Information_schema
4.information_schema库的字典信息
这个数据库,除了保存这两张表之外,还保存了其它表
接下来,我们看看这个数据库的字典信息,还有那些
我们打开来看看,use information_schema
show tables;我们看一下
这里有很多表,但是在注入攻击中,常用的字典表,不多,其中一个SCHEMATA,保存了所有有关数据库的定义信息,我们可以看一下,它的表结构是怎样的,show create table schemata;
我们看到这是分类名、数据库名、默认的字符集是什么,默认的字符集排序,sql的路径,我们还可以把它逐个查出来看看,select * from schemata;
我们看到实际上SCHEMA_NAME,就是所有的数据库名,下面默认的数据库字符集是什么,字符集的排序信息是什么等等
我们看下一个信息,刚刚看到的tables,show create table tables;
这个表保存了数据库中所有表的信息,也就是表的属性定义信息,我们看到这个表的分类,表的数据库,表名是什么,表的类型是什么,存储引擎,版本,行的格式,表的行数
我们先创建hxf数据库,create database hxf default charset utf8;
我们打开hxf看一下,use hxf
然后创建user表,create table user(uid int,uname varchar(32),password varchar(32),mobile bigint(20),isadmin tinyint(4),blog varchar(100),gold int,email varchar(32));
我们先查出hxf数据库下有什么表,show tables;
我们看到一共有一张表
我们在Information_schema数据库下,select table_name from Information_schema.tables where table_schema=‘hxf’;
我们看到打开hxf,是得到了一张表,和这个查询得到的是一样的,也就是查tables中的表名,并且它的数据库是hxf,那么除了这两张表之外,我们基本上得到我们想要的信息,一个是表信息,一个是数据库名信息,另外还有很重要的字段信息
我们重新打开Information_schema,use Information_schema
show tables;
这里有个columns,columns是保存了数据库中,所有表的所有字段,我们可以看一下,它的表结构是怎么样的,show create table columns;
我们看到TABLE_SCHEMA是表的数据库名,这是表的名字,这是字段名,因此这是最基本的字段信息
字段有哪些属性,字段所在的位置是什么,字段的默认值是什么,是否允许为空,数据的类型,字符串,以及它的字符信息等等
这三个表,是保存了数据库有关最基本的数据库名、表、字段以及相对应的属性,所有的信息,这部分信息,可以说已经满足了我们所有注入攻击中,所需要的所有信息
当然,有时候,我们在上面,无所作为的时候,我们还要寻找,其它的对象是否有漏洞
其它对象,包括函数和存储过程,触发器和视图,如果是存储过程和函数,那么它就是保存在routines,show create table routines;
这是保存了存储过程函数的用户表,有关的信息,大家可以自己看一下
我们还有视图,叫views,show create table views;
视图只是对表的查询,其中保存的是,数据库名,数据库的表名,还有视图的定义,这是最重要的
另外,我们还有其它的触发器,因为我们涉及的比较少,我们就概括一下
Information_schema库的重要性
保存了所有数据库相关的元数据信息,包括所有数据库,表和字段等字典元数据信息。
1.information_schema数据库中有哪些重要的元数据字典表
表SCHEMATA 保存了数据库相关的定义信息
表TABLES 保存了表定义属性的所有元数据信息
表COLUMNS保存了所有数据库下的所有表的所有字段信息,包括字段的属性信息
我们用的比较多的,发挥的最多的,也是前面三种,也就是数据库、表、字段的信息
ROUTINES 存储过程或者函数信息
VIEWS 视图信息
TRIGGERS 触发器信息
这是我们获得的字典信息
如果上面都无法发挥的时候,我们可能在存储过程、视图和触发器中,寻找漏洞,但是往往在这些方面,发挥的比较少,灵活性也比较差
5.如何获取当前数据库所有表名
我们获得这些字典信息,如何获得当前数据库的所有表名呢
我们在上面已经做过一个示范了,use hxf
但是当前的数据库名,我们先获得,我们看到打开hxf数据库,它当前数据库就是hxf,那我们如何查出当前数据库是hxf,select database();
我们先查看一下,database()这个函数,保存的就是当前的数据库名
如果我们切换这个数据库,use mysql
那么这个函数的值它就会变化,select database();
我们看到它又变成了mysql了,原因是,我们已经打开了mysql,当前是在mysql数据库下
如果,我们在打开hxf,use hxf
select database();
那么当前就是hxf数据库信息
所以,我们要获得当前数据库下的所有表名
我们还是要通过刚才的数据库字典信息,table信息,我们就回车看一下,select table_name from information_schema.tables where table_schema=database();
我们看到具有1张表,这样,我们就获得了当前数据库的所有表
这个查询,我们在盲注或者显注中,经常使用到的,我们在下一部分,注入攻击中,还会在网页注入中,利用这条信息,进行显示
我们概括一下
1.如何获取当前数据库下所有数据表名?
Select table_name from information_schema.tables where table_schema=database()
我们使用的是tables表, information_schema下的tables表,表名是table_name,当前数据库,我们要通过条件来限制,table_schema=database(),这是当前数据库
6.如何查询获取一个表的所有字段
我们打开hxf数据库,use hxf
show tables;看一下
我们看下这个表叫user表
user表的结构中,show create table user;
我们看到有这些字段信息,也是,我们所熟悉的
那么,我们如何通过字典的办法,把这些字段的字段名查找出来呢
我们可以通过查找columns表的办法,查找出来,字段名叫column_name,我们回车看一下,select column_name from information_schema.columns where table_schema=database() and table_name=‘user’;
我们看到得出的字段名,跟刚才我们表结构中的字段名是一致的,这样,我们就是实现了,查找,特定数据库下的指定表的所有字段名,所有字段名,对于我们了解这个字段,它的内容是什么,它的含义是什么,进而推断整个表的功能,以及敏感的信息,对注入者,有相当的意义
我们概括一下
1.一条查询中获得一个表的所有字段名
Select column_name from columns where table_schema=database() and table_name=‘users’;
我们通过表columns来查找,columns所在的数据库是information_schema,字段名是column_name,如果,我们指定数据库和表,那我们需要通过条件来限制,table_schema代表的是数据库是什么,table_name代表的是表名是什么
7.小结
1.系统字典信息
2.mysql权限字典
3.information_schema元数据字典
我们来概括一下,我们主要是探讨了数据库中,有那些字典信息,这些字典信息的敏感信息在那里,重要的数据元信息又在那里,我们如何利用它对注入攻击有所帮助,而实际上,这部分信息,通过结合我们第一部分和上几节的内容来结合,灵活的得到各种信息非常重要,同时,如何把这些字典信息跟mysql中的函数相结合,得到跟灵活,跟敏感的信息,