NTLM Relaying
Last updated
Last updated
NTLM authentication uses a 3-way handshake between a client and server. The high-level steps are as follows:
The client makes an authentication request to a server for a resource it wants to access.
The server sends a challenge to the client - the client needs to encrypt the challenge using the hash of their password.
The client sends the encrypted response to the server, which contacts a domain controller to verify the encrypted challenge is correct.
In an NTLM relay attack, an attacker is able to intercept or capture this authentication traffic and effectively allows them to impersonate the client against the same, or another service. For instance, a client attempts to connect to Service A, but the attacker intercepts the authentication traffic and uses it to connect to Service B as though they were the client.
Windows Server 2022 domain controllers enable "Network Server: Digitally sign communications (always)" to Enabled by default, making this style of attack unviable.
\
During an on-premise penetration test, NTLM relaying with tools like Responder and ntlmrelayx is quite trivial. However, it's a different story with this style of red team assessment, not least because we can't typically run Python tools on Windows. Port 445 is always bound and in use by Windows - even local admins can't arbitrarily redirect traffic bound to this port or bind another tool to this port.
It's still possible to do with Cobalt Strike, but requires the use of multiple capabilities simultaneously.
A driver to redirect traffic destined for port 445 to another port (e.g. 8445) that we can bind to.
A reverse port forward on the port the SMB traffic is being redirected to. This will tunnel the SMB traffic over the C2 channel to our Team Server.
The tool of choice (ntlmrelayx) will be listening for SMB traffic on the Team Server.
A SOCKS proxy is to allow ntlmrelayx to send traffic back into the target network.
\
The flow looks something like this:
\
\
First, ensure all the pre-requisites are in place before launching the actual attack. Obtain a SYSTEM beacon on the machine you will capture the SMB traffic on.
\
\
Next, allow those ports inbound on the Windows firewall.
\
Then start two reverse port forwards - one for the SMB capture, the other for a PowerShell download cradle.
\
The final part of the setup is to start a SOCKS proxy that ntlmrelayx can use to send relay responses back into the network.
\
Now we can start ntlmrelayx.py
listening for incoming connections on the Team Server. The -c
parameter allows us to execute an arbitrary command on the target after authentication has succeeded.
\
Where:
10.10.122.10 is the IP address of dc-2.dev.cyberbotic.io
, which is our target.
The encoded command is a download cradle pointing at http://10.10.123.102:8080/b
, and /b
is an SMB payload.
\
PortBender is a reflective DLL and aggressor script specifically designed to help facilitate relaying through Cobalt Strike. It requires that the driver be located in the current working directory of the Beacon. It makes sense to use C:\Windows\System32\drivers
since this is where most Windows drivers go.
\
Then go to Cobalt Strike > Script Manager and load PortBender.cna
from C:\Tools\PortBender
- this adds a new PortBender
command to the console.
\
Execute PortBender to redirect traffic from 445 to port 8445.
This pretty much breaks any legitimate SMB service on the machine.
\
To trigger the attack, we need to coerce a user or a machine to make an authentication attempt to Workstation 2. Let's do it manually for now, by using the console of Workstation 1 as the user nlamb. This user is a domain admin, so we can relay the authentication request to the domain controller.
\
You should see PortBender log the connection and ntlmrelayx will spring into action.
\
ntlmrelayx reports that the command was executed - we can check the web log to confirm we received a hit.
\
All that's left is to link to the Beacon.
\
\
To stop PortBender, stop the job and kill the spawned process.
\
OPSEC One of the main indicators of this activity is the driver load event for WinDivert. You can find driver loads in Kibana using the "Loaded Drivers" saved search.
\
You can find driver loads in Kibana using Sysmon Event ID 6. Even though the WinDivert driver has a valid signature, seeing a unique driver load on only one machine is an anomalous event.
\
In the real world, it's unlikely you can just jump onto the console of a machine as a privileged user and authenticate to your malicious SMB server. You can of course just wait for a random event to occur, or try to socially engineer a privileged user. However, there are also lots of techniques to "force" users to unknowingly trigger NTLM authentication attempts to your endpoint.
Here are a few possibilities.
1x1 Images in Emails
If you have control over an inbox, you can send emails that have an invisible 1x1 image embedded in the body. When the recipients view the email in their mail client, such as Outlook, it will attempt to download the image over the UNC path and trigger an NTLM authentication attempt.
\
A sneakier means may be to modify the sender's email signature, so that even legitimate emails they send will trigger NTLM authentication from every recipient who reads them.
Windows Shortcuts
A Windows shortcut can have multiple properties including a target, working directory and an icon. Creating a shortcut with the icon property pointing to a UNC path will trigger an NTLM authentication attempt when it's viewed in Explorer (it doesn't even have to be clicked). A good location for these is on publicly readable shares.
The easiest way to create a shortcut is with PowerShell.
\
Remote Authentication Triggers
Tools such as SpoolSample, SharpSystemTriggers and PetitPotam can force a computer into authenticating to us. These generally work via Microsoft RPC protocols, such as MS-RPRN and MS-EFS.