Leveraging SOCKS to proxy tools from a Windows attacker machine through a compromised host is a topic that contains some nuance and room for confusion. This nuance stems from protocol requirements of common network traffic being proxied into a target network, as well as the tools (or lack thereof) available for Windows to facilitate proxying network traffic via SOCKS. However, there is significant value in the ability to proxy existing Windows tools and native utilities into a network from an offensive perspective. To that end, this post aims to step through:
- Clarity of material being covered vs. what is already well-documented
- Value proposition of executing Windows tooling remotely vs. on-host
- Network topology levelset and diagram for examples
- Identification of a tool’s traffic to focus what is routed through SOCKS
- The process of proxying Windows tools and utilities that rely on protocols such as DNS, RPC (DCOM/ WMI, MS-DRSR / DRSUAPI), Kerberos, LDAP, and SMB
- Address nuances with common protocols an attacker would want to proxy, as well as Proxifier client specifics to maximize value for the offensive use case
- Operational tips while proxying using this technique
TLDR; Enable remote name resolution, as well as the proxying of Windows service / SYSTEM processes within Proxifier to resolve DNS issues and also coerce traffic from SYSTEM processes / Kernel-initiated TCP through your SOCKS proxy. Skip to the Proxying Offensive Windows Tooling section for practical examples.
Proxying offensive tools into a network is not a new concept, from *nix-based or Windows operating systems. Pushing traffic associated with tools such as Impacket, through utilities like Proxychains, is a well-documented topic  . This post will instead cover proxying Windows tooling through a compromised host via SOCKS, such as several of the C# and Powershell projects we’ve come to know and love, along with some of the nuances that come along with leveraging this technique. The idea is not to replace the resources and tools that already exist, but to extend usability of tools (largely Windows-based) that otherwise would have required some kind of on-host execution. Proxying traffic for offensive purposes has also been addressed previously  and this post will build on these resources by focusing on the protocols being proxied and address issues that may arise regarding configuration of SOCKS.
A Value Proposition
The value I wanted to stress with this post is the ability to proxy RPC traffic (and more) from Windows tools into a target network. What makes this beneficial? Not having to reinvent the wheel by reimplementing a specific protocol, or using a reimplementation that may not fit your specific needs. Using .NET, the Win32 API, or even the native Windows API, to handle interaction with protocols such as WMI, MS-DRSR (DRSUAPI), MS-SCMR, and more, can save a headache on this front.
Combining this with the ability to create a process and associated token in the context of a user within the target domain from a remote, non-domain-joined Windows machine, results in the ability to leverage native Windows functionality to proxy even more existing tools into a compromised network. Two ways to accomplish this would be to either simply use the runas.exe binary, or by using the mimikatz PTH functionality in the instance of only having an NT hash for the target user. The underlying win32 API calls these tools rely on, such as CreateProcessWithLogonW or CreateProcess could also be used for the same purpose.
The perks of proxying your Windows tools into a network also align with many of the same benefits associated with proxying any other tool into a network. Several potential host-based indicators that would typically be taken into consideration to maintain OPSEC when conducting dynamic code execution or dropping to disk will not be created when using this proxying technique, such as:
- AMSI — assembly obfuscation for .NET 4.8+, Powershell, WSH (Windows Script Host)
- Fork&Run — behavioral considerations regarding parent-child process relationships
- API Hooking — potentially remapping NTDLL, syscalls with dynamic ordinal resolution
- ETW — patching in such a way that typical Assembly.Load functionality is less obvious
- Kernel Callbacks — loading an EV-signed custom driver or exploiting a vulnerable one
There is a time and place for this technique. Some tools will require a significant amount of data transfer between agent and C2. Proxying your tools through C2 will likely increase the amount of network traffic egressing to the internet. If you cannot drop the sleep / jitter on your agent down to interactive (sleep of 0) then the timeouts associated with the protocol being proxied, the tool’s usage of that protocol, and the proxy client (in this case Proxifier), should all be taken into consideration. Veering off the beaten path, in terms of standard network traffic from specific processes, leaves room for behavioral and network-level detection opportunities. It would be beneficial to weigh these items against potential indicators generated from executing on-host as an alternative.
Infrastructure Topology Levelset
This is an example of how attacker infrastructure might look when proxying Windows tools into a network:
For the purpose of the upcoming examples, the Windows Attacker Machine will be a Windows VM using Proxifier to route our tools’ traffic through a SOCKS proxy, in combination with runas.exe or mimikatz to conduct tool execution in the appropriate remote domain user context. C2 will be a Cobalt Strike teamserver listening with a SOCKS4A service. The Target Network is a compromised Active Directory environment where the Compromised Machine is running Cobalt Strike’s beacon and can route to a Target Workstation as well as Target Server, a Domain Controller.
Tip: When the Cobalt Strike server has its SOCKS service listening, it will bind to 0.0.0.0 by default. Securing this service in some way is essential to prevent unfettered access into your target network. Ensuring communication between your attacker machine and C2 is secured will also be an OPSEC consideration to ensure traffic such as cleartext RPC and NetNTLM hashes are not traversing the internet.
The same outcome can be accomplished using several other techniques and tools, such as native OpenSSH (on the server-side of SOCKS, Compromised Machine) in Windows 10 1803 or later, or even using the Microsoft-signed SSH binary and its associated DLL dependency for older Windows versions (there’s backwards compatibility here). ProxyCap is a viable alternative to Proxifier (on the client-side of SOCKS, Windows Attacker Machine). For demonstration purposes, we will stick to Cobalt Strike’s beacon in combination with Proxifier in the upcoming examples.
Several issues can arise while routing your tools through SOCKS from a Windows machine. Here are a few items that will hopefully help mitigate some potential issues:
- Ensure that service and/or system process traffic is routed through the proxy. This can be done by enabling an option within Services and Other Users in the GUI or Running Proxifier as a Windows Service.
- Enable remote hostname resolution so DNS resolves appropriately by selecting resolve hostnames through proxy option in Proxifier configuration.
Note: It was @_EthicalChaos_ responding to a conversation in Bloodhound Gang slack that prompted me to troubleshoot ensuring SYSTEM process traffic would be appropriately routed.
Tip: When configuring your proxy server to work with Cobalt Strike’s beacon, ensure the SOCKS Version 4 protocol is selected, in combination with checking the Use SOCKS 4A extension (remote hostname resolution) option.
Identifying Traffic for Proxy Filtering
Knowing what processes generate what traffic when routing your tool’s through a SOCKS proxy will be important for a few reasons. With some protocols, the tool you are using is likely to rely on SYSTEM processes during communication with remote resources. As previously mentioned, this is relevant to how Proxifier is configured. Understanding how and why the traffic is generated will help you filter only essential traffic through your SOCKS proxy and into the target network. As an example, we will:
- Use `runas` to create a new process in the context of a domain user that has Local Administrator privileges on a target workstation routable from the compromised machine
- Execute SharpWMI to enumerate environment variables on the target workstation
- Monitor network traffic associated with SharpWMI by using Sysinternal’s Procmon
From the screenshot above, we can see that upon execution of SharpWMI, svchost.exe in the context of nt authority\network service conducts RPC endpoint mapping over port 135/tcp. This makes sense because WMI sits on top of DCOM, which relies on RPC for remote communication capability. Once a high, dynamic port is determined for RPC communication (in this case port 49754/tcp), SharpWMI.exe wraps up and we receive the output from our WMI query. As an example of filtering to only route SharpWMI traffic through Proxifier, the following proxification rules could be configured to route only SharpWMI-related traffic to the compromised host:
Note: The specific target port range for the sharpwmi rule shown above was set because this is the default ephemeral port range used for RPC communication in modern Windows operating systems.
Proxying Offensive Windows Tooling
With the information previously covered, we can identify traffic associated with a Windows utility to push through SOCKS, configure Proxifier accordingly, and start routing that tool’s traffic into your target network in the appropriate user context.
Reference the Infrastructure Topology Levelset section for where and how execution is happening in upcoming examples. Hostnames and IPs from the examples will align with the network diagram from that section. These tools will be executed and proxied from the Windows Attacker Machine, a non-domain-joined, remote Windows VM. Cobalt Strike’s beacon is running on WORKSTATIONA. From the C2 server in the network diagram, a SOCK4A service has been started with Cobalt Strike’s beacon. To demonstrate with commonly used tools, examples will include:
- RPC/DCOM (WMI) with Seatbelt & WMIC
- MS-DRSR (DCSync) with SharpKatz
- SMB with native Windows functionality
- LDAP with ADExplorer & PowerView
- Kerberos with Rubeus
RPC/DCOM (WMI) with Seatbelt & WMIC
From Windows Attacker Machine, a new process is spawned in the appropriate remote user context (CITADEL\jason) to access WORKSTATIONB with Local Administrator privileges through the proxy. The hostname of the remote target host is used in the seatbelt.exe arguments, and will resolve successfully because of the Proxifier configuration previously mentioned.
The two proxification rules created, which can be seen in the Rule : Proxy column, were successfully triggered to route only our tool-specific traffic through the SOCKS server. Notice one of the svchost.exeprocesses conducting RPC endpoint mapping is executing in SYSTEM context. This would have failed unless the appropriate Proxifier option had been selected, as mentioned in the Proxifier Configuration section. Endpoint mapping for WMI is successful because seatbelt.exe opened a socket and conducted data transfer over an ephemeral port on WORKSTATIONB (49746/tcp in this case).
The native wmic.exe Windows binary can be used to achieve a similar outcome. WMI network traffic is proxied, so the same actions can be observed:
- RPC endpoint mapping on port 135/tcp
- svchost.exe spawning as SYSTEM for a portion of RPC endpoint mapping
- wmic.exe conducts the bulk of communication once an ephemeral port has been established
MS-DRSR (DCSync) with SharpKatz
If you have the NT hash for the user you want to create an access token for, one way to create a process in the context of the user for which you have the hash is Mimikatz PTH functionality. Similar to runas.exe, Mimikatz spawns a new process in the context of a domain user, but instead of supplying a cleartext password, an NT hash was supplied.
The default Domain Administrator account and its NT hash are used to create a new process in the necessary user context to conduct a DCSync. SharpKatz is executed and MS-DRSR is utilized to conduct a DCSync of a specific user. Similarly to WMI, because this is an RPC-based protocol, we observe the endpoint mapping and high port traffic being routed.
Note: Notice the traffic originating from searchapp.exe. The proxification rule successfully routed this traffic unrelated to the DCSync directly to the internet, preventing unnecessary traffic from routing through our compromised host.
SMB with native Windows functionality
With the appropriate user context, common utilities such as dir and redirection of stdout to a remote resource, as well as the SMB traffic associated with these actions, can be routed through a SOCKS proxy. This traffic is initiated from the kernel, which is demonstrated by traffic originating from the System process.
The explorer.exe file browser can similarly be routed through the proxy, resulting in the ability to mount network drives and interact with contents of the remote file system, graphically.
Native applications can also be used to interact with the contents of the remote file system that is now accessible via SOCKS. For example, a local text editor could be used to modify a text file on the remote machine directly.
LDAP with ADExplorer & PowerView
Providing the remote domain controller IP address and credentials to access the target domain on the other side of our SOCKS proxy, the Sysinternals ADExplorer64.exe is executed. Active Directory objects can be viewed and modified interactively.
Mimikatz’s Pass-The-Hash (PTH) functionality was used to create a process in a domain user context. Any domain user within the target domain would work, because we only need permissions to conduct standard LDAP queries for this example. PowerView’s Get-DomainUser function was executed and LDAP communication was properly routed to the target Domain Controller at the other end of the SOCKS tunnel.
Note: When PowerView was downloaded with Web.Client, our proxification rule properly routed the HTTPS traffic directly to the internet, instead of through our SOCKS tunnel.
Kerberos with Rubeus
In this example, we will use a different domain user for spawning a process in the context of an authenticated user of the target domain on the other side of our SOCKS tunnel.
Rubeus is executed and attempts an ASREPRoast of all users in the target domain. ASREPRoast with Rubues only requires authenticated access to the target domain so any domain user would suffice (CITADEL\john used here). The proxification rule for routing traffic specific to the Rubeus process is triggered. LDAP (389/tcp) is proxied and queries for any users in the domain have the do not require Kerberos preauthentication attribute enabled. When a user with this attribute is identified, Kerberos (88/tcp) traffic is proxied to obtain the potentially crackable, encrypted TGT blob.
Tip: Remember that it is important to have DNS configured correctly when interacting with Kerberos.
Routing your Windows tooling through SOCKS can alleviate potential pain-points in a typical offensive workflow, such as OPSEC risks associated with on-host execution, as well as troubleshooting bugs associated with the usage of reimplemented protocols. Understanding what you’re routing, and how it is being routed, will help you determine when this technique might be an ideal alternative to your current code execution strategy.