-
Notifications
You must be signed in to change notification settings - Fork 11
/
Copy pathsaver.py
108 lines (85 loc) · 4.21 KB
/
saver.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# burp extension to save page response content from the site map via a right click
#burp imports
from burp import IBurpExtender
from burp import IContextMenuFactory
#Java imports
from javax.swing import JMenuItem
from java.util import List,ArrayList
from java.net import URL
#python imports
import threading
import os
import sys
from binascii import hexlify
# basedir in which to save responses
baseDir = '/tmp/'
siteMapRetrieve = False # try and rget response data from site map if its not in selected message
class BurpExtender(IBurpExtender,IContextMenuFactory):
def registerExtenderCallbacks(self,callbacks):
self.callbacks = callbacks
self.helpers = callbacks.getHelpers()
self.callbacks.setExtensionName("Item response saver")
self.callbacks.registerContextMenuFactory(self)
self._createIfNotExist(baseDir)
self.stdout = callbacks.getStdout()
self.stderr = callbacks.getStderr()
return
def createMenuItems(self, IContextMenuInvocation):
self.selectedMessages = IContextMenuInvocation.getSelectedMessages()
menuItemList = ArrayList()
menuItemList.add(JMenuItem("Save responses", actionPerformed = self.onClick))
return menuItemList
def _createIfNotExist(self, dir):
if not os.path.isdir(dir):
os.mkdir(dir)
def download(self, messages):
print 'About to save {} requests to disk...'.format(len(messages))
filenames = {}
try:
for message in messages:
srv_a = self.helpers.analyzeRequest(message)
this_url = srv_a.getUrl().toString().split(":")[0] + ":" + srv_a.getUrl().toString().split(":")[1] + "/" + srv_a.getUrl().toString().split(":")[2].split("/",1)[1]
responseInMessage = False
if 'getResponse' in dir(message):
rd = message.getResponse()
if rd:
ar = self.helpers.analyzeResponse(rd)
bo = ar.getBodyOffset()
response = self.helpers.bytesToString(rd)[bo:]
if len(response) > 2:
responseInMessage = True
else:
print 'Response content for {} could not be retrieved from selected message'.format(this_url)
if siteMapRetrieve and not responseInMessage: # response not in message, try and retrieve from site map
sm = self.callbacks.getSiteMap(this_url)
for sme in sm:
srv_b = self.helpers.analyzeRequest(sme)
entry_url = srv_b.getUrl().toString().split(":")[0] + ":" + srv_b.getUrl().toString().split(":")[1] + "/" + srv_b.getUrl().toString().split(":")[2].split("/",1)[1]
if this_url == entry_url:
rd = sme.getResponse()
if rd:
ar = self.helpers.analyzeResponse(rd)
bo = ar.getBodyOffset()
response = self.helpers.bytesToString(rd)[bo:]
if len(response) > 2:
break
bits = [a for a in ("/" + srv_a.getUrl().toString().split(":")[2].split("/",1)[1].split('?')[0]).split('/') if a]
fn = baseDir + '/'.join(bits)
od = baseDir
for di in bits[:-1]:
od = os.path.join(od, di)
self._createIfNotExist(od)
if fn in filenames:
filenames[fn] += 1
fn = '{}_{}'.format(fn, str(filenames[fn]-1))
else:
filenames[fn] = 0
open(fn, 'wb').write(response.encode('utf8'))
except Exception as e:
self.stderr.write('An error occurred: {}'.format(e))
print 'Saved {} requests to disk!'.format(len(messages))
def onClick(self, event):
requests = self.selectedMessages
t = threading.Thread(target=self.download,args=[requests])
t.daemon = True
t.start()