forked from zangzhe/burp-suite-extensions
-
Notifications
You must be signed in to change notification settings - Fork 0
/
JSONBeautifier.py
151 lines (122 loc) · 4.43 KB
/
JSONBeautifier.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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
# Burp Extension - JSON Beautifier
# python imports
import json
# burp imports
from burp import IBurpExtender
from burp import IMessageEditorTabFactory
from burp import IMessageEditorTab
from burp import IParameter
from burp import IContextMenuFactory
# Java imports
from javax.swing import JMenuItem
from java.util import List, ArrayList
# Menu items
menuItems = {
False: "Turn JSON active detection on",
True: "Turn JSON active detection off"
}
# Global Switch
_forceJSON = False
# use IBurpExtender for the callback register and helpers functions
# use IMessageEditorTabFactory for creating message editor tab
# use IContextMenuFactory for creating menu item
class BurpExtender(IBurpExtender, IMessageEditorTabFactory, IContextMenuFactory):
# the implement of IBurpExtender's method
def registerExtenderCallbacks(self, callbacks):
print "JSON Beautifier"
# use callbacks
self._callbacks = callbacks
# use helpers
self._helpers = callbacks.getHelpers()
# set extension's name
callbacks.setExtensionName('JSON Beautifier')
# register message editor tab factory
callbacks.registerMessageEditorTabFactory(self)
# register menu item factory
callbacks.registerContextMenuFactory(self)
return
# the implement of message editor tab factory's method, will be invoked
# when see message details
def createNewInstance(self, controller, editable):
## create tab use the user's class
return JSONBeautifierTab(self, controller, editable)
# the implement of menu item factory's method, will be called when
# invoke the menu of burp
def createMenuItems(self, IContextMenuInvocation):
global _forceJSON
# a list for menu items
menuItemList = ArrayList()
# add the items you need, use JMenuItem component, set the name and event
# method
menuItemList.add(JMenuItem(menuItems[_forceJSON], actionPerformed = self.onClick))
return menuItemList
# the menu click event method
def onClick(self, event):
global _forceJSON
_forceJSON = not _forceJSON
# the message editor tab class
class JSONBeautifierTab(IMessageEditorTab):
def __init__(self, extender, controller, editable):
# inherit some methods
self._extender = extender
self._helpers = extender._helpers
self._editable = editable
# we need a text editor under the tab
self._txtInput = extender._callbacks.createTextEditor()
self._txtInput.setEditable(editable)
self._jsonMagicMark = ['{"', '["', '[{']
return
# set tab caption
def getTabCaption(self):
return "JSON Beautifier"
# put the text editor under the tab
def getUiComponent(self):
return self._txtInput .getComponent()
# when invoke a message detail, the method will be used to judge enable
def isEnabled(self, content, isRequest):
global _forceJSON
## a request or a response ?
if isRequest:
r = self._helpers.analyzeRequest(content)
else:
r = self._helpers.analyzeResponse(content)
msg = content[r.getBodyOffset():].tostring()
## use the decoder ?
if not _forceJSON:
return False
## have json data in body ?
if len(msg) > 2 and msg[:2] in self._jsonMagicMark:
print "Forcing JSON parsing and magic mark found: %s"%msg[:2]
return True
## no body content, but the header content-type mark it as json
for header in r.getHeaders():
if header.lower().startswith("content-type:"):
content_type = header.split(":")[1].lower()
if content_type.find("application/json") > 0:
return True
else:
return False
return False
# if isenabled, next will call this method, to process the req/res content
# put needed content in the text editor
def setMessage(self, content, isRequest):
if content is None:
self._txtInput.setText(None)
self._txtInput.setEditable(False)
else:
if isRequest:
r = self._helpers.analyzeRequest(content)
else:
r = self._helpers.analyzeResponse(content)
msg = content[r.getBodyOffset():].tostring()
garbage = msg[:msg.find("{")]
clean = msg[msg.find("{"):]
try:
pretty_msg = garbage + json.dumps(json.loads(clean), indent=4)
except:
print "problem parsing data in setMessage"
pretty_msg = garbage + clean
self._txtInput.setText(pretty_msg)
self._txtInput.setEditable(self._editable)
self._currentMessage = content
return