关于 hunt-ntlm-info
面向安全测试人员的 NTLM 信息泄露检测技能,指导探测匿名 NTLM 挑战并解析其中的主机、域和时间信息。还提供影响评估、验证步骤及缓解建议。
主要功能
- 01探测匿名 NTLM 挑战
- 02解析 NTLM Type-2 信息
- 03识别主机名与 AD 域信息
- 04按暴露情况评估影响
- 05提供缓解建议
适用场景
- 01检查公网 IIS、SharePoint 或 Exchange
- 02确认匿名端点是否泄露 AD 拓扑
- 03为认证攻击链补充侦察信息
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ elementalsouls/ claude-bughunter --skill hunt-ntlm-info安装后在 Claude Code 中输入/hunt-ntlm-info确认已加载。
详细介绍
皇冠上的明珠目标
NTLM 信息泄露在与上下文结合时属于中危发现——泄露本身是有意的协议行为(符合 RFC 的 NTLMSSP 挑战),但在暴露于互联网的企业基础设施上,它能为攻击的下一阶段提供精确的侦察信息。价值最高的目标:
- 可从互联网访问的 IIS / SharePoint / Exchange / OWA,采用双重身份验证(Forms + NTLM,或 NTLM + Kerberos)
- 面向互联网的 Citrix NetScaler / VMware Horizon View 网关,使用 NTLM 进行 AD 身份验证
- Lync / Skype for Business / Teams On-Prem 边缘服务器
- WSUS / Windows Update Services,其管理路径受 NTLM 保护
- CIFS 风格的文件共享代理(HCL Sametime、IBM Notes Domino),可代理 NTLM
- 旧版 SharePoint 场,在公共区域的 IIS 绑定上仍启用了 NTLM
收益来源:
- 内部 AD 域信息泄露(父林映射,例如
customer.parent-corp.example→ 企业 AD 树中的租户) - 默认 Windows 主机名泄露(
WIN-XXXXXXXXXXX模式表明配置仓促 → 服务帐户可能使用默认密码) - 时间戳泄露(用于加速破解 NTLMv2 哈希)
- 为结合
hunt-auth-bypassLegacy-Protocol Matrix 进行凭据喷洒,直接丰富攻击地图
攻击面信号
表明可使用 NTLM 的响应标头:
WWW-Authenticate: NTLM
WWW-Authenticate: Negotiate
WWW-Authenticate: NTLM, Negotiate
WWW-Authenticate: Negotiate, NTLM
常见的 NTLM 暴露 URL 模式:
/_api/web/CurrentUser (SharePoint REST)
/_vti_bin/*.asmx (SharePoint legacy SOAP)
/EWS/Exchange.asmx (Exchange Web Services)
/Autodiscover/Autodiscover.xml (Exchange autodiscover)
/owa/ (Outlook Web App)
/Microsoft-Server-ActiveSync (ActiveSync)
/PowerShell (Exchange Mgmt Shell over HTTPS)
/api/v3/ (TeamCity, Atlassian)
/wsus/ (Windows Server Update Services)
/manager/html (some Tomcat behind IIS)
/iisstart.htm (default IIS, sometimes reveals NTLM upstream)
技术栈信号:
- 公共互联网中的 IIS(几乎始终支持 NTLM,即使前端是 Forms)
- SharePoint Web Front End(几乎始终采用 Forms + NTLM 双重身份验证)
- Exchange 边缘传输
- 服务器标头
Microsoft-HTTPAPI/2.0、Microsoft-IIS/*、IIS/*
分步狩猎方法
-
探测每个匿名端点是否提供
WWW-Authenticate: NTLM。 发送普通的 GET 请求并检查响应标头。如果提供 NTLM,则继续。 -
匿名发送有效的 NTLMSSP Type-1 消息。 下方的 Type-1 Base64 内容会向服务器请求 NetBIOS 域和工作站信息:
Authorization: NTLM TlRMTVNTUAABAAAAB4IIogAAAAAAAAAAAAAAAAAAAAAGAbEdAAAADw==这是标准测试 Type-1 消息,其协商标志为
NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_NEGOTIATE_OEM | NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_ALWAYS_SIGN | NTLMSSP_NEGOTIATE_KEY_EXCH | NTLMSSP_NEGOTIATE_56 | NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_TARGET_INFO。OS Version字段(06 01 B1 1D 00 00 00 0F)表示 Windows 7 build 7601,几乎所有 NTLM 响应方都会接受。 -
使用支持保持连接的原始套接字,不要使用 Python requests / curl 单次请求。 大多数 HTTP 库会在发送 Type-1 和接收 Type-2 之间关闭连接。可使用以下任一方式:
- 显式设置
Connection: keep-alive的 Burp Repeater - Burp
mcp__burp__send_http1_request(原生处理保持连接) - Python 原始
socket+ssl.wrap_socket(参见载荷部分)
- 显式设置
-
从
WWW-Authenticate: NTLM <base64>响应标头中解析 Type-2 挑战。 对该值进行 Base64 解码。根据 MS-NLMP,其结构为 NTLMSSP:- 字节 0-7:字面值
NTLMSSP\0 - 字节 8-11:MessageType =
\x02\x00\x00\x00 - 字节 12-19:TargetName SecurityBuffer(长度、分配长度、偏移量)
- 字节 20-23:NegotiateFlags
- 字节 24-31:服务器挑战值(8 个字节,可用于离线破解)
- 字节 40-47:TargetInfo SecurityBuffer(长度、分配长度、偏移量)
- TargetInfo 主体:
AV_PAIRS数组,由 (AvId u16、AvLen u16、Value) 组成
- 字节 0-7:字面值
-
解码 AV_PAIRS。 需要关注的 AvId:
1= NetBIOS 计算机名称2= NetBIOS 域名称3= DNS 计算机名称(响应服务器的 FQDN)4= DNS 域名称(AD 域)5= DNS 树名称(AD 林根)7= 时间戳(FILETIME,可用于 NTLMv2 哈希中继 / 破解)9= 目标名称(较新版本的 NTLMSSP 中)
-
根据发现确定严重性级别:
- 暴露于互联网 + 默认
WIN-XXXXXXXXXXX主机名 + 泄露企业 AD 树信息 → 中 - 暴露于互联网 + 命名服务器主机名(
SPWEB01.corp.example)+ 企业 AD 树信息 → 低-中 - 仅限内网 + 任意信息泄露 → 信息
- 将同一主机上
hunt-auth-bypassLegacy-Protocol Matrix 的发现结合起来 → 提高身份验证绕过发现的严重性,因为攻击者已可直接使用 UPN/SAM 格式
- 暴露于互联网 + 默认
-
检查时间戳。 如果
AV[7]返回的 FILETIME 与Date:标头相差约 5 秒以内,则说明系统时钟已同步——这对伪造 Kerberos 黄金票据很有用(不在漏洞赏金范围内,但与红队行动相关)。 -
与子域枚举结果交叉比对。 DNS 树名称通常会揭示父林,例如,
customer.parent-corp.example表明该客户是 corporate-parent AD 内部的子域,而非独立租户。这属于隐私 / 拓扑信息泄露升级,有些项目会将其评为中危。
载荷与检测模式
通用 NTLM Type-1 匿名探测(curl + 原始套接字回退方案):
# Most one-shot curl runs DON'T return Type-2 because the connection closes.
# Use this as a quick probe to confirm NTLM is offered:
curl -sk -I -H "Authorization: NTLM TlRMTVNTUAABAAAAB4IIogAAAAAAAAAAAAAAAAAAAAAGAbEdAAAADw==" \
"https://target.example/_api/web/CurrentUser" 2>&1 | grep -i "WWW-Authenticate"
Burp send_http1_request(建议用于完整捕获 Type-2):
GET /_api/web/CurrentUser HTTP/1.1
Host: target.example
Authorization: NTLM TlRMTVNTUAABAAAAB4IIogAAAAAAAAAAAAAAAAAAAAAGAbEdAAAADw==
Connection: keep-alive
User-Agent: Mozilla/5.0
Python 原始套接字 + AV_PAIR 解码器:
import socket, ssl, base64, struct, re
from datetime import datetime, timezone
HOST = "target.example"
ctx = ssl.create_default_context()
ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE
s = ctx.wrap_socket(socket.create_connection((HOST, 443)), server_hostname=HOST)
s.sendall(
f"GET /_api/web/CurrentUser HTTP/1.1\r\n"
f"Host: {HOST}\r\n"
"Authorization: NTLM TlRMTVNTUAABAAAAB4IIogAAAAAAAAAAAAAAAAAAAAAGAbEdAAAADw==\r\n"
"User-Agent: Mozilla/5.0\r\nConnection: keep-alive\r\n\r\n".encode()
)
data = b""
while True:
chunk = s.recv(8192)
if not chunk: break
data += chunk
if b"\r\n\r\n" in data: break
m = re.search(rb"WWW-Authenticate:\s*NTLM\s+([A-Za-z0-9+/=]{20,})", data, re.I)
if m:
b = base64.b64decode(m.group(1).decode("ascii"))
assert b[:8] == b"NTLMSSP\x00"
tn_len, _, tn_off = struct.unpack_from('<HHI', b, 12)
ti_len, _, ti_off = struct.unpack_from('<HHI', b, 40)
print(f"TargetName: {b[tn_off:tn_off+tn_len].decode('utf-16-le', errors='ignore')!r}")
av_types = {1:'NetBIOS Computer Name', 2:'NetBIOS Domain Name',
3:'DNS Computer Name', 4:'DNS Domain Name',
5:'DNS Tree Name', 7:'Timestamp', 9:'Target Name'}
i = 0
ti = b[ti_off:ti_off+ti_len]
while i < len(ti):
av_id, av_len = struct.unpack_from('<HH', ti, i)
if av_id == 0: break
val = ti[i+4:i+4+av_len]
if av_id == 7:
ts = struct.unpack('<Q', val[:8])[0]
secs = (ts - 116444736000000000) / 10000000
vs = datetime.fromtimestamp(secs, tz=timezone.utc).isoformat()
else:
vs = val.decode('utf-16-le', errors='ignore')
print(f" AV[{av_id}] {av_types.get(av_id, '?'):28s}: {vs!r}")
i += 4 + av_len
此类发现不需要 Burp Collaborator——数据泄露发生在同步响应中,而不是通过带外(OOB)方式。
常见根本原因
-
面向公网的区域存在双重身份验证的 IIS 绑定。 即使管理员原本打算使用 Forms 身份验证作为入口,仍会在面向公网的 IIS 站点上启用 NTLM。内部用户可通过 SSO 登录;外部攻击者则会获知 AD 拓扑。
-
IIS 默认应用程序池标识仍为
ApplicationPoolIdentity。 再结合默认主机名,表明系统配置从首次启动后就再未进行后续处理。 -
服务器仍使用 Windows 安装程序生成的主机名,未重命名。 Microsoft 默认的 11 个字符
WIN-XXXXXXXXXXX模式一眼即可识别。旧设备有时还会显示WORKGROUP\WIN-...。 -
子域已加入企业林,但未进行区域隔离。 欧洲集成商案例:欧洲进口商的 SharePoint 测试环境是企业全局 AD 中的子域,这一点通过 NTLM DNS Tree Name 泄露。客户可能原本打算让
customer.parent-corp.example独立运行,但 NTLM Type-2 会向任何进行探测的人暴露其林成员身份。 -
未启用 IIS 扩展保护。 当
<system.webServer><security><authentication><windowsAuthentication extendedProtection>为None(默认值)时,NTLM 挑战会发送给任何匿名客户端。设为Required后,NTLM 将仅限经过身份验证的调用方使用,从而缓解 AV 对泄露。 -
面向互联网的站点未从
applicationHost.config中移除WindowsAuthentication。 即使 SharePoint 区域配置只启用了 Forms 身份验证,SharePoint Central Admin 有时仍会保留此设置。
绕过技术
此技能描述的是信息泄露,而非身份验证绕过。“绕过”问题是:防御者如何在允许合法 NTLM 身份验证的同时,阻止此 AV 对泄露?
| 防御措施 | 有效性 |
|---|---|
| 完全禁用面向公网的 IIS 绑定上的 NTLM(仅使用 Forms) | 最佳——彻底消除攻击面 |
| 将 IIS 扩展保护设为 Required | 将 NTLM 挑战限制为经过身份验证的调用方;缓解 AV 对泄露 |
通过反向代理从匿名响应中移除 WWW-Authenticate | 有时有效,但会导致合法客户端无法正常工作 |
| 对 Type-1 → Type-2 端点进行速率限制 | 无法阻止信息泄露,只能减缓枚举 |
将 Windows 主机从 WIN-XXXXXXXXXXX 重命名 | 消除“配置草率”的迹象;无法阻止泄露 |
| 将 SP/Exchange 服务器场迁移到与企业无跨林信任关系的子 AD | 缓解林信息泄露;无法阻止泄露 |
对攻击者而言:无需“绕过”——这项泄露本身就是发现的问题。
Gate 0 验证
撰写报告前,请确认:
-
攻击者现在可以利用这项泄露做什么?
- 面向互联网 + 使用默认主机名 + 企业林信息已泄露 → 中危:攻击者获得了用于
hunt-auth-bypass矩阵探测的 UPN 格式,也知道服务器很可能使用默认服务帐户。 - 仅限内网或只泄露 NetBIOS 名称 → 信息级。
- 面向互联网 + 使用默认主机名 + 企业林信息已泄露 → 中危:攻击者获得了用于
-
该计划是否接受没有关联影响的信息泄露问题?
- 许多计划(Microsoft、大型企业 VDP)在泄露信息包含内部 AD 拓扑时,会接受此类报告。
- 许多计划(Shopify、GitHub)会拒绝没有关联影响的信息泄露报告。
- 提交前请阅读计划范围;若情况不明确,可关联
hunt-auth-bypass中的 Tier-A 发现。
-
能否在全新 shell 中用不到 5 分钟复现?
- 上面的 Python 代码片段是标准复现方式。请在报告中原样附上。
真实影响示例
场景 A — 父级企业 AD 中的 SharePoint
目标:https://target-portal.example/ — 由系统集成商运营的企业经销商门户(测试镜像)。
向 /_api/web/CurrentUser 发送匿名 Type-1 消息后,返回了 Type-2 挑战,其 AV_PAIRS 解码结果为:
NetBIOS Domain Name: <CustomerName>
NetBIOS Computer Name: WIN-XXXXXXXXXXX
DNS Domain Name: customer.parent-corp.example
DNS Computer Name: WIN-XXXXXXXXXXX.customer.parent-corp.example
DNS Tree Name: customer.parent-corp.example
Timestamp: 2026-05-13T15:55:37.922Z
三条升级路径:
- 默认 Windows 安装程序主机名(
WIN-XXXXXXXXXXX) — 服务器在安装操作系统后从未重命名;这是配置草率的强烈信号。SQL 后端可能使用默认服务帐户密码、默认 WSUS 配置等。 - 企业父级 AD 内的子域(
customer.parent-corp.example) — 客户是 全局 Active Directory 中的子域。攻陷此测试场可能通过跨信任关系影响企业父级。 - 已知 UPN 格式 — 结合
hunt-auth-bypass发现/_vti_bin/Authentication.asmx上存在匿名暴力破解端点,攻击者既掌握凭据格式([email protected]或<CustomerName>\firstname.lastname),也掌握不受限制的提交端点。
报告的严重程度:中,并注明与 Authentication.asmx 匿名暴力破解结合后,整体攻击为严重级别。
场景 B — 使用 NTLM 保护 EWS 的 Exchange 边缘服务器
目标:https://mail.example.com/EWS/Exchange.asmx。Type-1 探测返回 Type-2,其中 DNS Tree Name 为 corp.example.com,DNS Computer Name 为 MAIL01.corp.example.com。这确认 Exchange 边缘服务器已加入企业 AD 域(而非在与 AD 隔离的 DMZ 中运行)。对于拥有匹配的 hunt-mfa-bypass / hunt-auth-bypass 攻击链的攻击者,泄露的 UPN 格式和服务器名称格式可省去侦察步骤,从而加快凭据喷洒。报告的严重程度:低至中,视项目而定。
场景 C — 有意泄露,仅限内网(不构成安全问题)
目标:https://intranet.corp.example(显然仅限内部,通过 VPN 访问)。Type-1 返回完整的 AV 配对集。不应报告 — 这是内网中预期的 NTLM 行为,且信息仅泄露给已通过 VPN 身份验证的用户;这些用户已经可以通过 nltest /dsgetdc:corp.example.com 看到相同数据。识别并忽略。
相关技能与攻击链
hunt-sharepoint— SharePoint 场通常会在/_vti_bin/上默认发出匿名 Type-2 挑战;这是获取内部 AD 拓扑最可靠的方法之一。攻击链原语:发现 SharePoint → 在/_vti_bin/Lists.asmx上捕获 NTLM Type-2 → 使用hunt-ntlm-info解码 AV_PAIR → 获取内部林名称 → 对与该林关联的 Entra 租户使用m365-entra-attack进行 ROPC 喷洒。m365-entra-attack— 泄露的 NetBIOS 域名 + UPN 后缀是进行可信密码喷洒所缺少的关键信息。攻击链原语:NTLM Type-2 返回corp.example.comDNS 树 → 通过https://login.microsoftonline.com/corp.example.com/.well-known/openid-configuration交叉查询 Entra 租户 → 对解析出的租户使用m365-entra-attack,通过 AADSTS 错误差异枚举用户名。hunt-aspnet— 运行 ASP.NET 的 IIS 网站经常会在管理路径上暴露 NTLM。攻击链原语:在/owa/、/ecp/、/rpc/、/aspnet_client/上获取 NTLM Type-2 → 确认 IIS + ASP.NET 版本 → 在同一主机上使用hunt-aspnet枚举 ViewState /.axd。offensive-osint— 主机名模式WIN-XXXXXXXXXXX表明系统配置草率,也预示其他安全卫生问题。攻击链原语:NTLM Type-2 返回默认安装程序生成的主机名 → 将其标记为成熟度较低的环境 → 针对该组织进行offensive-osint深度侦察(证书透明度、GitHub 泄露、泄露数据集关联)通常收效颇丰。triage-validation— 大多数 NTLM 信息披露发现项在“是否可利用”这一项上无法通过 7-Question Gate;单纯的拓扑披露属于低危/提示级。攻击链原语:在撰写报告之前,先用triage-validation检查所有 NTLM 信息发现项;仅在以下情况下报告:(a) 泄露可加速喷洒的 UPN 格式,或 (b) 泄露生产环境主机名映射(使用redteam-report-template编写攻击链叙述)。