
How to Set Up Extensions and Session Handling for HMAC Signature
In this tutorial, we are going to see how to add a Python script to Burp extender and set up the session handling rule to run the extender.Things that we need:
- Python script from https://github.com/malcomvetter/BurpHmac/blob/master/BurpHmac.py
- Burp Suite - any type (free/community/pro) https://portswigger.net/burp
Modify the Python Script
I did some modifications to the script because I want to use the header, timestamp, and body for creating the HMAC Header. I also, for some reason, cannot seem to make the createHmac definition to work properly.
from burp import IBurpExtender
from burp import ISessionHandlingAction
from burp import IParameter
from java.io import PrintWriter
from datetime import datetime
import hashlib
import hmac
import base64
import sys
class BurpExtender(IBurpExtender, ISessionHandlingAction):
#
# implement IBurpExtender
#
#update me:
global key;
def registerExtenderCallbacks(self, callbacks):
stdout = PrintWriter(callbacks.getStdout(), True)
self._callbacks = callbacks
self._helpers = callbacks.getHelpers()
callbacks.setExtensionName("HMAC Header")
stdout.println("HMAC Header register")
callbacks.registerSessionHandlingAction(self)
stdout.println("Session handling")
return
def getActionName(self):
return "HMAC Header"
#def createHmac(message):
# stdout = PrintWriter(self._callbacks.getStdout(), True)
# stdout.println("createHmac")
# Print("creating hmac")
# msg = bytes(message).encode('utf-8')
# #stdout.println("message: " + msg)
# Print("message: " + msg)
# #stdout.println("key: " + b64decode(key))
# Print("key: " + b64decode(key))
# _hmac = base64.b64encode(hmac.new(b64decode(key), msg, digestmod=hashlib.sha256).digest())
# Print(_hmac)
# #stdout.println("hmac: "+_hmac)
# return _hmac
def performAction(self, currentRequest, macroItems):
#key need to be change with the HMAC key that is used for the encryption
key = "fuM0sCVI/EGFcAAAAlQqsdMmRRRRC2/iLqCWK7khdpU=";
stdout = PrintWriter(self._callbacks.getStdout(), True)
stdout.println("performAction")
requestInfo = self._helpers.analyzeRequest(currentRequest)
#acquire token and timestamp
headers = requestInfo.getHeaders()
for header in headers:
if(header.split(" ")[0]=="Authorization:"):
token=header.split(" ")[2]
elif(header.split(" ")[0]=="Timestamp:"):
timestamp=header.split(" ")[1]
#acquire body
msgBody = currentRequest.getRequest()[requestInfo.getBodyOffset():]
msg=(''.join(chr(i) for i in msgBody))
msg=(((msg.replace(" ","")).replace("n","")).replace("r","")).replace(" ","")
hashstring = token +":"+ timestamp +":"+ msg
hashstring = bytes(hashstring).encode('utf-8')
key=bytes(key).encode('utf-8')
_hmac = base64.b64encode(hmac.new(key, hashstring, digestmod=hashlib.sha256).digest())
#hmac_sting=createHmac(hashstring)
#headers.add('HMAC-Signature: %s' % _hmac)
i=0
for header in headers:
if(header.split(" ")[0]==”HMAC-Signature:"):
headers[i]="HMAC-Signature: "+ _hmac
i=i+1
# Build new Http Message with the new Hash Header
message = self._helpers.buildHttpMessage(headers, msgBody)
#stdout.println(message)
# Print Header into UI
#print self._helpers.bytesToString(message)
# Update Request with New Header
currentRequest.setRequest(message)
return
Setting Up Burp Suite Extender
After we have the script, we then upload it to Burp Suite. We are going to upload the script to Burp extender so we can run it when the session handling finds the invalid session, run macro, then the script.
- Open Burp Suite.
- We are going to use the temporary project (free version). Just follow the wizard until there are tabs showing on the window.
- Find the “Extender” tab and click it.
- Next, we are going to click “Add.”
- Load Burp Extension. A window will open up.
- Choose “Python” as the “Extension type.”
- Select the Python script for the “Extension file.”
- Then click “next.”
- If everything goes as planned (fingers crossed), we will see “HMAC Header Register” and “Session Handling” as the Output for loading the script.
- Click close.
- We will see “HMAC Header Script” as an option for Burp Extensions.
- Make sure the ”Loaded” and “Extension Loaded” at the bottom are checked.
Setting Up Session Handling
In this section, we will create a rule for session handling with an empty macro. Basically, we are creating a rule which will find the invalid session (403 on the header) and then run macro (which is empty, so skip), which in turn will run the script on the defined scope at the Target scope.
- Click the “Project options” tab.
- Then click the “Session” tab in the Project options tab.
- Click “Add” to open “Session Handling Rule Editor.”
- Enter “HMAC Header” as the Rule Description (This should be the same with the getActionName return in the script.) def getActionName(self): return "HMAC Header"
- Click “Add” on the “Rule Action.” Then choose “Check session is valid” to open the “Session Handling Action Editor” window.
- Check “HTTP Headers” and uncheck “URL of redirection target” at the Location(s).
- Enter “403” for the “Look for expression” and switch “Match indicates” to “Invalid session.”
- Scroll down a little and check “if session is invalid, perform….”
- Select “Run a macro.” Then click “Add.”
- When the “Macro Editor” opens up, just click “OK.”
- Check “After running the macro, invoke burp extensions action handler.”
- If we uploaded the script (and the script works), then we will see the script name on the dropdown (ex. HMAC Header).
- After that, we click the “Scope” tab at the top of the window.
- Check all “Tool Scope” so this rule will be applied to all Burp functions.
- Choose “Use Suite Scope.” I tried to use the custom scope but it didn't work.
- Click OK; then we will see the rule in the Session Handling Rules option.
Testing the HMAC Script
Add packet, which responds 403 to the repeater. When we click on GO, the session handling rule will be applied and create the HMAC-Signature header, which will be sent to the server.