轉儲活動目錄資料庫憑證的方法總結

wyzsk發表於2020-08-19
作者: Her0in · 2016/01/11 10:21

原文地址: https://adsecurity.org/?p=2398

0x00 前言


ADS 的大牛發表的文章都堪稱佳作,值得仔細拜讀,遂花了點時間對全文進行了翻譯,以饗各位。

我之前發表過兩篇關於如何轉儲 AD 資料庫憑證的文章: “攻擊者如何從一個域控制器中讀取活動目錄資料庫(NTDS.DIT)”和“在 Active Directory 域中獲得管理員許可權的攻擊方法”。

這篇文章涵蓋了許多不同的方法,攻擊者可以轉儲 Active Directory 的憑據,包括 DC 本地的和遠端的。這方面的一些資訊,我已經在 2015年的(BSides,Shakacon,Black Hat,DEF CON,&DerbyCon)安全會議談到過。

從 Active Directory 轉儲憑據資料的主要技術包括與一臺存活的 DC 的 LSASS 程式進行互動,抓取 AD 資料檔案(NTDS.DIT)的副本,或者欺騙域控制器為攻擊者複製密碼資料。

這裡所介紹的方法需要許可權提升,因為它們需要連線到域控制器轉儲憑據。

如下:

注意:如果已經發現了 Active Directory 資料庫(NTDS.DIT)的副本,那麼攻擊者無需提升許可權即可從中轉儲憑據。

0x01 遠端執行命令方式


有幾種不同的方式可以在域控制器上遠端執行命令,假設它們已經有了相應的執行許可權。最可靠的遠端執行方法包括兩種 PowerShell(利用 WinRM )和 WMI。

  • WMI

    #!bash
    Wmic /node:COMPUTER/user:DOMAIN\USER /password:PASSWORD process call create "COMMAND"
    
  • PowerShell (WMI)

    #!bash
    Invoke-WMIMethod -Class Win32_Process -Name Create –ArgumentList $COMMAND –ComputerName $COMPUTER -Credential $CRED
    
  • WinRM

    #!bash
    winrs –r:COMPUTER COMMAND
    
  • 遠端 PowerShell

    #!bash
    Invoke-Command –computername $COMPUTER -command { $COMMAND}
    New-PSSession -Name PSCOMPUTER –ComputerName $COMPUTER; Enter-PSSession -Name PSCOMPUTER
    

0x02 Active Directory 資料庫檔案(NTDS.DIT)


Active Directory 域資料庫儲存在 Ntds.dit 檔案中(預設存放在 C:\WINDOWS\NTDS 中,但一般是在不同的邏輯驅動器上的)。 AD 資料庫是一個使用了可擴充套件儲存引擎(ESE)Jet 資料庫引擎,它提供了資料儲存和索引服務; ESE 級別的索引使得物件的屬效能夠快速定位。 ESE 確保資料庫符合 ACID(原子性,一致性,隔離性和永續性)即 在一個事務中的所有操作要麼全部完成要麼全部不完成。AD 的 ESE 資料庫是非常快速且可靠的。

p1

注:微軟同樣使用了 Jet 資料庫作為 Exchange 的郵箱資料庫。

Active Directory 將 Ntds.dit 檔案的一部分載入到了記憶體(已被 LSASS 程式保護)中,並且快取時使用了基於 LRU-K 的演算法,以確保被頻繁訪問的資料是在記憶體中的,這樣可以提高效能,並且能夠提高二次讀取的效能。資料庫的更改會在記憶體中執行,寫入事務日誌,之後會有一個緩慢的提交到資料庫檔案的過程。check point 檔案(edb.chk)將會跟蹤到事務寫入操作點。這個有點類似於指標的操作。
版本儲存”是一個物件例項的副本,這使得資料從記憶體中被讀取時,更新操作可以在不改變被讀取的資料(ESE事務處理檢視)的前提下進行讀取。一旦讀取操作完成,該版本儲存的例項也將結束。
Active Directory 包括三個目錄分割槽:域,配置和架構,這是資料庫資料最精簡的抽象檢視。 Ntds.dit 檔案包括三個主要的表:資料表,連結表,以及 SD 表

資料表

資料表包含了 Active Directory 資料儲存的所有資訊:使用者,使用者組,應用程式的特定資料,還有在 Active Directory 安裝後儲存的任何其他資料。資料表可以被看作是具有行(每一個都代表了一個物件的例項,如:使用者)和列(每一個都代表了架構中的屬性,如GivenName)的表。對於架構中的每個屬性,表中包含一個列,稱為欄位。欄位的大小是固定的或可變的。固定大小的欄位包含一個整型或長整型作為資料型別。可變大小的欄位通常為字串型別,例如,Unicode 字串。資料庫會盡可能分配多的空間滿足可變大小的欄位的需求:16 位為 1 個字元的 Unicode 字串,160 位為 10 個字元的 Unicode 字串,等等。

用於儲存一個物件的資料庫空間的大小取決於為其已設定的值的屬性數量和值的大小。例如,如果管理員建立了兩個使用者物件(使用者1 和使用者2 ),並只給它們設定了最小的屬性,然後給使用者2 增加一個 10 個字元的描述時,使用者2 的空間會比使用者1 的空間大 80 個位元組左右(20位元組為 10 個字元的大小,再加上的後設資料新生成的屬性)。

資料庫記錄是不能跨資料庫頁的;因此,每一個物件被限制為了 8KB 大小。然而,針對此限制,一個物件的有些屬性值是不會進行完全計算的。長度較長的和可變長度的值可以儲存不同的頁中,在物件記錄之後,只剩下了一個 9個位元組的引用。以這種方式,一個物件及其所有的屬性值的大小會比 8KB 大得多。

連結表

連結表包含的資料表示被連結的屬性,其中包含的值指向了 Active Directory 中的其他物件。例如,一個使用者物件的 MemberOf 屬性,其包含的值指向了該使用者所屬的組。另外,連結表比資料表小得多。

SD 表

SD 表包含的資料表示了每個物件所繼承的安全描述符。在 Windows Server 2003 或更高版本的 Windows 作業系統中引入了 SD 表,被繼承的安全描述符不再被複制到每個繼承安全描述符的物件上。相反,被繼承的安全描述符被儲存在了 SD 表並被連結到了相應的物件上。

0x03 Active Directory 中的密碼雜湊使用的加密方式


Csaba Barta([email protected])於2011年7月 發表過一份白皮書 —— “ Active Directory 的 HASH 離線轉儲和取證分析技術”。

需要注意的是在前一個列表中,有很多被描述為加密的欄位,加密的目的是提供保護,防止資料被離線提取。

微軟為了提供這種保護所引入的解決方案比較複雜,其加密共有三層,前兩層使用了 RC4 加密演算法,第三層使用了 DES 加密演算法。

要解密儲存在 NTDS.DIT 中的雜湊,需要執行下面的步驟:

  • 1.使用 BOOTKEY(RC4 - 第一層加密)解密 PEK(密碼加密的金鑰)
  • 2.HASH 解密第一輪(使用 PEK 和 RC4 - 第二層加密)
  • 3.HASH 解密第二輪(DES - 第三層加密)

密碼加密金鑰 —— PEK

PEK 用於加密儲存在 NTDS.DIT 檔案中的資料。在整個域中,這個金鑰都是同一個,這意味著它在所有的域控制器中也是相同的。該 PEK 本身也以加密的形式儲存在 NTDS.DIT 中。要解密 PEK 則需要從獲得 Ntds.dit 檔案所在的同一個域控制器中匯出登錄檔資料(SYSTEM hive)。這是因為 PEK 使用了 BOOTKEY 進行了加密並且 BOOTKEY 在所有的域控制器中(事實上在域中的所有計算機)上是不同的。

為了解密該 PEK 則必須從 NTDS.DIT 檔案中獲取 ATTk590689 欄位。由於上述所提到的所有儲存在資料庫中的物件都具有此欄位,因此,為了確定哪一個才是解密需要的值,則需要檢查值是否為空即可。

該欄位的值的長度是 76 個位元組(二進位制資料)。值的結構如下:

p2

解密後得到的 PEK 的值可以分為兩部分。跳過前 36 位元組(因此實際上 PEK 金鑰的長度只有 16 個位元組)。

去掉 RC4 加密層後的演算法如下:

#!cpp       
md5 = MD5.new()
md5.update(pek)
md5.update(enc_hash[0:16])
rc4_key = md5.digest();
rc4 = ARC4.new(rc4_key)
denc_hash = rc4.encrypt(enc_hash[16:])

最後一步是去掉 DES 加密層,實際上這和儲存在登錄檔中的密碼 HASH 所使用的所謂的“標準” SYSKEY加密演算法及其相似,該演算法的具體細節可以在這找到,http://moyix.blogspot.com/2008/02/syskey-and-sam.html

下面是該演算法的最後一部分:

#!cpp
(des_k1,des_k2) = sid_to_key(rid)
d1 = DES.new(des_k1, DES.MODE_ECB)
d2 = DES.new(des_k2, DES.MODE_ECB)
hash = d1.decrypt(denc_hash[:8]) + d2.decrypt(denc_hash[8:])

需要注意的是,它必須要有使用者的 SID 以確定 RID 並計算出用於 DES 加解密的金鑰。

0x04 緩和措施


最好的緩解措施是防止攻擊者能夠獲得域控制器中相關檔案的訪問許可權。在這篇文章中——“在 Active Directory 域中獲得管理員許可權的攻擊方法”涵蓋了保護管理員憑據的方法。

0x05 使用 VSS 卷影副本遠端讀取 ntds.dit(透過 WMI or PowerShell 遠端管理)


在 Windows 中有內建的管理元件—— WMI,允許遠端執行命令(需要管理員許可權)。 WMIC 是 WMI 的命令列工具,可以在遠端計算機上執行命令。

Matt Graeber 在 Black Hat USA 2015 安全會議中演示了利用 WMI 進行攻擊的技術(paperPPT影片)。他還在 DEF CON 23 中(影片)與同事一起進一步演示了 WMI 的攻擊能力。(還有在 DerbyCon 的影片

利用 WMIC (或者是 PowerShell 遠端管理)建立(或 copy 已存在的)VSS。

p3

當 VSS 快照完成後,我們就可以從 VSS 中將 NTDS.dit 檔案和 登錄檔中的 System hive 複製到域控制器的 C 盤中。

p4

p5

之後就可以將域控制器中 c:\\temp 目錄的檔案複製到本地的計算機中。

p6

上圖中顯示了攻擊者使用 Mimikatz 獲取的明文密碼,進行遠端連線操作。不過,就算我們沒有密碼又有什麼關係呢?

攻擊者可以透過 WMIC 傳遞 Kerberos 票證同樣可以進行遠端連線操作。

p7

需要注意的是在較新版本的 Windows 中 WMIC 已經有些過時了。 PowerShell 提供了 Invoke-WMIMethod cmdlet 可以執行相同的功能。

0x06 使用 NTDSUtil 建立 IFM 抓取 DC 本地的Ntds.dit檔案 (VSS 卷影複製)


NTDSUTIL 是一個命令列實用程式,在本地工作時需要 AD 資料庫(NTDS.DIT)並支援為 DCPROMO 建立 IFM 。DCPROMO 將使用 IFM 以“從媒體介質中安裝”,這樣伺服器就不需要透過網路從另一臺 DC 上覆制域資料。

#!bash
ntdsutil “ac i ntds” “ifm” “create full c:\temp” q q

在下圖中,IFM 是一個 NTDS.dit 檔案的副本,放在 c:\\temp 目錄中。

當建立一個 IFM 時,也會產生並掛載一個 VSS 快照,同時 Ntds.dit 檔案和相關的資料也被複制到目標資料夾中。

該檔案可能儲存在一個正在 promot 的新的 DC 的共享資料夾中,也可能出現在還沒有 promot 的新的伺服器上。此伺服器可能無法確保IFM 資料的安全,包括複製 Ntds.dit 檔案並提取憑證資料。

p8

這個命令也可以透過 WMI 或 PowerShell 遠端執行。

0x07 使用 PowerSploit 的 Invoke-NinjaCopy 遠端讀取 ntds.dit(需要目標 DC 啟用 PowerShell 遠端管理)


Invoke-NinjaCopy 是一個 PowerShell 函式,可以利用 PowerShell 遠端管理複製遠端計算機的檔案(需要目標 DC 啟用 PowerShell 遠端管理)。

Invoke-NinjaCopy 檔案介紹:

該指令碼可以開啟整個卷(如C:)的讀取控制程式碼並解析 NTFS 結構,從而從一個 NTFS 卷複製檔案。此操作需要目標伺服器的管理員許可權。利用此指令碼可以繞過以下保護措施:

  1. 一個已被程式開啟且不能被其他程式操作的檔案,如 Ntds.dit 檔案或登錄檔中的 SYSTEM hive 配置檔案。
  2. 已被設定 SACL 標誌的檔案,在開啟此類檔案時,會有提醒(此指令碼沒有使用 Win32 API 開啟檔案,因此Windows 沒有反應)。
  3. 繞過 DACL ,例如 DACL 只允許 SYSTEM 許可權開啟一個檔案。

如果指定了 LocalDestination 引數,則檔案將被複制到本地伺服器(指令碼正在從執行的伺服器)中指定的檔案路徑。

如果指定了 RemoteDestination 引數,則該檔案將被複制到遠端伺服器中指定的檔案路徑。

該指令碼使用了 cyb70289 的NTFS解析程式碼並已釋出到了 CodePlex 上進行 NTFS 結構解析。由於 NTFS 解析程式碼使用 C++ 編寫,所以我將程式碼編譯到了一個 DLL 中,並透過反射使用 PowerShell 的 Invoke-ReflectivePEInjection.ps1 指令碼載入它(原始程式碼請參閱以下連結)。

Joe Bialek (@JosephBialek)在他的部落格中寫了如下關於 Invoke-NinjaCopy 的資訊。

目前,已有好幾種方法可以轉儲 Active Directory 和本地密碼的 HASH。不過直到最近,我發現目前獲取 HASH 的技術,需 要依賴於注入程式碼到 LSASS 程式或使用 VSS ,以獲得含有 HASH 檔案的副本。我建立了一個名為 Invoke-NinjaCopy 的 PowerShell 指令碼,支援任何檔案(包括NTDS.DIT)的複製,無需啟動可疑的服務,無需注入程式碼到程式中,或者提升到 SYSTEM 許可權。

命令如下:

#!bash
Invoke-NinjaCopy -Path “c:\windows\ntds\ntds.dit” -ComputerName “RDLABDC02” -LocalDestination “c:\temp\ntds.dit”

下面這個示例是從外網下載並完全是在記憶體中執行程式碼,然後執行 Invoke-Ninjacopy。如果攻擊者已經拿到了域管理員已登入的主機,那麼在這種情況下會很有效,從而使攻擊者可以將 Active Directory 資料庫檔案從域控制器複製到主機中,然後上傳到外網。

使用 DIT 快照檢視器 ,可以驗證我們是否順利拿到了Ntds.dit 檔案。

從正在執行的系統中抓取檔案時,我必須對 Ntds.dit 檔案進行“拍攝快照”以便糾正錯誤。

p9

注意:

Invoke-NinjaCopy 的作者 Joe Bialek (@JosephBialek) 提示說,他並沒有測試使用 Invoke-NinjaCopy 複製較大的 ntds.dit 檔案,因此在一個繁忙的 DC 中使用時,很有可能會損壞檔案。這裡是 Harmj0y 對嘗試轉儲 AD 憑據時 NTDS.DIT 檔案損壞的一些見解

0x08 在 DC 中使用 Mimikatz 轉儲 Active Directory 憑據


一般情況下服務帳戶就是域管理員組(或同等許可權)的成員或者攻擊者從域管理員最近登入到的計算機中 dump 出登入憑證。使用這些憑據,攻擊者可以訪問域控制器,並可以得到所有的域憑據,其中包括用於建立 Kerberos 的黃金票證的 KRBTGT 帳戶的 NTLM 雜湊值。

PS:

有許多不同的工具可以在本地 DC 上執行時, dump 出 AD 的憑證,但我更傾向於使用 Mimikatz ,因為其具有大量的的憑證竊取和程式碼注入功能(當然不止這些)使得攻擊者可以從多種來源和場景中轉儲憑證資料。

命令:

#!bash      
mimikatz lsadump::lsa /inject exit

可以在域控制器上執行,轉儲 Active Directory 的域憑證資料。

需要使用 debug 模式獲取本地管理員許可權或者系統許可權進行訪問。

注意:

UID 為 502 的帳戶是 KRBTGT 帳戶 與 RID 為 500 的帳戶一樣都是域中預設的管理員。

p10

0x09 在 DC 中使用 Invoke-Mimikatz 轉儲 Active Directory 憑據


Invoke-MimikatzPowerSploit 的一部分,由 Joe Bialek (@JosephBialek) 編寫,在一個 Powershell 函式中整合了 Mimikatz 的所有功能。它利用 Mimikatz 2.0 和 Invoke-ReflectivePEInjection 在記憶體中反射式的載入了 Mimikatz 的全部程式碼。這使得你在轉儲憑證時無需寫入 Mimikatz 的二進位制資料到磁碟中。

PS: PowerSploit 框架目前託管在 PowerShellMafia 的 GitHub 資源庫中。

是什麼讓 Invoke-Mimikatz 如此有“魔力”,就是使用了反射式載入 Mimikatz DLL(已內嵌了指令碼)到記憶體的能力。Invoke-Mimikatz 的程式碼可以從外網下載並在記憶體中執行,無需向磁碟寫入任何東西。此外,如果使用相應的許可權執行 Invoke-Mimikatz 並且目標計算機中啟用了 PowerShell 遠端管理時,就可以從其他系統中匯出憑證資料,並可以遠端執行標準的 Mimikatz 命令,不需要向遠端系統上丟任何檔案。

Invoke-Mimikatz 不再更新,不過我們可以使用較新的 Mimikatz 轉換出 DLL(32位和64位版本)。

  • 使用 mimikatz 從 LSASS 程式轉儲憑證:Invoke-Mimikatz -DumpCreds
  • 使用 mimikatz 匯出所有私有證照(即使它們已被標記為不可匯出): Invoke-Mimikatz –DumpCerts
  • 在遠端計算機上使用 debug 提升許可權:Invoke-Mimikatz -Command “privilege::debug exit” -ComputerName “computer1”

Invoke-Mimikatz “Command” 引數允許 Invoke-Mimikatz 執行自定義的 Mimikatz 命令列。

命令:

#!bash      
Invoke-Mimikatz -Command ‘”privilege::debug” “LSADump::LSA /inject” exit’

在域控制器上執行並轉儲 Active Directory 的域憑證資料是需要使用 debug 模式獲取本地管理員許可權或者系統許可權進行訪問。

注意:
UID 為 502 的帳戶是 KRBTGT 帳戶 與 RID 為 500 的帳戶一樣都是域中預設的管理員。

p11

0x0A 使用 Invoke-Mimikatz 遠端轉儲 Active Directory 憑據 ( 透過 PowerShell 遠端管理)


命令:

#!bash      
Invoke-Mimikatz -Command '"privilege::debug" "LSADump:LSA /inject"' -Computer RDLABDC02.rd.adsecurity.org

下面這個這個示例是從外網下載並完全是在記憶體中執行程式碼,然後執行 Invoke-Mimikatz 。如果攻擊者已經拿到了域管理員已登入的主機,那麼在這種情況下會很有效,從而使攻擊者可以將 Active Directory 資料庫檔案從域控制器複製到主機中,然後上傳到外網。

p12

0x0B 使用 Mimikatz 的 DCSync 功能遠端轉儲 Active Directory 憑據


在 2015 年八月, Mimikatz 加入了一個新的特性—— “DCSync”,可以有效地“假冒”一個域控制器,並可以向目標域控制器請求帳戶密碼資料。

之前利用 DCSync 的攻擊方法是在域控制器上執行 Mimikatz 或 Invoke-Mimikatz 得到 KRBTGT 賬戶的密碼雜湊建立黃金票證。

如果使用適當的許可權執行 Mimikatz 的 DCSync 功能,攻擊者就可以透過網路遠端讀取域控制器的密碼雜湊,以及以前的密碼的雜湊,且無需互動式登入或複製 Active Directory 的資料庫檔案(NTDS.DIT)。

執行 DCSync 所要求的特殊許可權有管理員組(Administrators),域管理員組( Domain Admins)或企業管理員組(Enterprise Admins)以及域控制器計算機帳戶的任何成員都能夠執行 DCSync 去讀取密碼資料。需要注意的是隻讀域控制器預設是不允許讀取使用者密碼資料的。

DCSync 是何如工作的:

  1. 使用指定的域名稱發現域控制器。
  2. 請求域控制器透過 DSGetNCChanges 複製使用者憑據(利用目錄複製服務(DRS)遠端協議

我之前捕獲了一些域控制器複製資料的資料包,並確認了有關域控制器如何複製內部 DC 資料的通訊流。

Samba Wiki 描述了 DSGetNCChanges 函式,如下:

“當第一個得到的 AD 物件從第二個更新時,客戶端 DC 會向伺服器傳送 DSGetNCChanges 請求。響應的資料包含了一組客戶端必須應用到其 NC 副本的更新。...

當 DC 收到一個 DSReplicaSync 請求後,它會執行一個複製週期,去複製每一個它要複製的 DC (儲存在 RepsFrom 資料結構中),此時它的行為就像一個客戶端,會傳送 DSGetNCChanges 請求到那個所要複製的 DC 去。所以它獲得了每個它所複製的 DC 的最新的 AD 物件。

DCSync 選項:

  • /user - 要拉取資料的使用者的 id 或 SID
  • /domain(可選的) Active Directory 域的 FQDN 域名,Mimikatz 會發現域中的一個 DC 並去連線。如果不提供該引數,Mimikatz 會預設設定為當前域。
  • /dc(可選的)指定你想要使用 DCSync 連線並收集資料的域控制器。

另外還有一個/guid引數。

DCSync 命令列示例:

拉取 rd.adsecurity.org 域中的 KRBTGT 使用者帳戶的密碼資料:

#!bash
Mimikatz "privilege::debug" "lsadump::dcsync /domain:rd.adsecurity.org /user:krbtgt" exit

拉取 rd.adsecurity.org 域中的 Administrator 使用者帳戶的密碼資料:

#!bash
Mimikatz "privilege::debug" "lsadump::dcsync /domain:rd.adsecurity.org /user:Administrator" exit

拉取 lab.adsecurity.org 域中 ADSDC03 域控制器的計算機帳戶的密碼資料:

#!bash
Mimikatz "privilege::debug" "lsadump::dcsync /domain:lab.adsecurity.org /user:adsdc03$" exit

p13

如果帳戶啟用了 “可逆加密”,則會顯示明文密碼。

p14

0x0C 參考及引用


本文章來源於烏雲知識庫,此映象為了方便大家學習研究,文章版權歸烏雲知識庫!

相關文章