While investigating our clients’ attack surfaces, I find myself repeating tasks frequently enough to demonstrate a need for automation, yet not frequently enough to justify the time needed to develop an automated solution. For routine tasks, such as a standard port scan, building a scripted solution makes sense. For one-off tasks though, this need for automation is less apparent. Unfortunately, the moment you need an automated solution is also the moment you need to finish the task at hand. How is it possible to do both? That’s where our story begins.
In this blog post, I describe an instance where the Bishop Fox Cosmos (formerly CAST) team contributed to an open source tool to achieve automation during investigations. This instance also sheds some light on how the human element in Cosmos partners hand in hand with the automation aspect.
One method that helps the team is building out an automated solution while simultaneously accomplishing the task. An example of this method occurred recently as we investigated an information disclosure vulnerability where a client exposed an API token through a publicly accessible web endpoint. The Cosmos team often finds API tokens during our assessments. When a sensitive token is leaked, it often accompanies source code. Other times when there is no available source code, the token itself informs us to which service it belongs. Did you find an API token starting with 'Aiza?' That's Google. Did you stumble on another token beginning with 'AKIA?' Yep, that's an Amazon Web Services token. Sometimes these tokens do not have any context, making them difficult to validate. In this case, the API token we found was a 32-byte hexadecimal string. Fairly generic. Attempts to identify the use of this token included testing it against lists of regular expressions matching well-known API token schemas. This was unsuccessful. We wanted to leverage the open source 'streaak/keyhacks' repository which provided a list of quick checks to determine the validity of API tokens, but we needed context: we did not know for which service the API token was intended. Without context, we were left testing the API token against each service. Slowly, one at a time.
That is how we started, and the entire time we thought: "Surely, someone has automated this." We did not find this to be true, so we created the automation concurrently while testing each token. Instead of executing each line from the 'keyhack' repository one at a time, we tried leveraging to automate the testing of an unknown API token against popular API endpoints. Nuclei is a scanning tool that identifies vulnerabilities based on definitions within templates. You feed Nuclei both an endpoint and a template, and it tells you whether that endpoint matches the vulnerability defined within the template. At the time of the investigation, Nuclei limited the use of variables within templates. Fortunately, a developed feature request enabled us to create Nuclei templates which quickly test an API token against over 60 API endpoints. Creating a template for each API endpoint was our way of making the task repeatable, as we will no doubt run into the same scenario again. We submitted a pull-request to add the new templates into the community-led 'projectdiscovery/nuclei-templates' Git repository for others to use and build on.
Below is an example template to test the API token against GitHub's API endpoint:
id: api-github
info:
name: GitHub API Test
author: zzeitlin
reference: https://docs.github.com/en/rest/reference/users
severity: info
tags: token-spray,github
requests:
- method: GET
path:
- "https://api.github.com/user"
headers:
Authorization: Basic
matchers:
- type: word
part: body
words:
- 'login'
The above template is different than a traditional Nuclei template because the path is static. There was no need to supply a path because the tested API endpoint was the well-known path of 'https://api.github.com/user.' The template also required the user to input a 'token' variable. The following command showed how to test a token against all API templates:
$ nuclei -u null -t token-spray/ -var token=thisIsMySecretTokenThatIWantToTest
Nuclei expected an input target specified either by the `-u` or `-l` flag. Given we were not testing a specified target (as the targets were the well-known API endpoints), we simply provided a null value to satisfy the input requirement. Additionally, the templates we created were not limited to HTTP. An example service that demonstrated testing on another protocol is the SendGrid service. Below is the template to test an API token using SMTPS:
id: api-sendgrid
info:
name: Sendgrid API Test
author: zzeitlin
reference: https://docs.sendgrid.com/for-developers/sending-email/getting-started-smtp
severity: info
tags: token-spray,sendgrid
network:
- inputs:
- data: "ehlo\r\n"
read: 1024
- data: "AUTH PLAIN \r\n"
read: 1024
host:
- "tls://smtp.sendgrid.net:465"
matchers:
- type: word
words:
- "Authentication successful"
In the above template, we transmitted the 'AUTH PLAIN...' string containing the tested API token to the 'smtp.sendgrid.net' endpoint using TLS over TCP port 465. We determined success based on a simple string matched against the response. For the complete list of Nuclei templates used for testing API tokens, see the 'token-spray' folder here.
After an iteration of creating several API templates, testing API tokens is no longer such a slow process. Additionally, new API endpoints can be included in the list by simply creating new templates. This is one way the Cosmos team at Bishop Fox continuously improves efficient investigations. With an ever-increasing attack surface, we must also sharpen our tools and ensure repeatable tasks are as streamlined as possible. At the same time, it is important to maintain a balance of automation and manual involvement: an overreliance on established monolithic automations can hinder the supporting human expertise. Because automation is key for efficiency, the Cosmos team pairs automation with the human element to maximize the reach for both avenues.
For further reading on how Cosmos augments automation with human expertise, see When Automation Isn’t Enough: The True Impact of Human Expertise on Your Perimeter and Continuous Testing Finds Major Risks Under the Surface.