If you’re not familiar with domain fronting then the tl;dr is a number of large CDNs route based on the Host: header which means you can connect to google.com and ask it for any other google service behind the CDN like maps.google.com, and it’ll fetch that instead. If you’re looking this request from the networks perspective, you’ll see the client resolve dns for google.com, connect to that IP, but really the client gets back maps.google.com.

This gets interesting when the CDN allows you to forward to domains that you control, either through hosting with the same CDN/company or finding a permissible one. This allows you to associate yourself with a high value domain. Privacy tools often use this technique to defeat censorship by lumping themselves in with a larger and more powerful company such as google or microsoft - e.g. signal was recently blocked in Egypt so they moved to a google domain, meaning Egypt would have to block google to block signal.

With that in mind I’ve been looking into domains that point to Azure addresses that I can potentially use as a frontable domain. But first a quick word on setting up an Azure CDN for this.

Azure Setup

Setting up a CDN to do domain fronting with Azure is dead simple but there are some caveats.

Note: I’ve taken down the Azure CDN I setup for this this blog post because CDN’s charge for the traffic that flows through them, meaning internet jerks like you could send traffic through and I’d get charged $$$.


You want to go with Verzion (in the pricing tier section) because the other option, Akami, doesn’t work for domains outside azure, I think. Or at least with extensive testing I couldn’t get it to work and Verizon worked straight away, which is good enough of an argument for me.


There are two options here which are very important:

  • Name: this is going to be the sub domain which you’ll use in the Host header, so make it something that looks legit. I’ve been using names which imply advertising tracking or normal cdn usage.
  • Origin hostname: this is where it’ll forward your traffic.

Once you’ve hit ok on all this, Azure will spin it up slowly and then you’ll have to wait another 45 minutes for the CDN to finish setting up in the background. During this 45 minutes your CDN will 404 legitimate requests. They won’t warn you about this or anything, it’s just something that happens.

While you’re waiting for that to tick away, set the caching for your new URL to “bypass string caching behaviour”.

Bypass caching for URL with query strings: In this mode, requests with query strings are not cached at the CDN edge node. The edge node retrieves the asset directly from the origin and passes it to the requestor with each request.

Without this set the CDN might behave like a real CDN and cache your requests which could cause problems for your c&c. Setting this caching behaviour also took a while to go through, so be patient if it doesn’t work immediately.


Then once it all works you can use a high profile domain to front with, like below:

# socat - openssl:ajax.microsoft.com:443
GET /?a=b HTTP/1.1
Host: 2legit2quit.azureedge.net

HTTP/1.1 200 OK
Accept-Ranges: bytes
Content-Type: text/html
Date: Mon, 24 Jul 2017 13:20:00 GMT
Etag: "659-5550f52d06b95"
Last-Modified: Mon, 24 Jul 2017 12:26:25 GMT
Server: Apache/2.4.7 (Ubuntu)
Vary: Accept-Encoding
Content-Length: 1625

<title>We shall tear down the ivory tower and build an obsidian one in its place</title>



Cool, so now we’ve got our magic CDN to use we need to find some high value domains. To do this I turned to censys.io:


This will pull up all the certificates it can find which contain an entry for azureedge.net, the domain which azure hosts are currently assigned. There are other domains which azure uses like msecnd.net but I didn’t investigate them.

I used the following python script to pull out the domain names using the censys.io API, but got hit by the 10k limit that censys imposes when exporting data in a naive way like I did. For my hackish/nonexaustive testing it was more than enough. Censys does supply an export API but I needed to write SQL for that and fuck SQL.

SECRET="no really"

c = censys.certificates.CensysCertificates(api_id=API_ID, api_secret=SECRET)

fields = ["parsed.names"]
for cert in c.search("azureedge.net", fields=fields):
    for domain in cert["parsed.names"]:
        print domain

Once I had this list I tested each domain with curl to make sure it would go through to my domain. I’ve uploaded the list of known good domains here which total around 2150 domains + 150 wildcards.

There are a fair few wildcard domains included that I haven’t tested properly since I needed to find a valid subdomain that points to an azure host, so that’s on you. For example there is a *.cdn.skype.com domain in the list, if you google this you’ll find swx.cdn.skype.com which you can use to front with.

Some other microsoft domain highlights:

# cat known-good.txt | grep microsoft | grep -v goskope

# cat known-good.txt | grep skype | grep -v goskope

# cat known-good.txt | grep msn | grep -v goskope

And my personal favourite - a.faggot.party.

# wget -q -O - https://a.faggot.party/?a=b --header 'Host: 2legit2quit.azureedge.net'  | grep title
<title>We shall tear down the ivory tower and build an obsidian one in its place</title>


Further info