Microsoft Exchange漏洞分析
此篇為漏洞分析,想看漏洞利用可以點這
前言
前一段時間Exchange出現了CVE-2018-8581漏洞,整個漏洞利用超讚,很值得復現以及分析,因為其中需要的不僅僅是Web方面的,更多還需要Windows相關的安全知識,其中相結合才能達到如此大的危害。
其根本原因由於 PushSubscription
介面存在SSRF,它允許為任何使用者推送訂閱所指定的URL,當Exchange嘗試連線URL時候,將會用 CredentialCache.DefaultCredentials
方式進行。
其中 CredentialCache.DefaultCredentials
是以最高許可權 SYSTEM
許可權執行,通過SSRF傳送Exchange的最高許可權net NTLM給攻擊者,注意SSRF回連Attack是以MAIL許可權。
攻擊1、在呼叫介面時候,使用其他使用者SID來偽造攻擊,從而可以達到收取他人郵件,模擬他人傳送郵件。攻擊者利用反射攻擊回到Exchange伺服器去呼叫介面,這個時候是最高許可權的呼叫。
攻擊2、通過NTLM Relay中 HTTP -> LDAP
協議的轉變,進而攻擊域控。由於Exchange角色許可權具有修改writeDACL許可權,可以將普通域使用者賦予具有DCSync許可權,從而Dump域控中的Hash資訊。
測試環境:
windows 2008: 域控: 192.168.186.100 windows 2012: Exchange 2013: mail.lemon.com -> 192.168.186.101 uuntu: attack: 192.168.186.133
漏洞分析
NTLM Relay
1、LM、NTLM、NET-NTLM三種Hash
一般我們通過Mimikatz抓取的Hash值為如下:
test:1003:E52CAC67419A9A22664345140A852F61:67A54E1C9058FCA16498061B96863248:::
其中 E52CAC67419A9A22664345140A852F61
便為LM hash, 67A54E1C9058FCA16498061B96863248
為NTLM hash,因為Windows本身不儲存明文密碼,都是通過加密後儲存為以上的hash,也就是放置在SAM檔案中。
Vista、Server 2008後預設只儲存NTLM Hash值,可以理解為NTLM Hash為LM Hash的升級版,所以在後續的系統都是以NTLM Hash為主,下面主要也是以NTLM Hash作為分析。
Net-NTLM hash通常是用於網路環境下的NTLM Hash驗證,它是由NTLM Hash去加密Chanllenge最後生成的一個值,比如下面是Net-NTLMv2的格式:
username::domain:server challenge:HMAC-MD5:blob
Responder
工具獲取到的就是一個Net-NTLM hash,它是不能夠進行Pass The Hash!Pass The Hash的那個Hash是NTLM Hash!原因在於Pass The Hash挑戰中,需要的是NTLM Hash去加密Chanllenge然後傳送給服務端,下面挑戰機制會詳細說明。
雖然沒法Pass the Hash,但是我們可以通過利用hashcat去爆破它得到明文密碼。
另外微軟中提供了很多SSP(security support provider),這是一些已封裝好的流程,主要用於一些安全中,比如身份驗證等。NTLM SSP就屬於其中,所使用的也是挑戰響應機制,主要用於工作組中。如果是在域下,一般會用到的SSP是Kerberos。
2、挑戰響應機制
這裡引用 n1nty師傅文中的詳解
這裡假設客戶端以賬號 admin 密碼 123,連線服務端,身份驗證方式為 NTLM SSP。 共 4 步: 1、客戶端利用 NTLM SSP 生成 NTLM_NEGOTIATE 訊息 (被稱為 TYPE 1 訊息),並將 TYPE 1 訊息傳送給服務端。 2、服務端接收到客戶端傳送過來的 TYPE 1 訊息,傳入 NTLM SSP,得到 NTLM_CHALLENGE 訊息(被稱為 TYPE 2 訊息),並將此訊息發回客戶端。此訊息中包含了一個由服務端生成的隨機值,此隨機值被稱為 challenge。 3、客戶端收到服務端返回的 TYPE 2 訊息,並取出其中的隨機值 challenge。客戶端將密碼 (123) 轉換為 LM HASH 與 NT HASH,同時利用計算出來的 LM HASH 與/或 NT HASH 對 challenge 進行一些計算。算出來的那段資料,根據具體的情況,有可能是(為了簡潔,這裡的描述並不十分準確): Net LM-Hash(在有的文章裡也被稱為 LM Response) Net NTLM-Hash(在有的文章裡也被稱為 NTLM Response) Net NTLM2-Hash(在有的文章裡也被稱為 NTLM2 Response/NTLM2 Session Response) Net NTLMv2-Hash(在有的文章裡也被稱為 NTLMv2 Response) Net LMv2-Hash(在有的文章裡也被稱為 LMv2 Response) 總而言之,計算出來的這段 hash 資料,將會封裝到 NTLM_AUTH 訊息中(被稱為 TYPE 3 訊息),發往服務端 4、服務端收到 TYPE 3 訊息後,將會重複第 3 步客戶端的操作,也計算出來一個 hash。然後將自己計算出來的 hash 與客戶端傳送過來的 TYPE 3 訊息中的 hash 進行對比,如果一樣,則客戶端驗證成功。不一樣,則客戶端驗證失敗。
提取 Net NTLMv2-Hash
,主要是看第二個、第三個資料包。
第二個資料包:
可以看到其中 Server Challenge
為: 26cba11eceb4b243
這裡要注意到Negotiate Flag是 0xa2890205
,如果為 0x00004000
,則是本地進行驗證,將不會走網路驗證方面,因為本地可能已經建立好憑證。
第三個資料包:
可以獲取到Response為:
f8556d6ff9a66795e945da784e115a21:0101000000000000abf29cf9a5b7d4017369543035617758000000000100060050004300310002000a004c0045004d004f004e0003001a007000630031002e006c0065006d006f006e002e0063006f006d00040012006c0065006d006f006e002e0063006f006d00050012006c0065006d006f006e002e0063006f006d0007000800abf29cf9a5b7d4010900100063006900660073002f005000430031000000000000000000
最後通過 username::domain:server challenge:HMAC-MD5:blob
格式可以構造出 Net NTLMv2-Hash
:
administrator::'':26cba11eceb4b243:f8556d6ff9a66795e945da784e115a21:0101000000000000abf29cf9a5b7d4017369543035617758000000000100060050004300310002000a004c0045004d004f004e0003001a007000630031002e006c0065006d006f006e002e0063006f006d00040012006c0065006d006f006e002e0063006f006d00050012006c0065006d006f006e002e0063006f006d0007000800abf29cf9a5b7d4010900100063006900660073002f005000430031000000000000000000
這裡name和domain是從第三步中可以獲取到,我這裡domain有點奇怪,被設定為空。
破解: hashcat -m 5600 Net-NTLMv2-Hash password.txt -o found.txt --force
3、NTLM Relay
觀察上圖 NTLM Relay
過程,下面將把左邊的Server稱為Server1,右邊的Server稱為Server2
單看一邊,Server1 與 Attack的過程就是在進行挑戰響應,但是Attack還會將Server1的請求轉發一次到Server2,最終結果就是Attack將會模擬了Server1的身份對Server2進行操作。
通常 Server1、Server2是在同一臺機器上 ,這樣將可以無需密碼就能對 某一臺機器 進行攻擊,一般叫這個為 反射攻擊 。
在講解挑戰響應機制的時候,使用的是SMB協議,在Exchange漏洞中是以HTTP協議進行。
- 因為SMB Relay危害較大,所以在
MS08-068
中已經進行修復,主要是禁止SMB -> SMB
在 同一臺機器 上的重放。 - 但是對於跨協議
HTTP -> SMB
,之後的MS16-075
進行修復,禁止這種方式進行攻擊。
完成這種協議之間的轉換隻需要將NTLM的一些訊息提取,然後再次放到另外一種協議中即可。
從NTLM驗證有HTTP、SMB、LDAP、IMAP多種協議實現、Relay到其他機器兩個方面可以進行拓展。
第一種: HTTP -> HTTP
為了清晰表達,將一臺Exchange畫分開,左邊為Exchange向Attack進行請求,右邊為Attack重放流量給Exchange。 192.168.186.101
為Exchange, 192.168.186.133
為Attack。
左邊的4、5步驟便是下面的第一個紅框,6、7步驟是下面的第二個紅框。
右邊的4、5步驟則是下面的11請求,6、7步驟則是下面的12請求。
可以通過impacket.ntlm來看資料中的具體資訊。
from impacket.ntlm import * import base64 negotiate_data = base64.b64decode('TlRMTVNTUAABAAAAB7IIogUABQAsAAAABAAEACgAAAAGAvAjAAAAD01BSUxMRU1PTg==') type1 = NTLMAuthNegotiate() type1.fromString(negotiate_data) print type1.dump() challenge_data = base64.b64decode('TlRMTVNTUAACAAAACgAKADgAAAAFwomiVsVkxYeRe4UQygVl2QAAAHYAdgBCAAAABgLwIwAAAA9MAEUATQBPAE4AAgAKAEwARQBNAE8ATgABAAgATQBBAEkATAAEABIAbABlAG0AbwBuAC4AYwBvAG0AAwAcAG0AYQBpAGwALgBsAGUAbQBvAG4ALgBjAG8AbQAFABIAbABlAG0AbwBuAC4AYwBvAG0ABwAIAHG08hGEotQBAAAAAA==') type2 = NTLMAuthChallenge() type2.fromString(challenge_data) print type2.dump() ayth_data = base64.b64decode('TlRMTVNTUAADAAAAAAAAAFgAAAAAAAAAWAAAAAAAAABYAAAAAAAAAFgAAAAAAAAAWAAAAAAAAABYAAAABcKIogYC8CMAAAAPCzgjA4s1xh35cbnnHoR1AA==') type3 = NTLMAuthChallengeResponse() type3.fromString(ayth_data) print type3.dump()
這裡提一下 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\DisableLoopbackCheck
登錄檔,預設是為1(不會進行loopback check),如果想進行修復,則刪除它或者修改為0。
如果存在 Loopback Check
,它是在檢測記憶體中的type3快取訊息與傳送到此計算機的其他type3訊息是否相同,相同則是有反射攻擊。
事實上http的Net-ntlm hash還是能夠relay到其他機器上,並且它有一定許可權,只不過在同一臺的Exchange上會認證失敗從而無法呼叫介面。另外有人提到叢集情況下補丁無效,正如上面所提到的,它是relay到另外一臺機器,所以以上只是一個緩解措施。
第二種: HTTP -> LDAP
這裡就是通過Exchange獲取到相關資料,然後通過LDAP協議Relay到域控上。比如下面就是通過HTTP將challenge Relay到了LDAP協議上。
這裡有幾點比較關鍵
1、LDAP可以讀取與修改活動目錄的物件
2、Exchange所在的Exchange Windows Permissions組預設具有writeDACL許可權,也就是寫ACL許可權
如果許可權比較高的話,比如域管,可以通過LDAP直接提權普通使用者,如果稍微低一點,比如Exchange中只是具有某些威脅的許可權組,將普通使用者添加了 Replication-Get-Changes-All(1131f6ad-9c07-11d1-f79f-00c04fc2dcd2)
、 DS-Replication-GetChanges(1131f6aa-9c07-11d1-f79f-00c04fc2dcd2)
許可權。
這樣普通使用者就能使用DCSync進行Dump域控的Hash。
PS: 關於跨協議是有一些問題,比如SMB簽名來防止Relay。可以關注一下JAVA中的SSRF進行Relay,原因在於JAVA預設會以當前許可權去認證401網頁。
gpedit.msc
處進行檢視SMB簽名是否開啟