Apache Rewrite Rules

It is recommended to use a C2 Proxy to maintain operational security by proxying all traffic to the C2 Server. A simple VPS running Apache can be stood up and mod_rewrite used to silently redirect traffic from the proxy to the C2 Server without the client knowing, allowing the red team to keep their C2 infrastructure hidden and allowing flexibility should the proxy IP be compromised.

A typical example could look like this:


This provides operational security by not exposing the C2 infrastructure to the target or the internet at large, and allows the red team to pivot onto a different C2 proxy if the existing one is compromised, without the need to change the C2 server itself.

Using Apache Rewrite rules we can redirect traffic that is intended for the C2 server but also retain a fully functional web site on the same host that does not hit our Rewrite Rules, so that if bots, unrelated browsers or the blue-team come a-lookin’ they are only served a benign website.

To help explain this Nettitude created a short blog which explains one way of achieving this using a VPS with OpenVPN:


Once you’ve setup a VPS you will need to configure Apache to rewrite your C2 traffic back to the C2 Server instance. The example below details a typical example:

You will need to install Apache HTTPd and enable some modules before running the webserver:

apt-get install apache2
apt install libapache2-mod-security2
a2enmod security2
a2enmod ssl
a2enmod rewrite
a2enmod proxy
a2enmod proxy_http
a2enmod headers

As part of the C2 Server’s bootstrap process when it first launches for a new project it generates a rewrite-rules.txt file with the required rules for that C2 server for the Apache configuration. We then place the rules within your Apache configuration file for relevant virtual hosts:

<VirtualHost *:80>
    ServerAdmin webmaster@localhost
    DocumentRoot /var/www/html
    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined

<IfModule mod_ssl.c>
    <VirtualHost _default_:443>
        RewriteEngine On
        SSLProxyEngine On
        SSLProxyCheckPeerCN Off
        SSLProxyVerify none
        SSLProxyCheckPeerName off
        SSLProxyCheckPeerExpire off

        # If running Apache 2.4.52 or Later
        Proxy100Continue Off

        # If you want 404 cookie information for OPSEC
        # https://labs.nettitude.com/blog/operational-security-with-poshc2-framework/
        SecAuditEngine RelevantOnly
        SecAuditLog /var/log/apache2/sec.log
        SecAuditLogParts BSecAudit
        LogRelevantStatus ^(404)

        # Change IPs to point at C2 infrastructure below
        Define PoshC2
        Define SharpSocks
        RewriteRule ^/wpaas/(.*) https://${PoshC2}/wpaas/$1 [NC,L,P]
        RewriteRule ^/bh/sync/(.*) https://${PoshC2}/bh/sync/$1 [NC,L,P]
        RewriteRule ^/status/995598521343541248/(.*) https://${PoshC2}/status/995598521343541248/$1 [NC,L,P]
        RewriteRule ^/adsense/troubleshooter/1631343/(.*) https://${PoshC2}/adsense/troubleshooter/1631343/$1 [NC,L,P]
        RewriteRule ^/vssf/wppo/site/bgroup/visitor/(.*) https://${PoshC2}/vssf/wppo/site/bgroup/visitor/$1 [NC,L,P]
        RewriteRule ^/adServingData/PROD/TMClient/6/8736/(.*) https://${PoshC2}/adServingData/PROD/TMClient/6/8736/$1 [NC,L,P]
        RewriteRule ^/vfe01s/1/(.*) https://${PoshC2}/vfe01s/1/$1 [NC,L,P]
        RewriteRule ^/GoPro5/black/2018/(.*) https://${PoshC2}/GoPro5/black/2018/$1 [NC,L,P]
        RewriteRule ^/qqzddddd/2018/(.*) https://${PoshC2}/qqzddddd/2018/$1 [NC,L,P]
        RewriteRule ^/usersync/tradedesk/(.*) https://${PoshC2}/usersync/tradedesk/$1 [NC,L,P]
        RewriteRule ^/classroom/sharewidget/(.*) https://${PoshC2}/classroom/sharewidget/$1 [NC,L,P]
        RewriteRule ^/uasclient/0.1.34/modules/(.*) https://${PoshC2}/uasclient/0.1.34/modules/$1 [NC,L,P]
        RewriteRule ^/bootstrap/3.1.1/(.*) https://${PoshC2}/bootstrap/3.1.1/$1 [NC,L,P]
        RewriteRule ^/babel-polyfill/6.3.14/(.*) https://${PoshC2}/babel-polyfill/6.3.14/$1 [NC,L,P]
        RewriteRule ^/trader-update/(.*) https://${PoshC2}/trader-update/$1 [NC,L,P]
        RewriteRule ^/work/embedded/(.*) https://${PoshC2}/work/embedded/$1 [NC,L,P]
        RewriteRule ^/cisben/(.*) https://${PoshC2}/cisben/$1 [NC,L,P]
        RewriteRule ^/utag/lbg/main/prod/(.*) https://${PoshC2}/utag/lbg/main/prod/$1 [NC,L,P]
        RewriteRule ^/load/pages/(.*) https://${PoshC2}/load/pages/$1 [NC,L,P]
        RewriteRule ^/types/translation/v1/articles/(.*) https://${PoshC2}/types/translation/v1/articles/$1 [NC,L,P]
        RewriteRule ^/async/(.*) https://${PoshC2}/async/$1 [NC,L,P]
        RewriteRule ^/business/(.*) https://${PoshC2}/business/$1 [NC,L,P]
        RewriteRule ^/branch-locator/(.*) https://${PoshC2}/branch-locator/$1 [NC,L,P]
        RewriteRule ^/business/retail-business/(.*) https://${PoshC2}/business/retail-business/$1 [NC,L,P]
        RewriteRule ^/Philips/v902/(.*) https://${PoshC2}/Philips/v902/$1 [NC,L,P]
        RewriteRule ^/web/20110920084728/(.*) https://${SharpSocks}/web/20110920084728/$1 [NC,L,P]
        RewriteRule ^/putil/2018/0/11/(.*) https://${SharpSocks}/putil/2018/0/11/$1 [NC,L,P]

        ServerAdmin webmaster@localhost
        DocumentRoot /var/www/html
        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined
        SSLEngine on
        SSLCertificateFile    /etc/ssl/certs/ssl-cert-snakeoil.pem
        SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key

Any C2 URLs that match these rules will therefore be rewritten to the C2 Server. Any that do not match these URLs will instead be served content from the usual DocumentRoot, in this case /var/www/html.

Apache Whitelist

When performing a Red Team engagement, it is imperative that your C2 infrastructure be sufficiently locked down and should only allow implants from the correct IP address range of the Customer. This is known as whitelisting.

To add a whitelist to the C2 Proxy, create a file with all the IP addresses that are known to be the client. There is a slight nuance with Apache as the file format is the below: – –

This Python script will help convert a IP CIDR range into the correct format for Apache:

from netaddr import IPNetwork
import sys

for ip in IPNetwork(""):
    print '%s -' % ip

Once you have the whitelist, you can use the RewriteMap function to add the IP address list for use in rewrite conditions. Below is a simple Rewrite Rule which will respond to the client with a 404 Not Found response if the requesting IP is not in the whitelist.

RewriteMap IP txt:/etc/apache2/whitelist
Define PoshC2
RewriteRule ^/images/static/content/(.*) https://${PoshC2}/images/static/content/$1 [NC,P,L]

You have to do this for each rewrite rule you want to apply for each URL. In this case we are applying to the /images/static/content/ path.

Whitelists and Domain Fronting

Another nuance is that if you are using Domain Fronting then the requesting IP will be that of the CDN provider, as they are making the request. They will however, put the originating IP in the X-Forwarded-For header, and it is this IP that we also whitelist on:

RewriteMap ips txt:/etc/apache2/whitelist.txt
RewriteCond ${ips:%{HTTP:X-Forwarded-For}|NOT-FOUND} !NOT-FOUND
RewriteRule ^/images/static/content/(.*) https://${PoshC2}/images/static/content/$1 [NC,P,L]

Please see the Apache HTTPd and mod_rewrite websites for more information.

Operational Security with PoshC2 Framework

The following post describes the capability that has been deployed within PoshC2, which is designed to assist with revealing a wider set of target environment variables at the dropper stage, as part of operational security controls.

  • https://labs.nettitude.com/blog/operational-security-with-poshc2-framework/

Imagine the following scenario. You’ve deployed IP address white-listing on the proxy as above in order to limit implant installation to a specific environment. A connection arrives back from a host that’s not associated with your target environment, so the connection is dropped and PoshC2 never sees the incoming connection attempt. By adding some additional logging on the proxy, and utilising the new CookieDecrypter.py script, you can now reveal specific environment variables about where the dropper was executed. This information allows for better decision making on what to do next in this scenario. It yields greater situational awareness.