Skip to content

Instantly share code, notes, and snippets.

@thomaspatzke
Created February 15, 2017 09:09
Show Gist options
  • Save thomaspatzke/8bcaa3b7e056e6c730e648399d5069f7 to your computer and use it in GitHub Desktop.
Save thomaspatzke/8bcaa3b7e056e6c730e648399d5069f7 to your computer and use it in GitHub Desktop.
Burp Session Handling Extension: CSRF tokens with random parameter names
from burp import (IBurpExtender, IBurpExtenderCallbacks, ISessionHandlingAction, IHttpListener)
import re
class BurpExtender(IBurpExtender, ISessionHandlingAction, IHttpListener):
def registerExtenderCallbacks(self, callbacks):
self.callbacks = callbacks
self.helpers = callbacks.getHelpers()
callbacks.setExtensionName("Handling of CSRF Tokens with Random Names")
self.callbacks.registerSessionHandlingAction(self)
self.callbacks.registerHttpListener(self)
self.out = callbacks.getStdout()
# CONFIG: find token in tools defined by this bitmask, constants defined in IBurpExtenderCallback
self.findTools = 0xffffffff
# CONFIG: this RE matches the CSRF token
self.reFindTokenName = re.compile("csrftokenname='(.*?)';")
self.reFindTokenValue = re.compile("csrftokenvalue='(.*?)';")
# CONFIG: Replacement RE must match complete token name, equal and token value
self.reReplaceToken = re.compile("&[0-9a-f]{8}=[0-9a-f]{8}")
self.token = None
def log(self, msg):
self.out.write(msg + "\n")
### IHttpListener ###
def processHttpMessage(self, tool, messageIsRequest, message):
if tool & self.findTools and not messageIsRequest:
response = self.helpers.bytesToString(message.getResponse())
matchName = self.reFindTokenName.search(response)
matchValue = self.reFindTokenValue.search(response)
if matchName and matchValue:
newToken = matchName.group(1) + "=" + matchValue.group(1)
if self.token != newToken:
self.token = newToken
self.log("New CSRF Token: " + self.token)
### ISessionHandlingAction ###
def getActionName(self):
return "Update CSRF Token with Random Name"
def performAction(self, currentRequest, macroItems):
request = self.helpers.bytesToString(currentRequest.getRequest())
# CONFIG: replacement must include possibly matched HTML syntax, e.g. parameter delimiters like & and ?
result = self.reReplaceToken.sub("&" + self.token, request)
currentRequest.setRequest(result)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment