Overview
In a previous article titled “Active Directory Computer Account SMB Relaying Attack,” we discussed how an attacker could leverage computers assigned administrative rights to other computers to escalate privileges or move laterally using the printer spooler service. Colloquially we often refer to this as a “Computer AdminTo Computer” vulnerability.
Exploiting this issue in practice during a red team engagement has often historically been difficult. Often, we need to perform this attack from a compromised Windows system where the built-in SMB service is already listening on port 445/TCP. Furthermore, it is not uncommon for our team to perform name resolution poisoning during red team engagements to harvest credentials within an environment. Unfortunately, in previous scenarios, we have been primarily limited to passive credential collection and unable to perform relaying attacks when obtaining credentials through SMB.
To overcome this operational hurdle, we have developed a custom utility named “PortBender” [7] which allows us to redirect traffic from an incoming TCP port to an alternative TCP port. For example, a user may wish to modify traffic destined for the 445/TCP port to 8445/TCP. We have also included a feature in PortBender which allows an attacker to simulate the PortServ.sys persistence technique leveraged by the Duqu 2.0 threat actor.
Methods for Performing SMB Relaying on Windows
Our initial attempt at performing SMB relaying through Cobalt Strike attempted to use the “NetSh PortProxy” mechanism [2]Â to redirect traffic destined for port 445/TCP. However, in this case, it appears that this mechanism doesn’t work for redirecting traffic destined for the SMB service running on port 445/TCP. Francisco Dominguez also notes this limitation of the “NetSh PortProxy” interface in his article titled “Remote NTLM relaying through meterpreter on Windows port 445” [1].
Another option we considered was disabling SMB services on the host and rebooting. However, we typically try to avoid making any permanent system changes or modifications during red team operations (and avoid rebooting production systems). Therefore, this option, while viable, was not sufficient for our requirements.
We wanted a tool that we could run for a short period to redirect traffic without rebooting and then subsequently stop redirecting traffic after performing an attack. Furthermore, we wanted to execute the tool entirely in memory with a minimum on-disk footprint. We also needed to integrate the capability with multiple C2 frameworks, so any mechanism for implementing in-memory execution should be portable across various C2 frameworks.
PortBender Design Overview
To satisfy these requirements we have developed the PortBender utility. When designing PortBender, we based much of the initial design on the DivertTCPConn tool by Arno0x0x [5]. However, in this case, we decided to create a new and separate utility to satisfy some of our unique requirements. These requirements included factors such as the ability to execute the tool in memory as a reflective DLL, integration with Cobalt Strike, support for Duqu 2.0 style backdoor persistence, leveraging static linking for all dependencies, and the use of an object-oriented design using C++ to promote modularity and code reuse.
When designing PortBender, we decided to leverage the existing WinDivert driver by Basil00 [4] for performing network traffic interception and modification. We considered several alternative designs, including writing a custom device driver, but these introduced operational hurdles for deployment. For example, a custom driver would require obtaining a code signing certificate to load the driver. Alternatively, we could bypass driver signing protections by loading an existing vulnerable signed driver and exploiting it to get ring0 code execution. However, both scenarios had a distinct disadvantage to leveraging an established tool for performing this interception and inspection.
Design Decision #1: Intercepting Network Traffic
The first option of developing a custom driver and signing it with a code signing certificate was non-ideal, primarily due to cost (time) concerns. Furthermore, suppose a defender ever discovered the driver. In that case, defenders would have a high-fidelity IOC they could leverage across multiple systems as the code signing certificate for the driver would only ever be used for malicious purposes.
One advantage of WinDivert is that it leverages a signed device driver that is legitimately used by several enterprise software applications. For example, Cloudflare’s Warp VPN agent (part of the Cloudflare Teams/Zero Trust product lineup) for Windows leverages the WinDivert framework for intercepting and modifying network traffic. Therefore, the usage of WinDivert is probably not a sufficient indicator to differentiate between normal and abnormal activity.
The second option (loading a driver by exploiting a signed vulnerable driver) was undesirable mainly due to system stability concerns. Because we have an extremely low tolerance for any activities that may disrupt or crash a system, we decided to avoid this approach.
Design Decision #2: Integrating with Cobalt Strike
To integrate PortBender with Cobalt Strike, we leverage the “Reflective DLL Injection” project developed by Stephen Fewer [6]. We included the source code for the reflective loader in the PortBender project. It exports a function named “ReflectiveLoader,” which functions as a bundled PE loader for injecting the module into a remote process. We can then leverage aggressor scripting in Cobalt Strike with the “bdllspawn” functionality to register the PortBender utility as a new post-exploitation job. Additionally, this functionality supports passing an argument string to the reflective loader which is then passed to the DLLMain function within the PortBender application. By building the PortBender utility as a reflective DLL, it can more easily be integrated into any C2 framework that supports loading a reflective DLL as an external plugin.
TCP Port Redirection Using the PortBender Utility
PortBender leverages a connection manager subsystem to track redirected connections and their state. It accomplishes this by monitoring the flags set on incoming TCP packets to track connection states. When a new incoming TCP session is detected, it adds that session to the list of established connections within the connection manager subsystem. The session is removed from this list when the client sends a TCP packet with the RST flag set.
PortBender monitors both inbound and outbound connections. It modifies the destination port for inbound packets to point to the redirected port (e.g., changing a packet destined for port 445/TCP to 8445/TCP. For outbound connections, it modifies the source port of the message back to the original destination port (e.g., modifying the source port from 8445/TCP to 445/TCP).
Because the application leverages a modular object-oriented approach, it is relatively straightforward to add additional behavior to customize this mechanism. For example, one could implement support for conditional rules-based redirection without majorly refactoring the existing code-base.
Duqu 2.0 PortServ.sys Persistence: TCP Port Redirection
In an article titled “The Duqu 2.0 Persistence Module,” Kaspersky discusses a persistence method used whereby the attacker installs a malicious NDIS filter-driver (PortServ.sys) on a compromised internet-facing web server [3]. Kaspersky describes a scenario where if the attacker sends a specially crafted TCP packet with a given keyword in the data section of the TCP packet, in this case, the password was either “romanian.antihacker” or “ugly.gorilla” the backdoor activates. When activated, the backdoor then redirects traffic from an attacker IP address to an alternative service on the compromised host (e.g., RDP).
For example, an attacker may deploy this style of payload on a compromised internet-facing IIS server to redirect all traffic from port 443/TCP to port 3389/TCP. This mechanism allows the attacker to bypass any network-based firewalls as the traffic leverages a port permitted through the victim’s firewall. The diagram given below outlines this use-case.
[image id=”2997″ filter=”false”]
In this scenario, the attacker has compromised an Internet-facing Microsoft Exchange server and deployed the PortBender backdoor on the compromised system. Here we assume the compromised Microsoft Exchange server is directly exposed on the Internet (i.e. not behind an F5 load balancer). The attacker has installed the PortBender backdoor on the compromised system (in the diagram this is shown as a separate component but in reality this is running on the compromised server).
Within PortBender, we have added the “backdoor” command, which allows a red team operator to simulate this technique leveraged by the Duqu 2.0 threat actor for persistence. In this scenario, PortBender will listen on a given port (e.g., 443/TCP), and when it sees a TCP packet with both the SYN and RST flags set, it inspects the data section of the payload for a given keyword. If that keyword matches, it adds the attacker IP to a list of backdoor client IP addresses and redirects all future traffic to the user-specified redirect port (e.g., 3389/TCP). The attacker can then disable the backdoor by sending another TCP packet with the SYN and RST flags set and the keyword included, which instructs PortBender that it should stop redirecting traffic from this IP.
Using PortBender to Perform an SMB Relay Attack
In this section, we walk through an SMB relaying attack through a compromised Windows 10 system using PortBender and NTLMRelayX in conjunction with Cobalt Strike’s remote port-forwarding feature. Administrative access to the underlying Windows 10 system is required in this case because the WinDivert driver requires administrative rights to load successfully.
We start by creating a socks proxy using the “socks” command. Next, we leverage the “rportfwd” command given below to forward all incoming traffic to 8445/TCP on the victim host to port 445/TCP on the TeamServer.
rportfwd 8445 127.0.0.1 445
Then we install both Impacket and proxychains and configure proxychains to leverage our socks proxy on the TeamServer. We then execute the following command to perform an SMB relaying attack targeting another internal system (192.168.109.9 in this example).
sudo proxychains python3 examples/ntlmrelayx.py -t smb://192.168.109.9 -smb2support
Next, we download [7] and import the “PortBender.cna” aggressor script into Cobalt Strike. This is shown in the image given below:
[image id=”2998″ filter=”false”]
We must then upload the “WinDivert32.sys” or “WinDivert64.sys” device driver onto the target system depending on if the operating system architecture is 32-bit or 64-bit, respectively. In this case, we must upload the device driver file to the current working directory associated with the beacon process. Unfortunately, Windows does not appear to provide an API or mechanism to load a device driver without writing it to disk.
In most cases, this isn’t a significant concern. As previously mentioned, enterprise products, such as Cloudflare Warp, legitimately use this driver. Therefore, it is unlikely an antivirus or endpoint detection and response (EDR) solution will flag the presence of this file on a system. To upload the file we use the upload command in Cobalt Strike as shown below:
[image id=”2999″ filter=”false”]
Next, we execute the PortBender utility using the command “PortBender redirect 445 8445” to redirect connections to 445/TCP to 8445/TCP (our remote port forwarded port). This is shown below:
[image id=”3000″ filter=”false”]
Next, we simulate an SMB authentication from a domain administrator account for testing purposes. An SMB relaying attack is performed targeting another internal host for demonstration purposes. The expected output from a successful relaying attack is below:
[image id=”3001″ filter=”false”]
To stop the PortBender service we then use the jobkill and kill commands to kill the job and the process. From our testing, killing the job is not a sufficient measure to exit the process completely. We accomplish this by leveraging the “jobkill” and “kill” commands within beacon. The expected output is shown in the image below.
[image id=”3002″ filter=”false”]
Leveraging PortBender for Duqu 2.0 Style Persistence
The PortBender backdoor mode can be leveraged for Duqu 2.0 style persistence as described previously. In this instance, the command takes as input a fake destination port, redirect port, and a password/keyword to leverage to activate the backdoor.
We first execute the “PortBender backdoor 443 3389 praetorian.antihacker” command to deploy the persistence mechanism. This command instructs the backdoor to redirect traffic destined for 443/TCP to 3389/TCP when the backdoor is activated using the keyword “praetorian.antihacker”.
[image id=”3003″ filter=”false”]
To activate the backdoor we must send a TCP packet with both the SYN and RST flags set and the keyword/password included in the data portion of the TCP packet and the src address set to the host we want to be able to access the RDP service over 443/TCP. We can accomplish this with Python using the scapy library with the script given below:
import argparsefrom scapy.all import *TCP_ACTIVATE=TCP(dport=445, flags="SR", seq=100)data = "praetorian.antihacker"a = IP(dst="192.168.109.10", src="192.168.109.8")/TCP_ACTIVATE/datasend(a)
We can then run the script as shown in the image below:
[image id=”3004″ filter=”false”]
We then see the output given below within the Cobalt Strike console showing a new client connection was registered successfully:
[image id=”3005″ filter=”false”]
Then we query the RDP configuration by querying the registry key used to configure the RDP service. In this case, the key is “HKLMSystemCurrentControlSetControlTerminal ServerWinStationsRDP-Tcp”. We observe that the configured port is 3389/TCP (0xD3D in base 16). The image below shows the expected output for this configuration:
[image id=”3006″ filter=”false”]
Next, we RDP from the attacker system to 443/TCP and authenticate using valid domain user account credentials as shown below:
[image id=”3007″ filter=”false”]
After the attacker finishes accessing the system, they can re-run the “activate.py” script to disconnect. The expected output is shown below:
[image id=”3008″ filter=”false”]
Future Work
Several opportunities exist for future work and extensions to the PortBender utility. First, we could improve the persistence module by adding additional security checks. Additionally, we could also improve the algorithms’ performance for performing lookups as they currently use linear-time searching algorithms. Finally, there may be an undocumented Windows API or another mechanism to load the WinDivert driver without writing it to disk.
Conclusion
This article discussed how red team operators could leverage our recently released PortBender tool to perform attacks, such as an SMB relay attack, that have historically been difficult to accomplish through a C2 framework such as Cobalt Strike. We also discussed how an attacker could leverage TCP port redirection with PortBender to establish covert persistence on an Internet-facing Windows server to better simulate certain threat actors such as the Duqu 2.0 APT.
References
[1] https://diablohorn.com/2018/08/25/remote-ntlm-relaying-through-meterpreter-on-windows-port-445/
[2] https://parsiya.net/blog/2016-06-07-windows-netsh-interface-portproxy/
[3] https://securelist.com/the-duqu-2-0-persistence-module/70641/
[4] https://github.com/basil00/Divert
[5] https://github.com/Arno0x/DivertTCPconn
[6] https://github.com/stephenfewer/ReflectiveDLLInjection
[7] https://github.com/praetorian-inc/PortBender
Share via: