Walkthrough: Configuring Burpsuite to Intercept the AWS CLI (Powershell)

Lizzie Moratti
7 min readSep 15, 2022

--

When you’re first learning how to pentest or are performing cloud security research there’s a lot of configuration involved to test properly. There are also assumptions made that you intuitively know how to do said configuration. Someone will eventually ramble off the phrase “Just doing [concept] worked for me” where the concept they described was a 1–2 hour rabbit hole and it’s been just long enough for them to forget that fact.

In my experience as a pentester, there’s always some part of the setup that I end up Googling around for and I won’t find a *great* resource but instead something serviceable. Usually, what I find is documentation that reads like a field manual or someone on StackOverflow has solved an adjacent problem to mine but not quite mine. After some time, I will create a janky configuration that works just long enough for me to forget all the different steps I took to get it working. This is until someone asks me how to recreate my setup. Of course, I will tell them “just doing [concept] worked for me”. This vicious cycle will repeat until a sunbeam hits my hard drive just right and I have to redo my setup all over again.

This was the case when I was researching how to intercept the HTTP requests of the AWS CLI on PowerShell. So I’m going to write the documentation I wish I had instead of the documentation I found. I also used BurpSuite community edition and it was because I was too lazy to go find my actual burp key.

Step 0: Why?

An often overlooked fact. Why would we want to intercept the AWS CLI? There are a few good reasons you might want to intercept the AWS CLI while conducting research.

  • You want to modify the HTTP request itself
  • You want to fuzz/Bruteforce a parameter quickly with no code writing involved
  • You want to bypass client-side validation of the AWS CLI for a parameter to test the server-side controls for research purposes. (i.e. a parameter should only be an integer and you want to give it a string. Normally the CLI will give you an error that is from client-side checks and will not send it to the service in the first place)
  • You want a record of all the HTTP requests/responses you sent to a service

Step 1: Installing the AWS CLI

This page has the download links and commands to run to install the AWS CLI for all Windows, Mac, and Linux.

I’m going to choose Windows and specifically PowerShell. Just because there’s more information readily available for Mac & Linux. At least from what I’ve seen in my professional Googling.

 msiexec.exe /i https://awscli.amazonaws.com/AWSCLIV2.msi

Go ahead and click through the installer with all the defaults, no gotcha’s here.

Check if you installed it properly using the version flag.

aws --version
Oh, yeah that little rabbit hole known as PATH where you need to ensure when you type a command the terminal needs to know what binary maps to an alias. If you see this it's most likely because you need to close and restart your PowerShell terminal. If it persists Google “adding something to PATH [OS you have]”.
Ah yes, that’s more like it.

(Optional) Step 1.5: Trusting the Burpsuite Certificate at the OS level

If you’ve used BurpSuite before you will likely will have already learned how to trust a certificate for a web browser. When doing this on the CLI it’s common to install the Burp certificate at the OS level in most cases. This is NOT required for intercepting the AWS CLI because there is a flag you can use to disregard SSL verification. This is still useful for other CLI tools using the system certificate store that you want to intercept.

Here’s a guide that’s adjacent to this one that has a great segment that’s sweet and to the point from @ropnop.

Step 2: Setting Environment Variables to Proxy Requests

For the Powershell users doing this, you are welcome. The previously mentioned ropnop guide has excellent descriptions of how to do this with proper syntax for Linux and Mac. The AWS CLI will pick up its proxy settings from the environment variables from the system.

Copy and paste environment variables for you to use:

$env:HTTP_PROXY = ‘http://127.0.0.1:8080'$env:HTTPS_PROXY = ‘http://127.0.0.1:8080'

Where I went wrong was not including the ‘http://’ portion of the URL. That seems to be Windows specific syntax.

Let’s configure the AWS CLI to use our credentials now.

aws configure Access key: AKIAIOSFODNN7EXAMPLESecret key: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEYRegion: us-east-2Format: json

Now let’s make one of the most basic AWS CLI calls possible with those credentials.

aws s3 ls

You would see the following because it has certificate pinning (UPDATE: this is actually an example of certificate validation).

PS C:\Windows\system32> aws s3 lsSSL validation failed for https://s3.us-east-2.amazonaws.com/ [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self signed certificate in certificate chain (_ssl.c:1129)

You might ask yourself or already be googling, “What is certificate pinning?”

Certificate pinning is an online application security technique, originally devised as a means of thwarting man-in-the-middle attacks (MITM), that accepts only authorized (“pinned”) certificates for authentication of client-server connections. Any attempted secure connection requests utilizing certificates other than those that are pinned are refused.
https://sectigo.com/resource-library/what-is-certificate-pinning

We either need to turn that setting off or we need to bypass certificate pinning through some other (usually more obnoxious to do) means.

UPDATE: It was pointed out to me there’s technically no certificate pinning in place from the AWS CLI. Nuance is extremely important in infosec so I’m adding an update to this post to say that certificate pinning is not in use. Thank you to @ch1cken who took the time to read this post and correct me.

Under the hood, the AWS CLI uses the boto3 SDK which sends HTTP requests through the python requests library. It just so happens the requests library has a cacert.pem file it checks a certificate against instead of defaulting to checking the system certificate store.

If this was truly certificate pinning the AWS CLI would be checking for a singular certificate or, in some cases, for a certificate that had been signed by that pinned certificate.

Using a code snippet from @ch1cken to locate the cacert.pem the requests library checks against.

This means you could alter this cacert.pem file to include the BurpSuite certificate to enable the interception of requests that are using the python requests library.

Luckily for us, there’s a simple flag to turn that off validation against called --no-verify-ssl. It’ll be easier than modifying that .pem file described above. Remember to use this for all commands you use to interact with a service.

Let’s use that same command but add the no verify SSL flag.

aws s3 ls --no-verify-ssl
Now you’ll see in BurpSuite that you’re now intercepting the request. You’ll also see a warning about how it’s not verifying the certificate but you can ignore that.

Step 3: SigV4 Signing

You can now send a single request to the AWS service. If you attempt to replay or modify that request in BurpSuite it will give you the following error.

An error occurred (SignatureDoesNotMatch) when calling the ListBuckets operation: The request signature we calculated does not match the signature you provided. Check your key and signing method.

This is because AWS signs its requests with SigV4 to prevent Man-in-the-Middle tampering.

Signature Version 4 (SigV4) is the process to add authentication information to AWS API requests sent by HTTP. For security, most requests to AWS must be signed with an access key. The access key consists of an access key ID and secret access key, which are commonly referred to as your security credentials.

When an AWS service receives the request, it performs the same steps that you did to calculate the signature you sent in your request. AWS then compares its calculated signature to the one you sent with the request. If the signatures match, the request is processed. If the signatures don’t match, the request is denied.
https://docs.aws.amazon.com/general/latest/gr/signature-version-4.html

To get around this we need to install a BurpSuite extension that will use our AWS credentials to properly sign a modified request before forwarding it to the service.

The extension I use

Navigate to the new tab that appeared after installation and enter those credentials as appropriate.

If you have temporary credentials you’ll also need to supply the session token.

Be sure to also check this box to allow it to sign the requests.

Step 4: Confirm the Setup Works

Now we can send multiple modified requests to the service but let’s test it to make sure.

Suppose the scenario where I, for some insane reason, want to brute force all possible EC2 instance ids and I want to perform the describe action on each of those. We could use BurpSuite’s intruder feature to do so now.

Intercept the following request:

aws ec2 describe-instances --instance-ids i-1234567890abcdef --no-verify-ssl
Set the payload position for the instance ID
Provide a list of payload options
Check the responses to make sure you’re not seeing signing issues any longer. In this case, it’s returning a valid error and is accepting my requests.

I hope this was helpful or at the very least interesting. If you’d like to see more writeups from me follow me on Twitter or here on Medium.

--

--

Lizzie Moratti

Security Professional - Pentester, former security project manager & technical program manager.