Skip to content

Instantly share code, notes, and snippets.

@mgeeky
Forked from lanmaster53/pyscripter-snippets.py
Created June 14, 2019 10:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save mgeeky/36cff7c973116df7a972d14188d5221c to your computer and use it in GitHub Desktop.
Save mgeeky/36cff7c973116df7a972d14188d5221c to your computer and use it in GitHub Desktop.
Burp Python Scripter scripts
from burp import IScanIssue
class CustomIssue(IScanIssue):
def __init__(self, BasePair, Confidence='Certain', IssueBackground=None, IssueDetail=None, IssueName='Python Scripter generated issue', RemediationBackground=None, RemediationDetail=None, Severity='High'):
self.HttpMessages=[BasePair] # list of HTTP Messages
self.HttpService=BasePair.getHttpService() # HTTP Service
self.Url=BasePair.getUrl() # Java URL
self.Confidence = Confidence # "Certain", "Firm" or "Tentative"
self.IssueBackground = IssueBackground # String or None
self.IssueDetail = IssueDetail # String or None
self.IssueName = IssueName # String
self.IssueType = 134217728 # always "extension generated"
self.RemediationBackground = RemediationBackground # String or None
self.RemediationDetail = RemediationDetail # String or None
self.Severity = Severity # "High", "Medium", "Low", "Information" or "False positive"
def getHttpMessages(self):
return self.HttpMessages
def getHttpService(self):
return self.HttpService
def getUrl(self):
return self.Url
def getConfidence(self):
return self.Confidence
def getIssueBackground(self):
return self.IssueBackground
def getIssueDetail(self):
return self.IssueDetail
def getIssueName(self):
return self.IssueName
def getIssueType(self):
return self.IssueType
def getRemediationBackground(self):
return self.RemediationBackground
def getRemediationDetail(self):
return self.RemediationDetail
def getSeverity(self):
return self.Severity
import sys
# Provides introspection into the Python Scripter API.
# View the output in the Extender tab.
apis = ('extender', 'callbacks', 'helpers', 'toolFlag', 'messageIsRequest', 'messageInfo')
funcs = (type, dir)
if messageIsRequest:
for api in apis:
print '\n{}:\n{}'.format(api, '='*len(api))
for func in funcs:
print '\n{}:\n'.format(func.__name__)
try:
print func(locals()[api])
except Exception as e:
print func(globals()[api])
# ***********************************************
from pyscripter_utils import CustomIssue
import re
import sys
# Adds custom passive audit checks.
# Requires pyscripter_utils.py to be loaded with Burp.
if not messageIsRequest:
if toolFlag in (callbacks.TOOL_PROXY,):
if callbacks.isInScope(messageInfo.getUrl()):
response = messageInfo.getResponse()
# check for autocomplete on form fields
results = re.findall('(<input [^>]*>)', response)
for result in results:
if re.search('type=[\'"]text[\'"]', result) and not re.search('autocomplete', result):
issue = CustomIssue(
BasePair=messageInfo,
IssueName='Text field with autocomplete enabled',
IssueDetail='The following text field has autocomplete enabled:\n\n<ul><li>' + result.replace('<', '&lt;').replace('>', '&gt;') + '</li></ul>',
Severity='Low',
)
callbacks.addScanIssue(issue)
# check for verbose headers
bad_headers = ('server', 'x-powered-by', 'x-aspnet-version')
for header in helpers.analyzeResponse(messageInfo.getResponse()).getHeaders():
name = header.split(':')[0]
if name.lower() in bad_headers:
issue = CustomIssue(
BasePair=messageInfo,
IssueName='Verbose header',
IssueDetail='The following HTTP response header may disclose sensitive information:\n\n<ul><li>' + header + '</li></ul>',
Severity='Low',
)
callbacks.addScanIssue(issue)
# ***********************************************
import re
import sys
# Extracts multiple instances of a REGEX capture group from responses.
try:
if not messageIsRequest:
if toolFlag in (callbacks.TOOL_INTRUDER,):
response = helpers.bytesToString(messageInfo.getResponse())
matches = re.findall('{regex}', response)
for match in matches:
print match
except:
print sys.exc_info()
# ***********************************************
import re
# Replaces the body of a response.
# Great for swapping SPA UI build definitions between user roles.
pattern = r'<regex for response URL>'
body = r'''<new body>'''
if not messageIsRequest:
if toolFlag == callbacks.TOOL_PROXY:
url = messageInfo.url.toString()
if re.search(pattern, url):
headers = helpers.analyzeResponse(messageInfo.getResponse()).getHeaders()
response = helpers.bytesToString(messageInfo.getResponse())
new_response = helpers.buildHttpMessage(headers, helpers.stringToBytes(body))
messageInfo.setResponse(new_response)
print('Response from %s replaced.' % url)
# ***********************************************
import sys
import re
from hashlib import md5
# Overwrites a previously attempted password signature to bypass client-side anti-automation logic.
# Not sure why anyone would do this, but they did, or this wouldn't be a thing.
try:
if messageIsRequest:
if toolFlag in (callbacks.TOOL_INTRUDER,):
request = helpers.bytesToString(messageInfo.getRequest())
if '&nonce=' in request:
nonce = re.search('&nonce=([^&]*)', request).group(1)
password = re.search('&password=([^&]*)', request).group(1)
token = md5(password+nonce).hexdigest()
orig_token = re.search('&token=([^\s]*)', request).group(1)
request = request.replace(orig_token, token)
messageInfo.setRequest(helpers.stringToBytes(request))
except:
print sys.exc_info()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment