Trustwave and Cybereason Merge to Form Global MDR Powerhouse for Unparalleled Cybersecurity Value. Learn More
Get access to immediate incident response assistance.
Get access to immediate incident response assistance.
Trustwave and Cybereason Merge to Form Global MDR Powerhouse for Unparalleled Cybersecurity Value. Learn More
In the web application penetration testing industry, Burp Suite is considered a must-have tool – it includes an intercepting proxy, both active and passive web vulnerability scanners, crawler, session ID analysis tools and various other useful features, all under a single application. One of Burp's best features is the Intruder, a tool which allows the tester to provide a list of values which should be sent to the application as parameter values. By providing values which trigger SQL errors or inject JavaScript into the resulting page, one can easily determine if and how the application is doing filtering on the parameters, and whether it is vulnerable to a given issue.
Burp's Intruder works perfectly when the application responds to those requests as if they came from the user. The screenshot above shows the submission of the following HTML form:
<formaction="/CSRFGuardTestAppVulnerable/HelloWorld"method="POST"name="first"><inputtype="text"value="SpiderLabs"name="name"><inputtype="submit"value="submit"name="submit"></form>
However, modern application frameworks are adding support for Anti-CSRF (Cross-Site Request Forgery) techniques, which protect the application from forged requests such as those Burp uses. The most commonly implemented prevention measure is the Synchronizer Token Pattern, which adds a parameter with a random value to all forms generated by the application for a given user session, and validates this token when the form is submitted. For example:
<formaction="/CSRFGuardTestApp/HelloWorld"method="POST"name="first"><inputtype="text"value="SpiderLabs"name="name"><inputtype="submit"value="submit"name="submit"><inputtype="hidden"value="Z0XN-1FRF-975E-GB9F-GGQM-L2RC-04H1-GKHQ"name="OWASP_CSRFTOKEN"></form>
Because the OWASP_CSRFTOKEN parameter will change between every submission, the Intruder will not work, as it expects the application to respond to the request as if they came from the user. The solution is rather simple: instead of simply feeding a set of values to the parameters being tested, we need to have the Intruder populate the Anti-CSRF token parameter from the form page.
This changes the default behavior of the Intruder tool quite a bit. First, it must know which parameter represents the Anti-CSRF token in the request. While many frameworks will use parameter names that include the "csrf" string, this can be configured per application, and thus we cannot rely on automatic detection. Second, it means the Intruder must make twice the number of requests it would normally perform: one to fetch the form page, which contains the Anti-CSRF token embedded in it, and a second one to actually submit the form with the parameter values provided by the tester. We will address both issues by developing a Burp extension called CSRF Intruder.
Burp offers an extensibility API, called Burp Extender, which allows us to hook into various points in the application, including the UI and the request interception engine. The first thing we need to do is create a Java class which will host our extension.
package burp;import spiderlabs.burp.intruder.CSRFIntruder;publicclass BurpExtender {private IBurpExtenderCallbacks callbacks;private CSRFIntruder csrfIntruder;publicvoid registerExtenderCallbacks(IBurpExtenderCallbacks callbacks){this.callbacks = callbacks;this.csrfIntruder =new CSRFIntruder(this.callbacks);this.callbacks.registerMenuItem("CSRF Intruder",this.csrfIntruder);this.callbacks.issueAlert(String.format("Starting up CSRF Intruder extension [%s]",this.getClass().getCanonicalName()));}publicvoid processHttpMessage(java.lang.String toolName,boolean messageIsRequest, IHttpRequestResponse messageInfo){/* Intercept Intruder requests and check if they came from CSRF Intruder */if(toolName.equals("intruder")&& messageIsRequest)this.callbacks.issueAlert("TODO: Intercept CSRF Intruder requests");}}
The registerExtenderCallbacks() method acts as the extension constructor, and is the first method called by Burp when the extension is loaded. It provides us with a IBurpExtenderCallbacks instance, which we use to create a new context menu entry for our CSRF Intruder handler. We also implement a processHttpMessage() method, which we will use to intercept Intruder requests and modify the Anti-CSRF token velues before they are sent to the remote application.
How does Burp use this class? It must obey a series of restrictions before Burp can find and use it:
java -classpath burp.jar;BurpProxyExtender.jar burp.StartBurp
If these criteria are met, then when Burp starts up our CSRF Intruder extension message should show up in the Alerts tab.
We can now right-click everywhere where a "Send to [...]" menu entry is displayed and click on "CSRF Intruder".
Clicking on the CSRF Intruder menu entry will trigger the handler in our CSRFIntruder class, shown below:
package spiderlabs.burp.intruder;import javax.swing.JOptionPane;import spiderlabs.burp.intruder.gui.CSRFConfigurationDialog;import burp.IBurpExtenderCallbacks;import burp.IHttpRequestResponse;import burp.IMenuItemHandler;publicclass CSRFIntruder implements IMenuItemHandler {private IBurpExtenderCallbacks callbacks;public CSRFIntruder(IBurpExtenderCallbacks callbacks){this.callbacks = callbacks;}@Override publicvoid menuItemClicked(String caption, IHttpRequestResponse[] messageInfo){try{ IHttpRequestResponse message = messageInfo[0];String refererUrl =newString();for(String header:this.callbacks.getHeaders(message.getRequest())){System.out.println(header);if(header.startsWith("Referer:")) refererUrl = header.split(":\\s")[1];}String parameters[][]=this.callbacks.getParameters(message.getRequest()); CSRFIntruderConfiguration configuration = CSRFConfigurationDialog.getConfigurationFromDialog(refererUrl, parameters);this.callbacks.issueAlert(configuration.toString());}catch(Exception exception){this.callbacks.issueAlert(String.format("Error while obtaining request URL: %s", exception.toString()));}}}
The menuItemClicked() handler does two things: first, it fetches the value of the Referer header (if present) from the request the user right-clicked on and uses it as the suggested source form URL, that is, the place where we can find the Anti-CSRF token values; next, it obtain a list of all parameters in that request. It then sends those to a CSRFConfigurationDialog, which displays the URL and parameters, and waits for the user to configure the Anti-CSRF parameters.
When the user provides the URL and the token parameter to be used, we already have all the information necessary to start up Intruder and manipulate its requests. This will come on a second post.
Trustwave is a globally recognized cybersecurity leader that reduces cyber risk and fortifies organizations against disruptive and damaging cyber threats. Our comprehensive offensive and defensive cybersecurity portfolio detects what others cannot, responds with greater speed and effectiveness, optimizes client investment, and improves security resilience. Learn more about us.
Copyright © 2024 Trustwave Holdings, Inc. All rights reserved.