RTOps: Automating Redirector Deployment With Ansible

This blog will cover what redirectors are, why they are important for red teams, and how to automate their deployment with Ansible. This is the first post in our RTOps blog series, and will serve as a jumping off point for further redirector strategies, and Red Team infrastructure automation

What are redirectors

Redirectors sit in front of our actual C2 servers, and securely proxy command and control traffic from the target back to our C2 listeners. These prevent the client from being able to see our actual C2, and should be easy to spin up and tear down.

Redirectors come in many forms, from hop.php applications popularized by Metasploit and Empire, to something as simple as socat

We are going to focus on deploying a C2 using hop.php AND/OR mod_rewrite, allowing the redirectors to support Empire and Cobalt agents with the following features:

Proxy traffic to our C2 servers

Redirect or proxy unwanted traffic away from our c2 servers

Have legimate publicly signed certificates with communication over https

To meet all these goals, Apache with mod_rewrite is an excellent choice.

Redirecting using mod_rewrite

Mod_rewrite is a great component of Apache that allows us to transparently proxy or redirect requests based on regular expression matches. This could, for example, allow our evil 'amazonss.com' site redirect or proxy traffic to 'amazon.com', making it appear legit, unless traffic matching our C2 hits the server, in which case mod_rewrite will transparently proxy the request to our C2 servers.

@bluescreenofjeff has an awesome writeup on how to do this. Rather than cover what Jeff has already, this blog will go over how to deploy redirectors using his method, and a few tweaks to work better with ansible and lets-encrypt.

Automating Redirector Deployment with Ansible

To deploy our redirectors, we will be using Ansible, a configuration management tool comparable to puppet, chef, and fabric. Ansible is nice because is it agentless and works completely over SSH. We are introducing ansible now as we will be baking many of our commands and configurations into Ansible configs, so will be covering both redirector setup and Ansible features as we go.

Ansible Primer

If you already know ansible, feel free to skip this section. For those that don't, this section is mostly guidance on which portions of Ansible's documentation you need to read or reference to understand the configurations we go over in this post.

Playbooks
Ansible uses config files in YAML format to specify actions it takes on remote servers. These configurations are called 'playbooks'.

We leverage this in our automation by creating a redirector role, which consists of all the legwork to spin up and configure a redirector. Our playbooks to deploy specific redirectors largely consist of variables to be passed to this role. This allows us to separate the configuration of a unique redirector instance from the general process of setting up a redirector.

If you don't fully follow the documentation for ansible roles, don't worry. Most of this post will go through creating the redirector role, so you can learn by example.

Ansible Redirector Role

Requirements

Alright, we are almost ready to dive into creating our Ansible Role to facilitate redirector provisioning. First, lets walk through some formal requirememts of our role so we know what tasks we need to implement:

Apache Installation: We need to make sure we have apache installed with the proper modules

Apache Configuration: We need to setup configurations for our redirectors. We can use vhosts for per domain configuration

Copy Hop.php File(s) to Server: We need to get our hop.php file to the server if using that method of redirection.

Redirector Rules: We need to install the redirector rules. We can do this in our apache config's vhost section instead of .htaccess files

Lets Encrypt Installation: We need to install lets encrypt on the target servers and python-certbot-apache

Lets Encrypt Configuration: We will want let's encrypt to setup legit public certs for our sites.

Ok, we've got a pretty decent list to get started on. Lets start making our role.

Role Structure

We wont need all these folders for our role, but it is good to layout the initial structure before we start work. Each folder has special meaning in the context of a role. Most importantly, the tasks folder will contain all the tasks we want to run. When you import or include a role in a playbook, it will execute the file main.yml in the tasks folder.

We could put all our tasks in that main.yml file, but it would be better top break them out into multiple files for readability and re-use. Looking at our requirements list, we can see our tasks break down into two general categories: setting up apache, and setting up lets config.

We can 'include' the apache and letsencrypt files in main.yml, allowing them to be run when we use the redirectors role.

main.yml

---
- include: "apache.yml"
- include: "letsencrypt.yml"

Right now both apache.yml, and letsencrypt.yml are empty, so using the role will not do anything. However, we now are ready to start implementing our tasks in those two files.

Setup Apache

Installation

Installing modules in ansible is a cinch. To keep it even simpler, we will just be supporting debian based systems with this role. We can leverage the 'apt' task to make sure apache and required dependencies are installed on our target server.

Our apache.yml file now will install apache, php, and libapache2-mod-php.

Next, we will append the following to our apache.yml to enable the headers, rewrite, proxy, ssl, proxyhttp, and php7.0 mods. We will also disable moddeflate and mod_cache to ensure our redirector doesn't encode or otherwise process our C2 traffic in undesireable ways. apache.yml continued

Now when we have the hop_dir variable defined in our redirector instance playbook, it will copy the contents of that directory on our local host into the root of our site.

Before we go any further, we need to cover how variables will be layed out in our instance playbooks, and how they interact with our role. Let's do that by walking through a completed playbook that will setup our redirector instance using our redirectors role.

OK, that was a lot to cover, but hopefully this config file and layout is making sense. We formatted this config mostly in JSON (YAML is a superset of JSON) but you can format it however you like as long as it matches up.

Notice in the config how there are multiple vhosts, and each one can use one or more methods of specifying the config

Back to the Role: VHOST Configs

With a schema decided for our redirector Role variables, we can move back to developing the role.

Now, we will set up our vhost configs. This is a bit more complicated than our previous tasks as we will need to not only add a task but include templates to define the config files.

These template files will allow us to build most of the config file, and dynamically replace portions with it based on our ansible variables.

First, lets create the tasks to instantiate the templates and copy them to the server.

These tasks:
1. take in the specified template files
2. for EACH vhost in vhosts, do the following:
a. pass them the 'vhost' variable which will be named 'item' in the template
b. Run the Jinga 2 templating engine
c. Copy the output to the apache directory on the server with the filname prefixed rt_ for http sites, rtssl_ for https sites and appended with the servername for the vhost.

The reason we create one configuration file per vhost is that Letsencrypt, specifically the certbot-apache component, does not support more than one vhost per config file. Because of this we will be provisioning multiple configuration files to the server.

Now lets create the SSL and HTTP templates. Make the template files and place them in your templates folder so that your directory tree should now look like:

These tasks will disable all existing sites, to prevent having more than 1 vhost per config file and breaking lets encrypt. Then, all the red team sites will be enabled. Boom, we now have our apache sever stood up with all the proper configs!

Ok, thats it! We've done it! We've developed a role that allows us to quickly deploy a redirector to an existing server!

Next steps are to run the role. Create your playbook in the form of the example we covered and run ansible-playbook -i <your_hosts_file> <your_playbook>. Ensure that this roles is in the roles directory in the same path of your playbook, and your hop and/or config files are placed correctly. Your directory layout should look like:

Closing Thoughts

This redirector configuration automation is just a basis for our red team infrastructure automation. By building on this substrate, we can build powerful tools to bring up C2 servers quickly and effectively. Next post we'll discuss how we can automate the server creation itself and provision these redirectors based on dynamic Terraform state files. See you then.