Automatically Adding New Header with Burp

By Johnny Yu ·

Most web application penetration testers agree that Burp Suite Pro is the “de facto” proxy tool for assessing web applications. Recently updated, Burp Suite Pro now features extensibility, which allows an assessor to leverage the new Burp API to include additional capabilities.

One of the problems I often encountered when conducting web assessment was updating the integrity hash value of a request that was submitted as part of the HTTP headers.  Mobile and web applications often use some sort of hash value as a way to hinder an attacker from modifying a HTTP request. As assessors, we know this control isn’t very effective, as the algorithm for generating the integrity value most likely resides in the client-side code of the application.

Now that we know the algorithm for generating the integrity value, we would like to automate this process so we can submit the proper integrity value for each request we modify. The new extension from Burp Suite Pro makes this job easy, as it exposes new API and interfaces called “ISessionHandlingAction” that can be used to add or update HTTP headers prior to a request being sent to the target:

from burp import IBurpExtender

from burp import ISessionHandlingAction

from burp import IParameter

from hashlib import md5

class BurpExtender(IBurpExtender, ISessionHandlingAction):

    #

    # implement IBurpExtender

    #

    def registerExtenderCallbacks(self, callbacks):  

        self._callbacks = callbacks

        # helpers object for analyzing HTTP request

        self._helpers = callbacks.getHelpers()

        callbacks.setExtensionName("Custom Header")

        # register the handler that does that alters the HTTP request

        callbacks.registerSessionHandlingAction(self)

        return

Next, we need to include the method that updates the current HTTP request that will be sent off to the target. In our example, we include the MD5 hash of the HTTP body as the integrity value that will be sent as one of the HTTP headers:

def performAction(self, currentRequest, macroItems):

        #Convert request into an object accessible with members

        requestInfo = self._helpers.analyzeRequest(currentRequest)

        headers = requestInfo.getHeaders()

        #getBodyOffset is the starting position of BODY

        msgBody = currentRequest.getRequest()[requestInfo.getBodyOffset():]

        m = md5()

        m.update(self._helpers.bytesToString(msgBody))

        # Add Custom Hash Header Here

        headers.add('Hash: %s' % m.hexdigest())

        # Build new Http Message with the new Hash Header

        message = self._helpers.buildHttpMessage(headers, msgBody)

        # Print Header into UI

        print self._helpers.bytesToString(message)

        # Update Request with New Header

        currentRequest.setRequest(message)

        return

So the complete code is:

from burp import IBurpExtender

from burp import ISessionHandlingAction

from burp import IParameter

from hashlib import md5

class BurpExtender(IBurpExtender, ISessionHandlingAction):

    #

    # implement IBurpExtender

    #

    def registerExtenderCallbacks(self, callbacks):

        self._callbacks = callbacks

        self._helpers = callbacks.getHelpers()

        callbacks.setExtensionName("Custom Header")

        callbacks.registerSessionHandlingAction(self)

        return

    def performAction(self, currentRequest, macroItems):

        requestInfo = self._helpers.analyzeRequest(currentRequest)

        headers = requestInfo.getHeaders()

        msgBody = currentRequest.getRequest()[requestInfo.getBodyOffset():]

        m = md5()

        m.update(self._helpers.bytesToString(msgBody))

        # Add Custom Hash Header Here

        headers.add('Hash: %s' % m.hexdigest())

        # Build new Http Message with the new Hash Header

        message = self._helpers.buildHttpMessage(headers, msgBody)

        # Print Header into UI

        print self._helpers.bytesToString(message)

        # Update Request with New Header

        currentRequest.setRequest(message)

        return 

To invoke the extender python script in Burp Suite Pro, we first save the script into a .py extension, then add the script to Burp Suite Pro from the new  “extender” tab.

Figure 1: Loading python script as Burp Extender

Figure 2: Python Burp Extension successfully loaded

Then we go to the  “Sessions” tab under the  “Options” tab

Figure 3: Add Burp Extension to Session Rules

And click on the “Add” button under the  “Session Handling Rules” and select the  “Invoke a Burp Extension” under the ”Rule Actions”

Figure 4: Add Rules to Invoke a Burp Extension

We can then select the extender that is loaded into Burp Suite Pro:

Figure 5: Select the Burp Extension to be added to rule

Once the extension is selected, we need to set the scope, so click on the  “Scope” tab and click the checkbox for  “Proxy (use with caution)“ and “Include all URLs”. This will include our custom header for every request that goes through Burp Suite Pro.

Figure 6: Enable the rule for Proxy interception and for requesting all URLs

Now everything is setup, we can perform our HTTP request manipulation as usual, and the custom header will be included prior to submitting the request to the target.

We can observe whether Burp Suite Pro did include our custom header by viewing this site: http://www.ericgiguere.com/tools/http-header-viewer.html

Figure 7: The "hash" header is now included as part of the HTTP request

Sometimes we might want to test the application to see if it may return us something special if it was accessed from the local host. One way to achieve this is to include the “X-Forwarded-For” header as part of the HTTP request. According to Wikipedia, X-Forwarded-For “is a de facto standard for identifying the originating IP address of a client connecting to a web server through an HTTP proxy or load balancer.” Therefore, if an application treats the content of X-Forwarded-For header as the originating IP address, we can spoof it. To automatically include the X-Forwarded-For header, we can update the “performAction” to the following:

def performAction(self, currentRequest, macroItems):

        requestInfo = self._helpers.analyzeRequest(currentRequest)          

        headers = requestInfo.getHeaders()

        # Add Custom Header Here

        headers.add('X-Forwarded-For: 127.0.0.1')

        # Build new Http Message with the new Hash Header

        message = self._helpers.buildHttpMessage(headers, msgBody)

        # Print Header into UI

        print self._helpers.bytesToString(message)

        # Update Request with New Header

        currentRequest.setRequest(message)

        return 

I hope this will save application assessors some time with including custom headers to their modified HTTP request using the Burp Suite Pro tool.

Happy Pen-Testing!