1.LM Hash & NTLM Hash
windows內(nèi)部是不保存明文密碼的,只保存密碼的hash。
其中,本機(jī)用的密碼hash是保存在本地的SAM文件中,域用戶的密碼hash保存在域控下的NTDS.DIT文件中。那么,hash是以什么樣的形式進(jìn)行保存的呢?
在我們抓取用戶hash時(shí),經(jīng)??吹饺缦赂袷剑?br>
Administrator:500:AAD3B435B51404EEAAD3B435B51404EE:31D6CFE0D16AE931B73C59D7E0C089C0:::
需要明確的是:AAD3B435B51404EEAAD3B435B51404EE是LM Hash,31D6CFE0D16AE931B73C59D7E0C089C0是NTLM Hash
下面就詳細(xì)的來(lái)了解一下這兩種hash。
1.1.LM Hash
全稱是LAN Manager Hash, windows最早用的加密算法,由IBM設(shè)計(jì)。
LM Hash的計(jì)算:
- 用戶的密碼轉(zhuǎn)換為大寫,密碼轉(zhuǎn)換為16進(jìn)制字符串,不足14字節(jié)將會(huì)用0來(lái)再后面補(bǔ)全。
- 密碼的16進(jìn)制字符串被分成兩個(gè)7byte部分。每部分轉(zhuǎn)換成比特流,并且長(zhǎng)度位56bit,長(zhǎng)度不足使用0在左邊補(bǔ)齊長(zhǎng)度
- 再分7bit為一組,每組末尾加0,再組成一組
- 上步驟得到的二組,分別作為key 為 KGS!@#$%進(jìn)行DES加密。
- 將加密后的兩組拼接在一起,得到最終LM HASH值。
下面貼一個(gè)計(jì)算腳本,感興趣的同學(xué)可自行實(shí)驗(yàn):
#coding=utf-8
import re
import binascii
from pyDes import *
def DesEncrypt(str, Des_Key):
k = des(binascii.a2b_hex(Des_Key), ECB, pad=None)
EncryptStr = k.encrypt(str)
return binascii.b2a_hex(EncryptStr)
def group_just(length,text):
# text 00110001001100100011001100110100001101010011011000000000
text_area = re.findall(r'.{%d}' % int(length), text) # ['0011000', '1001100', '1000110', '0110011', '0100001', '1010100', '1101100', '0000000']
text_area_padding = [i + '0' for i in text_area] #['00110000', '10011000', '10001100', '01100110', '01000010', '10101000', '11011000', '00000000']
hex_str = ''.join(text_area_padding) # 0011000010011000100011000110011001000010101010001101100000000000
hex_int = hex(int(hex_str, 2))[2:].rstrip("L") #30988c6642a8d800
if hex_int == '0':
hex_int = '0000000000000000'
return hex_int
def lm_hash(password):
# 1. 用戶的密碼轉(zhuǎn)換為大寫,密碼轉(zhuǎn)換為16進(jìn)制字符串,不足14字節(jié)將會(huì)用0來(lái)再后面補(bǔ)全。
pass_hex = password.upper().encode("hex").ljust(28,'0') #3132333435360000000000000000
print(pass_hex)
# 2. 密碼的16進(jìn)制字符串被分成兩個(gè)7byte部分。每部分轉(zhuǎn)換成比特流,并且長(zhǎng)度位56bit,長(zhǎng)度不足使用0在左邊補(bǔ)齊長(zhǎng)度
left_str = pass_hex[:14] #31323334353600
right_str = pass_hex[14:] #00000000000000
left_stream = bin(int(left_str, 16)).lstrip('0b').rjust(56, '0') # 00110001001100100011001100110100001101010011011000000000
right_stream = bin(int(right_str, 16)).lstrip('0b').rjust(56, '0') # 00000000000000000000000000000000000000000000000000000000
# 3. 再分7bit為一組,每組末尾加0,再組成一組
left_stream = group_just(7,left_stream) # 30988c6642a8d800
right_stream = group_just(7,right_stream) # 0000000000000000
# 4. 上步驟得到的二組,分別作為key 為 "KGS!@#$%"進(jìn)行DES加密。
left_lm = DesEncrypt('KGS!@#$%',left_stream) #44efce164ab921ca
right_lm = DesEncrypt('KGS!@#$%',right_stream) # aad3b435b51404ee
# 5. 將加密后的兩組拼接在一起,得到最終LM HASH值。
return left_lm + right_lm
if __name__ == '__main__':
hash = lm_hash("123456")
lm協(xié)議的脆弱之處在于
- des的key是固定的
- 可以根據(jù)hash判斷密碼長(zhǎng)度是否大于7位,如果密碼強(qiáng)度是小于7位,那么第二個(gè)分組加密后的結(jié)果肯定是aad3b435b51404ee
- 密碼不區(qū)分大小寫并且長(zhǎng)度最大為14位
- 7+7字符分開(kāi)加密明顯復(fù)雜度降低14個(gè)字符整體加密 957+ 957 <95 14
- Des密碼強(qiáng)度不高
1.2.NTLM Hash
由上面可知,LM hash其實(shí)是很脆弱的,對(duì)此,微軟于1993年在Windows NT 3.1中引入了NTLM協(xié)議。NTLM Hash是支持Net NTLM認(rèn)證協(xié)議及本地認(rèn)證過(guò)程中的一個(gè)重要參與物,其長(zhǎng)度為32位,由數(shù)字與字母組成。
下面是各個(gè)版本針對(duì)LM和NTLM的支持。

也就是說(shuō),從windows visita和 Windows Server 2008開(kāi)始,默認(rèn)情況下只存儲(chǔ)NTLM Hash,LM Hash將不再存在。如果密碼為空或者計(jì)算機(jī)不存儲(chǔ)LM Hash,那么我們抓取到的hash為
AAD3B435B51404EEAAD3B435B51404EE所以,在windows7中,我們抓取到的LM Hash都是
AAD3B435B51404EEAAD3B435B51404EE
2.NTLM身份驗(yàn)證
NTLM驗(yàn)證是一種Challenge/Response 驗(yàn)證機(jī)制,由三種消息組成:通常稱為type 1(協(xié)商),類型type 2(質(zhì)詢)和type 3(身份驗(yàn)證)。值得注意的是,NTLM協(xié)議為嵌入式協(xié)議。
它基本上是這樣工作的:

- 用戶登錄客戶端電腦
- (type 1)客戶端向服務(wù)器發(fā)送type 1(協(xié)商)消息,它主要包含客戶端支持和服務(wù)器請(qǐng)求的功能列表。
- (type 2)服務(wù)器用type 2消息(質(zhì)詢)進(jìn)行響應(yīng),這包含服務(wù)器支持和同意的功能列表。但是,最重要的是,它包含服務(wù)器產(chǎn)生的Challenge。
- (type 3)客戶端用type 3消息(身份驗(yàn)證)回復(fù)質(zhì)詢。用戶接收到步驟3中的challenge之后,使用用戶hash與challenge進(jìn)行加密運(yùn)算得到response,將response,username,challeng發(fā)給服務(wù)器。消息中的response是最關(guān)鍵的部分,因?yàn)樗鼈兿蚍?wù)器證明客戶端用戶已經(jīng)知道帳戶密碼。
- 服務(wù)器拿到type 3之后,使用challenge和用戶hash進(jìn)行加密得到response2與type 3發(fā)來(lái)的response進(jìn)行比較。如果用戶hash是存儲(chǔ)在域控里面的話,那么沒(méi)有用戶hash,也就沒(méi)辦法計(jì)算response2。也就沒(méi)法驗(yàn)證。這個(gè)時(shí)候用戶服務(wù)器就會(huì)通過(guò)netlogon協(xié)議聯(lián)系域控,建立一個(gè)安全通道,然后將type 1,type 2,type3 全部發(fā)給域控(這個(gè)過(guò)程也叫作Pass Through Authentication認(rèn)證流程)
-
域控使用challenge和用戶hash進(jìn)行加密得到response2,與type 3的response進(jìn)行比較
image-20220210104124516.png
下面我將詳細(xì)介紹一下type1,type2,type3
2.1.type1
type1過(guò)程發(fā)送的內(nèi)容主要包含客戶端支持和服務(wù)器的功能列表。包結(jié)構(gòu)如下:

數(shù)據(jù)包中的具體體現(xiàn)如下:

需要澄清的一點(diǎn)是,在網(wǎng)絡(luò)上現(xiàn)存的大部分文章中,都表示在type1階段會(huì)發(fā)送明文用戶名,這樣的說(shuō)法是存在問(wèn)題的,數(shù)據(jù)包中根本就找不到用戶名信息,用戶名是在 type 和 net-hash,一起發(fā)送的,還有些文章不僅在 type1 中加入了用戶名,還給 NTLM 的過(guò)程增加了幾步,屬實(shí)給讀者帶來(lái)很大困擾。
2.2.type2
這個(gè)過(guò)程是服務(wù)器用type 2消息(質(zhì)詢)進(jìn)行響應(yīng),這包含服務(wù)器支持和同意的功能列表。但是,最重要的是,它包含服務(wù)器產(chǎn)生的Challenge。
主要 包含以下結(jié)構(gòu):

其中最主要的信息是challenge。后面加密驗(yàn)證依賴于challenge
抓包查看對(duì)應(yīng)的信息如下:

可以看到 TYPE 2 信息中,操作系統(tǒng)類型,主機(jī)名,netbios名,通常會(huì)利用改特性收集系統(tǒng)信息。
2.3.type3
這個(gè)過(guò)程客戶端接收到challenge之后,使用用戶hash與challenge進(jìn)行加密運(yùn)算得到response,將response,username,challenge發(fā)給服務(wù)器。消息中的response是最關(guān)鍵的部分,因?yàn)樗蚍?wù)器證明客戶端用戶已經(jīng)知道帳戶密碼。
主要包含以下結(jié)構(gòu):

數(shù)據(jù)包的表現(xiàn)形式:

這里的Challeng不同于type2 的Challenge,這里的Challenge是一個(gè)隨機(jī)的客戶端nonce。
提取 ntlmv2 hash,格式
username::domain:challenge:HMAC-MD5:blob前十六個(gè)字節(jié)位 HMAC-MD5,后面blob,challenge是 Type 2 中的 ServerChallenge,拼接起來(lái)就是 ntlmv2 hash
3.Net-ntlm hash
在type3中的響應(yīng),有六種類型的響應(yīng)
● LM(LAN Manager)響應(yīng) - 由大多數(shù)較早的客戶端發(fā)送,這是“原始”響應(yīng)類型。
● NTLM v1響應(yīng) - 這是由基于NT的客戶端發(fā)送的,包括Windows 2000和XP。
● NTLMv2響應(yīng) - 在Windows NT Service Pack 4中引入的一種較新的響應(yīng)類型。它替換啟用了 NTLM版本2的系統(tǒng)上的NTLM響應(yīng)。
● LMv2響應(yīng) - 替代NTLM版本2系統(tǒng)上的LM響應(yīng)。
● NTLM2會(huì)話響應(yīng) - 用于在沒(méi)有NTLMv2身份驗(yàn)證的情況下協(xié)商N(yùn)TLM2會(huì)話安全性時(shí),此方案會(huì)更改LM NTLM響應(yīng)的語(yǔ)義。
● 匿名響應(yīng) - 當(dāng)匿名上下文正在建立時(shí)使用; 沒(méi)有提供實(shí)際的證書,也沒(méi)有真正的身份驗(yàn)證?!按?根”字段顯示在類型3消息中。
這六種使用的加密流程一樣,都是前面我們說(shuō)的Challenge/Response 驗(yàn)證機(jī)制,區(qū)別在Challenge和加密算法不同。
這里我們側(cè)重講下NTLM v1響應(yīng)和NTLMv2響應(yīng)
● v2是16位的Challenge,而v1是8位的Challenge
v1是將 16字節(jié)的NTLM hash空填充為21個(gè)字節(jié),然后分成三組,每組7比特,作為3DES加密算法的三組密鑰,加密Server發(fā)來(lái)的Challenge。 將這三個(gè)密文值連接起來(lái)得到response。
而v2是的加密算法是:
(1). 將Unicode后的大寫用戶名與Unicode后的身份驗(yàn)證目標(biāo)(在Type 3消息的"TargetName"字段中指定的域或服務(wù)器名稱)拼在一起。請(qǐng)注意,用戶名將轉(zhuǎn)換為大寫,而身份驗(yàn)證目標(biāo)區(qū)分大小寫,并且必須與“TargetName”字段中顯示的大小寫匹配。使用16字節(jié)NTLM哈希作為密鑰,得到一個(gè)值。
(2) 構(gòu)建一個(gè)blob信息

(3). 使用16字節(jié)NTLMv2哈希作為密鑰,將HMAC-MD5消息認(rèn)證代碼算法加密一個(gè)值(來(lái)自type 2的Challenge與Blob拼接在一起)。得到一個(gè)16字節(jié)的NTProofStr。
(4). 將NTProofStr與Blob拼接起來(lái)形成得到response。
至于選擇哪個(gè)版本的響應(yīng)由LmCompatibilityLevel決定。
Challenge/Response驗(yàn)證機(jī)制里面type3 response里面包含Net-ntlm hash,NTLM v1響應(yīng)和NTLMv2響應(yīng)對(duì)應(yīng)的就是Net-ntlm hash分為Net-ntlm hash v1和Net-ntlm hash v2。
Net-ntlm hash v1的格式為:
username::hostname:LM response:NTLM response:challengeNet-ntlm hash v2的格式為:
username::domain:challenge:HMAC-MD5:blob
