Skip to content

Instantly share code, notes, and snippets.

@thypon
Created January 7, 2022 00:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save thypon/21bd25a36149256115905e5c330ed14d to your computer and use it in GitHub Desktop.
Save thypon/21bd25a36149256115905e5c330ed14d to your computer and use it in GitHub Desktop.
Create a CSV containing all the cookies encountered during a BURP scan
# Author: Andrea Brancaleoni
# Version: 1.0
# License: MIT License
from burp import IBurpExtender
from burp import IHttpListener
from burp import IProxyListener
from burp import IContextMenuFactory
from javax.swing import JMenuItem, JFileChooser
from java.awt.event import ActionListener
from java.lang import System
from java.io import File
from java.io import PrintWriter
import re
import csv
import json
class BurpExtender(IBurpExtender,IContextMenuFactory,ActionListener):
def registerExtenderCallbacks( self, callbacks):
# Keep a reference to our callbacks and helper object
self.callbacks = callbacks
self.helpers = callbacks.getHelpers()
self.stdout = PrintWriter(callbacks.getStdout(), True)
self.callbacks.setExtensionName("GDPR Reporter")
self.stdout.println("GDPR Reporter is loaded")
self.enable_cookiejar()
#IExtensionHelpers helpers = callbacks.getHelpers()
callbacks.registerContextMenuFactory(self)
return
def enable_cookiejar(self):
try:
j = json.loads(self.callbacks.saveConfigAsJson())
j['project_options']['sessions']['cookie_jar']['monitor_extender'] = True
j['project_options']['sessions']['cookie_jar']['monitor_intruder'] = True
j['project_options']['sessions']['cookie_jar']['monitor_proxy'] = True
j['project_options']['sessions']['cookie_jar']['monitor_repeater'] = True
j['project_options']['sessions']['cookie_jar']['monitor_scanner'] = True
j['project_options']['sessions']['cookie_jar']['monitor_sequencer'] = True
self.callbacks.loadConfigFromJson(json.dumps(j))
except Exception as ex:
print("Cannot enable * Cookie Jar! %s" % ex)
finally:
sys.stdout.flush()
sys.stderr.flush()
def prepare_cookies(self):
self.cookies = {}
self.attributes_keys = set()
for r in self.callbacks.getProxyHistory():
reqinfo = self.helpers.analyzeRequest(r)
url = reqinfo.getUrl()
self._process_request(url, reqinfo, r.getRequest())
self._process_reponse(url, self.helpers.analyzeResponse(r.getResponse()), r.getResponse())
for icookie in self.callbacks.getCookieJarContents():
self.add_cookie(icookie.getName(), {"Value": icookie.getValue(), "Domain": icookie.getDomain(), "Path": icookie.getPath(), "Expiration": icookie.getExpiration()}, override=True)
def merge_two_dicts(self, x, y):
z = x.copy() # start with keys and values of x
z.update(y) # modifies z with keys and values of y
return z
def add_cookie(self, cookie, attributes, override=False):
for k in attributes.keys():
self.attributes_keys.add(k)
if not cookie in self.cookies:
self.cookies[cookie] = {}
if override is False:
self.cookies[cookie] = self.merge_two_dicts(attributes, self.cookies[cookie])
else:
self.cookies[cookie] = self.merge_two_dicts(self.cookies[cookie], attributes)
def _process_request(self, url, reqinfo, reqbody):
"""
Process request and extract key values
:param domain:
:param reqinfo:
:param reqbody:
:return:
"""
for h in reqinfo.getHeaders():
if h.lower().startswith("cookie:"):
cookies = h[7:].strip()
for c in cookies.split(';'):
ckey, cvalue = c.strip().split('=')
self.add_cookie(ckey, {'Value': cvalue, 'Domain': url.getHost()})
def _process_reponse(self, url, respinfo, respbody):
"""
Process response and extract key values
:param domain:
:param reqinfo:
:param reqbody:
:return:
"""
for h in respinfo.getHeaders():
if h.lower().startswith("set-cookie:"):
set_cookies = h[11:].strip()
ckey, cvalue = set_cookies.split(';', 1)[0].strip().split("=")
attributes = {'Value': cvalue, 'Domain': url.getHost()}
for s in set_cookies.split(';', 1)[1].strip().split(';'):
if '=' in s:
attrkey, attrvalue = s.strip().split("=")
else:
attrkey = s.strip()
attrvalue = True
attributes[attrkey] = attrvalue
self.add_cookie(ckey, attributes, override=True)
def createMenuItems(self, invocation):
if invocation.getInvocationContext() == invocation.CONTEXT_PROXY_HISTORY:
mymenu = []
item = JMenuItem("Generate GDRP report")
item.addActionListener(self)
mymenu.append(item)
return mymenu
else:
return None
def _directory_picker(self):
"""
Run the filepicker and return if approved
:return: boolean, true if approved
"""
fileChooser = JFileChooser()
fileChooser.setCurrentDirectory(File(System.getProperty("user.home")))
fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY)
result = fileChooser.showOpenDialog(None)
isApproveOption = result == JFileChooser.APPROVE_OPTION
if isApproveOption:
selectedFile = fileChooser.getSelectedFile()
self.write_file(selectedFile.getAbsolutePath())
return isApproveOption
def write_file(self, dname):
attributes = list(self.attributes_keys)
header = ['Cookie Name'] + attributes
with open(dname+"/gdpr.csv", 'w') as f:
writer = csv.writer(f)
# write the header
writer.writerow(header)
for k in self.cookies.keys():
v = self.cookies[k]
row = [k]
for a in attributes:
if a in v:
row += [v[a]]
else:
row += [None]
writer.writerow(row)
def actionPerformed(self, actionEvent):
self.prepare_cookies()
selectedFile = self._directory_picker()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment