NTLM深入分析


LMhash&NTLMhash

已知windows密碼都不是明文保存的,都是以hash的形式放在了本地sam內,域內的密碼hash則保存在了域控的ntds.dit內

導入的密碼hash如下:
Administrator:500:AAD3B435B51404EEAAD3B435B51404EE:CCEF208C6485269C20DB2CAD21734FE7:::
LMhash:
AAD3B435B51404EEAAD3B435B51404EE
NTLMhash:
CCEF208C6485269C20DB2CAD21734FE7

LMhash

全稱為LAN Manager Hash

計算方式:
用戶的密碼轉換為大寫,密碼轉換為16進制字符串,不足14字節將會用0來再后面補全。
密碼的16進制字符串被分成兩個7byte部分。每部分轉換成比特流,並且長度位56bit,長度不足使用0在左邊補齊長度
再分7bit為一組,每組末尾加0,再組成一組
上步驟得到的二組,分別作為key為"KGS!@#$%"進行DES加密
將加密后的兩組拼接在一起,得到最終LM HASH值

加密方式

#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. 用戶的密碼轉換為大寫,密碼轉換為16進制字符串,不足14字節將會用0來再后面補全。
    pass_hex = password.upper().encode("hex").ljust(28,'0') #3132333435360000000000000000
    print(pass_hex) 
    # 2. 密碼的16進制字符串被分成兩個7byte部分。每部分轉換成比特流,並且長度位56bit,長度不足使用0在左邊補齊長度
    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!@#$%"進行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")

安全問題

密碼長度最大只能為14個字符
密碼不區分大小寫,在生成哈希值之前,所有密碼都將轉換為大寫
查看我們的加密過程,就可以看到使用的是分組的DES,如果密碼強度是小於7位,那么第二個分組加密后的結果肯定是AAD3B435B51404EEAAD3B435B51404EE,如果我們看到lm hash的結尾是aad3b435b51404ee,就可以很輕易的發現密碼強度少於7位
一個14個字符的密碼分成7 + 7個字符,並且分別為這兩個半部分計算哈希值。這種計算哈希值的方式使破解難度大大降低,這使得14個字符的密碼的有效強度等於,7個字符的密碼的兩倍,該密碼的復雜度明顯低於  14個字符的密碼的理論強度。
Des密碼強度不高

NTLMhash

為了解決LMhash而推出的NTLM協議,下方為版本支持情況

這里我們的機器是2012的環境,從上圖可以知道是不使用lmhash的,因為如果使用空密碼或者LMhash進行存儲的話抓的密碼LMhash部分就是AAD3B435B51404EEAAD3B435B51404EE,LMhash並沒有什么價值,所以着重關注NTLMhash即可

考慮到一些工具需要填寫固定的hash密碼的格式,也就是必須要有LMhash,所以可以將LMhash部分全部填0,結合當前環境
原來密碼:
AAD3B435B51404EEAAD3B435B51404EE:CCEF208C6485269C20DB2CAD21734FE7
現在密碼:
00000000000000000000000000000000:CCEF208C6485269C20DB2CAD21734FE7

計算方式:
將用戶密碼轉換為十六進制格式。
將十六進制格式的密碼進行Unicode編碼。
使用MD4摘要算法對Unicode編碼數據進行Hash計算

加密方式

python2 -c 'import hashlib,binascii; print binascii.hexlify(hashlib.new("md4", "Admin12345".encode("utf-16le")).digest())'

此處同我們獲取到的密碼hash一致

NTLM身份驗證

主要是一種challenge/response的驗證機制,由三種消息組成,通常為type1協商、type2質詢、type3身份驗證

1、用戶登錄客戶端電腦
2、客戶端向服務器發送type 1協商請求,包含客戶端支持和服務器請求的功能列表
3、服務器用type 2質詢進行響應,這包含服務器支持和同意的功能列表,同時包含服務器產生的Challenge其實也就是個字符串
4、客戶端用type 3身份驗證回復質詢,用戶接收到上一步中的challenge之后,使用用戶hash與challenge進行加密運算得到response,將response,username,challeng發給服務器,其中reponse向服務器證明客戶端用戶已經知道帳戶密碼。
5、服務器拿到type 3之后,使用challenge和用戶hash進行加密得到response2與type 3發來的response進行比較。如果用戶hash是存儲在域控里面的話,那么沒有用戶hash,也就沒辦法計算response2。也就沒法驗證。這個時候用戶服務器就會通過netlogon協議聯系域控,建立一個安全通道,然后將type 1,type 2,type3 全部發給域控(這個過程也叫作Pass Through Authentication認證流程)
6、域控使用challenge和用戶hash進行加密得到response2,與type 3的response進行比較

抓包分析整個階段的數據包

type1協商

官方文檔:
https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-nlmp/b34032e5-3aae-4bc6-84c3-c6d80eadf7f2

客戶端向服務器發生協商消息,包含客戶端支持和服務端請求的功能列表

type2質詢

官方文檔:
https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-nlmp/801a4681-8809-4be9-ab0d-61dcfe762786

包含服務器支持和統一的功能列表,產生challenge為eb759c11e09dbb2b

type3身份驗證

官方文檔:
https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-nlmp/033d32cc-88f9-4483-9bf2-b273055038ce

用戶接收到上一步中的challenge之后,使用用戶hash與challenge進行加密運算得到response,將response,username,challeng發給服務器,其中reponse向服務器證明客戶端用戶已經知道帳戶密碼

如下這里的challenge為e3d463fde72d2e3f,其實就是加密后的
Response為7427b887027d29fceb6f49963ba9007201010000000000004a881d1672e9d601e3d463fde72d2e3f0000000002000e0052004f004f0054004b004900540001000e004f005700410032003000310033000400160072006f006f0074006b00690074002e006f0072006700030026004f005700410032003000310033002e0072006f006f0074006b00690074002e006f00720067000500160072006f006f0074006b00690074002e006f0072006700070008004a881d1672e9d60106000400020000000800300030000000000000000000000000200000f1b5d13b0a0b1ac4bb031cf68b7998834190b70a212dc594e727ec58921d61750a001000000000000000000000000000000000000900240063006900660073002f003100390032002e003100360038002e0033002e00310034003400000000000000000000000000

Net-ntlm hash

在type3身份驗證階段的響應具備六種類型的響應

LM(LAN Manager)響應 - 由大多數較早的客戶端發送,這是“原始”響應類型。

NTLM v1響應 - 這是由基於NT的客戶端發送的,包括Windows 2000和XP。

NTLMv2響應 - 在Windows NT Service Pack 4中引入的一種較新的響應類型。它替換啟用了 NTLM版本2的系統上的NTLM響應。

LMv2響應 - 替代NTLM版本2系統上的LM響應。

NTLM2會話響應 - 用於在沒有NTLMv2身份驗證的情況下協商NTLM2會話安全性時,此方案會更改LM NTLM響應的語義。

匿名響應 - 當匿名上下文正在建立時使用; 沒有提供實際的證書,也沒有真正的身份驗證。“存 根”字段顯示在類型3消息中。
這六種使用的加密流程一樣,都是前面我們說的Challenge/Response 驗證機制,區別在Challenge和加密算法不同。


關於NTLMv1&v2
NTLMv2是16位的Challenge,而v1是8位的Challenge
NTLMv1是將 16字節的NTLM hash空填充為21個字節,然后分成三組,每組7比特,作為3DES加密算法的三組密鑰,加密Server發來的Challenge。 將這三個密文值連接起來得到response。

而v2是的加密算法是。
(1). 將Unicode后的大寫用戶名與Unicode后的身份驗證目標(在Type 3消息的"TargetName"字段中指定的域或服務器名稱)拼在一起。請注意,用戶名將轉換為大寫,而身份驗證目標區分大小寫,並且必須與“TargetName”字段中顯示的大小寫匹配。使用16字節NTLM哈希作為密鑰,得到一個值。
(2) 構建一個blob信息
(3). 使用16字節NTLMv2哈希作為密鑰,將HMAC-MD5消息認證代碼算法加密一個值(來自type 2的Challenge與Blob拼接在一起)。得到一個16字節的NTProofStr。
(4). 將NTProofStr與Blob拼接起來形成得到response。
至於選擇哪個版本的響應由LmCompatibilityLevel決定。

驗證機制里邊包含了Net-ntlm hash,NTLM v1響應和NTLMv2響應對應的就是Net-ntlm hash分為Net-ntlm hash v1和Net-ntlm hash v2

Net-ntlm v1的格式為:
username::hostname:LM response:NTLM response:challenge
Net-ntlm v2的格式為:
username::domain:challenge:HMAC-MD5:blob

關於NTLMv2

已知格式如下
username::domain:challenge:HMAC-MD5:blob

challenge為ntlm server challenge  eb759c11e09dbb2b
domain可以從數據包獲得
HMAC-MD5為NTProofStr  7427b887027d29fceb6f49963ba90072
NTLMv2的Response  7427b887027d29fceb6f49963ba9007201010000000000004a881d1672e9d601e3d463fde72d2e3f0000000002000e0052004f004f0054004b004900540001000e004f005700410032003000310033000400160072006f006f0074006b00690074002e006f0072006700030026004f005700410032003000310033002e0072006f006f0074006b00690074002e006f00720067000500160072006f006f0074006b00690074002e006f0072006700070008004a881d1672e9d60106000400020000000800300030000000000000000000000000200000f1b5d13b0a0b1ac4bb031cf68b7998834190b70a212dc594e727ec58921d61750a001000000000000000000000000000000000000900240063006900660073002f003100390032002e003100360038002e0033002e00310034003400000000000000000000000000
blob為Response減去NTProofStr的后半部分  01010000000000004a881d1672e9d601e3d463fde72d2e3f0000000002000e0052004f004f0054004b004900540001000e004f005700410032003000310033000400160072006f006f0074006b00690074002e006f0072006700030026004f005700410032003000310033002e0072006f006f0074006b00690074002e006f00720067000500160072006f006f0074006b00690074002e006f0072006700070008004a881d1672e9d60106000400020000000800300030000000000000000000000000200000f1b5d13b0a0b1ac4bb031cf68b7998834190b70a212dc594e727ec58921d61750a001000000000000000000000000000000000000900240063006900660073002f003100390032002e003100360038002e0033002e00310034003400000000000000000000000000

結合hashcat效果如下
hashcat -m 5600 Administrator::ROOTKIT:eb759c11e09dbb2b:7427b887027d29fceb6f49963ba90072:01010000000000004a881d1672e9d601e3d463fde72d2e3f0000000002000e0052004f004f0054004b004900540001000e004f005700410032003000310033000400160072006f006f0074006b00690074002e006f0072006700030026004f005700410032003000310033002e0072006f006f0074006b00690074002e006f00720067000500160072006f006f0074006b00690074002e006f0072006700070008004a881d1672e9d60106000400020000000800300030000000000000000000000000200000f1b5d13b0a0b1ac4bb031cf68b7998834190b70a212dc594e727ec58921d61750a001000000000000000000000000000000000000900240063006900660073002f003100390032002e003100360038002e0033002e00310034003400000000000000000000000000 pass.txt --force

SSP&SSPI

SSPI

Security Support Provider Interface

Windows 定義的一套接口,此接口定義了與安全有關的功能函數, 用來獲得驗證、信息完整性、信息隱私等安全功能,就是定義了一套接口函數用來身份驗證,簽名等,但是沒有具體的實現

SSP

Security Support Provider

根據SSPI所生成的具體產物,簡稱SSP,如微軟的NTLMSSP為NTLM認證的實現提供了基本功能,是windowsSSPI的一種實現,除了NTLMSSP外還有kerberos,Cred SSP,Digest SSP等等

數據包內可以發現ntlm信息是放在GSS-API內,產生GSSAPI的原因是因為SSPI是GSSAPI的專有變體,進行了擴展並具有許多特定於Windows的數據類型

LmCompatibilityLevel

用來確定網絡登錄使用的質詢/響應身份驗證協議。此選項會影響客戶端使用的身份驗證協議的等級、協商的會話安全的等級以及服務器接受的身份驗證的等級

發送 LM NTLM 響應:
客戶端使用 LM 和 NTLM 身份驗證,而決不會使用 NTLMv2 會話安全;域控制器接受 LM、NTLM 和 NTLMv2 身份驗證

發送 LM & NTLM:
如果協商一致,則使用 NTLMv2 會話安全: 客戶端使用 LM 和 NTLM 身份驗證,並且在服務器支持時使用 NTLMv2 會話安全;域控制器接受 LM、NTLM 和 NTLMv2 身份驗證

僅發送 NTLM 響應:
客戶端僅使用 NTLM 身份驗證,並且在服務器支持時使用 NTLMv2 會話安全;域控制器接受 LM、NTLM 和 NTLMv2 身份驗證

僅發送 NTLMv2 響應:客戶端僅使用 NTLMv2 身份驗證,並且在服務器支持時使用 NTLMv2 會話安全;域控制器接受 LM、NTLM 和 NTLMv2 身份驗證

僅發送 NTLMv2 響應\拒絕 LM: 客戶端僅使用 NTLMv2 身份驗證,並且在服務器支持時使用 NTLMv2 會話安全;域控制器拒絕 LM (僅接受 NTLM 和 NTLMv2 身份驗證)

僅發送 NTLMv2 響應\拒絕 LM & NTLM:客戶端僅使用 NTLMv2 身份驗證,並且在服務器支持時使用 NTLMv2 會話安全;域控制器拒絕 LM 和 NTLM (僅接受 NTLMv2 身份驗證)

安全問題

pth

此處在type3階段時候客戶端是使用用戶的hash進行計算的,而不是基於密碼,因此在登錄時候是可以用hash進行登錄的,針對防范pth微軟推出補丁kb2871997進行緩解,當然這個也可以方法mimikatz抓取明文密碼

關於kb2871997只能進行緩解,是因為他對於本地的administrator(rid為500,操作系統只核對rid忽略用戶名)和本地管理員組的域用戶都是不受影響的

也就是說rid為500的用戶、本地管理員組的域用戶在打補丁后都是可以pth

常用操作

mimikatz
impacket組件
msf

ntlm信息泄露

如下已知返回challenge時候將同時發送操作系統相關信息,如主機名、BIOS名等等,如果能夠偽造第一階段的typ1的請求,就能如下拿到服務器返回第二階段type2的信息

ntlm認證通常適用於多協議,如http、smb、ldap等

C#版本的smb_version

using System;
using System.Data;
using System.Text;
using System.Text.RegularExpressions;
using System.Collections;
using System.Collections.Generic;
using System.Threading;
using System.Diagnostics;
using System.IO;
using System.Security.Cryptography;
using System.Net;
using System.Net.Sockets;
using System.Reflection;
using System.Runtime;
using System.Runtime.InteropServices;

namespace Zcg.Tests
{
    class smbver
    {
        static byte[] d1 ={
    0x00, 0x00, 0x00, 0x85, 0xFF, 0x53, 0x4D, 0x42, 0x72, 0x00, 0x00, 0x00, 0x00, 0x18, 0x53, 0xC8, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFE, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0x00, 0x02, 0x50, 0x43, 0x20, 0x4E, 0x45, 0x54, 0x57, 0x4F, 
    0x52, 0x4B, 0x20, 0x50, 0x52, 0x4F, 0x47, 0x52, 0x41, 0x4D, 0x20, 0x31, 0x2E, 0x30, 0x00, 0x02, 
    0x4C, 0x41, 0x4E, 0x4D, 0x41, 0x4E, 0x31, 0x2E, 0x30, 0x00, 0x02, 0x57, 0x69, 0x6E, 0x64, 0x6F, 
    0x77, 0x73, 0x20, 0x66, 0x6F, 0x72, 0x20, 0x57, 0x6F, 0x72, 0x6B, 0x67, 0x72, 0x6F, 0x75, 0x70, 
    0x73, 0x20, 0x33, 0x2E, 0x31, 0x61, 0x00, 0x02, 0x4C, 0x4D, 0x31, 0x2E, 0x32, 0x58, 0x30, 0x30, 
    0x32, 0x00, 0x02, 0x4C, 0x41, 0x4E, 0x4D, 0x41, 0x4E, 0x32, 0x2E, 0x31, 0x00, 0x02, 0x4E, 0x54, 
    0x20, 0x4C, 0x4D, 0x20, 0x30, 0x2E, 0x31, 0x32, 0x00
};
        static byte[] d2 ={
    0x00, 0x00, 0x01, 0x0A, 0xFF, 0x53, 0x4D, 0x42, 0x73, 0x00, 0x00, 0x00, 0x00, 0x18, 0x07, 0xC8, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFE, 
    0x00, 0x00, 0x40, 0x00, 0x0C, 0xFF, 0x00, 0x0A, 0x01, 0x04, 0x41, 0x32, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x4A, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD4, 0x00, 0x00, 0xA0, 0xCF, 0x00, 0x60, 
    0x48, 0x06, 0x06, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x02, 0xA0, 0x3E, 0x30, 0x3C, 0xA0, 0x0E, 0x30, 
    0x0C, 0x06, 0x0A, 0x2B, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x02, 0x02, 0x0A, 0xA2, 0x2A, 0x04, 
    0x28, 0x4E, 0x54, 0x4C, 0x4D, 0x53, 0x53, 0x50, 0x00, 0x01, 0x00, 0x00, 0x00, 0x07, 0x82, 0x08, 
    0xA2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x05, 0x02, 0xCE, 0x0E, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x57, 0x00, 0x69, 0x00, 0x6E, 0x00, 
    0x64, 0x00, 0x6F, 0x00, 0x77, 0x00, 0x73, 0x00, 0x20, 0x00, 0x53, 0x00, 0x65, 0x00, 0x72, 0x00, 
    0x76, 0x00, 0x65, 0x00, 0x72, 0x00, 0x20, 0x00, 0x32, 0x00, 0x30, 0x00, 0x30, 0x00, 0x33, 0x00, 
    0x20, 0x00, 0x33, 0x00, 0x37, 0x00, 0x39, 0x00, 0x30, 0x00, 0x20, 0x00, 0x53, 0x00, 0x65, 0x00, 
    0x72, 0x00, 0x76, 0x00, 0x69, 0x00, 0x63, 0x00, 0x65, 0x00, 0x20, 0x00, 0x50, 0x00, 0x61, 0x00, 
    0x63, 0x00, 0x6B, 0x00, 0x20, 0x00, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x57, 0x00, 0x69, 0x00, 
    0x6E, 0x00, 0x64, 0x00, 0x6F, 0x00, 0x77, 0x00, 0x73, 0x00, 0x20, 0x00, 0x53, 0x00, 0x65, 0x00, 
    0x72, 0x00, 0x76, 0x00, 0x65, 0x00, 0x72, 0x00, 0x20, 0x00, 0x32, 0x00, 0x30, 0x00, 0x30, 0x00, 
    0x33, 0x00, 0x20, 0x00, 0x35, 0x00, 0x2E, 0x00, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00
};
static byte[] d3={
0x81,0x00,0x00,0x44,0x20,0x43,0x4b,0x46,0x44,0x45,0x4e,0x45,0x43,0x46,0x44,0x45
,0x46,0x46,0x43,0x46,0x47,0x45,0x46,0x46,0x43,0x43,0x41,0x43,0x41,0x43,0x41,0x43
,0x41,0x43,0x41,0x43,0x41,0x00,0x20,0x43,0x41,0x43,0x41,0x43,0x41,0x43,0x41,0x43
,0x41,0x43,0x41,0x43,0x41,0x43,0x41,0x43,0x41,0x43,0x41,0x43,0x41,0x43,0x41,0x43
,0x41,0x43,0x41,0x43,0x41,0x41,0x41,0x00
};
        static void Main(string[] args)
        {
            Console.WriteLine("SMB Version Detection tool 0.1");
            Console.WriteLine("Part of GMH's fuck Tools, Code By zcgonvh.\r\n");
            if (args.Length < 1) { Console.WriteLine("usage: smbver host [port]"); return; }
            string host = args[0];
            int port = 445;
            try { port = int.Parse(args[1]); }
            catch { }
            try
            {
                byte[] buf = new byte[1024];
                Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                sock.Connect(host, port);
                if(port==139)
                {
                  sock.Send(d3);
                  sock.Receive(buf);
                }
                sock.Send(d1);
                sock.Receive(buf);
                sock.Send(d2);
                sock.Receive(buf);
                int len = BitConverter.ToInt16(buf, 43);
                string[] ss = Encoding.Unicode.GetString(buf, len + 47, buf.Length - len - 47).Split('\0');
                Console.WriteLine("native os: " + ss[0]);
                Console.WriteLine("native lan manager: " + ss[1]);
                int off = 0;
                for (int i = 47; i < len - 7; i++)
                {
                    if (buf[i] == 'N' && buf[i + 1] == 'T' && buf[i + 2] == 'L' && buf[i + 3] == 'M' && buf[i + 4] == 'S' && buf[i + 5] == 'S' && buf[i + 6] == 'P') { off = i; break; }
                }
                byte[] ntlm = new byte[len];
                Array.Copy(buf, off, ntlm, 0, len);
                len = BitConverter.ToInt16(ntlm, 0xc);
                off = BitConverter.ToInt16(ntlm, 0x10);
                Console.WriteLine("negotiate target: " + Encoding.Unicode.GetString(ntlm, off, len));
                Console.WriteLine("os major version: " + ntlm[off - 8]);
                Console.WriteLine("os minor version: " + ntlm[off - 7]);
                Console.WriteLine("os build number: " + BitConverter.ToInt16(ntlm, off - 6));
                Console.WriteLine("ntlm current revision: " + ntlm[off - 1]);
                off += len;
                int type = BitConverter.ToInt16(ntlm, off);
                while (type != 0)
                {
                    off += 2;
                    len = BitConverter.ToInt16(ntlm, off);
                    off += 2;
                    switch (type)
                    {
                        case 1:
                            {
                                Console.WriteLine("NetBIOS computer name: " + Encoding.Unicode.GetString(ntlm, off, len));
                                break;
                            }
                        case 2:
                            {
                                Console.WriteLine("NetBIOS domain name: " + Encoding.Unicode.GetString(ntlm, off, len));
                                break;
                            }
                        case 3:
                            {
                                Console.WriteLine("DNS computer name: " + Encoding.Unicode.GetString(ntlm, off, len));
                                break;
                            }
                        case 4:
                            {
                                Console.WriteLine("DNS domain name: " + Encoding.Unicode.GetString(ntlm, off, len));
                                break;
                            }
                        case 5:
                            {
                                Console.WriteLine("DNS tree name: " + Encoding.Unicode.GetString(ntlm, off, len));
                                break;
                            }
                        case 7:
                            {
                                Console.WriteLine("time stamp: {0:o}", DateTime.FromFileTime(BitConverter.ToInt64(ntlm, off)));
                                break;
                            }
                        default:
                            {
                                Console.Write("Unknown type {0}, data: ", type);
                                for (int i = 0; i < len; i++)
                                {
                                    Console.Write(ntlm[i + off].ToString("X2"));
                                }
                                Console.WriteLine();
                                break;
                            }
                    }
                    off += len;
                    type = BitConverter.ToInt16(ntlm, off);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("err: " + ex);
            }
        }
    }
}

msf的smb_version

ntlm relay

原先的傳輸方式

中間出現攻擊者,改變傳輸方式如下

可以知道攻擊者作為中間人,將來自用戶的type1發送給服務器,將服務器的type2發送給用戶,用戶加入challenge計算完成后中間人再發送給服務器,服務器驗證后,直接給與中間人相關權限

后續將細論ntlm relay


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM