Given the importance of REST API endpoints for most networks and applications, we wanted a way to use (existing) Canarytokens, or Canaries to detect unauthorized access to a REST API.
(Like all things Canary) We wanted something easy to use that delivers immediate value. Here we present several new approaches, and look forward to hearing from the community on the usefulness and ways to increase insight here for network defenders.
Challenge:
APIs are everywhere and permeate most organization’s daily web based workflows. Both internal and external services often rely on the use of REST APIs. From workstation management to web applications, from complex business logic and application integrations, to payment processing services, APIs form a backbone for all kinds of crucial services.
It started us thinking, how we might be able to create and use Canaries and Canaryokens to catch or detect unauthorized REST API endpoint or key usage? Our end goal would be for teams to receive an alert when an API key, or tokened URL endpoint they want to monitor, is used by an attacker.
(The AWS API-key is already our most popular Canarytoken, with hundreds of thousands deployed world wide, but we wanted to mint API keys for our own internal services and have them be as useful)
Solution:
At its core, a REST API call is an HTTP request. What we need is a way to receive a request, log relevant headers or parameters and HTTP methods, then send an alert to the Canary console.
We can do that.
There are already a number of HTTP request related primitives built into Canaries and Canarytokens. We can easily leverage these to create a REST API Canary endpoint. This allows defenders to quickly gain insight into unauthorized use of REST APIs within their organization with low setup costs.
We will show three types of REST APIs you can consider using:
- Using the simple Web Bug Canarytoken.
- Using the (fake) Webserver on a Canary.
- Creating a Custom Canary TCP Service.
Setup One : Web Bug Canarytoken
This is the most basic form of the request, create a Web / URL Canarytoken, then leave a hint to its use in a document someplace and see if anyone ever runs a script or curl command to trigger the alert.
We will create a Web Bug Canarytoken, annotate our Token Reminder, for later. We will then use PostMan, an API testing tool to send a sample request to start out.
First we will create the Canarytoken, either in our private Canary Console or at canarytokens.org.
Notice the full/returned token-URL is:
http://canarytokens.com/traffic/ww0mayx9rro4h2l3keazj0zdk/contact.php
Next, we will modify the generated URL slightly to make it appear more like a REST API endpoint.
This ought to do the trick:
http://canarytokens.com/api/v1/users/list/ww0mayx9rro4h2l3keazj0zdk
Remember, this URL is just an example. Apart from the hostname and the actual token (in red), you can change all other parts of the token-URL.
Test with a curl command
curl http://canarytokens.com/api/v1/users/list/ww0mayx9rro4h2l3keazj0zdk
Or send requests and track responses with a tool like Postman
This generates the expected alert:
This is a simple example to showcase the captured HTTP request, source IP address and the User-Agent string. We can see the utility of a quick alert or signal that someone finds this url interesting (and by extension that someone had access to the place it was stored).
However, it is pretty clear by the hostname, that we are hitting a Canarytoken URL. Teams using our commercial Canary offering have the ability to use a custom domain. If you are using the free service, you can abstract away the Domain Name by using a DNS CNAME record.
We create a CNAME record in a domain we control. We want api.example.com to resolve to canarytokens.com. We add a CNAME record to point api.example.com to canarytokens.com, so that when the request is made, we still receive the alert!
Test:
curl http://api.example.com/ww0mayx9rro4h2l3keazj0zdk/api/v1/endpoint
Alert:
We can see that we receive the same alert, even though the hostname was changed.
Setup Two: Webserver On Canary
Canaries have a built-in feature that allows you to configure a Webserver on it with a single click. With another click you can choose one of the default HTTP Skins. This is a great way to create an enticing server that attackers may attempt to interact with. Below is a basic example of applying the Jenkins Login HTTP Page Skin. Enable Webserver settings in the Canary Console:
When someone browses to the page they will see this.
(By default this exists to capture the credentials an attacker enters – and lets you know that somebody is messing around where they shouldnt be). A Skin here is simply a set of files, styles, scripts and images that you want to present to a visitor to the page. You can also upload custom skins to create any style you want. But! Even having a basic Canary-website like this allows us to capture REST API request attempts. You can post a reference to the service and usage. This could be in Github or other places with script snippets or command documentation. These are basic examples, but we think you get the idea. Below is a modified example of a REST API that allows you to transfer money between accounts. Place this example near the Accounting or Finance developers and lets see what happens.
Test:
curl http://srv02.example.com/api/v1/transfers \
-u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \
-d amount=530 \
-d currency=usd \
-d destination=acct_acdcD82eZvKYlo2C8675309 \
-d transfer_group=ORDER_66 \
-v
Alert:
When anyone attempts to use this command, we will get the following alert!
In the above example, we only see the basic attributes of the request. (Canary won’t log the request
parameters by default). To capture the POST parameters, we add a custom file. Then alert would include
more context: how much money was attempted to be transferred and to which account!
For more detail on these parameters see this blog post about custom webroot configurations. In order to capture the POST parameters, we created a Defined Skin, you can read further about this here, Capturing Incident Data on POSTs.
Setup Three: Canarys Custom TCP Service
In addition to the built-in HTTP Page Skins, Canaries allow you to create a Custom TCP Service that listen on a port you define, and gives you control over various interactions. This allows you to mimic services that may reflect websites or a REST API without using the standard HTTP service (80,443). If you would like to learn more about enabling and configuring a Custom TCP Service, be sure to review be sure to review our Service Configuration steps.
We can expand on the basic examples above.
We enable the Custom TCP Service on port 8443 in the Canary Console.
To make sure we don’t easily alert for false positives, we can configure the service to only alert when
TCP Connections send a string we are expecting by adding it to the Alert String field.
Test:
curl -X POST \
-H ‘X-Auth-Token:15dd7c486d81899f64643d6618c47a4efeedacdc’ \
http://srv02.example.com:8443/api/v1/resetpwd
Alert:
As we can see, our alert was triggered when the X-Auth-Token string in the Header matched our
configured Alert string. The Alert string is not required, if you are interested in alerting on any
connection attempts and logging the data sent, then leave the Alert string setting off.
An additional benefit of a Custom TCP Service is we can create tokens that are context specific.
The request URI, consists of: {URI-scheme} :// {URI-host} / {resource-path} ? {query-string} .
Given this is the case, we could create query strings in the request that identify the token.
curl -G -H “Authorization: Bearer 15dd7c486d81899f64643d6618c47a4efeedac” \
http://srv02.example.com:8443/api/v1/resetpwd/subscriptions \
-d “api- version=2014-04-01-preview” \
-d “location=ThisisinStevesAzureADAuthenticationscript”
We never had to create a specific token, we can infer from the Request the key location dynamically. We don’t have to be as obvious in the parameter value either. We simply place these examples in links or in scripts. When the request arrives we receive an alert with the complete HTTP Request.
Placement:
One last topic needs to be considered here. How would an attacker find these examples, and what might
entice them to use them? That is a great question. There are a number of places where details for how to
connect to a REST API might show up. Much like opening a document with a Canarytoken or a URL
Canarytoken. We want to find ways that would cause someone to interact with our fake REST API. Here are a few thoughts and ideas. We would love to hear more about what you come up with as well.
Idea One: Place the REST API Canarytoken example in an Internal code repo, disguised as a comment,
or a reply or a code snippet.
Idea Two: Place a link in an internal page that calls out to the specific URL, or a file share, or laptop,
that looks like a developers workspace. There are a number of additional references and resources that
may also be useful to think about how your organization may find helpful.
We found the blog below from Detectify to be a helpful resource to get teams started thinking about how
an attacker might find and use a REST API endpoint or keys they discover.
Source: https://labs.detectify.com/2021/08/10/how-to-hack-apis-in-2021/
Conclusion
We can leverage already existing Canarytokens and Canary HTTP services to receive and alert
on unauthorized REST API request attempts. With the already existing HTTP primitives teams can extend or embed these examples within their organization and applications to detect and alert on unauthorized use.
References:
API Examples:
https://docs.github.com/en/rest/billing#about-the-billing-api
https://docs.microsoft.com/en-us/rest/api/azure/
https://betterprogramming.pub/the-anatomy-of-an-http-request-728a469ecba9
https://labs.detectify.com/2021/08/10/how-to-hack-apis-in-2021/
Hacking APIs ,Breaking Web Application Programming Interfaces – by Corey Ball.