內網滲透之Windows認證(二)
title: 內網滲透之Windows認證(二)
categories:
- 內網滲透
id: 6
key: 域滲透基礎
description: Windows認證協議
abbrlink: d6b7
date: 2022-06-26 14:01:22
- 為什麼有這篇文章呢,因為我們知道平常的Web系統有註冊、登錄是依賴資料庫和後端的加密解密演算法。那麼Windows系統登錄的時候是如何進行身份驗證的呢,是否也有一個類似資料庫的東西,或者就是一個單純的文本呢?
- 參考–Windows內網協議學習NTLM篇之NTLM基礎介紹
- Windows也有一個類似於數據的東西,存放在
%SystemRoot%\system32\config\sam
,裡面存放著用戶的憑證資訊,當然這肯定不是明文,不然Windows這麼寫也太不安全了。這裡的加密演算法不同於常見的MD5,加密後的數據有兩種分別為LM Hash
和NTLM Hash
。
LM Hash
- LM Hash全稱
LAN Manager Hash
,由IBM設計一般用於Windows XP
、Windows 2000
、Windows 2003
這一類系統中。加密演算法如下。 - 密碼長度不能超過14個字元。
- 密碼轉換為大寫,再轉換成16進位的字元串,沒有28位長度的,在右邊加0。
- 再將十六進位的字元串分為兩組14位的字元串。
- 再將這兩組14位的字元串進行十六進位轉二進位,轉換完成後不滿足56位的在左邊加0。
- 兩部分分別劃分為每組七位,在其末尾加0,再分別轉換為十六進位。
- 最後將這兩組數據作為DES加密所需的Key,
KGS!@#$%
作為需加密的字元,將DES加密後的數據依次拼接。 - 這裡借用zjun的腳本。
import binascii
import codecs
from pyDes import *
def DesEncrypt(str, Key):
k = des(Key, ECB, pad=None)
EncryptStr = k.encrypt(str)
return binascii.b2a_hex(EncryptStr)
def ZeroPadding(str):
b = []
l = len(str)
num = 0
for n in range(l):
if (num < 8) and n % 7 == 0:
b.append(str[n:n + 7] + '0')
num = num + 1
return ''.join(b)
if __name__ == "__main__":
passwd = sys.argv[1]
print('你的輸入是:', passwd)
print('轉化為大寫:', passwd.upper())
# 用戶的密碼轉換為大寫,並轉換為 16 進位字元串
passwd = codecs.encode(passwd.upper().encode(), 'hex_codec')
print('轉為 hex:', passwd.decode())
# 密碼不足 28 位,用 0 在右邊補全
passwd_len = len(passwd)
if passwd_len < 28:
passwd = passwd.decode().ljust(28, '0')
print('補齊 28 位:', passwd)
# 28 位的密碼被分成兩個 14 位部分
PartOne = passwd[0:14]
PartTwo = passwd[14:]
print('兩組 14 位的部分:', PartOne, PartTwo)
# 每部分分別轉換成比特流,並且長度為 56 位,長度不足用 0 在左邊補齊長度
PartOne = bin(int(PartOne, 16)).lstrip('0b').rjust(56, '0')
PartTwo = bin(int(PartTwo, 16)).lstrip('0b').rjust(56, '0')
print('兩組 56 位比特流:', PartOne, PartTwo)
# 兩組分別再分為 7 位一組末尾加 0,再分別組合成新的字元
PartOne = ZeroPadding(PartOne)
PartTwo = ZeroPadding(PartTwo)
print('兩組再 7 位一組末尾加 0:', PartOne, PartTwo)
# 兩組數據轉 hex
PartOne = hex(int(PartOne, 2))[2:]
PartTwo = hex(int(PartTwo, 2))[2:]
if '0' == PartTwo:
PartTwo = "0000000000000000"
print('兩組轉為 hex:', PartOne, PartTwo)
# 16 位的二組數據,分別作為 DES key 為"KGS!@#$%"進行加密。
LMOne = DesEncrypt("KGS!@#$%", binascii.a2b_hex(PartOne)).decode()
LMTwo = DesEncrypt("KGS!@#$%", binascii.a2b_hex(PartTwo)).decode()
print('兩組 DES 加密結果:', LMOne, LMTwo)
# 將二組 DES 加密後的編碼拼接,得到 LM HASH 值。
LM = LMOne + LMTwo
print('LM hash:', LM)
- 可以看出密碼長度小於7時,後面加密的數據是固定的,均為aad3b435b51404ee,因此其加密是不安全的。
NTML Hash
- NTML Hash全稱
NT LAN Manager
, 目前 Windows 基本都使用 NTLM hash ,一個32
位長度的字元串。支援Net NTLM認證協議及本地認證過程中的關鍵憑據。加密演算法如下: - 密碼轉換為十六進位
Unicode
編碼MD4
加密- Python腳本如下:
import hashlib
import binascii
import sys
print(binascii.hexlify(hashlib.new("md4", sys.argv[1].encode("utf-16le")).digest()).decode())
123456
經過加密後則為32ed87bdb5fdc5e9cba88547376818d4
。
Windows本地認證
winlogon.exe
-> 接收用戶密碼 ->lsass.exe
-> 比對sam表。- winlogon就是登陸介面,接受用戶密碼之後會發送明文到
lsass.exe
,lsass.exe
會存儲一份明文,然後加密明文和sam表的hash做比對,判斷是否可以登陸。 - Windows Logon Process(即 winlogon.exe),是Windows NT 用戶登陸程式,用於管理用戶登錄和退出。LSASS用於微軟Windows系統的安全機制。它用於本地安全和登陸策略。
- 這裡注意如果打了修補程式
KB2871997
,或者機器是win2012
之後,則不會保存明文密碼了。
NTLM認證協議
- 什麼是
NTLM
認證協議呢?和NTLM Hash
又有什麼區別呢?NTLM
是一種網路認證協議,它是基於挑戰(Chalenge)/響應(Response)認證機制的一種認證模式。NTLM 網路認證協議是以NTLM Hash
作為根本憑證進行認證的協議。 - 在內網滲透中,經常遇到工作組環境,而工作組環境是一個邏輯上的網路環境(工作區),隸屬於工作組的機器之間無法互相建立一個完美的信任機制,只能點對點,是比較落後的認證方式, 沒有信託機構。
- 假設A主機與B主機屬於同一個工作組環境,A想訪問B主機上的資料,需要將一個存在於B主機上的賬戶憑證發送至B主機,經過認證才能夠訪問B主機上的資源。
- 早期SMB協議在網路上傳輸明文口令。後來出現LAN Manager Challenge/Response驗證機制,簡稱LM,它是如此簡單以至很容易就被破解,現在又有了
NTLM
以及Kerberos
。 - 認證流程分為三部分,分別是:
協商
、質詢
、身份驗證
。
協商
- 客戶端向伺服器發送協商請求,包含用戶名、密碼、認證協議版本等資訊。
質詢
- 伺服器接收到客戶端發送到協商資訊,這時伺服器會生成一個隨機數,叫做
challenge
,這裡的不同的協議隨機數長度不同,NTLM V1是8位,NTLM V2是16位。 - 伺服器將登陸的用戶對應的
NTLM Hash
加密challenge
,得到Net NTLM Hash
,和生成的challenge
一起發送給客戶端。
驗證
- 客戶端收到challenge後,將用戶的hash與challenge進行加密運算得到resposne,將username、response、challenge發送給伺服器,最後伺服器進行校驗返回認證結果。
WireShark
- 知道了基本原理自己實戰試試