MySQL/MariaDB UDF 命令执行
UDF(User Defined Function) 命令执行的思路是:向 MySQL 插件目录写入一个含 sys_eval 函数的共享库,再用 CREATE FUNCTION 注册,之后就能通过 SQL 直接执行系统命令。它是数据库会话到系统 shell 的经典路径。
仅限授权环境
写入共享库并执行系统命令仅可在授权测试或靶场环境进行。
判断前提
SHOW VARIABLES LIKE 'secure_file_priv';
SHOW VARIABLES LIKE 'plugin_dir';
| 检查项 | 要求 |
|---|---|
secure_file_priv | 为空,否则 INTO DUMPFILE 受限 |
plugin_dir | 知道路径,且数据库进程对其有写权限 |
| 当前用户权限 | FILE 权限与 CREATE FUNCTION 权限,root 常见 |
容器内 MariaDB 场景中,root@'%' 空密码 + FILE 权限是常见组合。
方法 A:标准 UDF 链
第一步,用 UNHEX 写入含 sys_eval 的共享库:
SELECT UNHEX('<hex>') INTO DUMPFILE '<plugin_dir>/udf.so';
优先用 UNHEX 而非 FROM_BASE64:十六进制没有转义问题,更可靠;so 体积保持小。
第二步,注册函数并调用:
CREATE FUNCTION sys_eval RETURNS STRING SONAME 'udf.so';
SELECT sys_eval('id');
方法 B:plugin_dir 不可写时的变体
若插件目录不可写,但能满足以下条件,可以走配置文件路线:
- 能写入配置文件(如用户家目录的
.my.cnf) - 服务会被重启
把 [mysqld] 段的 plugin_dir=/可写目录 写入配置,触发重启后再回到标准 UDF 链。
用 OUTFILE 写文本配置时,加 FIELDS ESCAPED BY '' 防止反斜杠转义污染内容;写完用 SELECT HEX(LOAD_FILE(...)) 核验换行与内容未被污染。
复核要点
SELECT sys_eval('id');的返回确认执行身份与主机。- 配置文件路线写完后必须核验字节级内容,防止转义污染导致服务启动失败。
- 注册失败时核对 so 文件是否完整落入了插件目录。
防御建议
secure_file_priv固定指向专用空目录,不给业务库写文件能力。- 插件目录归属 root,数据库进程不可写。
- 禁止业务账号持有 FILE 权限与 CREATE FUNCTION 权限。
- 数据库服务重启流程纳入配置变更监控。