Monday, July 8, 2013

Anti-CSRF token support using Burp Extender API

I was recently faced with a problem where I was using SQL Map to scan a URL for SQL injection vulnerabilities. The issue was that after every POST request to the server my Anti-CSRF token would get reset and I could not figure out a way to retrieve the Anti-CSRF token form the response body and set it back in the next request sent by SQLMap.
I overcame this issue using Burp's Extender functionality and proxying SQLMap traffic thru burp. For those who are not familiar with Burp Extender, check http://portswigger.net/burp/extender/ out. Burp Extender allows us to hook into various events of the Burp application.
I've written a small program to record the Anti-CSRF token from the server response and then add it back to the request sent to the server.

PS: I will fix formatting issues and beautify the code soon. ;)

Download API : http://portswigger.net/burp/extender/api/burp_extender_api.zip
Follow the setup instruction present in http://blog.portswigger.net/2009/04/using-burp-extender.html

Modify the processHttpMessage method as follows :

@Override
public void processHttpMessage(int toolFlag, boolean messageIsRequest,IHttpRequestResponse messageInfo) {
 
 //HostName of the host you want to test. 
        String HOST = "m.test.isecpartners.com";
 
 IHttpService httpService = messageInfo.getHttpService();
 
 // If this is a response then record the CSRF token.
 if (!messageIsRequest) {
 
  if (HOST.equalsIgnoreCase(httpService.getHost())) {
   byte[] responseBytes = messageInfo.getResponse();
   String responseString = new String(responseBytes);
   int start = responseString.indexOf("<input type=\"hidden\" name=\"token\" id=\"token\" value=\"");
   if (start > 0) {
    // Extract the CSRF token value.
    String token = responseString.substring(start + 52,start + 51 + 57);
    stdout.println("Response Token:" + token);
    globalToken = token;
   }
  }
 } else {
  // In the request, we replace the CSRF token in the request with the
  // globalToken
 
  if (HOST.equalsIgnoreCase(httpService.getHost())) {
   IRequestInfo info = helpers.analyzeRequest(messageInfo);
   List<String> headers = info.getHeaders();
   IParameter token = helpers.getRequestParameter(messageInfo.getRequest(), "token");
   byte[] byteMessage = messageInfo.getRequest();
   if (token != null && !globalToken.isEmpty()) {
    stdout.println("Request Token :" + token.getValue()+ " Global Token : " + globalToken);
    // Remove the incorrect Anti-CSRF token from the request
    byteMessage = helpers.removeParameter(byteMessage, token);
    IParameter newToken = helpers.buildParameter("token", globalToken, IParameter.PARAM_BODY);
    // Add the correct Anti-CSRF token to the request.
    byteMessage = helpers.addParameter(byteMessage, newToken);
    // Set the request with the new token.
    messageInfo.setRequest(byteMessage);
   }
 
  }
 }
}

Run the extender jar file :
java -Xmx512m -classpath burpextender.jar;burp.jar burp.StartBurp
Output generated by the Extender Plugin can be seen in the Extender Tab's output sub-tab.


This can also be used with the BURP Scanner tool which modifies the same request packet without considering the values present in the response packet.



There are several possibilities using the BURP Extender tool. 

No comments:

Post a Comment