LM-Hash与NTLM-Hash

在windows下通过SAMInside提取到的密码Hash时,可以看到有两条,分别是LM-Hash和NTLM-HASH
这是对同一个密码的两种不同的加密方式,下面对其生成原理做个实验。

Windows下LM-Hash生成原理(IBM设计的LM Hash算法)

实验环境:windows server 2003
使用工具:SAMinside

LM HASH生成规则如下:

测试服务器密码为123456

python实现LM-HASH脚本

# coding=utf-8
import base64
import binascii
from pyDes import *


def DesEncrypt(str, Des_Key):
    k = des(Des_Key, ECB, pad=None)
    EncryptStr = k.encrypt(str)
    return binascii.b2a_hex(EncryptStr)


def Zero_padding(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__":

    test_str = "123456"
    # 用户的密码转换为大写,并转换为16进制字符串
    test_str = test_str.upper().encode('hex')
    str_len = len(test_str)

    # 密码不足14字节将会用0来补全
    if str_len < 28:
        test_str = test_str.ljust(28, '0')

    # 固定长度的密码被分成两个7byte部分
    t_1 = test_str[0:len(test_str) / 2]
    t_2 = test_str[len(test_str) / 2:]

    # 每部分转换成比特流,并且长度位56bit,长度不足使用0在左边补齐长度
    t_1 = bin(int(t_1, 16)).lstrip('0b').rjust(56, '0')
    t_2 = bin(int(t_2, 16)).lstrip('0b').rjust(56, '0')

    # 再分7bit为一组末尾加0,组成新的编码
    t_1 = Zero_padding(t_1)
    t_2 = Zero_padding(t_2)
    print t_1
    t_1 = hex(int(t_1, 2))
    t_2 = hex(int(t_2, 2))
    t_1 = t_1[2:].rstrip('L')
    t_2 = t_2[2:].rstrip('L')

    if '0' == t_2:
        t_2 = "0000000000000000"
    t_1 = binascii.a2b_hex(t_1)
    t_2 = binascii.a2b_hex(t_2)

    # 上步骤得到的8byte二组,分别作为DES key为"KGS!@#$%"进行加密。
    LM_1 = DesEncrypt("KGS!@#$%", t_1)
    LM_2 = DesEncrypt("KGS!@#$%", t_2)

    # 将二组DES加密后的编码拼接,得到最终LM HASH值。
    LM = LM_1 + LM_2
    print LM

挑战/响应模式(鉴权协议)

鉴权协议如下的鉴权协议又被称作挑战--认证模式,使用明文口令模式时,网络上传输的就是明文口令本身,这很容易被Sniffer捕获。
挑战/响应模式在传输信道是可被侦听Sniffer,但不可被篡改的情况下,这是一种简单而安全的方法。

LAN Manager Challenge/Response

LAN Manager Challenge/Response 验证机制,简称LM。该方案比NTLM响应时间更早,安全性更低。

SMB通信,Client A访问Server B通过LM身份验证的过程

Client A最终获得一个24字节响应应"CA1200723C41D577AB18C764C6DEF34FA61BFA0671EA5FC8"(这个结果被称为response)

NTLM-HASH

IBM设计的LM Hash算法存在几个弱点,微软在保持向后兼容性的同时提出了自己的挑战响应机制,NTLM Hash便应运而生。

NTLM-HASH计算如下
密码为123456,首先将密码字符串转化为ASCII字符串,ASCII字符串再转换为十六进制字符串,十六进制字符串再转化为Unicode字符串,然后对Unicode字符串使用MD4消息摘要算法,这会产生一个16字节的值, NTLM-HASH

计算结果与SAMinside提取结果相同
32ed87bdb5fdc5e9cba88547376818d4

各类HASH

NTLM消息介绍

NTLM验证是一种Challenge/Response 验证机制,由三种消息组成:通常称为类型1(协商),类型2(质询)和类型3(身份验证)。

它基本上是这样工作的:

协商消息示例(此处为NTLMv2)

协商消息从客户端发送到服务器以启动NTLM身份验证。其主要目的是通过FLAG指明支持的选项来建立认证的“基本规则”。

十六进制协商消息:

4e544c4d53535000010000000732000006000600330000000b000b0028000000050093080000000f574f524b53544154494f4e444f4d41494e

将其分解如下:

wireshark 抓包分析协商消息数据包:

质询消息示例(此处为NTLMv2)

质询消息由服务器发送到客户端以响应客户端的协商消息。它用于完成与客户的选择的谈判,并且向客户提供挑战。它可以选择包含有关认证目标的信息。

十六进制质询消息:

4e544c4d53535000020000000c000c003000000001028100
0123456789abcdef0000000000000000620062003c000000
44004f004d00410049004e0002000c0044004f004d004100
49004e0001000c0053004500520056004500520004001400
64006f006d00610069006e002e0063006f006d0003002200
7300650072007600650072002e0064006f006d0061006900
6e002e0063006f006d0000000000

将其分解为其组成字段给出:

wireshark 抓包分析协商消息数据包:

身份验证消息示例(此处为NTLMv2)

身份验证消息
是身份验证的最后一步。该消息包含客户端对上一步挑战的响应,这表明客户知道账户密码而不直接发送密码。
身份验证消息
还指示身份验证目标(域或服务器名称)和身份验证帐户的用户名以及客户端工作站名称。

身份验证消息结构

客户端创建一个或多个挑战的响应,有六种类型的回应:

wireshark 抓包分析身份验证消息数据包:

NTLM响应

NTLM响应由较新的客户端发送。该方案解决了LM响应中的一些缺陷; 然而,它仍然被认为相当薄弱。
此外,NTLM响应几乎总是与LM响应一起发送。该算法的弱点可以用来获取不区分大小写的密码,以及用于查找NTLM响应使用的区分大小写密码的试错法。

NTLM响应计算如下:

客户端计算密码字符串的NTLM哈希。
将16字节的NTLM散列填充为21个字节,
该值分成三个7字节。
这些值用于创建三个DES密钥(每个7字节的作为一个密钥)。
这每一个密钥用于对来自质询消息的挑战进行DES加密(产生三个8字节密文值)。
这三个密文值被连接在一起形成一个24字节的值。这是NTLM的回应。
请注意:只有散列值的计算与LM方案不同; 响应的计算方式是相同的。

例子(一个使用密码“ SecREt01 ” 的用户,质询消息的挑战为“ 0x0123456789abcdef ”)。

NTLMv2响应

NTLM版本2(“NTLMv2”)被用来解决NTLM中存在的安全问题。当启用NTLMv2时,NTLM响应被替换为NTLMv2响应,并且LM响应被替换为LMv2响应。

NTLMv2响应计算如下:
计算获得NTLM密码哈希,方法和上文一样。
计算获得 NTLMv2哈希值,先将用户名转换为大写,然后和目标拼接在一起(目标为 domain or server name 的值,且区分大小写)组成字符串,然后计算这个字符串的Unicode十六进制字符串,使用上文16字节NTLM散列作为密钥,将HMAC-MD5消息认证码算法应用于Unicode十六进制字符串,得到16字节的值,即为NTLMv2-HASH。
构建被称为“blob”的数据块。“blob”的数据块简述:

使用16字节NTLMv2散列(在上面步骤中计算)作为密钥,将HMAC-MD5消息认证码算法应用于质询消息的挑战与blob连接字符串。这会产生一个16字节的HASH输出值。该值与blob连接以形成NTLMv2响应。

使用上图NTLMv2数据包,计算NTLMv2响应示例:

Hashcat的NTLMv2密码字典暴力破解应该就是还原上述过程对比ntlmv2_response,命令如下:

hashcat64.exe -m 5600 testapp::DESKTOP-DVIA6R3:4e783a49fe733dce:03b4e9129fbe586e457d55412b39f324:0101000000000000891b7768f8b6d301bd64ae0fc8b412280000000002001e004400450053004b0054004f0050002d004d00490037004b0033003900560001001e004400450053004b0054004f0050002d004d00490037004b0033003900560004001e004400450053004b0054004f0050002d004d00490037004b0033003900560003001e004400450053004b0054004f0050002d004d00490037004b0033003900560007000800891b7768f8b6d30106000400020000000800300030000000000000000100000000200000cde827d049d6339086424b6e6880b54b98a279af64f927eb1db25b319c7d211e0a001000000000000000000000000000000000000900260063006900660073002f003100390032002e003100360038002e00310030002e00310030003200000000000000000000000000 pwd.txt -o found.txt --force

源链接

Hacking more

...