關注這個專欄的其他相關筆記:[內網安全] 內網滲透 - 學習手冊-CSDN博客
0x01:SAM 文件 & Windows 本地認證流程
0x0101:SAM 文件簡介
Windows 本地賬戶的登錄密碼是存儲在系統本地的 SAM 文件中的,在登錄 Windows 的時候,系統會將用戶輸入的密碼與 SAM 文件中的密碼進行對比,如果相同,則認證成功,你就可以登錄了。
SAM 文件存儲在系統的 %SystemRoot%\system32\config\
目錄下,該文件用于存儲本地所有用戶的憑證信息。值得注意的是,哪怕我們能看到該文件,我們也是無法直接查看到文件內容的:
0x0102:Windows 本地認證流程
下圖就是 Windows 本地認證的流程,這個流程每當我們進行登錄時系統就會自動走一遍:
Windows 本地認證流程如下:
-
首先,用戶注銷、重啟、鎖屏后,操作系統會讓 winlogon.exe 顯示登錄界面,接收用戶輸入的賬號密碼。
-
用戶在 winlogon.exe 中輸入賬號密碼后,winlogon.exe 會將明文密碼發送到 lsass.exe 進程中。
-
lsass.exe 將收到的明文密碼保存到內存中,并將明文密碼進行 NTLM Hash 加密。
-
lsass.exe 將加密后的密碼與 SAM 文件中的值進行比對,比對成功就允許登錄,反之,登錄失敗。
Winlogon.exe 即 Windows Logon Process,是 Windows NT 用戶登錄程序,用于管理用戶的登錄和退出。
Lsass.exe 是微軟 Windows 系統的一個安全機制,它用于控制本地安全和登錄策略。
在進行本地認證的過程中,用來處理用戶輸入密碼的進程 lsass.exe 會將用戶的密碼以明文形式存儲一份在內存中,以供該進程將密碼計算成 NTLM Hash 與 SAM 進行比對。我們后面使用 Mimikatz 來獲取的明文密碼,便是通過該進程讀取到的。
即,若要讓 Mimikatz 成功抓取密碼,被抓密碼的用戶必須在該機器中登陸過,且明文密碼被保存在了內存中。(關機重啟后內存就刷新了,密碼就消失了,也就抓不到了)
0x02:NTLM Hash & LM Hash 原理剖析
Windows 操作系統中的密碼一般由兩部分組成,一部分為 LM Hash,另一部分為 NTLM Hash。在 Windows 操作系統中,Hash 的結構通常如下:
username:RID:LM-HASH:NTLM-HASH
LM Hash 簡介 — DES 加密(可逆)
LM Hash 的全名為 “LAN Manager Hash”,是微軟為了提高 Windows 操作系統的安全性而采用的散列加密算法,其本質是 DES 加密(DES 加密是可逆的,可被破解的)。
由于 LM Hash 比較容易被破解,微軟又為了保證系統的兼容性,所以從 Windows Vista 和 Windows Server 2008 開始,LM Hash 默認是被禁用了(開始使用 NTLM Hash)。
LM Hash 明文密碼被限定在 14 位以內,即,如果要停止使用 LM Hash,將用戶的密碼設置為 14 位以上即可。如果 LM Hash 被禁用了,攻擊者通過工具抓取到的 LM Hash 通常為 “ad3b435b51404eead3b435b51404ee” 標示 LM Hash 為空值或者被禁用。
NTLM Hash 簡介 — MD4 加密(不可逆)
NTLM Hash 是微軟為了在提高安全性的同時保證兼容性而設計的散列加密算法。NTLM Hash 是基于 MD4 加密算法進行加密的。
個人版從 Windows Vista 以后,服務器版從 Windows Server 2003 以后,Windows 操作系統的認證方式均為 NTLM Hash。
為了解決 LM 加密和身份驗證方案中固有的安全弱點,Microsoft 于 1993 年在 Windows NT 3.1 中引入了 NTLM 協議,下面是各個版本對 LM 和 NTLM 的支持:
0x0201:LM Hash 加密原理
這部分我們將以明文口令 Admin@123
為例一步一步的演示 LM Hash 加密的流程,以此加深大家對 LM Hash 加密的理解(下面加密流程中,字節之間是沒有空格的,筆者這樣寫只是方便大家看清而已)。
第一步:將明文口令轉換為其大寫形式 => ADMIN@123
第二步:將大寫的明文口令轉換為十六進制字符串 => 41 44 4D 49 4E 40 31 32 33
字符串HEX轉換hex轉string,string轉hex,hex轉字符串,字符串轉hex
https://www.lddgo.net/string/hex
第三步:密碼不足 14 字節要求用 0 補全,1Byte=8bit,上面十六進制字符串共 9 字節,還差 5 字節,我們需要用 00 補全,最終結果為:
41 44 4D 49 4E 40 31 32 33 00 00 00 00 00
第四步:將上述編碼每 7 個字節一組,分成兩組:
第一組: 41 44 4D 49 4E 40 31
第二組: 32 33 00 00 00 00 00
第五步:將每一組 7 個字節的十六進制轉換為二進制:
第一組: 41 44 4D 49 4E 40 31
轉化過程:41 => 4 1 => 0100 000144 => 4 4 => 0100 01004D => 4 D => 0100 110149 => 4 9 => 0100 10014E => 4 E => 0100 111040 => 4 0 => 0100 000031 => 3 1 => 0011 0001
轉化后: 0100 0001 0100 0100 0100 1101 0100 1001 0100 1110 0100 0000 0011 0001
第二組: 32 33 00 00 00 00 00
轉化過程:32 => 3 2 => 0011 001033 => 3 3 => 0011 001100 => 0 0 => 0000 0000
轉化后: 0011 0010 0011 0011 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
第六步:每 7bit 一組末尾加零,再轉化成十六進制得到 2 組 8 字節的編碼:
第一組: 0100 0001 0100 0100 0100 1101 0100 1001 0100 1110 0100 0000 0011 0001
轉換過程: 每 7 bit 一組末尾加零,并轉化為十六進制:
0100 0000 => 40
1010 0010 => A2
0001 0010 => 12
1010 1000 => A8
1001 0100 => 94
0111 0010 => 72
0000 0000 => 00
0110 0010 => 62
轉換后: 40 A2 12 A8 94 72 00 62
第二組: 0011 0010 0011 0011 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
轉換過程: 每 7 bit 一組末尾加零,并轉化為十六進制:
0011 0010 => 32
0001 1000 => 18
1100 0000 => C0
0000 0000 => 00
0000 0000 => 00
0000 0000 => 00
0000 0000 => 00
0000 0000 => 00
轉換后: 32 18 C0 00 00 00 00 00
第七步:將前面步驟得到的兩組 8 字節編碼分別作為密鑰,對字符串 KGS!@#$%
的十六進制值(4B47532140232425
)進行 DES 加密:
DES 加密工具:DES加密工具.exe
被加密的明文: 4B47532140232425
第一組(密鑰): 40A212A894720062
第二組(密鑰): 3218C00000000000
第八步:將兩次 DES 加密的結果拼接在一起就是最終的 LM Hash值:
6F08D7B306B1DAD4B75E0C8D76954A50
0x0202:NTLM Hash 加密原理
這部分我們將以明文口令 Admin@123
為例一步一步的演示 NTLM Hash 加密的流程,以此加深大家對 NTLM Hash 加密的理解(下面加密流程中,字節之間是沒有空格的,筆者這樣寫只是方便大家看清而已)。
第一步:將明文口令轉化為十六進制格式 => 41 64 6D 69 6E 40 31 32 33
第二步:將轉化的十六進制再轉化為 Unicode 格式(在每個字節后面補兩個 0):
原始: 41 64 6D 69 6E 40 31 32 33
轉 Unicode 格式: 4100 6400 6D00 6900 6E00 4000 3100 3200 3300
最終值: 410064006D0069006E004000310032003300
第三步:對 Unicode 字符串進行 MD4 加密,生成 32 位的 NTLM Hash 值:
HashCalc 工具獲取:HashCalc.exe
570a9a65db8fba761c1008a51d4c95ab
綜上所屬,如果我們有一個用戶賬號信息為:admin : Admin@123
,那么其在 SAM 文件中的格式就長下面這樣:
admin:RID:6F08D7B306B1DAD4B75E0C8D76954A50:570a9a65db8fba761c1008a51d4c95ab
這里筆者簡單介紹一下 RID:
在 WIndows 操作系統中,RID(Relative Identifier,相對標識符)是安全標識符(SID)的一部分,用于唯一標識用戶賬戶、組或其他安全主體。
-
SID(Security Identifier,安全標識符): 是一個唯一標識用戶、組或計算機賬戶的數字。它由兩部分組成:域 SID 和 RID。
-
RID(Relative Identifier,相對標識符): 是 SID 中的一部分,用于區分同一域內的不同對象。每次創建新賬戶或組時,RID 會遞增。
例如,一個用戶賬戶的 SID 可能是 S-1-5-21-1234567890-1234567890-1234567890-1000
,其中 1000
就是 RID。
常見的 RID 值有以下幾個:
-
500
=> 本地管理員賬戶。 -
501
=> 來賓賬戶。 -
1000
即以上 => 普通用戶賬戶。