Working with Macros in Burp Suite

Varsha Chahal
5 min readJan 14, 2024

--

Recently, while testing for Server Side Template Injection on a website, I observed that the payload was reflected on a different web page rather than in the immediate HTTP response. It’s easier to test if the payload is reflected in the same response, but if you need to make an extra request to get the different page after POSTing your payload, then it becomes very tedious. Why not automate this task?

This is when I learned about Macros in Burp Suite. Burp Suite Macros allow you to run a set of instructions in a certain order, which can be integrated with various tasks and tools. A replacement for Macros would be writing scripts to make multiple requests and grab interesting responses. But, why not use Burp Suite to do it?

Our goal is to create a Macro that we will integrate with Burp Intruder to make multiple requests to the server.

What is the strategy?
1. Submit a POST request with the SSTI payload (performed by the Intruder).
2. Execute a subsequent GET request to retrieve the page containing the reflected payload. (performed by the Macro we will be creating).
3. Analyze the response for SSTI and any template engine-related information that might be returned.

To illustrate this, I am using Portswigger’s SSTI lab.

After authenticating, you will see that a user can select the name (user.name, user.first_name, user.nickname) displayed on their blog post comments through the /my-account/change-blog-post-author-display path. You want to test the blog-post-author-display field for a possible SSTI, but the response does not return any information to identify a potential SSTI.

The blog-post-author-display field value is reflected on the blog post page in the comment section which needs to be fetched again.

Let’s say you have a set of SSTI payloads for different template engines to read the contents of a file and you want this task to be automated by the Burp Intruder. The clear challenge is how to read the reflected payload on the blog post after every POST request to /my-account/change-blog-post-author-display.

To solve this, we will create a Macro that would make a second GET request to the server after every POST request by the Intruder.

There are 3 parts to creating the macro:
1. Create the macro
2. Add a rule to run the Macro
3. Limit the number of maximum concurrent requests to view the blog post response mapped to the correct request.

To begin, capture the HTTP traffic in the Burp Suite Proxy.
Click on Settings gear on the top right of the Burp Suite window and click on Sessions. There you will see an option to create rules and macros.

Let’s create our macro first.

Click on the Add button under the Macros subsection. A macro recorder window opens where you see the HTTP traffic you captured earlier.

We will select only the GET request to fetch the blog post as the POST request will be executed by the Intruder.
Click “OK”. The selected request then appears in the Macro Editor.

You can test the Macro here.
Looking good? Click OK to save the macro.

Now let’s add this Macro as a rule to run with Intruder every time you send a particular request.
Click on Add under the Session Handling Rules section. You are presented with a window to add the rule, Select “Run a post-request macro” from the dropdown.

You will find the already created Macro added in the Session handling editor. Select the macro. By default, the option to return the final response of the macro to the invoking tool is selected.

You don’t have to configure anything here as we are creating a simple Macro. Click OK to save the action.

In the Scope tab, we will define the scope in which this Macro should be run. Select only Intruder (or any other option if you are integrating it with another tool).
Use Custom scope. Under “Include in scope section” add the URL that should trigger this rule.

Save the rule.
Time to test it now.

Send the /my-account/change-blog-post-author-display request to Intruder.
Set the blog-post-author-display field value as the payload position.
Attack type: Sniper
Paste or upload your list of payloads in the “Payloads” tab.
Under Resource pool, Create a new resource pool and set Maximum concurrent requests to 1.

In one of the payload results, you will see the contents of the /etc/passwd file.

Notice that the response you are seeing is for the GET blog post request that we added in our Macro whereas the request sent by the Intruder is POST request for /my-account/change-blog-post-author-display.

This was your Macro in action.

--

--