In a previous post I discussed to setup basic redirectors with Covenant C2. In this post, I hope to show you how to use domain fronting through an Azure CDN for your C2 traffic. A lot of this is based on another post I read from ar-infosec that you can find here.
What is Domain Fronting?
Domain fronting takes advantage of features of Content Delivery Networks (CDN). To use Azure as an example, you can create a “Origin Server” that will be your CDN. Let’s say the origin server is myorigin.azureedge.net. When an application or payload wants to reach myorigin.azureedge.net, the Host header of the request will need to contain myorigin.azureedge.net. This is so when the “Edge Server” located at azureedge.net receives your request, it knows to redirect it to myorigin.azureedge.net.
One thing you can do with this then is try and find a “frontable” domain that uses the same edge server as myorigin.azureedge.net. Let’s say that “frontable.microsoft.com” uses azureedge.net as an edge server. Then, you can set your payload to use frontable.microsoft.com as the “host” it will connect to, but the HTTP request itself will have your myorigin.azureedge.net CDN endpoint in the Host header of the request. When your payload’s request is received, it will connect to the IP address of frontable.microsoft.com, and then be forwarded to myorigin.azureedge.net. If someone were to investigate your activity above, they would see your victim making connections out to what looks like frontable.microsoft.com. They would only be aware of your myorigin.microsoft.com if they do man-in-the-middle TLS decryption and can then see your payload’s Host header.
The Red Team Infrastructure Wiki has good information on Domain Fronting you may want to review. It’s also just a good general resource to save for later.
Setting Up Azure CDN
Before you start, make sure you have a Covenant C2 server with a public IP / domain name already setup. I talk about setting up Covenant C2 in AWs here and here.
Microsoft will allow you to set up a 30 free trial on Azure here https://signup.azure.com. You can use this to setup your CDN that will be used for this. I used my personal email for this, but if you are performing a real engagement you may want to use an email address that isn’t tied back to you. Microsoft will ask for a phone number and credit card number that they need to verify. Your employer/organization might be able to help you out with what can or cannot be used.
Once you are signed up and in the Azure portal, you will need to setup your Azure subscription to allow for CDNs. Click in the top left, then “All Services.”

Click on “General” then “Subscriptions.”

Click on your subscription that you want to edit. For a new account, there should only be one option.
Under the “Settings” heading on the new page, select “Resource providers.”

Search for “Microsoft.cdn”, select it, then click on “Register.”

Registering took a few minutes for me so you may need to take a break and entertain yourself for a little while until it completes. Click the “Refresh” button to see if it has registered.

With Microsoft.cdn registered, click on the top left again and select “Create a resource.”

In the “New” menu, select “Web” then “CDN”

You will now setup the CDN profile. Set the name to whatever you want it to be, though probably not something that can be identified back to you or obviously malicious like “c2-cdn” or something like that. You will also want to create a new resource group if one doesn’t already exist.

Once you create the resource, you will continue setting up the CDN. The following values will be important:
- CDN Endpoint Name – This will be the name you use in the Host header for your payload requests. Remember this.
- Origin hostname – This will be the IP address or public DNS name of your C2 server. Mine was hosted in AWS, so it amazonaws.com hostname.

Click on “Create,” and your CDN profile should be created. Under your “notifications” section of the Azure Portal, you will see the CDN profile is being created. This can take up to several hours if you are unlucky. For this test, it took about 2 minutes.

If you go to your “resources”, you should now see your CDN profile.

You will want to disable caching on your endpoint. Under resources, select the one labeled “endpoint,” then “Caching rules,” and set it to “Bypass caching for query strings.”

Finding a Frontable Domain
Next, we will need to find a frontable domain to be used. This is what our payload will use in the SNI / DNS. rvrsh3ll created the FindFrontableDomains tool that can automate this process for you. For this test I chose to use Microsoft.com as the domain to try and find frontable subdomains for. FindFrontableDomains will first try and enumerate subdomains for the domain you provide, and it then checks if those domains are hosted through edge servers and are frontable.
python3 FindFrontableDomains.py -d microsoft.com

For this test I wanted to try natick.research.microsoft.com for my frontable domain.
Configure Covenant Listener and Profile
To test the domain fronting, you will need to create a profile that includes your host header. I created a new profile that was basically blank. One VERY IMPORTANT thing to note is that the Azure CDN endpoint will only ignore caching of pages if there is a query string. If you don’t already know, a query string is the ?query=string you see at the end of URLs. A new blank Covenant listener profile will create one by default, but you can add more.

The {GUID} will make sure all requests contain a unique query string. This is necessary for domain fronting to work as your C2.
Then, under “HTTPRequestHeaders,” you will need to click “+ Add” and add a host header with the name of your CDN server.

Next, you will need to create a listener that has “natick.research.microsoft.com” as the ConnectAddress, and uses the DomainFront profile as the HttpProfile. For this test I kept everything using HTTP / port 80 to keep things simple.


I then hosted a test file on the listener so I could test the domain fronting. Once the file is hosted, you can test the fronting with the following command.
curl -k --header "Host: my-domain-front.azureedge.net" "http://natick.research.microsoft.com/test.txt"

Executing Payload
To test the fronting payload, I just used the default binary launcher. I’m not testing the payload itself, I just want to make sure that the domain fronting C2 works.
I used Wireshark to see what was happening on the network level when I ran the payload. After I first execute the powershell launcher, I see a DNS request for natick.research.microsoft.com.

This will resolve to 13.107.246.10. If I follow the TCP stream for my grunt’s HTTP traffic, I can see that it is connecting to 13.107.246.10, and setting my domain fronting endpoint in the Host header.

Note on using SSL with Domain Fronting
While testing domain fronting, I tried to setup my Covenant listener over port 443 with SSL. I kept getting errors on the grunt trying to make its connect to the frontable domain, saying things like “The underlying connection was closed: An unexpected error occurred on a send.”
Googling that error message brought me to this StackOverflow post. A few users mentioned the error had to do with the SecurityProtocolType being set. If you look at the Code for the Covenant binary grunt, you will see the following:
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls;
So, I tried changing that to this:
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls12 | SecurityProtocolType.Tls | SecurityProtocolType.Tls11;
Then I rebuilt the grunt code in VS and ran it, and got my grunt back.
Before, when using plaintext HTTP, your CDN endpoint could be discovered in a packet capture if they looked for the “Host” header. When you run the grunt using domain fronting and SSL, you first see the DNS request for the frontable domain, natick.research.microsoft.com.
The rest of the capture will be encrypted, so you won’t see the Host header anywhere. It will look like this:
