Authentication Token Obtain and Replace (ATOR) Burp plugin to handle complex login sequences

The Authentication Token Obtain and Replace (ATOR) plugin, built on ExtendedMacro, supports complex login sequences in Burp and is fast and easy to use.

Authentication Token Obtain and Replace (ATOR) Burp plugin to handle complex login sequences

AppSec/API Security 2022

By Ashwath Krishna Reddy and Manikandan Rajappan

Automated scanners require a constant flow of requests, and most tools have built-in session-handling logic. But automated scanning / session handling for web applications is tricky these days, especially because of the following vectors:

  • CSRF tokens
  • JavaScript-based apps (React, Angular) and APIs using authentication tokens
  • Header values instead of cookies (JWT)
  • Use of double tokens (access/refresh tokens), mostly for mobile apps

Existing solutions

Burp sessions and macros

Burp has sessions, macros, and the ability to invoke extenders, which help with CSRF tokens (most scenarios), cookie-based session handling, and a few API-based scenarios. Shortcomings:

  • Lack of support. Not all scenarios are supported. Cookies can be replaced in most scenarios. XML and JSON body replacement is not supported.
  • Difficult to use. It’s hard to set up in complex scenarios.
  • Slow. The speed drops because of duplicate requests (especially in header replacement scenarios).

Custom macro extender

The ExtendedMacro plugin (GitHub) provides a UI-based workflow to select and replace tokens. The UI is great and is a superb start to solve a tough problem. But the plugin has a few bugs that make it unreliable. It’s also slow because it sends multiple login requests. Shortcomings:

  • Difficult to set up. It’s hard to select the error condition that triggers the login sequence. Instead, every request triggers the login sequence.
  • Very slow. The speed is reduced because of repeated login requests for every request.
  • Unreliable. Sometimes the replacement of tokens doesn’t work.

Our solution: ATOR Burp plugin

We wanted to build a Burp plugin supporting complex login sequences with the following features:

  • Easy to use. The plugin should be easy to use and intuitive.
  • Support for complex scenarios. The plugin should be generic so that it could support complex scenarios.
  • Fast. The plugin should avoid duplicate requests and, instead, change parameters in memory wherever possible.

To achieve the above, we built on the great work done by Fruh (ExtendedMacro) to create the Authentication Token Obtain and Replace (ATOR) plugin. Our work can be summarized in the following points:

  • Ease of use. ExtendedMacro was already easy to use, but we added another tab to handle error conditions. We also wrote blog posts about how to handle complex scenarios.
  • Bugs. We made ExtendedMacro more reliable. Once we fixed the bugs, we immediately started seeing value.
  • Speed. We used in-memory replacement of tokens instead of sending extra network traffic.
  • Support for complex scenarios. We used regex for both figuring out error conditions and replacing tokens. Using regex makes it super easy to handle replacement in JSON, XML, the body, cookies, and URLs.
  • Configurations. We added In-Scope and Targets options. The Targets option is for content discovery and simulates manual testing options provided by Burp.

How the ATOR plugin works

ATOR Burp plugin workflow

Let’s break down how the ATOR plugin works using an example. Say an access token is valid for 30 minutes and then expires (after which a new access token has to be fetched). We have three scenarios:

1. Token is valid (Minute 0–29). ATOR sees that the request is valid and forwards the request to the server.

2. Token is expired (Minute 30). ATOR sees that the error condition is met. It triggers the login sequence, fetches a new access token (AT2), and saves the new access token in memory.

3. New access token needs to be used (Minute 31–59). ATOR replaces the token in request headers with AT2 till the error condition is met again. At that time—in this case, on Minute 60—ATOR goes back to Step 2 to fetch a new access token to store in memory.

How to use the ATOR plugin

Before using ATOR

1. Install the ATOR plugin.

Install the ATOR burp plugin

2. Recommended: Install the Flow or Logger++ extender on Burp, and enable traffic from the extender.

Enable extender traffic

Using ATOR

Follow this four-step process for any application or API:

  1. Identify the login sequence (from the proxy or repeater) and configure it in ATOR.
  2. Specify the error pattern.
  3. Specify the regex pattern to replace in the request.
  4. Specify the new data to use in the request.

Testing ATOR with a sample application

Let’s use the sample application TiredfulAPI by Payatu Labs for a walkthrough. The dockerized version works reliably. We highly recommend doing a sample setup once.

1. Generate an access token:

Generate an access token in Tiredful

2. Test API access with the generated token:

Test API access with a valid token

3. Test API access with an invalid token:

Test API access with an invalid token

Configure ATOR for the Tiredful application

In this example, we’ll fetch each new access token using a simple one-step login.

1. Identify the login sequence and configure it in ATOR.

We send an existing login response to ATOR:

Send existing login response to ATOR

ATOR receives existing login response

We configure ATOR to extract the access token from the login response. Here, the variable “token” will contain the token string:

Extract access token from response

2. Specify the error pattern.

You can specify the error condition in four ways:

  1. Status Code: 401, 400
  2. Error in Body: specific text from the body (e.g., “Access token expired”)
  3. Error in Header: specific text from the header (e.g., “Unauthorized”)
  4. Free Form: combination of multiple conditions (e.g., status code is 400, body contains “Access token expired”: st=400 && bd=Access token expired || hd=Unauthorized). This is useful when 400 can be thrown in multiple scenarios.

In this example, the server returns a status code of 401 when the access token is invalid:

Invalid access token returns 401

So we specify the error type as “Status Code” and the message / status code value as “401”:

Set error type as status code = 401

3. Specify the regex pattern to replace in the request.

Sample regex patterns:

  • Use Authorization: Bearer w* to match Authorization: Bearer AXXFFPPNSUSSUSSNSUSN
  • Use Authentication: Bearer ([w+_-.]*) to match Authorization: Bearer AXX-F+FPPNS.USSUSSNSUSN

In this example, we can see where the access token appears in the request:

Access token in request

So we specify the replacement pattern as Authorization: Bearer w*.

Specify replacement pattern

4. Specify the new data to use in the request.

We set the replacement area as Authorization: Bearer token (we created the variable “token” in Step 1):

Set replacement area

Scenario walkthrough

Using the same example as above, where the access token is valid for 30 minutes, let’s walk through the different scenarios:

1. Token is valid (Minute 0–29)

The repeater sends a request with a valid token (AT1). ATOR checks the status code in the response. It’s OK (200), so ATOR sends the response to the repeater:

ATOR sends valid response

2: Token is expired (Minute 30)

The Tiredful application allows us to revoke a token. Let’s use this feature to expire AT1:

Expire access token in Tiredful

The next repeater request contains AT1, which we just revoked:

Request uses expired token

So the server returns a status code of 401. ATOR senses that the error condition is met, invokes the login sequence, and extracts and stores a new token (AT2). Then it checks the flow, finds the last request, replaces the token with AT2, and resends the request:

ATOR retrieves and sends new token

3. New access token needs to be used (Minute 31–59)

The next repeater request is still using the expired token:

Another request using expired token

So ATOR replaces it with AT2 (the token currently stored in memory):

ATOR replaces token

Revoking the new token (AT2) and generating a new one (AT3)

For the sake of completion, let’s run through another revocation of the token:

Revoke Tiredful access token again

The next request uses the expired token (AT2):

Request using expired token again

When the server returns a status code of 401, ATOR invokes the login sequence again and stores the newest token (AT3) in memory. It checks the flow for the last request and resends it with AT3:

ATOR retrieves and sends new token again

The next repeater request uses an expired token:

Another request using expired token again

This time, ATOR just replaces the expired token with AT3 (the token currently stored in memory) instead of invoking the login sequence:

ATOR replaces token again

Want to read more? Subscribe to the blog!

*** This is a Security Bloggers Network syndicated blog from Software Integrity Blog authored by Synopsys Editorial Team. Read the original post at: