├── .gitignore
├── gui
├── __init__.py
├── menu.py
├── interception_filters.py
├── match_replace.py
├── tabs.py
├── save_restore.py
├── configuration_tab.py
├── table.py
├── enforcement_detector.py
└── export.py
├── helpers
├── __init__.py
├── filters.py
├── initiator.py
└── http.py
├── authorization
├── __init__.py
└── authorization.py
├── Autorize.png
├── interceptionFilters.png
├── BappManifest.bmf
├── Autorize.py
├── BappDescription.html
└── README.md
/.gitignore:
--------------------------------------------------------------------------------
1 | *.class
--------------------------------------------------------------------------------
/gui/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/helpers/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/authorization/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Autorize.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PortSwigger/autorize/master/Autorize.png
--------------------------------------------------------------------------------
/interceptionFilters.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PortSwigger/autorize/master/interceptionFilters.png
--------------------------------------------------------------------------------
/BappManifest.bmf:
--------------------------------------------------------------------------------
1 | Uuid: f9bbac8c4acf4aefa4d7dc92a991af2f
2 | ExtensionType: 2
3 | Name: Autorize
4 | RepoName: autorize
5 | ScreenVersion: 1.8.2
6 | SerialVersion: 27
7 | MinPlatformVersion: 0
8 | ProOnly: False
9 | Author: Barak Tawily, AppSec Labs
10 | ShortDescription: Automatically detects authorization enforcement.
11 | EntryPoint: Autorize.py
12 | BuildCommand:
13 | SupportedProducts: Pro, Community
14 |
--------------------------------------------------------------------------------
/Autorize.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | from burp import IBurpExtender, IHttpListener, IProxyListener
5 | from authorization.authorization import handle_message
6 | from helpers.initiator import Initiator
7 | from helpers.filters import handle_proxy_message
8 |
9 | class BurpExtender(IBurpExtender, IHttpListener, IProxyListener):
10 |
11 | def registerExtenderCallbacks(self, callbacks):
12 | self._callbacks = callbacks
13 | self._helpers = callbacks.getHelpers()
14 |
15 | callbacks.setExtensionName("Autorize")
16 |
17 | initiator = Initiator(self)
18 |
19 | initiator.init_constants()
20 |
21 | initiator.draw_all()
22 |
23 | initiator.implement_all()
24 |
25 | initiator.init_ui()
26 |
27 | initiator.print_welcome_message()
28 |
29 | return
30 |
31 | #
32 | # implement IHttpListener
33 | #
34 | def processHttpMessage(self, toolFlag, messageIsRequest, messageInfo):
35 | handle_message(self, toolFlag, messageIsRequest, messageInfo)
36 |
37 | #
38 | # implement IProxyListener
39 | #
40 | def processProxyMessage(self, messageIsRequest, message):
41 | handle_proxy_message(self,message)
42 |
43 |
--------------------------------------------------------------------------------
/BappDescription.html:
--------------------------------------------------------------------------------
1 |
Autorize is an extension aimed at helping the penetration tester to detect
2 | authorization vulnerabilities, one of the more time-consuming tasks in a web
3 | application penetration test.
4 |
5 | It is sufficient to give to the extension the cookies of a low privileged
6 | user and navigate the website with a high privileged user. The extension
7 | automatically repeats every request with the session of the low privileged
8 | user and detects authorization vulnerabilities.
9 |
10 | It is also possible to repeat every request without any
11 | cookies in order to detect authentication vulnerabilities in
12 | addition to authorization ones.
13 |
14 | The plugin works without any configuration, but is also highly
15 | customizable, allowing configuration of the granularity of the authorization
16 | enforcement conditions and also which requests the plugin must test and
17 | which not. It is possible to save the state of the plugin and to export a
18 | report of the authorization tests in HTML or in CSV.
19 |
20 | The reported enforcement statuses are the following:
21 |
22 | - Bypassed! - Red color
23 | - Enforced! - Green color
24 | - Is enforced??? (please configure enforcement detector) - Yellow color
25 |
26 |
--------------------------------------------------------------------------------
/gui/menu.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | from burp import IContextMenuFactory
5 |
6 | from java.util import LinkedList
7 | from javax.swing import JMenuItem
8 | from java.awt.event import ActionListener
9 |
10 | from authorization.authorization import send_request_to_autorize
11 | from helpers.http import get_cookie_header_from_message, get_authorization_header_from_message
12 |
13 | from thread import start_new_thread
14 |
15 | class MenuImpl(IContextMenuFactory):
16 | def __init__(self, extender):
17 | self._extender = extender
18 |
19 | def createMenuItems(self, invocation):
20 | responses = invocation.getSelectedMessages()
21 | if responses > 0:
22 | ret = LinkedList()
23 | requestMenuItem = JMenuItem("Send request to Autorize")
24 | cookieMenuItem = JMenuItem("Send Cookie header to Autorize")
25 | authMenuItem = JMenuItem("Send Authorization header to Autorize")
26 |
27 | for response in responses:
28 | requestMenuItem.addActionListener(HandleMenuItems(self._extender,response, "request"))
29 | cookieMenuItem.addActionListener(HandleMenuItems(self._extender, response, "cookie"))
30 | authMenuItem.addActionListener(HandleMenuItems(self._extender, response, "authorization"))
31 | ret.add(requestMenuItem)
32 | ret.add(cookieMenuItem)
33 | ret.add(authMenuItem)
34 | return ret
35 | return None
36 |
37 | class HandleMenuItems(ActionListener):
38 | def __init__(self, extender, messageInfo, menuName):
39 | self._extender = extender
40 | self._menuName = menuName
41 | self._messageInfo = messageInfo
42 |
43 | def actionPerformed(self, e):
44 | if self._menuName == "request":
45 | start_new_thread(send_request_to_autorize, (self._extender, self._messageInfo,))
46 |
47 | if self._menuName == "cookie":
48 | self._extender.replaceString.setText(get_cookie_header_from_message(self._extender, self._messageInfo))
49 |
50 | if self._menuName == "authorization":
51 | self._extender.replaceString.setText(get_authorization_header_from_message(self._extender, self._messageInfo))
52 |
--------------------------------------------------------------------------------
/helpers/filters.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | from java.awt import GridLayout
5 | from burp import IInterceptedProxyMessage
6 |
7 | def addFilterHelper(typeObj, model, textObj):
8 | typeName = typeObj.getSelectedItem().split(":")[0]
9 | model.addElement(typeName + ": " + textObj.getText().strip())
10 | textObj.setText("")
11 |
12 | def delFilterHelper(listObj):
13 | index = listObj.getSelectedIndex()
14 | if not index == -1:
15 | listObj.getModel().remove(index)
16 |
17 | def modFilterHelper(listObj, typeObj, textObj):
18 | index = listObj.getSelectedIndex()
19 | if not index == -1:
20 | valt = listObj.getSelectedValue()
21 | val = valt.split(":", 1)[1].strip()
22 | modifiedFilter = valt.split(":", 1)[0].strip() + ":"
23 | typeObj.getModel().setSelectedItem(modifiedFilter)
24 | if ("Scope items" not in valt) and ("Content-Len" not in valt):
25 | textObj.setText(val)
26 | listObj.getModel().remove(index)
27 |
28 | def expand(extender, comp):
29 | comp.setSelectedIndex(0)
30 | comp.setTitleAt(2, "Collapse")
31 | extender.requests_panel.remove(extender.modified_requests_tabs)
32 | extender.requests_panel.remove(extender.original_requests_tabs)
33 | extender.requests_panel.remove(extender.unauthenticated_requests_tabs)
34 | extender.requests_panel.add(comp)
35 | extender.requests_panel.setLayout(GridLayout(1,0))
36 | extender.requests_panel.revalidate()
37 | extender.expanded_requests = 1
38 |
39 | def collapse(extender, comp):
40 | comp.setSelectedIndex(0)
41 | comp.setTitleAt(2, "Expand")
42 | extender.requests_panel.setLayout(GridLayout(3,0))
43 | extender.requests_panel.add(extender.modified_requests_tabs)
44 | extender.requests_panel.add(extender.original_requests_tabs)
45 | extender.requests_panel.add(extender.unauthenticated_requests_tabs)
46 | extender.requests_panel.revalidate()
47 | extender.expanded_requests = 0
48 |
49 | def handle_proxy_message(self,message):
50 | currentPort = message.getListenerInterface().split(":")[1]
51 | for i in range(0, self.IFList.getModel().getSize()):
52 | interceptionFilter = self.IFList.getModel().getElementAt(i)
53 | interceptionFilterTitle = interceptionFilter.split(":")[0]
54 | if interceptionFilterTitle == "Drop proxy listener ports":
55 | portsList = interceptionFilter[27:].split(",")
56 | portsList = [int(i) for i in portsList]
57 | if int(currentPort) in portsList:
58 | message.setInterceptAction(IInterceptedProxyMessage.ACTION_DROP)
--------------------------------------------------------------------------------
/helpers/initiator.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | from gui.enforcement_detector import EnforcementDetectors
5 | from gui.interception_filters import InterceptionFilters
6 | from gui.configuration_tab import ConfigurationTab
7 | from gui.match_replace import MatchReplace
8 | from gui.tabs import Tabs, ITabImpl
9 | from gui.table import TableFilter
10 | from gui.export import Export
11 | from gui.menu import MenuImpl
12 |
13 | from java.util import ArrayList
14 | from threading import Lock
15 |
16 | class Initiator():
17 | def __init__(self, extender):
18 | self._extender = extender
19 |
20 | def init_constants(self):
21 | self.contributors = ["Federico Dotta", "mgeeky", "Marcin Woloszyn", "jpginc", "Eric Harris"]
22 | self._extender.version = 1.8
23 | self._extender._log = ArrayList()
24 | self._extender._lock = Lock()
25 |
26 | self._extender.BYPASSSED_STR = "Bypassed!"
27 | self._extender.IS_ENFORCED_STR = "Is enforced??? (please configure enforcement detector)"
28 | self._extender.ENFORCED_STR = "Enforced!"
29 |
30 | self._extender.intercept = 0
31 | self._extender.lastCookiesHeader = ""
32 | self._extender.lastAuthorizationHeader = ""
33 |
34 | self._extender.currentRequestNumber = 1
35 | self._extender.expanded_requests = 0
36 |
37 | def draw_all(self):
38 | interception_filters = InterceptionFilters(self._extender)
39 | interception_filters.draw()
40 |
41 | enforcement_detectors = EnforcementDetectors(self._extender)
42 | enforcement_detectors.draw()
43 | enforcement_detectors.draw_unauthenticated()
44 |
45 | export = Export(self._extender)
46 | export.draw()
47 |
48 | match_replace = MatchReplace(self._extender)
49 | match_replace.draw()
50 |
51 | table_filter = TableFilter(self._extender)
52 | table_filter.draw()
53 |
54 | cfg_tab = ConfigurationTab(self._extender)
55 | cfg_tab.draw()
56 |
57 | tabs = Tabs(self._extender)
58 | tabs.draw()
59 |
60 | def implement_all(self):
61 | itab = ITabImpl(self._extender)
62 | menu = MenuImpl(self._extender)
63 |
64 | self._extender._callbacks.registerContextMenuFactory(menu)
65 | self._extender._callbacks.addSuiteTab(itab)
66 | self._extender._callbacks.registerHttpListener(self._extender)
67 | self._extender._callbacks.registerProxyListener(self._extender)
68 |
69 |
70 | def init_ui(self):
71 | self._extender._callbacks.customizeUiComponent(self._extender._splitpane)
72 | self._extender._callbacks.customizeUiComponent(self._extender.logTable)
73 | self._extender._callbacks.customizeUiComponent(self._extender.scrollPane)
74 | self._extender._callbacks.customizeUiComponent(self._extender.tabs)
75 | self._extender._callbacks.customizeUiComponent(self._extender.filtersTabs)
76 |
77 | def print_welcome_message(self):
78 | print("""Thank you for installing Autorize v{} extension
79 | Created by Barak Tawily
80 | Contributors: {}
81 |
82 | Github:\nhttps://github.com/Quitten/Autorize""".format(self._extender.version, ", ".join(self.contributors)))
83 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Autorize
2 | Autorize is an automatic authorization enforcement detection extension for Burp Suite. It was written in Python by Barak Tawily, an application security expert. Autorize was designed to help security testers by performing automatic authorization tests. With the last release now Autorize also perform automatic authentication tests.
3 |
4 | 
5 |
6 | # Installation
7 | 1. Download Burp Suite (obviously): http://portswigger.net/burp/download.html
8 | 2. Download Jython standalone JAR: http://www.jython.org/download.html
9 | 3. Open burp -> Extender -> Options -> Python Environment -> Select File -> Choose the Jython standalone JAR
10 | 4. Install Autorize from the BApp Store or follow these steps:
11 | 5. Download Autorize source code: `git clone git@github.com:Quitten/Autorize.git`
12 | 6. Open Burp -> Extender -> Extensions -> Add -> Choose Autorize.py file.
13 | 7. See the Autorize tab and enjoy automatic authorization detection :)
14 |
15 |
16 | # User Guide - How to use?
17 | 1. After installation, the Autorize tab will be added to Burp.
18 | 2. Open the configuration tab (Autorize -> Configuration).
19 | 3. Get your low-privileged user authorization token header (Cookie / Authorization) and copy it into the textbox containing the text "Insert injected header here".
20 | **Note**: Headers inserted here will be replaced if present or added if not.
21 | 4. Uncheck "Check unauthenticated" if the authentication test is not required (request without any cookies, to check for authentication enforcement in addition to authorization enforcement with the cookies of low-privileged user)
22 | 5. Check "Intercept requests from Repeater" to also intercept the requests that are sent through the Repeater.
23 | 6. Click on "Intercept is off" to start intercepting the traffic in order to allow Autorize to check for authorization enforcement.
24 | 7. Open a browser and configure the proxy settings so the traffic will be passed to Burp.
25 | 8. Browse to the application you want to test with a high privileged user.
26 | 9. The Autorize table will show you the request's URL and enforcement status.
27 | 10. It is possible to click on a specific URL and see the original/modified/unauthenticated request/response in order to investigate the differences.
28 |
29 |
30 | # Authorization Enforcement Status
31 | There are 3 enforcement statuses:
32 |
33 | 1. Bypassed! - Red color
34 |
35 | 2. Enforced! - Green color
36 |
37 | 3. Is enforced??? (please configure enforcement detector) - Yellow color
38 |
39 | The first 2 statuses are clear, so I won't elaborate on them.
40 |
41 | The 3rd status means that Autorize cannot determine if authorization is enforced or not, and so Autorize will ask you to configure a filter in the enforcement detector tabs. There are two different enforcement detector tabs, one for the detection of the enforcement of low-privileged requests and one for the detection of the enforcement of unauthenticated requests.
42 |
43 | The enforcement detector filters will allow Autorize to detect authentication and authorization enforcement in the response of the server by content length or string (literal string or regex) in the message body, headers or in the full request.
44 |
45 | For example, if there is a request enforcement status that is detected as "Authorization enforced??? (please configure enforcement detector)" it is possible to investigate the modified/original/unauthenticated response and see that the modified response body includes the string "You are not authorized to perform action", so you can add a filter with the fingerprint value "You are not authorized to perform action", so Autorize will look for this fingerprint and will automatically detect that authorization is enforced. It is possible to do the same by defining content-length filter or fingerprint in headers.
46 |
47 | # Interception Filters
48 | The interception filter allows you configure what domains you want to be intercepted by Autorize plugin, you can determine by blacklist/whitelist/regex or items in Burp's scope in order to avoid unnecessary domains to be intercepted by Autorize and work more organized.
49 |
50 | Example of interception filters (Note that there is default filter to avoid scripts and images):
51 | 
52 |
53 |
54 | # Authors
55 | - Barak Tawily, CTO @ [enso.security](https://enso.security/) by day, [Application Security Researcher](https://quitten.github.io/) by night, former Application Security Consultant @ [AppSec Labs](https://appsec-labs.com/)
56 |
--------------------------------------------------------------------------------
/helpers/http.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | import re
5 | from burp import IHttpRequestResponse
6 |
7 | def isStatusCodesReturned(self, messageInfo, statusCodes):
8 | firstHeader = self._helpers.analyzeResponse(messageInfo.getResponse()).getHeaders()[0]
9 | if type(statusCodes) == list:
10 | for statusCode in statusCodes:
11 | if statusCode in firstHeader:
12 | return True
13 | elif type(statusCodes) == str or type(statusCodes) == unicode:
14 | # single status code
15 | if statusCodes in firstHeader:
16 | return True
17 | return False
18 |
19 | def makeRequest(self, messageInfo, message):
20 | requestURL = self._helpers.analyzeRequest(messageInfo).getUrl()
21 | return self._callbacks.makeHttpRequest(self._helpers.buildHttpService(str(requestURL.getHost()), int(requestURL.getPort()), requestURL.getProtocol() == "https"), message)
22 |
23 | def makeMessage(self, messageInfo, removeOrNot, authorizeOrNot):
24 | requestInfo = self._helpers.analyzeRequest(messageInfo)
25 | headers = requestInfo.getHeaders()
26 | if removeOrNot:
27 | headers = list(headers)
28 | # flag for query
29 | queryFlag = self.replaceQueryParam.isSelected()
30 | if queryFlag:
31 | param = self.replaceString.getText().split("=")
32 | paramKey = param[0]
33 | paramValue = param[1]
34 | # ([\?&])test=.*?(?=[\s&])
35 | pattern = r"([\?&]){}=.*?(?=[\s&])".format(paramKey)
36 | patchedHeader = re.sub(pattern, r"\1{}={}".format(paramKey, paramValue), headers[0], count=1, flags=re.DOTALL)
37 | headers[0] = patchedHeader
38 | else:
39 | removeHeaders = self.replaceString.getText()
40 |
41 | # Headers must be entered line by line i.e. each header in a new
42 | # line
43 | removeHeaders = [header for header in removeHeaders.split() if header.endswith(':')]
44 |
45 | for header in headers[:]:
46 | for removeHeader in removeHeaders:
47 | if header.lower().startswith(removeHeader.lower()):
48 | headers.remove(header)
49 |
50 | if authorizeOrNot:
51 | # simple string replace
52 | for k, v in self.badProgrammerMRModel.items():
53 | if(v["type"] == "Headers (simple string):"):
54 | headers = map(lambda h: h.replace(v["match"], v["replace"]), headers)
55 | if(v["type"] == "Headers (regex):") :
56 | headers = map(lambda h: re.sub(v["regexMatch"], v["replace"], h), headers)
57 |
58 | if not queryFlag:
59 | # fix missing carriage return on *NIX systems
60 | replaceStringLines = self.replaceString.getText().split("\n")
61 | for h in replaceStringLines:
62 | if h == "": # Logic to fix extraneous newline at the end of requests when no temporary headers are added
63 | pass
64 | else:
65 | headers.append(h)
66 |
67 | msgBody = messageInfo.getRequest()[requestInfo.getBodyOffset():]
68 |
69 | # apply the match/replace settings to the body of the request
70 | if authorizeOrNot and msgBody is not None:
71 | msgBody = self._helpers.bytesToString(msgBody)
72 | # simple string replace
73 | for k, v in self.badProgrammerMRModel.items():
74 | if(v["type"] == "Body (simple string):") :
75 | msgBody = msgBody.replace(v["match"], v["replace"])
76 | if(v["type"] == "Body (regex):") :
77 | msgBody = re.sub(v["regexMatch"], v["replace"], msgBody)
78 | msgBody = self._helpers.stringToBytes(msgBody)
79 | return self._helpers.buildHttpMessage(headers, msgBody)
80 |
81 | def getResponseHeaders(self, requestResponse):
82 | analyzedResponse = self._helpers.analyzeResponse(requestResponse.getResponse())
83 | return self._helpers.bytesToString(requestResponse.getResponse()[0:analyzedResponse.getBodyOffset()])
84 |
85 | def getResponseBody(self, requestResponse):
86 | analyzedResponse = self._helpers.analyzeResponse(requestResponse.getResponse())
87 | return self._helpers.bytesToString(requestResponse.getResponse()[analyzedResponse.getBodyOffset():])
88 |
89 | def getResponseContentLength(self, response):
90 | return len(response) - self._helpers.analyzeResponse(response).getBodyOffset()
91 |
92 | def get_cookie_header_from_message(self, messageInfo):
93 | headers = list(self._helpers.analyzeRequest(messageInfo.getRequest()).getHeaders())
94 | for header in headers:
95 | if header.strip().lower().startswith("cookie:"):
96 | return header
97 | return None
98 |
99 | def get_authorization_header_from_message(self, messageInfo):
100 | headers = list(self._helpers.analyzeRequest(messageInfo.getRequest()).getHeaders())
101 | for header in headers:
102 | if header.strip().lower().startswith("authorization:"):
103 | return header
104 | return None
105 |
106 | class IHttpRequestResponseImplementation(IHttpRequestResponse):
107 | def __init__(self, service, req, res):
108 | self._httpService = service
109 | self._request = req
110 | self._response = res
111 | self._comment = None
112 | self._highlight = None
113 |
114 | def getComment(self):
115 | return self._comment
116 |
117 | def getHighlight(self):
118 | return self._highlight
119 |
120 | def getHttpService(self):
121 | return self._httpService
122 |
123 | def getRequest(self):
124 | return self._request
125 |
126 | def getResponse(self):
127 | return self._response
128 |
129 | def setComment(self,c):
130 | self._comment = c
131 |
132 | def setHighlight(self,h):
133 | self._highlight = h
134 |
135 | def setHttpService(self,service):
136 | self._httpService = service
137 |
138 | def setRequest(self,req):
139 | self._request = req
140 |
141 | def setResponse(self,res):
142 | self._response = res
143 |
--------------------------------------------------------------------------------
/gui/interception_filters.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | import sys
5 | sys.path.append("..")
6 |
7 | from javax.swing import JList
8 | from javax.swing import JLabel
9 | from javax.swing import JPanel
10 | from javax.swing import JButton
11 | from javax.swing import JComboBox
12 | from javax.swing import JTextArea
13 | from javax.swing import JScrollPane
14 | from javax.swing import GroupLayout
15 | from javax.swing import DefaultListModel
16 | from javax.swing.border import LineBorder
17 | from helpers.filters import addFilterHelper, delFilterHelper, modFilterHelper
18 |
19 |
20 | class InterceptionFilters():
21 | def __init__(self, extender):
22 | self._extender = extender
23 |
24 | def draw(self):
25 | """ init interception filters tab
26 | """
27 | self._extender.savedHeaders = [{"title": "Temporary headers", "headers": "Cookie: Insert=injected; cookie=or;\nHeader: here"}]
28 | # IFStrings has to contains : character
29 | IFStrings = ["Scope items only: (Content is not required)",
30 | "URL Contains (simple string): ",
31 | "URL Contains (regex): ",
32 | "URL Not Contains (simple string): ",
33 | "URL Not Contains (regex): ",
34 | "Request Body contains (simple string): ",
35 | "Request Body contains (regex): ",
36 | "Request Body NOT contains (simple string): ",
37 | "Request Body Not contains (regex): ",
38 | "Response Body contains (simple string): ",
39 | "Response Body contains (regex): ",
40 | "Response Body NOT contains (simple string): ",
41 | "Response Body Not contains (regex): ",
42 | "Header contains: ",
43 | "Header doesn't contain: ",
44 | "Only HTTP methods (newline separated): ",
45 | "Ignore HTTP methods (newline separated): ",
46 | "Ignore spider requests: (Content is not required)",
47 | "Ignore proxy requests: (Content is not required)",
48 | "Ignore target requests: (Content is not required)",
49 | "Ignore OPTIONS requests: (Content is not required)",
50 | "Drop proxy listener ports: (Separated by comma)"
51 | ]
52 | self._extender.IFType = JComboBox(IFStrings)
53 | self._extender.IFType.setBounds(80, 10, 430, 30)
54 |
55 | self._extender.IFModel = DefaultListModel()
56 | self._extender.IFList = JList(self._extender.IFModel)
57 | self._extender.IFList.setPrototypeCellValue("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
58 |
59 | scrollIFList = JScrollPane(self._extender.IFList)
60 | scrollIFList.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED)
61 | scrollIFList.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED)
62 | scrollIFList.setBounds(80, 175, 300, 110)
63 |
64 | # Adding some default interception filters
65 | # self.IFModel.addElement("Scope items only: (Content is not required)") # commented for better first impression.
66 | self._extender.IFModel.addElement("URL Not Contains (regex): (\\.js|\\.css|\\.png|\\.jpg|\\.svg|\\.jpeg|\\.gif|\\.woff|\\.map|\\.bmp|\\.ico)(?![a-z]+)[?]*[\S]*$")
67 | self._extender.IFModel.addElement("Ignore spider requests: ")
68 |
69 | self._extender.IFText = JTextArea("", 5, 30)
70 |
71 | scrollIFText = JScrollPane(self._extender.IFText)
72 | scrollIFText.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED)
73 | scrollIFText.setBounds(80, 50, 300, 110)
74 |
75 | IFLType = JLabel("Type:")
76 | IFLType.setBounds(10, 10, 140, 30)
77 |
78 | IFLContent = JLabel("Content:")
79 | IFLContent.setBounds(10, 50, 140, 30)
80 |
81 | IFLabelList = JLabel("Filter List:")
82 | IFLabelList.setBounds(10, 165, 140, 30)
83 |
84 | self._extender.IFAdd = JButton("Add filter", actionPerformed=self.addIFFilter)
85 | self._extender.IFAdd.setBounds(390, 85, 120, 30)
86 | self._extender.IFDel = JButton("Remove filter", actionPerformed=self.delIFFilter)
87 | self._extender.IFDel.setBounds(390, 210, 120, 30)
88 | self._extender.IFMod = JButton("Modify filter", actionPerformed=self.modIFFilter)
89 | self._extender.IFMod.setBounds(390, 250, 120, 30)
90 |
91 | self._extender.filtersPnl = JPanel()
92 | layout = GroupLayout(self._extender.filtersPnl)
93 | self._extender.filtersPnl.setLayout(layout)
94 | layout.setAutoCreateGaps(True)
95 | layout.setAutoCreateContainerGaps(True)
96 |
97 | layout.setHorizontalGroup(layout.createSequentialGroup()
98 | .addGroup(
99 | layout.createParallelGroup()
100 | .addComponent(
101 | IFLType,
102 | GroupLayout.PREFERRED_SIZE,
103 | GroupLayout.PREFERRED_SIZE,
104 | GroupLayout.PREFERRED_SIZE,
105 | )
106 | .addComponent(
107 | IFLContent,
108 | GroupLayout.PREFERRED_SIZE,
109 | GroupLayout.PREFERRED_SIZE,
110 | GroupLayout.PREFERRED_SIZE,
111 | )
112 | .addComponent(
113 | IFLabelList,
114 | GroupLayout.PREFERRED_SIZE,
115 | GroupLayout.PREFERRED_SIZE,
116 | GroupLayout.PREFERRED_SIZE,
117 | )
118 | )
119 | .addGroup(
120 | layout.createParallelGroup()
121 | .addComponent(
122 | self._extender.IFType,
123 | GroupLayout.PREFERRED_SIZE,
124 | GroupLayout.PREFERRED_SIZE,
125 | GroupLayout.PREFERRED_SIZE,
126 | )
127 | .addComponent(
128 | scrollIFText,
129 | GroupLayout.PREFERRED_SIZE,
130 | GroupLayout.PREFERRED_SIZE,
131 | GroupLayout.PREFERRED_SIZE,
132 | )
133 | .addComponent(
134 | scrollIFList,
135 | GroupLayout.PREFERRED_SIZE,
136 | GroupLayout.PREFERRED_SIZE,
137 | GroupLayout.PREFERRED_SIZE,
138 | )
139 | .addComponent(
140 | self._extender.IFAdd,
141 | GroupLayout.PREFERRED_SIZE,
142 | GroupLayout.PREFERRED_SIZE,
143 | GroupLayout.PREFERRED_SIZE,
144 | )
145 | .addGroup(
146 | layout.createSequentialGroup()
147 | .addComponent(
148 | self._extender.IFDel,
149 | GroupLayout.PREFERRED_SIZE,
150 | GroupLayout.PREFERRED_SIZE,
151 | GroupLayout.PREFERRED_SIZE,
152 | )
153 | .addComponent(
154 | self._extender.IFMod,
155 | GroupLayout.PREFERRED_SIZE,
156 | GroupLayout.PREFERRED_SIZE,
157 | GroupLayout.PREFERRED_SIZE,
158 | )
159 | )
160 | )
161 | )
162 |
163 |
164 | layout.setVerticalGroup(layout.createSequentialGroup()
165 | .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
166 | .addComponent(
167 | IFLType,
168 | GroupLayout.PREFERRED_SIZE,
169 | GroupLayout.PREFERRED_SIZE,
170 | GroupLayout.PREFERRED_SIZE,
171 | )
172 | .addComponent(
173 | self._extender.IFType,
174 | GroupLayout.PREFERRED_SIZE,
175 | GroupLayout.PREFERRED_SIZE,
176 | GroupLayout.PREFERRED_SIZE,
177 | )
178 | )
179 | .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
180 | .addComponent(
181 | IFLContent,
182 | GroupLayout.PREFERRED_SIZE,
183 | GroupLayout.PREFERRED_SIZE,
184 | GroupLayout.PREFERRED_SIZE,
185 | )
186 | .addComponent(
187 | scrollIFText,
188 | GroupLayout.PREFERRED_SIZE,
189 | GroupLayout.PREFERRED_SIZE,
190 | GroupLayout.PREFERRED_SIZE,
191 | )
192 | )
193 | .addComponent(
194 | self._extender.IFAdd,
195 | GroupLayout.PREFERRED_SIZE,
196 | GroupLayout.PREFERRED_SIZE,
197 | GroupLayout.PREFERRED_SIZE,
198 | )
199 | .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
200 | .addComponent(
201 | IFLabelList,
202 | GroupLayout.PREFERRED_SIZE,
203 | GroupLayout.PREFERRED_SIZE,
204 | GroupLayout.PREFERRED_SIZE,
205 | )
206 | .addComponent(
207 | scrollIFList,
208 | GroupLayout.PREFERRED_SIZE,
209 | GroupLayout.PREFERRED_SIZE,
210 | GroupLayout.PREFERRED_SIZE,
211 | )
212 | )
213 | .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
214 | .addComponent(
215 | self._extender.IFDel,
216 | GroupLayout.PREFERRED_SIZE,
217 | GroupLayout.PREFERRED_SIZE,
218 | GroupLayout.PREFERRED_SIZE,
219 | )
220 | .addComponent(
221 | self._extender.IFMod,
222 | GroupLayout.PREFERRED_SIZE,
223 | GroupLayout.PREFERRED_SIZE,
224 | GroupLayout.PREFERRED_SIZE,
225 | )
226 | )
227 | )
228 |
229 |
230 |
231 |
232 |
233 | def addIFFilter(self, event):
234 | addFilterHelper(self._extender.IFType, self._extender.IFModel, self._extender.IFText)
235 |
236 | def delIFFilter(self, event):
237 | delFilterHelper(self._extender.IFList)
238 |
239 | def modIFFilter(self, event):
240 | modFilterHelper(self._extender.IFList, self._extender.IFType, self._extender.IFText)
241 |
--------------------------------------------------------------------------------
/gui/match_replace.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | from java.awt import Color
5 | from javax.swing import JList
6 | from javax.swing import JPanel
7 | from javax.swing import JLabel
8 | from javax.swing import JButton
9 | from javax.swing import JComboBox
10 | from javax.swing import JTextArea
11 | from javax.swing import JScrollPane
12 | from javax.swing import GroupLayout
13 | from javax.swing import DefaultListModel
14 | from javax.swing.border import LineBorder
15 |
16 | import re
17 |
18 | class MatchReplace():
19 | def __init__(self, extender):
20 | self._extender = extender
21 |
22 | def draw(self):
23 | """ init the match/replace tab
24 | """
25 | #todo add an option to ignore large requests
26 | padding = 5
27 | labelWidth = 140
28 | labelHeight = 30
29 | editHeight = 110
30 | editWidth = 300
31 | buttonWidth = 120
32 | buttonHeight = 30
33 | column1X = 10
34 | column2X = column1X + labelWidth + padding
35 | column3X = column2X + editWidth + padding
36 | MRStrings = ["Headers (simple string):",
37 | "Headers (regex):",
38 | "Body (simple string):",
39 | "Body (regex):"]
40 | row1Y = 10
41 | row2Y = row1Y + labelHeight + padding
42 | row3Y = row2Y + editHeight + padding
43 | row4Y = row3Y + editHeight + padding
44 | row5Y = row4Y + labelHeight + padding
45 | row6Y = row5Y + buttonHeight + padding
46 |
47 | MRTypeLabel = JLabel("Type:")
48 | MRTypeLabel.setBounds(column1X, row1Y, labelWidth, labelHeight)
49 |
50 | MContent = JLabel("Match:")
51 | MContent.setBounds(column1X, row2Y, labelWidth, labelHeight)
52 |
53 | RContent = JLabel("Replace:")
54 | RContent.setBounds(column1X, row3Y, labelWidth, labelHeight)
55 |
56 | MRLabelList = JLabel("Filter List:")
57 | MRLabelList.setBounds(column1X, row5Y, labelWidth, labelHeight)
58 |
59 | self._extender.MRType = JComboBox(MRStrings)
60 | self._extender.MRType.setBounds(column2X, row1Y, editWidth, labelHeight)
61 |
62 | self._extender.MText = JTextArea("", 5, 30)
63 | scrollMText = JScrollPane(self._extender.MText)
64 | scrollMText.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED)
65 | scrollMText.setBounds(column2X, row2Y, editWidth, editHeight)
66 |
67 | self._extender.RText = JTextArea("", 5, 30)
68 | scrollRText = JScrollPane(self._extender.RText)
69 | scrollRText.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED)
70 | scrollRText.setBounds(column2X, row3Y, editWidth, editHeight)
71 |
72 | # i couldn't figure out how to have a model that contained anythin other than a string
73 | # so i'll use 2 models, one with the data and one for the JList
74 | self._extender.badProgrammerMRModel = {}
75 | self._extender.MRModel = DefaultListModel()
76 | self._extender.MRList = JList(self._extender.MRModel)
77 |
78 | scrollMRList = JScrollPane(self._extender.MRList)
79 | scrollMRList.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED)
80 | scrollMRList.setBounds(column2X, row5Y, editWidth, editHeight)
81 | scrollMRList.setBorder(LineBorder(Color.BLACK))
82 |
83 | self._extender.MRAdd = JButton("Add filter", actionPerformed=self.addMRFilter)
84 | self._extender.MRAdd.setBounds(column2X, row4Y, buttonWidth, buttonHeight)
85 | self._extender.MRDel = JButton("Remove filter", actionPerformed=self.delMRFilter)
86 | self._extender.MRDel.setBounds(column3X, row5Y, buttonWidth, buttonHeight)
87 | self._extender.MRMod = JButton("Modify filter", actionPerformed=self.modMRFilter)
88 | self._extender.MRMod.setBounds(column3X, row5Y + buttonHeight + padding, buttonWidth, buttonHeight)
89 |
90 | self._extender.MRFeedback = JLabel("")
91 | self._extender.MRFeedback.setBounds(column1X, row6Y, column3X + buttonWidth, labelHeight)
92 |
93 | self._extender.MRPnl = JPanel()
94 | layout = GroupLayout(self._extender.MRPnl)
95 | self._extender.MRPnl.setLayout(layout)
96 | layout.setAutoCreateGaps(True)
97 | layout.setAutoCreateContainerGaps(True)
98 |
99 | layout.setHorizontalGroup(layout.createSequentialGroup()
100 | .addGroup(layout.createParallelGroup()
101 | .addComponent(
102 | MRTypeLabel,
103 | GroupLayout.PREFERRED_SIZE,
104 | GroupLayout.PREFERRED_SIZE,
105 | GroupLayout.PREFERRED_SIZE,
106 | )
107 | .addComponent(
108 | MContent,
109 | GroupLayout.PREFERRED_SIZE,
110 | GroupLayout.PREFERRED_SIZE,
111 | GroupLayout.PREFERRED_SIZE,
112 | )
113 | .addComponent(
114 | RContent,
115 | GroupLayout.PREFERRED_SIZE,
116 | GroupLayout.PREFERRED_SIZE,
117 | GroupLayout.PREFERRED_SIZE,
118 | )
119 | .addComponent(
120 | MRLabelList,
121 | GroupLayout.PREFERRED_SIZE,
122 | GroupLayout.PREFERRED_SIZE,
123 | GroupLayout.PREFERRED_SIZE,
124 | )
125 | )
126 | .addGroup(layout.createParallelGroup()
127 | .addComponent(
128 | self._extender.MRType,
129 | GroupLayout.PREFERRED_SIZE,
130 | GroupLayout.PREFERRED_SIZE,
131 | GroupLayout.PREFERRED_SIZE,
132 | )
133 | .addComponent(
134 | scrollMText,
135 | GroupLayout.PREFERRED_SIZE,
136 | GroupLayout.PREFERRED_SIZE,
137 | GroupLayout.PREFERRED_SIZE,
138 | )
139 | .addComponent(
140 | scrollRText,
141 | GroupLayout.PREFERRED_SIZE,
142 | GroupLayout.PREFERRED_SIZE,
143 | GroupLayout.PREFERRED_SIZE,
144 | )
145 | .addComponent(
146 | self._extender.MRAdd,
147 | GroupLayout.PREFERRED_SIZE,
148 | GroupLayout.PREFERRED_SIZE,
149 | GroupLayout.PREFERRED_SIZE,
150 | )
151 | .addComponent(
152 | self._extender.MRFeedback,
153 | GroupLayout.PREFERRED_SIZE,
154 | GroupLayout.PREFERRED_SIZE,
155 | GroupLayout.PREFERRED_SIZE,
156 | )
157 | .addComponent(
158 | scrollMRList,
159 | GroupLayout.PREFERRED_SIZE,
160 | GroupLayout.PREFERRED_SIZE,
161 | GroupLayout.PREFERRED_SIZE,
162 | )
163 | .addComponent(
164 | self._extender.MRMod,
165 | GroupLayout.PREFERRED_SIZE,
166 | GroupLayout.PREFERRED_SIZE,
167 | GroupLayout.PREFERRED_SIZE,
168 | )
169 | .addComponent(
170 | self._extender.MRDel,
171 | GroupLayout.PREFERRED_SIZE,
172 | GroupLayout.PREFERRED_SIZE,
173 | GroupLayout.PREFERRED_SIZE,
174 | )
175 | )
176 | )
177 |
178 | layout.setVerticalGroup(layout.createSequentialGroup()
179 | .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
180 | .addComponent(
181 | MRTypeLabel,
182 | GroupLayout.PREFERRED_SIZE,
183 | GroupLayout.PREFERRED_SIZE,
184 | GroupLayout.PREFERRED_SIZE,
185 | )
186 | .addComponent(
187 | self._extender.MRType,
188 | GroupLayout.PREFERRED_SIZE,
189 | GroupLayout.PREFERRED_SIZE,
190 | GroupLayout.PREFERRED_SIZE,
191 | )
192 | )
193 | .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
194 | .addComponent(
195 | MContent,
196 | GroupLayout.PREFERRED_SIZE,
197 | GroupLayout.PREFERRED_SIZE,
198 | GroupLayout.PREFERRED_SIZE,
199 | )
200 | .addComponent(
201 | scrollMText,
202 | GroupLayout.PREFERRED_SIZE,
203 | GroupLayout.PREFERRED_SIZE,
204 | GroupLayout.PREFERRED_SIZE,
205 | )
206 | )
207 | .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
208 | .addComponent(
209 | RContent,
210 | GroupLayout.PREFERRED_SIZE,
211 | GroupLayout.PREFERRED_SIZE,
212 | GroupLayout.PREFERRED_SIZE,
213 | )
214 | .addComponent(
215 | scrollRText,
216 | GroupLayout.PREFERRED_SIZE,
217 | GroupLayout.PREFERRED_SIZE,
218 | GroupLayout.PREFERRED_SIZE,
219 | )
220 | )
221 | .addGroup(layout.createSequentialGroup()
222 | .addComponent(
223 | self._extender.MRAdd,
224 | GroupLayout.PREFERRED_SIZE,
225 | GroupLayout.PREFERRED_SIZE,
226 | GroupLayout.PREFERRED_SIZE,
227 | )
228 | .addComponent(
229 | self._extender.MRFeedback,
230 | GroupLayout.PREFERRED_SIZE,
231 | GroupLayout.PREFERRED_SIZE,
232 | GroupLayout.PREFERRED_SIZE,
233 | )
234 | )
235 | .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
236 | .addComponent(
237 | MRLabelList,
238 | GroupLayout.PREFERRED_SIZE,
239 | GroupLayout.PREFERRED_SIZE,
240 | GroupLayout.PREFERRED_SIZE,
241 | )
242 | .addComponent(
243 | scrollMRList,
244 | GroupLayout.PREFERRED_SIZE,
245 | GroupLayout.PREFERRED_SIZE,
246 | GroupLayout.PREFERRED_SIZE,
247 | )
248 | )
249 | .addComponent(
250 | self._extender.MRMod,
251 | GroupLayout.PREFERRED_SIZE,
252 | GroupLayout.PREFERRED_SIZE,
253 | GroupLayout.PREFERRED_SIZE,
254 | )
255 | .addComponent(
256 | self._extender.MRDel,
257 | GroupLayout.PREFERRED_SIZE,
258 | GroupLayout.PREFERRED_SIZE,
259 | GroupLayout.PREFERRED_SIZE,
260 | )
261 | )
262 |
263 | def addMRFilter(self, event):
264 | typeName = self._extender.MRType.getSelectedItem()
265 | match = self._extender.MText.getText()
266 | replace = self._extender.RText.getText()
267 | key = typeName + " " + match + "->" + replace
268 | if key in self._extender.badProgrammerMRModel:
269 | self._extender.MRFeedback.setText("Match/Replace already exists")
270 | return
271 |
272 | regexMatch = None
273 | try:
274 | if "(regex)" in typeName:
275 | regexMatch = re.compile(match)
276 | except re.error:
277 | self._extender.MRFeedback.setText("ERROR: Invalid regex")
278 | return
279 | self._extender.badProgrammerMRModel[key] = {"match": match, "regexMatch": regexMatch, "replace" : replace, "type": typeName}
280 | self._extender.MRModel.addElement(key)
281 | self._extender.MText.setText("")
282 | self._extender.RText.setText("")
283 | self._extender.MRFeedback.setText("")
284 |
285 | def delMRFilter(self, event):
286 | index = self._extender.MRList.getSelectedIndex()
287 | if not index == -1:
288 | key = self._extender.MRList.getSelectedValue()
289 | del self._extender.badProgrammerMRModel[key]
290 | self._extender.MRList.getModel().remove(index)
291 |
292 | def modMRFilter(self, event):
293 | index = self._extender.MRList.getSelectedIndex()
294 | if not index == -1:
295 | key = self._extender.MRList.getSelectedValue()
296 | self._extender.MRType.getModel().setSelectedItem(self._extender.badProgrammerMRModel[key]["type"])
297 | self._extender.MText.setText(self._extender.badProgrammerMRModel[key]["match"])
298 | self._extender.RText.setText(self._extender.badProgrammerMRModel[key]["replace"])
299 | self.delMRFilter(event)
300 |
--------------------------------------------------------------------------------
/gui/tabs.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | from java.awt.datatransfer import StringSelection
5 | from javax.swing.table import TableRowSorter
6 | from java.awt.event import AdjustmentListener
7 | from java.awt.event import ActionListener
8 | from java.awt.event import MouseAdapter
9 | from javax.swing import JSplitPane
10 | from javax.swing import JMenuItem
11 | from javax.swing import JScrollPane
12 | from javax.swing import JPopupMenu
13 | from javax.swing import JTabbedPane
14 | from javax.swing import JPanel
15 | from java.awt import GridLayout
16 | from java.awt import Toolkit
17 | from java.lang import Math
18 | from java.awt import Dimension
19 |
20 | from burp import ITab
21 | from burp import IMessageEditorController
22 |
23 | from authorization.authorization import handle_message, retestAllRequests
24 |
25 | from thread import start_new_thread
26 |
27 | from table import Table, TableRowFilter
28 | from helpers.filters import expand, collapse
29 | from javax.swing import KeyStroke
30 | from javax.swing import JTable
31 | from javax.swing import AbstractAction
32 | from java.awt.event import KeyEvent
33 | from java.awt.event import InputEvent
34 | from javax.swing import SwingUtilities
35 |
36 | class ITabImpl(ITab):
37 | def __init__(self, extender):
38 | self._extender = extender
39 |
40 | def getTabCaption(self):
41 | return "Autorize"
42 |
43 | def getUiComponent(self):
44 | return self._extender._splitpane
45 |
46 | class Tabs():
47 | def __init__(self, extender):
48 | self._extender = extender
49 |
50 | def draw(self):
51 | """ init autorize tabs
52 | """
53 |
54 | self._extender.logTable = Table(self._extender)
55 |
56 | tableWidth = self._extender.logTable.getPreferredSize().width
57 | self._extender.logTable.getColumn("ID").setPreferredWidth(Math.round(tableWidth / 50 * 2))
58 | self._extender.logTable.getColumn("Method").setPreferredWidth(Math.round(tableWidth / 50 * 3))
59 | self._extender.logTable.getColumn("URL").setPreferredWidth(Math.round(tableWidth / 50 * 25))
60 | self._extender.logTable.getColumn("Orig. Len").setPreferredWidth(Math.round(tableWidth / 50 * 4))
61 | self._extender.logTable.getColumn("Modif. Len").setPreferredWidth(Math.round(tableWidth / 50 * 4))
62 | self._extender.logTable.getColumn("Unauth. Len").setPreferredWidth(Math.round(tableWidth / 50 * 4))
63 | self._extender.logTable.getColumn("Authz. Status").setPreferredWidth(Math.round(tableWidth / 50 * 4))
64 | self._extender.logTable.getColumn("Unauth. Status").setPreferredWidth(Math.round(tableWidth / 50 * 4))
65 |
66 | self._extender.tableSorter = TableRowSorter(self._extender.tableModel)
67 | rowFilter = TableRowFilter(self._extender)
68 | self._extender.tableSorter.setRowFilter(rowFilter)
69 | self._extender.logTable.setRowSorter(self._extender.tableSorter)
70 |
71 | self._extender._splitpane = JSplitPane(JSplitPane.HORIZONTAL_SPLIT)
72 | self._extender._splitpane.setResizeWeight(1)
73 | self._extender.scrollPane = JScrollPane(self._extender.logTable)
74 | self._extender.scrollPane.setMinimumSize(Dimension(1,1))
75 | self._extender._splitpane.setLeftComponent(self._extender.scrollPane)
76 | self._extender.scrollPane.getVerticalScrollBar().addAdjustmentListener(AutoScrollListener(self._extender))
77 |
78 | copyURLitem = JMenuItem("Copy URL")
79 | copyURLitem.addActionListener(CopySelectedURL(self._extender))
80 |
81 | sendRequestMenu = JMenuItem("Send Original Request to Repeater")
82 | sendRequestMenu.addActionListener(SendRequestRepeater(self._extender, self._extender._callbacks, True))
83 |
84 | sendRequestMenu2 = JMenuItem("Send Modified Request to Repeater")
85 | sendRequestMenu2.addActionListener(SendRequestRepeater(self._extender, self._extender._callbacks, False))
86 |
87 | # Define the key combination for the shortcut
88 | try:
89 | # The keystroke combo is: Mac -> Command + r / Windows control + r
90 | # This is used to send to the repeater function in burp
91 | controlR = KeyStroke.getKeyStroke(KeyEvent.VK_R, Toolkit.getDefaultToolkit().getMenuShortcutKeyMaskEx())
92 | except:
93 | controlR = KeyStroke.getKeyStroke(KeyEvent.VK_R, InputEvent.CTRL_DOWN_MASK)
94 |
95 | # The keystroke combo is: Mac -> Command + c / Windows control + c
96 | # This is used to copy the URL to the keyboard.
97 | controlC = KeyStroke.getKeyStroke(KeyEvent.VK_C, InputEvent.META_DOWN_MASK)
98 |
99 | # Get the input and action maps for the JTable
100 | inputMap = self._extender.logTable.getInputMap(JTable.WHEN_FOCUSED)
101 | actionMap = self._extender.logTable.getActionMap()
102 |
103 | # Bind the key combination to the action
104 | inputMap.put(controlR, "SendRequestToRepeaterAction")
105 | actionMap.put("SendRequestToRepeaterAction", SendRequestToRepeaterAction(self._extender, self._extender._callbacks))
106 |
107 | # Bind the key combination to the action
108 | inputMap.put(controlC, "copyToClipBoard")
109 | actionMap.put("copyToClipBoard",
110 | CopySelectedURLToClipBoard(self._extender, self._extender._callbacks))
111 |
112 | sendResponseMenu = JMenuItem("Send Responses to Comparer")
113 | sendResponseMenu.addActionListener(SendResponseComparer(self._extender, self._extender._callbacks))
114 |
115 | retestSelecteditem = JMenuItem("Retest selected request")
116 | retestSelecteditem.addActionListener(RetestSelectedRequest(self._extender))
117 |
118 | retestAllitem = JMenuItem("Retest all requests")
119 | retestAllitem.addActionListener(RetestAllRequests(self._extender))
120 |
121 | deleteSelectedItem = JMenuItem("Delete")
122 | deleteSelectedItem.addActionListener(DeleteSelectedRequest(self._extender))
123 |
124 | self._extender.menu = JPopupMenu("Popup")
125 | self._extender.menu.add(sendRequestMenu)
126 | self._extender.menu.add(sendRequestMenu2)
127 | self._extender.menu.add(sendResponseMenu)
128 | self._extender.menu.add(copyURLitem)
129 | self._extender.menu.add(retestSelecteditem)
130 | self._extender.menu.add(retestAllitem)
131 | self._extender.menu.add(deleteSelectedItem) # disabling this feature until bug will be fixed.
132 | message_editor = MessageEditor(self._extender)
133 |
134 | self._extender.tabs = JTabbedPane()
135 | self._extender._requestViewer = self._extender._callbacks.createMessageEditor(message_editor, False)
136 | self._extender._responseViewer = self._extender._callbacks.createMessageEditor(message_editor, False)
137 |
138 | self._extender._originalrequestViewer = self._extender._callbacks.createMessageEditor(message_editor, False)
139 | self._extender._originalresponseViewer = self._extender._callbacks.createMessageEditor(message_editor, False)
140 |
141 | self._extender._unauthorizedrequestViewer = self._extender._callbacks.createMessageEditor(message_editor, False)
142 | self._extender._unauthorizedresponseViewer = self._extender._callbacks.createMessageEditor(message_editor, False)
143 |
144 | self._extender.original_requests_tabs = JTabbedPane()
145 | self._extender.original_requests_tabs.addMouseListener(Mouseclick(self._extender))
146 | self._extender.original_requests_tabs.addTab("Original Request", self._extender._originalrequestViewer.getComponent())
147 | self._extender.original_requests_tabs.addTab("Original Response", self._extender._originalresponseViewer.getComponent())
148 | self._extender.original_requests_tabs.addTab("Expand", None)
149 | self._extender.original_requests_tabs.setSelectedIndex(0)
150 |
151 | self._extender.unauthenticated_requests_tabs = JTabbedPane()
152 | self._extender.unauthenticated_requests_tabs.addMouseListener(Mouseclick(self._extender))
153 | self._extender.unauthenticated_requests_tabs.addTab("Unauthenticated Request", self._extender._unauthorizedrequestViewer.getComponent())
154 | self._extender.unauthenticated_requests_tabs.addTab("Unauthenticated Response", self._extender._unauthorizedresponseViewer.getComponent())
155 | self._extender.unauthenticated_requests_tabs.addTab("Expand", None)
156 | self._extender.unauthenticated_requests_tabs.setSelectedIndex(0)
157 |
158 | self._extender.modified_requests_tabs = JTabbedPane()
159 | self._extender.modified_requests_tabs.addMouseListener(Mouseclick(self._extender))
160 | self._extender.modified_requests_tabs.addTab("Modified Request", self._extender._requestViewer.getComponent())
161 | self._extender.modified_requests_tabs.addTab("Modified Response", self._extender._responseViewer.getComponent())
162 | self._extender.modified_requests_tabs.addTab("Expand", None)
163 | self._extender.modified_requests_tabs.setSelectedIndex(0)
164 |
165 | self._extender.requests_panel = JPanel(GridLayout(3,0))
166 | self._extender.requests_panel.add(self._extender.modified_requests_tabs)
167 | self._extender.requests_panel.add(self._extender.original_requests_tabs)
168 | self._extender.requests_panel.add(self._extender.unauthenticated_requests_tabs)
169 |
170 | self._extender.tabs.addTab("Request/Response Viewers", self._extender.requests_panel)
171 |
172 | self._extender.tabs.addTab("Configuration", self._extender._cfg_splitpane)
173 | self._extender.tabs.setSelectedIndex(1)
174 | self._extender.tabs.setMinimumSize(Dimension(1,1))
175 | self._extender._splitpane.setRightComponent(self._extender.tabs)
176 |
177 |
178 | class SendRequestRepeater(ActionListener):
179 | def __init__(self, extender, callbacks, original):
180 | self._extender = extender
181 | self._callbacks = callbacks
182 | self.original = original
183 |
184 | def actionPerformed(self, e):
185 | if self.original:
186 | request = self._extender._currentlyDisplayedItem._originalrequestResponse
187 | else:
188 | request = self._extender._currentlyDisplayedItem._requestResponse
189 | host = request.getHttpService().getHost()
190 | port = request.getHttpService().getPort()
191 | proto = request.getHttpService().getProtocol()
192 | secure = True if proto == "https" else False
193 |
194 | self._callbacks.sendToRepeater(host, port, secure, request.getRequest(), "Autorize")
195 |
196 | class SendResponseComparer(ActionListener):
197 | def __init__(self, extender, callbacks):
198 | self._extender = extender
199 | self._callbacks = callbacks
200 |
201 | def actionPerformed(self, e):
202 | originalResponse = self._extender._currentlyDisplayedItem._originalrequestResponse
203 | modifiedResponse = self._extender._currentlyDisplayedItem._requestResponse
204 | unauthorizedResponse = self._extender._currentlyDisplayedItem._unauthorizedRequestResponse
205 |
206 | self._callbacks.sendToComparer(originalResponse.getResponse())
207 | self._callbacks.sendToComparer(modifiedResponse.getResponse())
208 | self._callbacks.sendToComparer(unauthorizedResponse.getResponse())
209 |
210 |
211 | class RetestSelectedRequest(ActionListener):
212 | def __init__(self, extender):
213 | self._extender = extender
214 |
215 | def actionPerformed(self, e):
216 | start_new_thread(handle_message, (self._extender, "AUTORIZE", False, self._extender._currentlyDisplayedItem._originalrequestResponse))
217 |
218 | class RetestAllRequests(ActionListener):
219 | def __init__(self, extender):
220 | self._extender = extender
221 |
222 | def actionPerformed(self, e):
223 | start_new_thread(retestAllRequests, (self._extender,))
224 |
225 |
226 | class DeleteSelectedRequest(AbstractAction):
227 | def __init__(self, extender):
228 | self._extender = extender
229 |
230 | def actionPerformed(self, e):
231 | # Its ready to delete multiple rows at a time once we can figure out how to select multiple row.
232 | rows = self._extender.logTable.getSelectedRows()
233 | if len(rows) != 0:
234 | rows = [self._extender.logTable.convertRowIndexToModel(row) for row in rows]
235 | SwingUtilities.invokeLater(lambda: self._extender.tableModel.removeRows(rows))
236 |
237 | class CopySelectedURL(ActionListener):
238 | def __init__(self, extender):
239 | self._extender = extender
240 |
241 | def actionPerformed(self, e):
242 | stringSelection = StringSelection(str(self._extender._helpers.analyzeRequest(self._extender._currentlyDisplayedItem._requestResponse).getUrl()))
243 | clpbrd = Toolkit.getDefaultToolkit().getSystemClipboard()
244 | clpbrd.setContents(stringSelection, None)
245 |
246 | class AutoScrollListener(AdjustmentListener):
247 | def __init__(self, extender):
248 | self._extender = extender
249 |
250 | def adjustmentValueChanged(self, e):
251 | if self._extender.autoScroll.isSelected():
252 | e.getAdjustable().setValue(e.getAdjustable().getMaximum())
253 |
254 | class MessageEditor(IMessageEditorController):
255 | def __init__(self, extender):
256 | self._extender = extender
257 |
258 | def getHttpService(self):
259 | return self._extender._currentlyDisplayedItem.getHttpService()
260 |
261 | def getRequest(self):
262 | return self._extender._currentlyDisplayedItem.getRequest()
263 |
264 | def getResponse(self):
265 | return self._extender._currentlyDisplayedItem.getResponse()
266 |
267 | class Mouseclick(MouseAdapter):
268 | def __init__(self, extender):
269 | self._extender = extender
270 |
271 | def mouseReleased(self, evt):
272 | if evt.getComponent().getSelectedIndex() == 2:
273 | if self._extender.expanded_requests == 0:
274 | expand(self._extender, evt.getComponent())
275 | else:
276 | collapse(self._extender, evt.getComponent())
277 |
278 | class SendRequestToRepeaterAction(AbstractAction):
279 | def __init__(self, extender, callbacks):
280 | self._extender = extender
281 | self._callbacks = callbacks
282 |
283 | def actionPerformed(self, e):
284 | # Get the selected row of the JTable
285 | row = self._extender.logTable.getSelectedRow()
286 |
287 | # Get the LogEntry object for the selected row
288 | rowModelIndex = self._extender.logTable.convertRowIndexToModel(row)
289 | entry = self._extender.tableModel.getValueAt(rowModelIndex, 0)
290 |
291 | # Get the modified request
292 | request = self._extender._currentlyDisplayedItem._requestResponse
293 | host = request.getHttpService().getHost()
294 | port = request.getHttpService().getPort()
295 | proto = request.getHttpService().getProtocol()
296 | secure = True if proto == "https" else False
297 |
298 | self._callbacks.sendToRepeater(host, port, secure, request.getRequest(), "Autorize")
299 |
300 | class CopySelectedURLToClipBoard(AbstractAction):
301 | def __init__(self, extender, callbacks):
302 | self._extender = extender
303 | self._callbacks = callbacks
304 |
305 | def actionPerformed(self, e):
306 | stringSelection = StringSelection(str(self._extender._helpers.analyzeRequest(
307 | self._extender._currentlyDisplayedItem._requestResponse).getUrl()))
308 | clpbrd = Toolkit.getDefaultToolkit().getSystemClipboard()
309 | clpbrd.setContents(stringSelection, None)
--------------------------------------------------------------------------------
/gui/save_restore.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | from javax.swing import SwingUtilities
5 | from javax.swing import JFileChooser
6 | from javax.swing import JFrame
7 |
8 | from table import LogEntry, UpdateTableEDT
9 | from helpers.http import get_cookie_header_from_message, get_authorization_header_from_message, IHttpRequestResponseImplementation
10 |
11 | import csv, base64, json, re, sys
12 |
13 | # This code is necessary to maximize the csv field limit for the save and
14 | # restore functionality
15 | maxInt = sys.maxsize
16 | decrement = True
17 | while decrement:
18 | decrement = False
19 | try:
20 | csv.field_size_limit(maxInt)
21 | except OverflowError:
22 | maxInt = int(maxInt/10)
23 | decrement = True
24 |
25 | class SaveRestore():
26 | def __init__(self, extender):
27 | self._extender = extender
28 | self._checkBoxes = [
29 | "autoScroll",
30 | "ignore304",
31 | "prevent304",
32 | "interceptRequestsfromRepeater",
33 | "doUnauthorizedRequest",
34 | "replaceQueryParam",
35 | "showAuthBypassModified",
36 | "showAuthPotentiallyEnforcedModified",
37 | "showAuthEnforcedModified",
38 | "showAuthBypassUnauthenticated",
39 | "showAuthPotentiallyEnforcedUnauthenticated",
40 | "showAuthEnforcedUnauthenticated",
41 | "showDisabledUnauthenticated"
42 | ]
43 |
44 | def saveState(self):
45 | parentFrame = JFrame()
46 | fileChooser = JFileChooser()
47 | fileChooser.setDialogTitle("State output file")
48 | userSelection = fileChooser.showSaveDialog(parentFrame)
49 |
50 | if userSelection == JFileChooser.APPROVE_OPTION:
51 | exportFile = fileChooser.getSelectedFile()
52 | with open(exportFile.getAbsolutePath(), 'wb') as csvfile:
53 | csvwriter = csv.writer(csvfile, delimiter='\t', quotechar='|', quoting=csv.QUOTE_MINIMAL)
54 |
55 | # Configuration
56 | tempRow = ["ReplaceString", base64.b64encode(self._extender.replaceString.getText())]
57 | csvwriter.writerow(tempRow)
58 |
59 | for EDFilter in self._extender.EDModel.toArray():
60 | tempRow = ["EDFilter", base64.b64encode(EDFilter)]
61 | csvwriter.writerow(tempRow)
62 |
63 | for EDFilterUnauth in self._extender.EDModelUnauth.toArray():
64 | tempRow = ["EDFilterUnauth", base64.b64encode(EDFilterUnauth)]
65 | csvwriter.writerow(tempRow)
66 |
67 | for IFFilter in self._extender.IFModel.toArray():
68 | tempRow = ["IFFilter", base64.b64encode(IFFilter)]
69 | csvwriter.writerow(tempRow)
70 |
71 | for t in ["AndOrType", "AndOrTypeUnauth"]:
72 | tempRow = [t, getattr(self._extender, t).getSelectedItem()]
73 | csvwriter.writerow(tempRow)
74 |
75 | for key in self._extender.badProgrammerMRModel:
76 | d = dict(self._extender.badProgrammerMRModel[key])
77 | d["regexMatch"] = d["regexMatch"] is not None
78 | tempRow = ["MatchReplace", base64.b64encode(json.dumps(d))]
79 | csvwriter.writerow(tempRow)
80 |
81 | d = dict((c, getattr(self._extender, c).isSelected()) for c in self._checkBoxes)
82 | tempRow = ["CheckBoxes", json.dumps(d)]
83 | csvwriter.writerow(tempRow)
84 |
85 | isSelected = self._extender.exportPnl.getComponents()[-1].isSelected()
86 | tempRow = ["RemoveDuplicates", json.dumps(isSelected)]
87 | csvwriter.writerow(tempRow)
88 |
89 | # Request/response list
90 | for i in range(0,self._extender._log.size()):
91 | tempRequestResponseHost = self._extender._log.get(i)._requestResponse.getHttpService().getHost()
92 | tempRequestResponsePort = self._extender._log.get(i)._requestResponse.getHttpService().getPort()
93 | tempRequestResponseProtocol = self._extender._log.get(i)._requestResponse.getHttpService().getProtocol()
94 | tempRequestResponseRequest = base64.b64encode(self._extender._log.get(i)._requestResponse.getRequest())
95 | tempRequestResponseResponse = base64.b64encode(self._extender._log.get(i)._requestResponse.getResponse())
96 |
97 | tempOriginalRequestResponseHost = self._extender._log.get(i)._originalrequestResponse.getHttpService().getHost()
98 | tempOriginalRequestResponsePort = self._extender._log.get(i)._originalrequestResponse.getHttpService().getPort()
99 | tempOriginalRequestResponseProtocol = self._extender._log.get(i)._originalrequestResponse.getHttpService().getProtocol()
100 | tempOriginalRequestResponseRequest = base64.b64encode(self._extender._log.get(i)._originalrequestResponse.getRequest())
101 | tempOriginalRequestResponseResponse = base64.b64encode(self._extender._log.get(i)._originalrequestResponse.getResponse())
102 |
103 | if self._extender._log.get(i)._unauthorizedRequestResponse is not None:
104 | tempUnauthorizedRequestResponseHost = self._extender._log.get(i)._unauthorizedRequestResponse.getHttpService().getHost()
105 | tempUnauthorizedRequestResponsePort = self._extender._log.get(i)._unauthorizedRequestResponse.getHttpService().getPort()
106 | tempUnauthorizedRequestResponseProtocol = self._extender._log.get(i)._unauthorizedRequestResponse.getHttpService().getProtocol()
107 | tempUnauthorizedRequestResponseRequest = base64.b64encode(self._extender._log.get(i)._unauthorizedRequestResponse.getRequest())
108 | tempUnauthorizedRequestResponseResponse = base64.b64encode(self._extender._log.get(i)._unauthorizedRequestResponse.getResponse())
109 | else:
110 | tempUnauthorizedRequestResponseHost = None
111 | tempUnauthorizedRequestResponsePort = None
112 | tempUnauthorizedRequestResponseProtocol = None
113 | tempUnauthorizedRequestResponseRequest = None
114 | tempUnauthorizedRequestResponseResponse = None
115 |
116 | tempEnforcementStatus = self._extender._log.get(i)._enfocementStatus
117 | tempEnforcementStatusUnauthorized = self._extender._log.get(i)._enfocementStatusUnauthorized
118 |
119 | tempRow = [tempRequestResponseHost,tempRequestResponsePort,tempRequestResponseProtocol,tempRequestResponseRequest,tempRequestResponseResponse]
120 | tempRow.extend([tempOriginalRequestResponseHost,tempOriginalRequestResponsePort,tempOriginalRequestResponseProtocol,tempOriginalRequestResponseRequest,tempOriginalRequestResponseResponse])
121 | tempRow.extend([tempUnauthorizedRequestResponseHost,tempUnauthorizedRequestResponsePort,tempUnauthorizedRequestResponseProtocol,tempUnauthorizedRequestResponseRequest,tempUnauthorizedRequestResponseResponse])
122 | tempRow.extend([tempEnforcementStatus,tempEnforcementStatusUnauthorized])
123 |
124 | csvwriter.writerow(tempRow)
125 |
126 | def restoreState(self):
127 | parentFrame = JFrame()
128 | fileChooser = JFileChooser()
129 | fileChooser.setDialogTitle("State import file")
130 | userSelection = fileChooser.showDialog(parentFrame, "Restore")
131 | modelMap = {
132 | "IFFilter": self._extender.IFModel,
133 | "EDFilter": self._extender.EDModel,
134 | "EDFilterUnauth": self._extender.EDModelUnauth
135 | }
136 |
137 | if userSelection == JFileChooser.APPROVE_OPTION:
138 | importFile = fileChooser.getSelectedFile()
139 |
140 | with open(importFile.getAbsolutePath(), 'r') as csvfile:
141 |
142 | csvreader = csv.reader(csvfile, delimiter='\t', quotechar='|')
143 |
144 | for row in csvreader:
145 | # Configuration
146 | if row[0] == "ReplaceString":
147 | self._extender.replaceString.setText(base64.b64decode(row[1]))
148 | continue
149 |
150 | if row[0] in modelMap:
151 | f = base64.b64decode(row[1])
152 | if f not in modelMap[row[0]].toArray():
153 | modelMap[row[0]].addElement(f)
154 | continue
155 |
156 | if row[0] in {"AndOrType", "AndOrTypeUnauth"}:
157 | getattr(self._extender, row[0]).setSelectedItem(row[1])
158 | continue
159 |
160 | if row[0] == "MatchReplace":
161 | d = json.loads(base64.b64decode(row[1]))
162 | key = d["type"] + " " + d["match"] + "->" + d["replace"]
163 | if key in self._extender.badProgrammerMRModel:
164 | continue
165 | regexMatch = None
166 | if d["regexMatch"]:
167 | try:
168 | d["regexMatch"] = re.compile(d["match"])
169 | except re.error:
170 | print("ERROR: Regex to restore is invalid:", d["match"])
171 | continue
172 | self._extender.badProgrammerMRModel[key] = d
173 | self._extender.MRModel.addElement(key)
174 | continue
175 |
176 | if row[0] == "CheckBoxes":
177 | d = json.loads(row[1])
178 | for k in d:
179 | getattr(self._extender, k).setSelected(d[k])
180 | continue
181 |
182 | if row[0] == "RemoveDuplicates":
183 | isSelected = json.loads(row[1])
184 | try:
185 | self._extender.exportPnl.getComponents()[-1].setSelected(isSelected)
186 | except TypeError: # suppress TypeError: None required for void return
187 | pass
188 | continue
189 |
190 | # Request/response list
191 | tempRequestResponseHost = row[0]
192 | tempRequestResponsePort = row[1]
193 | tempRequestResponseProtocol = row[2]
194 | tempRequestResponseRequest = base64.b64decode(row[3])
195 | tempRequestResponseResponse = base64.b64decode(row[4])
196 |
197 | tempRequestResponseHttpService = self._extender._helpers.buildHttpService(tempRequestResponseHost,int(tempRequestResponsePort),tempRequestResponseProtocol)
198 | tempRequestResponse = IHttpRequestResponseImplementation(tempRequestResponseHttpService,tempRequestResponseRequest,tempRequestResponseResponse)
199 |
200 | tempOriginalRequestResponseHost = row[5]
201 | tempOriginalRequestResponsePort = row[6]
202 | tempOriginalRequestResponseProtocol = row[7]
203 | tempOriginalRequestResponseRequest = base64.b64decode(row[8])
204 | tempOriginalRequestResponseResponse = base64.b64decode(row[9])
205 |
206 | tempOriginalRequestResponseHttpService = self._extender._helpers.buildHttpService(tempOriginalRequestResponseHost,int(tempOriginalRequestResponsePort),tempOriginalRequestResponseProtocol)
207 | tempOriginalRequestResponse = IHttpRequestResponseImplementation(tempOriginalRequestResponseHttpService,tempOriginalRequestResponseRequest,tempOriginalRequestResponseResponse)
208 |
209 | checkAuthentication = True
210 | if row[10] != '':
211 | tempUnauthorizedRequestResponseHost = row[10]
212 | tempUnauthorizedRequestResponsePort = row[11]
213 | tempUnauthorizedRequestResponseProtocol = row[12]
214 | tempUnauthorizedRequestResponseRequest = base64.b64decode(row[13])
215 | tempUnauthorizedRequestResponseResponse = base64.b64decode(row[14])
216 | tempUnauthorizedRequestResponseHttpService = self._extender._helpers.buildHttpService(tempUnauthorizedRequestResponseHost,int(tempUnauthorizedRequestResponsePort),tempUnauthorizedRequestResponseProtocol)
217 | tempUnauthorizedRequestResponse = IHttpRequestResponseImplementation(tempUnauthorizedRequestResponseHttpService,tempUnauthorizedRequestResponseRequest,tempUnauthorizedRequestResponseResponse)
218 | else:
219 | checkAuthentication = False
220 | tempUnauthorizedRequestResponse = None
221 |
222 | tempEnforcementStatus = row[15]
223 | tempEnforcementStatusUnauthorized = row[16]
224 |
225 | self._extender._lock.acquire()
226 |
227 | row = self._extender._log.size()
228 |
229 | if checkAuthentication:
230 | self._extender._log.add(
231 | LogEntry(self._extender.currentRequestNumber,
232 | self._extender._callbacks.saveBuffersToTempFiles(tempRequestResponse),
233 | self._extender._helpers.analyzeRequest(tempRequestResponse).getMethod(),
234 | self._extender._helpers.analyzeRequest(tempRequestResponse).getUrl(),
235 | self._extender._callbacks.saveBuffersToTempFiles(tempOriginalRequestResponse),
236 | tempEnforcementStatus,
237 | self._extender._callbacks.saveBuffersToTempFiles(tempUnauthorizedRequestResponse),
238 | tempEnforcementStatusUnauthorized))
239 | else:
240 | self._extender._log.add(
241 | LogEntry(self._extender.currentRequestNumber,
242 | self._extender._callbacks.saveBuffersToTempFiles(tempRequestResponse),
243 | self._extender._helpers.analyzeRequest(tempRequestResponse).getMethod(),
244 | self._extender._helpers.analyzeRequest(tempRequestResponse).getUrl(),
245 | self._extender._callbacks.saveBuffersToTempFiles(tempOriginalRequestResponse),
246 | tempEnforcementStatus,None,tempEnforcementStatusUnauthorized))
247 |
248 | SwingUtilities.invokeLater(UpdateTableEDT(self._extender,"insert",row,row))
249 | self._extender.currentRequestNumber = self._extender.currentRequestNumber + 1
250 | self._extender._lock.release()
251 |
252 | lastRow = self._extender._log.size()
253 | if lastRow > 0:
254 | cookiesHeader = get_cookie_header_from_message(self._extender, self._extender._log.get(lastRow - 1)._requestResponse)
255 | if cookiesHeader:
256 | self._extender.lastCookiesHeader = cookiesHeader
257 | self._extender.fetchCookiesHeaderButton.setEnabled(True)
258 | authorizationHeader = get_authorization_header_from_message(self._extender, self._extender._log.get(lastRow - 1)._requestResponse)
259 | if authorizationHeader:
260 | self._extender.lastAuthorizationHeader = authorizationHeader
261 | self._extender.fetchAuthorizationHeaderButton.setEnabled(True)
262 |
--------------------------------------------------------------------------------
/authorization/authorization.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | from operator import truediv
5 | import sys
6 | reload(sys)
7 |
8 | if (sys.version_info[0] == 2):
9 | sys.setdefaultencoding('utf8')
10 |
11 | sys.path.append("..")
12 |
13 | from helpers.http import get_authorization_header_from_message, get_cookie_header_from_message, isStatusCodesReturned, makeMessage, makeRequest, getResponseBody, IHttpRequestResponseImplementation
14 | from gui.table import LogEntry, UpdateTableEDT
15 | from javax.swing import SwingUtilities
16 | from java.net import URL
17 | import re
18 |
19 | def tool_needs_to_be_ignored(self, toolFlag):
20 | for i in range(0, self.IFList.getModel().getSize()):
21 | if self.IFList.getModel().getElementAt(i).split(":")[0] == "Ignore spider requests":
22 | if (toolFlag == self._callbacks.TOOL_SPIDER):
23 | return True
24 | if self.IFList.getModel().getElementAt(i).split(":")[0] == "Ignore proxy requests":
25 | if (toolFlag == self._callbacks.TOOL_PROXY):
26 | return True
27 | if self.IFList.getModel().getElementAt(i).split(":")[0] == "Ignore target requests":
28 | if (toolFlag == self._callbacks.TOOL_TARGET):
29 | return True
30 | return False
31 |
32 | def capture_last_cookie_header(self, messageInfo):
33 | cookies = get_cookie_header_from_message(self, messageInfo)
34 | if cookies:
35 | self.lastCookiesHeader = cookies
36 | self.fetchCookiesHeaderButton.setEnabled(True)
37 |
38 | def capture_last_authorization_header(self, messageInfo):
39 | authorization = get_authorization_header_from_message(self, messageInfo)
40 | if authorization:
41 | self.lastAuthorizationHeader = authorization
42 | self.fetchAuthorizationHeaderButton.setEnabled(True)
43 |
44 |
45 | def valid_tool(self, toolFlag):
46 | return (toolFlag == self._callbacks.TOOL_PROXY or
47 | (toolFlag == self._callbacks.TOOL_REPEATER and
48 | self.interceptRequestsfromRepeater.isSelected()))
49 |
50 | def handle_304_status_code_prevention(self, messageIsRequest, messageInfo):
51 | should_prevent = False
52 | if self.prevent304.isSelected():
53 | if messageIsRequest:
54 | requestHeaders = list(self._helpers.analyzeRequest(messageInfo).getHeaders())
55 | newHeaders = list()
56 | for header in requestHeaders:
57 | if not "If-None-Match:" in header and not "If-Modified-Since:" in header:
58 | newHeaders.append(header)
59 | should_prevent = True
60 | if should_prevent:
61 | requestInfo = self._helpers.analyzeRequest(messageInfo)
62 | bodyBytes = messageInfo.getRequest()[requestInfo.getBodyOffset():]
63 | bodyStr = self._helpers.bytesToString(bodyBytes)
64 | messageInfo.setRequest(self._helpers.buildHttpMessage(newHeaders, bodyStr))
65 |
66 | def message_not_from_autorize(self, messageInfo):
67 | return not self.replaceString.getText() in self._helpers.analyzeRequest(messageInfo).getHeaders()
68 |
69 | def no_filters_defined(self):
70 | return self.IFList.getModel().getSize() == 0
71 |
72 | def message_passed_interception_filters(self, messageInfo):
73 | urlString = str(self._helpers.analyzeRequest(messageInfo).getUrl())
74 | reqInfo = self._helpers.analyzeRequest(messageInfo)
75 | reqBodyBytes = messageInfo.getRequest()[reqInfo.getBodyOffset():]
76 | bodyStr = self._helpers.bytesToString(reqBodyBytes)
77 |
78 | resInfo = self._helpers.analyzeResponse(messageInfo.getResponse())
79 | resBodyBytes = messageInfo.getResponse()[resInfo.getBodyOffset():]
80 | resStr = self._helpers.bytesToString(resBodyBytes)
81 |
82 | message_passed_filters = True
83 | for i in range(0, self.IFList.getModel().getSize()):
84 | interceptionFilter = self.IFList.getModel().getElementAt(i)
85 | interceptionFilterTitle = interceptionFilter.split(":")[0]
86 | if interceptionFilterTitle == "Scope items only":
87 | currentURL = URL(urlString)
88 | if not self._callbacks.isInScope(currentURL):
89 | message_passed_filters = False
90 |
91 | if interceptionFilterTitle == "URL Contains (simple string)":
92 | if interceptionFilter[30:] not in urlString:
93 | message_passed_filters = False
94 |
95 | if interceptionFilterTitle == "URL Contains (regex)":
96 | regex_string = interceptionFilter[22:]
97 | if re.search(regex_string, urlString, re.IGNORECASE) is None:
98 | message_passed_filters = False
99 |
100 | if interceptionFilterTitle == "URL Not Contains (simple string)":
101 | if interceptionFilter[34:] in urlString:
102 | message_passed_filters = False
103 |
104 | if interceptionFilterTitle == "URL Not Contains (regex)":
105 | regex_string = interceptionFilter[26:]
106 | if not re.search(regex_string, urlString, re.IGNORECASE) is None:
107 | message_passed_filters = False
108 |
109 | if interceptionFilterTitle == "Request Body contains (simple string)":
110 | if interceptionFilter[40:] not in bodyStr:
111 | message_passed_filters = False
112 |
113 | if interceptionFilterTitle == "Request Body contains (regex)":
114 | regex_string = interceptionFilter[32:]
115 | if re.search(regex_string, bodyStr, re.IGNORECASE) is None:
116 | message_passed_filters = False
117 |
118 | if interceptionFilterTitle == "Request Body NOT contains (simple string)":
119 | if interceptionFilter[44:] in bodyStr:
120 | message_passed_filters = False
121 |
122 | if interceptionFilterTitle == "Request Body Not contains (regex)":
123 | regex_string = interceptionFilter[36:]
124 | if not re.search(regex_string, bodyStr, re.IGNORECASE) is None:
125 | message_passed_filters = False
126 |
127 | if interceptionFilterTitle == "Response Body contains (simple string)":
128 | if interceptionFilter[41:] not in resStr:
129 | message_passed_filters = False
130 |
131 | if interceptionFilterTitle == "Response Body contains (regex)":
132 | regex_string = interceptionFilter[33:]
133 | if re.search(regex_string, resStr, re.IGNORECASE) is None:
134 | message_passed_filters = False
135 |
136 | if interceptionFilterTitle == "Response Body NOT contains (simple string)":
137 | if interceptionFilter[45:] in resStr:
138 | message_passed_filters = False
139 |
140 | if interceptionFilterTitle == "Response Body Not contains (regex)":
141 | regex_string = interceptionFilter[37:]
142 | if not re.search(regex_string, resStr, re.IGNORECASE) is None:
143 | message_passed_filters = False
144 |
145 | if interceptionFilterTitle == "Header contains":
146 | for header in list(resInfo.getHeaders()):
147 | if interceptionFilter[17:] in header:
148 | message_passed_filters = False
149 |
150 | if interceptionFilterTitle == "Header doesn't contain":
151 | for header in list(resInfo.getHeaders()):
152 | if not interceptionFilter[17:] in header:
153 | message_passed_filters = False
154 |
155 | if interceptionFilterTitle == "Only HTTP methods (newline separated)":
156 | filterMethods = interceptionFilter[39:].split("\n")
157 | filterMethods = [x.lower() for x in filterMethods]
158 | reqMethod = str(self._helpers.analyzeRequest(messageInfo).getMethod())
159 | if reqMethod.lower() not in filterMethods:
160 | message_passed_filters = False
161 |
162 | if interceptionFilterTitle == "Ignore HTTP methods (newline separated)":
163 | filterMethods = interceptionFilter[41:].split("\n")
164 | filterMethods = [x.lower() for x in filterMethods]
165 | reqMethod = str(self._helpers.analyzeRequest(messageInfo).getMethod())
166 | if reqMethod.lower() in filterMethods:
167 | message_passed_filters = False
168 |
169 | if interceptionFilterTitle == "Ignore OPTIONS requests":
170 | reqMethod = str(self._helpers.analyzeRequest(messageInfo).getMethod())
171 | if reqMethod == "OPTIONS":
172 | message_passed_filters = False
173 |
174 | return message_passed_filters
175 |
176 | def handle_message(self, toolFlag, messageIsRequest, messageInfo):
177 | if tool_needs_to_be_ignored(self, toolFlag):
178 | return
179 |
180 | capture_last_cookie_header(self, messageInfo)
181 | capture_last_authorization_header(self, messageInfo)
182 |
183 | if (self.intercept and valid_tool(self, toolFlag) or toolFlag == "AUTORIZE"):
184 | handle_304_status_code_prevention(self, messageIsRequest, messageInfo)
185 |
186 | if not messageIsRequest:
187 | if message_not_from_autorize(self, messageInfo):
188 | if self.ignore304.isSelected():
189 | if isStatusCodesReturned(self, messageInfo, ["304", "204"]):
190 | return
191 |
192 | if no_filters_defined(self):
193 | checkAuthorization(self, messageInfo,
194 | self._helpers.analyzeResponse(messageInfo.getResponse()).getHeaders(),
195 | self.doUnauthorizedRequest.isSelected())
196 | else:
197 | if message_passed_interception_filters(self, messageInfo):
198 | checkAuthorization(self, messageInfo,self._helpers.analyzeResponse(messageInfo.getResponse()).getHeaders(),self.doUnauthorizedRequest.isSelected())
199 |
200 | def send_request_to_autorize(self, messageInfo):
201 | if messageInfo.getResponse() is None:
202 | message = makeMessage(self, messageInfo,False,False)
203 | requestResponse = makeRequest(self, messageInfo, message)
204 | checkAuthorization(self, requestResponse,self._helpers.analyzeResponse(requestResponse.getResponse()).getHeaders(),self.doUnauthorizedRequest.isSelected())
205 | else:
206 | request = messageInfo.getRequest()
207 | response = messageInfo.getResponse()
208 | httpService = messageInfo.getHttpService()
209 | newHttpRequestResponse = IHttpRequestResponseImplementation(httpService,request,response)
210 | newHttpRequestResponsePersisted = self._callbacks.saveBuffersToTempFiles(newHttpRequestResponse)
211 | checkAuthorization(self, newHttpRequestResponsePersisted,self._helpers.analyzeResponse(messageInfo.getResponse()).getHeaders(),self.doUnauthorizedRequest.isSelected())
212 |
213 | def auth_enforced_via_enforcement_detectors(self, filters, requestResponse, andOrEnforcement):
214 | response = requestResponse.getResponse()
215 | analyzedResponse = self._helpers.analyzeResponse(response)
216 | auth_enforced = False
217 | if andOrEnforcement == "And":
218 | andEnforcementCheck = True
219 | auth_enforced = True
220 | else:
221 | andEnforcementCheck = False
222 | auth_enforced = False
223 |
224 | for filter in filters:
225 | filter = self._helpers.bytesToString(bytes(filter))
226 | filter_kv = filter.split(":", 1)
227 | inverse = "NOT" in filter_kv[0]
228 | filter_kv[0] = filter_kv[0].replace(" NOT", "")
229 | filter = ":".join(filter_kv)
230 |
231 | if filter.startswith("Status code equals: "):
232 | statusCode = filter[20:]
233 | filterMatched = inverse ^ isStatusCodesReturned(self, requestResponse, statusCode)
234 |
235 | elif filter.startswith("Headers (simple string): "):
236 | filterMatched = inverse ^ (filter[25:] in self._helpers.bytesToString(requestResponse.getResponse()[0:analyzedResponse.getBodyOffset()]))
237 |
238 | elif filter.startswith("Headers (regex): "):
239 | regex_string = filter[17:]
240 | p = re.compile(regex_string, re.IGNORECASE)
241 | filterMatched = inverse ^ bool(p.search(self._helpers.bytesToString(requestResponse.getResponse()[0:analyzedResponse.getBodyOffset()])))
242 |
243 | elif filter.startswith("Body (simple string): "):
244 | filterMatched = inverse ^ (filter[22:] in self._helpers.bytesToString(requestResponse.getResponse()[analyzedResponse.getBodyOffset():]))
245 |
246 | elif filter.startswith("Body (regex): "):
247 | regex_string = filter[14:]
248 | p = re.compile(regex_string, re.IGNORECASE)
249 | filterMatched = inverse ^ bool(p.search(self._helpers.bytesToString(requestResponse.getResponse()[analyzedResponse.getBodyOffset():])))
250 |
251 | elif filter.startswith("Full response (simple string): "):
252 | filterMatched = inverse ^ (filter[31:] in self._helpers.bytesToString(requestResponse.getResponse()))
253 |
254 | elif filter.startswith("Full response (regex): "):
255 | regex_string = filter[23:]
256 | p = re.compile(regex_string, re.IGNORECASE)
257 | filterMatched = inverse ^ bool(p.search(self._helpers.bytesToString(requestResponse.getResponse())))
258 |
259 | elif filter.startswith("Full response length: "):
260 | filterMatched = inverse ^ (str(len(response)) == filter[22:].strip())
261 |
262 | if andEnforcementCheck:
263 | if auth_enforced and not filterMatched:
264 | auth_enforced = False
265 | else:
266 | if not auth_enforced and filterMatched:
267 | auth_enforced = True
268 |
269 | return auth_enforced
270 |
271 | def checkBypass(self, oldStatusCode, newStatusCode, oldContent,
272 | newContent, filters, requestResponse, andOrEnforcement):
273 | if oldStatusCode == newStatusCode:
274 | auth_enforced = 0
275 | if len(filters) > 0:
276 | auth_enforced = auth_enforced_via_enforcement_detectors(self, filters, requestResponse, andOrEnforcement)
277 | if auth_enforced:
278 | return self.ENFORCED_STR
279 | elif oldContent == newContent:
280 | return self.BYPASSSED_STR
281 | else:
282 | return self.IS_ENFORCED_STR
283 | else:
284 | return self.ENFORCED_STR
285 |
286 | def checkAuthorization(self, messageInfo, originalHeaders, checkUnauthorized):
287 | # Check unauthorized request
288 | if checkUnauthorized:
289 | messageUnauthorized = makeMessage(self, messageInfo, True, False)
290 | requestResponseUnauthorized = makeRequest(self, messageInfo, messageUnauthorized)
291 | unauthorizedResponse = requestResponseUnauthorized.getResponse()
292 | analyzedResponseUnauthorized = self._helpers.analyzeResponse(unauthorizedResponse)
293 | statusCodeUnauthorized = analyzedResponseUnauthorized.getHeaders()[0]
294 | contentUnauthorized = getResponseBody(self, requestResponseUnauthorized)
295 |
296 | message = makeMessage(self, messageInfo, True, True)
297 | requestResponse = makeRequest(self, messageInfo, message)
298 | newResponse = requestResponse.getResponse()
299 | analyzedResponse = self._helpers.analyzeResponse(newResponse)
300 |
301 | oldStatusCode = originalHeaders[0]
302 | newStatusCode = analyzedResponse.getHeaders()[0]
303 | oldContent = getResponseBody(self, messageInfo)
304 | newContent = getResponseBody(self, requestResponse)
305 |
306 | EDFilters = self.EDModel.toArray()
307 |
308 | impression = checkBypass(self, oldStatusCode, newStatusCode, oldContent, newContent, EDFilters, requestResponse, self.AndOrType.getSelectedItem())
309 |
310 | if checkUnauthorized:
311 | EDFiltersUnauth = self.EDModelUnauth.toArray()
312 | impressionUnauthorized = checkBypass(self, oldStatusCode, statusCodeUnauthorized, oldContent, contentUnauthorized, EDFiltersUnauth, requestResponseUnauthorized, self.AndOrTypeUnauth.getSelectedItem())
313 |
314 | self._lock.acquire()
315 |
316 | row = self._log.size()
317 | method = self._helpers.analyzeRequest(messageInfo.getRequest()).getMethod()
318 |
319 | if checkUnauthorized:
320 | self._log.add(LogEntry(self.currentRequestNumber,self._callbacks.saveBuffersToTempFiles(requestResponse), method, self._helpers.analyzeRequest(requestResponse).getUrl(),messageInfo,impression,self._callbacks.saveBuffersToTempFiles(requestResponseUnauthorized),impressionUnauthorized)) # same requests not include again.
321 | else:
322 | self._log.add(LogEntry(self.currentRequestNumber,self._callbacks.saveBuffersToTempFiles(requestResponse), method, self._helpers.analyzeRequest(requestResponse).getUrl(),messageInfo,impression,None,"Disabled")) # same requests not include again.
323 |
324 | SwingUtilities.invokeLater(UpdateTableEDT(self,"insert",row,row))
325 | self.currentRequestNumber = self.currentRequestNumber + 1
326 | self._lock.release()
327 |
328 | def checkAuthorizationV2(self, messageInfo):
329 | checkAuthorization(self, messageInfo, self._extender._helpers.analyzeResponse(messageInfo.getResponse()).getHeaders(), self._extender.doUnauthorizedRequest.isSelected())
330 |
331 | def retestAllRequests(self):
332 | self.logTable.setAutoCreateRowSorter(True)
333 | for i in range(self.tableModel.getRowCount()):
334 | logEntry = self._log.get(self.logTable.convertRowIndexToModel(i))
335 | handle_message(self, "AUTORIZE", False, logEntry._originalrequestResponse)
336 |
--------------------------------------------------------------------------------
/gui/configuration_tab.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | from javax.swing import DefaultComboBoxModel
5 | from java.awt.event import ActionListener
6 | from javax.swing import SwingUtilities
7 | from javax.swing import JToggleButton
8 | from javax.swing import JScrollPane
9 | from javax.swing import JTabbedPane
10 | from javax.swing import JOptionPane
11 | from javax.swing import GroupLayout
12 | from javax.swing import JSplitPane
13 | from javax.swing import JComboBox
14 | from javax.swing import JTextArea
15 | from javax.swing import JCheckBox
16 | from javax.swing import JButton
17 | from javax.swing import JPanel
18 | from javax.swing import JLabel
19 |
20 | from table import UpdateTableEDT
21 |
22 | class ConfigurationTab():
23 | def __init__(self, extender):
24 | self._extender = extender
25 |
26 | def draw(self):
27 | """ init configuration tab
28 | """
29 | self.DEFUALT_REPLACE_TEXT = "Cookie: Insert=injected; cookie=or;\nHeader: here"
30 | self._extender.startButton = JToggleButton("Autorize is off",
31 | actionPerformed=self.startOrStop)
32 | self._extender.startButton.setBounds(10, 20, 230, 30)
33 |
34 | self._extender.clearButton = JButton("Clear List", actionPerformed=self.clearList)
35 | self._extender.clearButton.setBounds(10, 80, 100, 30)
36 | self._extender.autoScroll = JCheckBox("Auto Scroll")
37 | self._extender.autoScroll.setBounds(145, 80, 130, 30)
38 |
39 | self._extender.ignore304 = JCheckBox("Ignore 304/204 status code responses")
40 | self._extender.ignore304.setBounds(280, 5, 300, 30)
41 | self._extender.ignore304.setSelected(True)
42 |
43 | self._extender.prevent304 = JCheckBox("Prevent 304 Not Modified status code")
44 | self._extender.prevent304.setBounds(280, 25, 300, 30)
45 | self._extender.interceptRequestsfromRepeater = JCheckBox("Intercept requests from Repeater")
46 | self._extender.interceptRequestsfromRepeater.setBounds(280, 45, 300, 30)
47 |
48 | self._extender.doUnauthorizedRequest = JCheckBox("Check unauthenticated")
49 | self._extender.doUnauthorizedRequest.setBounds(280, 65, 300, 30)
50 | self._extender.doUnauthorizedRequest.setSelected(True)
51 |
52 | self._extender.replaceQueryParam = JCheckBox("Replace query params", actionPerformed=self.replaceQueryHanlder)
53 | self._extender.replaceQueryParam.setBounds(280, 85, 300, 30)
54 | self._extender.replaceQueryParam.setSelected(False)
55 |
56 | self._extender.saveHeadersButton = JButton("Add",
57 | actionPerformed=self.saveHeaders)
58 | self._extender.saveHeadersButton.setBounds(315, 115, 80, 30)
59 |
60 | self._extender.removeHeadersButton = JButton("Remove",
61 | actionPerformed=self.removeHeaders)
62 | self._extender.removeHeadersButton.setBounds(400, 115, 80, 30)
63 |
64 | savedHeadersTitles = self.getSavedHeadersTitles()
65 | self._extender.savedHeadersTitlesCombo = JComboBox(savedHeadersTitles)
66 | self._extender.savedHeadersTitlesCombo.addActionListener(SavedHeaderChange(self._extender))
67 | self._extender.savedHeadersTitlesCombo.setBounds(10, 115, 300, 30)
68 |
69 | self._extender.replaceString = JTextArea(self.DEFUALT_REPLACE_TEXT, 5, 30)
70 | self._extender.replaceString.setWrapStyleWord(True)
71 | self._extender.replaceString.setLineWrap(True)
72 |
73 | scrollReplaceString = JScrollPane(self._extender.replaceString)
74 | scrollReplaceString.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED)
75 | scrollReplaceString.setBounds(10, 150, 470, 150)
76 |
77 | fromLastRequestLabel = JLabel("From last request:")
78 | fromLastRequestLabel.setBounds(10, 305, 250, 30)
79 |
80 | self._extender.fetchCookiesHeaderButton = JButton("Fetch Cookies header",
81 | actionPerformed=self.fetchCookiesHeader)
82 | self._extender.fetchCookiesHeaderButton.setEnabled(False)
83 | self._extender.fetchCookiesHeaderButton.setBounds(10, 330, 220, 30)
84 |
85 | self._extender.fetchAuthorizationHeaderButton = JButton("Fetch Authorization header",
86 | actionPerformed=self.fetchAuthorizationHeader)
87 | self._extender.fetchAuthorizationHeaderButton.setEnabled(False)
88 | self._extender.fetchAuthorizationHeaderButton.setBounds(260, 330, 220, 30)
89 |
90 | self._extender.filtersTabs = JTabbedPane()
91 | self._extender.filtersTabs = self._extender.filtersTabs
92 | self._extender.filtersTabs.addTab("Enforcement Detector", self._extender.EDPnl)
93 | self._extender.filtersTabs.addTab("Detector Unauthenticated", self._extender.EDPnlUnauth)
94 | self._extender.filtersTabs.addTab("Interception Filters", self._extender.filtersPnl)
95 | self._extender.filtersTabs.addTab("Match/Replace", self._extender.MRPnl)
96 | self._extender.filtersTabs.addTab("Table Filter", self._extender.filterPnl)
97 | self._extender.filtersTabs.addTab("Save/Restore", self._extender.exportPnl)
98 |
99 | self._extender.filtersTabs.setSelectedIndex(2)
100 | self._extender.filtersTabs.setBounds(0, 350, 2000, 700)
101 |
102 | self.config_pnl = JPanel()
103 | layout = GroupLayout(self.config_pnl)
104 | self.config_pnl.setLayout(layout)
105 | layout.setAutoCreateGaps(True)
106 | layout.setAutoCreateContainerGaps(True)
107 |
108 | layout.setHorizontalGroup(
109 | layout.createSequentialGroup()
110 | .addGroup(
111 | layout.createParallelGroup()
112 | .addComponent(
113 | self._extender.startButton,
114 | GroupLayout.PREFERRED_SIZE,
115 | GroupLayout.PREFERRED_SIZE,
116 | GroupLayout.PREFERRED_SIZE,
117 | )
118 |
119 | .addComponent(
120 | self._extender.clearButton,
121 | GroupLayout.PREFERRED_SIZE,
122 | GroupLayout.PREFERRED_SIZE,
123 | GroupLayout.PREFERRED_SIZE,
124 | )
125 | .addComponent(
126 | self._extender.savedHeadersTitlesCombo,
127 | GroupLayout.PREFERRED_SIZE,
128 | GroupLayout.PREFERRED_SIZE,
129 | GroupLayout.PREFERRED_SIZE,
130 | )
131 | .addComponent(
132 | scrollReplaceString,
133 | GroupLayout.PREFERRED_SIZE,
134 | GroupLayout.PREFERRED_SIZE,
135 | GroupLayout.PREFERRED_SIZE,
136 | )
137 | .addComponent(
138 | fromLastRequestLabel,
139 | GroupLayout.PREFERRED_SIZE,
140 | GroupLayout.PREFERRED_SIZE,
141 | GroupLayout.PREFERRED_SIZE,
142 | )
143 | .addGroup(layout.createSequentialGroup()
144 | .addComponent(
145 | self._extender.fetchCookiesHeaderButton,
146 | GroupLayout.PREFERRED_SIZE,
147 | GroupLayout.PREFERRED_SIZE,
148 | GroupLayout.PREFERRED_SIZE,
149 | )
150 | .addComponent(
151 | self._extender.fetchAuthorizationHeaderButton,
152 | GroupLayout.PREFERRED_SIZE,
153 | GroupLayout.PREFERRED_SIZE,
154 | GroupLayout.PREFERRED_SIZE,
155 | )
156 | )
157 |
158 |
159 | )
160 | .addGroup(
161 | layout.createParallelGroup()
162 | .addComponent(
163 | self._extender.ignore304,
164 | GroupLayout.PREFERRED_SIZE,
165 | GroupLayout.PREFERRED_SIZE,
166 | GroupLayout.PREFERRED_SIZE,
167 | )
168 | .addComponent(
169 | self._extender.prevent304,
170 | GroupLayout.PREFERRED_SIZE,
171 | GroupLayout.PREFERRED_SIZE,
172 | GroupLayout.PREFERRED_SIZE,
173 | )
174 | .addComponent(
175 | self._extender.interceptRequestsfromRepeater,
176 | GroupLayout.PREFERRED_SIZE,
177 | GroupLayout.PREFERRED_SIZE,
178 | GroupLayout.PREFERRED_SIZE,
179 | )
180 | .addComponent(
181 | self._extender.doUnauthorizedRequest,
182 | GroupLayout.PREFERRED_SIZE,
183 | GroupLayout.PREFERRED_SIZE,
184 | GroupLayout.PREFERRED_SIZE,
185 | )
186 | .addComponent(
187 | self._extender.autoScroll,
188 | GroupLayout.PREFERRED_SIZE,
189 | GroupLayout.PREFERRED_SIZE,
190 | GroupLayout.PREFERRED_SIZE,
191 | )
192 | .addComponent(
193 | self._extender.replaceQueryParam,
194 | GroupLayout.PREFERRED_SIZE,
195 | GroupLayout.PREFERRED_SIZE,
196 | GroupLayout.PREFERRED_SIZE,
197 | )
198 | .addComponent(
199 | self._extender.saveHeadersButton,
200 | GroupLayout.PREFERRED_SIZE,
201 | GroupLayout.PREFERRED_SIZE,
202 | GroupLayout.PREFERRED_SIZE,
203 | )
204 | .addComponent(
205 | self._extender.removeHeadersButton,
206 | GroupLayout.PREFERRED_SIZE,
207 | GroupLayout.PREFERRED_SIZE,
208 | GroupLayout.PREFERRED_SIZE,
209 | )
210 | )
211 | )
212 |
213 | layout.setVerticalGroup(
214 | layout.createSequentialGroup()
215 | .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
216 |
217 | .addComponent(
218 | self._extender.startButton,
219 | GroupLayout.PREFERRED_SIZE,
220 | GroupLayout.PREFERRED_SIZE,
221 | GroupLayout.PREFERRED_SIZE,
222 | )
223 | .addComponent(
224 | self._extender.ignore304,
225 | GroupLayout.PREFERRED_SIZE,
226 | GroupLayout.PREFERRED_SIZE,
227 | GroupLayout.PREFERRED_SIZE,
228 | )
229 | )
230 | .addComponent(
231 | self._extender.prevent304,
232 | GroupLayout.PREFERRED_SIZE,
233 | GroupLayout.PREFERRED_SIZE,
234 | GroupLayout.PREFERRED_SIZE,
235 | )
236 | .addComponent(
237 | self._extender.interceptRequestsfromRepeater,
238 | GroupLayout.PREFERRED_SIZE,
239 | GroupLayout.PREFERRED_SIZE,
240 | GroupLayout.PREFERRED_SIZE,
241 | )
242 | .addComponent(
243 | self._extender.doUnauthorizedRequest,
244 | GroupLayout.PREFERRED_SIZE,
245 | GroupLayout.PREFERRED_SIZE,
246 | GroupLayout.PREFERRED_SIZE,
247 | )
248 | .addComponent(
249 | self._extender.replaceQueryParam,
250 | GroupLayout.PREFERRED_SIZE,
251 | GroupLayout.PREFERRED_SIZE,
252 | GroupLayout.PREFERRED_SIZE,
253 | )
254 | .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
255 | .addComponent(
256 | self._extender.clearButton,
257 | GroupLayout.PREFERRED_SIZE,
258 | GroupLayout.PREFERRED_SIZE,
259 | GroupLayout.PREFERRED_SIZE,
260 | )
261 | .addComponent(
262 | self._extender.autoScroll,
263 | GroupLayout.PREFERRED_SIZE,
264 | GroupLayout.PREFERRED_SIZE,
265 | GroupLayout.PREFERRED_SIZE,
266 | )
267 | )
268 | .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
269 | .addComponent(
270 | self._extender.savedHeadersTitlesCombo,
271 | GroupLayout.PREFERRED_SIZE,
272 | GroupLayout.PREFERRED_SIZE,
273 | GroupLayout.PREFERRED_SIZE,
274 | )
275 | .addGroup(layout.createSequentialGroup()
276 | .addComponent(
277 | self._extender.saveHeadersButton,
278 | GroupLayout.PREFERRED_SIZE,
279 | GroupLayout.PREFERRED_SIZE,
280 | GroupLayout.PREFERRED_SIZE,
281 | )
282 | .addComponent(
283 | self._extender.removeHeadersButton,
284 | GroupLayout.PREFERRED_SIZE,
285 | GroupLayout.PREFERRED_SIZE,
286 | GroupLayout.PREFERRED_SIZE,
287 | ))
288 | )
289 | .addComponent(
290 | scrollReplaceString,
291 | GroupLayout.PREFERRED_SIZE,
292 | GroupLayout.PREFERRED_SIZE,
293 | GroupLayout.PREFERRED_SIZE,
294 | )
295 | .addComponent(
296 | fromLastRequestLabel,
297 | GroupLayout.PREFERRED_SIZE,
298 | GroupLayout.PREFERRED_SIZE,
299 | GroupLayout.PREFERRED_SIZE,
300 | )
301 | .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
302 | .addComponent(
303 | self._extender.fetchCookiesHeaderButton,
304 | GroupLayout.PREFERRED_SIZE,
305 | GroupLayout.PREFERRED_SIZE,
306 | GroupLayout.PREFERRED_SIZE,
307 | )
308 | .addComponent(
309 | self._extender.fetchAuthorizationHeaderButton,
310 | GroupLayout.PREFERRED_SIZE,
311 | GroupLayout.PREFERRED_SIZE,
312 | GroupLayout.PREFERRED_SIZE,
313 | ))
314 | )
315 |
316 | self._extender._cfg_splitpane = JSplitPane(JSplitPane.VERTICAL_SPLIT)
317 | self._extender._cfg_splitpane.setResizeWeight(0.5)
318 | self._extender._cfg_splitpane.setBounds(0, 0, 1000, 1000)
319 | self._extender._cfg_splitpane.setRightComponent(self._extender.filtersTabs)
320 | self._extender._cfg_splitpane.setLeftComponent(self.config_pnl)
321 |
322 | def startOrStop(self, event):
323 | if self._extender.startButton.getText() == "Autorize is off":
324 | self._extender.startButton.setText("Autorize is on")
325 | self._extender.startButton.setSelected(True)
326 | self._extender.intercept = 1
327 | else:
328 | self._extender.startButton.setText("Autorize is off")
329 | self._extender.startButton.setSelected(False)
330 | self._extender.intercept = 0
331 |
332 | def clearList(self, event):
333 | self._extender._lock.acquire()
334 | oldSize = self._extender._log.size()
335 | self._extender._log.clear()
336 | SwingUtilities.invokeLater(UpdateTableEDT(self._extender,"delete",0, oldSize - 1))
337 | self._extender._lock.release()
338 |
339 | def replaceQueryHanlder(self, event):
340 | if self._extender.replaceQueryParam.isSelected():
341 | self._extender.replaceString.setText("paramName=paramValue")
342 | else:
343 | self._extender.replaceString.setText(self.DEFUALT_REPLACE_TEXT)
344 |
345 | def saveHeaders(self, event):
346 | savedHeadersTitle = JOptionPane.showInputDialog("Please provide saved headers title:")
347 | self._extender.savedHeaders.append({'title': savedHeadersTitle, 'headers': self._extender.replaceString.getText()})
348 | self._extender.savedHeadersTitlesCombo.setModel(DefaultComboBoxModel(self.getSavedHeadersTitles()))
349 | self._extender.savedHeadersTitlesCombo.getModel().setSelectedItem(savedHeadersTitle)
350 |
351 | def removeHeaders(self, event):
352 | model = self._extender.savedHeadersTitlesCombo.getModel()
353 | selectedItem = model.getSelectedItem()
354 | if selectedItem == "Temporary headers":
355 | return
356 |
357 | delObject = None
358 | for savedHeaderObj in self._extender.savedHeaders:
359 | if selectedItem == savedHeaderObj['title']:
360 | delObject = savedHeaderObj
361 | self._extender.savedHeaders.remove(delObject)
362 | model.removeElement(selectedItem)
363 |
364 | def getSavedHeadersTitles(self):
365 | titles = []
366 | for savedHeaderObj in self._extender.savedHeaders:
367 | titles.append(savedHeaderObj['title'])
368 | return titles
369 |
370 | def fetchCookiesHeader(self, event):
371 | if self._extender.lastCookiesHeader:
372 | self._extender.replaceString.setText(self._extender.lastCookiesHeader)
373 |
374 | def fetchAuthorizationHeader(self, event):
375 | if self._extender.lastAuthorizationHeader:
376 | self._extender.replaceString.setText(self._extender.lastAuthorizationHeader)
377 |
378 | class SavedHeaderChange(ActionListener):
379 | def __init__(self, extender):
380 | self._extender = extender
381 |
382 | def actionPerformed(self, e):
383 | selectedTitle = self._extender.savedHeadersTitlesCombo.getSelectedItem()
384 | headers = [x for x in self._extender.savedHeaders if x['title'] == selectedTitle]
385 | self._extender.replaceString.setText(headers[0]['headers'])
386 |
387 |
--------------------------------------------------------------------------------
/gui/table.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | from java.awt import Color
5 | from java.lang import String
6 | from java.lang import Integer
7 | from java.lang import Runnable
8 | from javax.swing import JTable
9 | from javax.swing import JLabel
10 | from javax.swing import JPanel
11 | from javax.swing import RowFilter
12 | from javax.swing import JCheckBox
13 | from javax.swing import GroupLayout
14 | from javax.swing import ListSelectionModel
15 | from java.awt.event import MouseAdapter
16 | from java.awt.event import ItemListener
17 | from javax.swing.table import AbstractTableModel
18 | from javax.swing.event import ListSelectionListener
19 |
20 | from helpers.filters import expand, collapse
21 |
22 | class TableFilter():
23 | def __init__(self, extender):
24 | self._extender = extender
25 |
26 | def draw(self):
27 | """
28 | init show tab
29 | """
30 |
31 | filterLModified = JLabel("Modified:")
32 | filterLModified.setBounds(10, 10, 100, 30)
33 |
34 | filterLUnauthenticated = JLabel("Unauthenticated:")
35 | filterLUnauthenticated.setBounds(250, 10, 100, 30)
36 |
37 | self._extender.showAuthBypassModified = JCheckBox(self._extender.BYPASSSED_STR)
38 | self._extender.showAuthBypassModified.setBounds(10, 35, 200, 30)
39 | self._extender.showAuthBypassModified.setSelected(True)
40 | self._extender.showAuthBypassModified.addItemListener(TabTableFilter(self._extender))
41 |
42 | self._extender.showAuthPotentiallyEnforcedModified = JCheckBox("Is enforced???")
43 | self._extender.showAuthPotentiallyEnforcedModified.setBounds(10, 60, 200, 30)
44 | self._extender.showAuthPotentiallyEnforcedModified.setSelected(True)
45 | self._extender.showAuthPotentiallyEnforcedModified.addItemListener(TabTableFilter(self._extender))
46 |
47 | self._extender.showAuthEnforcedModified = JCheckBox(self._extender.ENFORCED_STR)
48 | self._extender.showAuthEnforcedModified.setBounds(10, 85, 200, 30)
49 | self._extender.showAuthEnforcedModified.setSelected(True)
50 | self._extender.showAuthEnforcedModified.addItemListener(TabTableFilter(self._extender))
51 |
52 | self._extender.showAuthBypassUnauthenticated = JCheckBox(self._extender.BYPASSSED_STR)
53 | self._extender.showAuthBypassUnauthenticated.setBounds(250, 35, 200, 30)
54 | self._extender.showAuthBypassUnauthenticated.setSelected(True)
55 | self._extender.showAuthBypassUnauthenticated.addItemListener(TabTableFilter(self._extender))
56 |
57 | self._extender.showAuthPotentiallyEnforcedUnauthenticated = JCheckBox("Is enforced???")
58 | self._extender.showAuthPotentiallyEnforcedUnauthenticated.setBounds(250, 60, 200, 30)
59 | self._extender.showAuthPotentiallyEnforcedUnauthenticated.setSelected(True)
60 | self._extender.showAuthPotentiallyEnforcedUnauthenticated.addItemListener(TabTableFilter(self._extender))
61 |
62 | self._extender.showAuthEnforcedUnauthenticated = JCheckBox(self._extender.ENFORCED_STR)
63 | self._extender.showAuthEnforcedUnauthenticated.setBounds(250, 85, 200, 30)
64 | self._extender.showAuthEnforcedUnauthenticated.setSelected(True)
65 | self._extender.showAuthEnforcedUnauthenticated.addItemListener(TabTableFilter(self._extender))
66 |
67 | self._extender.showDisabledUnauthenticated = JCheckBox("Disabled")
68 | self._extender.showDisabledUnauthenticated.setBounds(250, 110, 200, 30)
69 | self._extender.showDisabledUnauthenticated.setSelected(True)
70 | self._extender.showDisabledUnauthenticated.addItemListener(TabTableFilter(self._extender))
71 |
72 | self._extender.filterPnl = JPanel()
73 | layout = GroupLayout(self._extender.filterPnl)
74 | self._extender.filterPnl.setLayout(layout)
75 | layout.setAutoCreateGaps(True)
76 | layout.setAutoCreateContainerGaps(True)
77 |
78 | layout.setHorizontalGroup(layout.createSequentialGroup()
79 | .addGroup(layout.createParallelGroup()
80 | .addComponent(
81 | filterLModified,
82 | GroupLayout.PREFERRED_SIZE,
83 | GroupLayout.PREFERRED_SIZE,
84 | GroupLayout.PREFERRED_SIZE,
85 | )
86 | .addComponent(
87 | self._extender.showAuthBypassModified,
88 | GroupLayout.PREFERRED_SIZE,
89 | GroupLayout.PREFERRED_SIZE,
90 | GroupLayout.PREFERRED_SIZE,
91 | )
92 | .addComponent(
93 | self._extender.showAuthPotentiallyEnforcedModified,
94 | GroupLayout.PREFERRED_SIZE,
95 | GroupLayout.PREFERRED_SIZE,
96 | GroupLayout.PREFERRED_SIZE,
97 | )
98 | .addComponent(
99 | self._extender.showAuthEnforcedModified,
100 | GroupLayout.PREFERRED_SIZE,
101 | GroupLayout.PREFERRED_SIZE,
102 | GroupLayout.PREFERRED_SIZE,
103 | )
104 | )
105 | .addGroup(layout.createParallelGroup()
106 | .addComponent(
107 | filterLUnauthenticated,
108 | GroupLayout.PREFERRED_SIZE,
109 | GroupLayout.PREFERRED_SIZE,
110 | GroupLayout.PREFERRED_SIZE,
111 | )
112 | .addComponent(
113 | self._extender.showAuthBypassUnauthenticated,
114 | GroupLayout.PREFERRED_SIZE,
115 | GroupLayout.PREFERRED_SIZE,
116 | GroupLayout.PREFERRED_SIZE,
117 | )
118 | .addComponent(
119 | self._extender.showAuthPotentiallyEnforcedUnauthenticated,
120 | GroupLayout.PREFERRED_SIZE,
121 | GroupLayout.PREFERRED_SIZE,
122 | GroupLayout.PREFERRED_SIZE,
123 | )
124 | .addComponent(
125 | self._extender.showAuthEnforcedUnauthenticated,
126 | GroupLayout.PREFERRED_SIZE,
127 | GroupLayout.PREFERRED_SIZE,
128 | GroupLayout.PREFERRED_SIZE,
129 | )
130 | .addComponent(
131 | self._extender.showDisabledUnauthenticated,
132 | GroupLayout.PREFERRED_SIZE,
133 | GroupLayout.PREFERRED_SIZE,
134 | GroupLayout.PREFERRED_SIZE,
135 | )
136 | )
137 | )
138 |
139 |
140 | layout.setVerticalGroup(layout.createSequentialGroup()
141 | .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
142 | .addComponent(
143 | filterLModified,
144 | GroupLayout.PREFERRED_SIZE,
145 | GroupLayout.PREFERRED_SIZE,
146 | GroupLayout.PREFERRED_SIZE,
147 | )
148 | .addComponent(
149 | filterLUnauthenticated,
150 | GroupLayout.PREFERRED_SIZE,
151 | GroupLayout.PREFERRED_SIZE,
152 | GroupLayout.PREFERRED_SIZE,
153 | )
154 | )
155 | .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
156 | .addGroup(layout.createSequentialGroup()
157 | .addComponent(
158 | self._extender.showAuthBypassModified,
159 | GroupLayout.PREFERRED_SIZE,
160 | GroupLayout.PREFERRED_SIZE,
161 | GroupLayout.PREFERRED_SIZE,
162 | )
163 | .addComponent(
164 | self._extender.showAuthPotentiallyEnforcedModified,
165 | GroupLayout.PREFERRED_SIZE,
166 | GroupLayout.PREFERRED_SIZE,
167 | GroupLayout.PREFERRED_SIZE,
168 | )
169 | .addComponent(
170 | self._extender.showAuthEnforcedModified,
171 | GroupLayout.PREFERRED_SIZE,
172 | GroupLayout.PREFERRED_SIZE,
173 | GroupLayout.PREFERRED_SIZE,
174 | )
175 | )
176 | .addGroup(layout.createSequentialGroup()
177 | .addComponent(
178 | self._extender.showAuthBypassUnauthenticated,
179 | GroupLayout.PREFERRED_SIZE,
180 | GroupLayout.PREFERRED_SIZE,
181 | GroupLayout.PREFERRED_SIZE,
182 | )
183 | .addComponent(
184 | self._extender.showAuthPotentiallyEnforcedUnauthenticated,
185 | GroupLayout.PREFERRED_SIZE,
186 | GroupLayout.PREFERRED_SIZE,
187 | GroupLayout.PREFERRED_SIZE,
188 | )
189 | .addComponent(
190 | self._extender.showAuthEnforcedUnauthenticated,
191 | GroupLayout.PREFERRED_SIZE,
192 | GroupLayout.PREFERRED_SIZE,
193 | GroupLayout.PREFERRED_SIZE,
194 | )
195 | .addComponent(
196 | self._extender.showDisabledUnauthenticated,
197 | GroupLayout.PREFERRED_SIZE,
198 | GroupLayout.PREFERRED_SIZE,
199 | GroupLayout.PREFERRED_SIZE,
200 | )
201 | )
202 | )
203 | )
204 |
205 | class TabTableFilter(ItemListener):
206 | def __init__(self, extender):
207 | self._extender = extender
208 |
209 | def itemStateChanged(self, e):
210 | self._extender.tableSorter.sort()
211 |
212 | class TableModel(AbstractTableModel):
213 | def __init__(self, extender):
214 | self._extender = extender
215 |
216 | def removeRows(self, rows):
217 | rows.sort(reverse=True)
218 | for row in rows:
219 | self._extender._log.pop(row)
220 | self.fireTableDataChanged()
221 |
222 | def getRowCount(self):
223 | try:
224 | return self._extender._log.size()
225 | except:
226 | return 0
227 |
228 | def getColumnCount(self):
229 | return 8
230 |
231 | def getColumnName(self, columnIndex):
232 | data = ['ID','Method', 'URL', 'Orig. Len', 'Modif. Len', "Unauth. Len",
233 | "Authz. Status", "Unauth. Status"]
234 | try:
235 | return data[columnIndex]
236 | except IndexError:
237 | return ""
238 |
239 | def getColumnClass(self, columnIndex):
240 | data = [Integer, String, String, Integer, Integer, Integer, String, String]
241 | try:
242 | return data[columnIndex]
243 | except IndexError:
244 | return ""
245 |
246 | def getValueAt(self, rowIndex, columnIndex):
247 | logEntry = self._extender._log.get(rowIndex)
248 | if columnIndex == 0:
249 | return logEntry._id
250 | if columnIndex == 1:
251 | return logEntry._method
252 | if columnIndex == 2:
253 | return logEntry._url.toString()
254 | if columnIndex == 3:
255 | response = logEntry._originalrequestResponse.getResponse()
256 | return len(logEntry._originalrequestResponse.getResponse()) - self._extender._helpers.analyzeResponse(response).getBodyOffset()
257 | if columnIndex == 4:
258 | response = logEntry._requestResponse.getResponse()
259 | return len(logEntry._requestResponse.getResponse()) - self._extender._helpers.analyzeResponse(response).getBodyOffset()
260 | if columnIndex == 5:
261 | if logEntry._unauthorizedRequestResponse is not None:
262 | response = logEntry._unauthorizedRequestResponse.getResponse()
263 | return len(logEntry._unauthorizedRequestResponse.getResponse()) - self._extender._helpers.analyzeResponse(response).getBodyOffset()
264 | else:
265 | return 0
266 | if columnIndex == 6:
267 | return logEntry._enfocementStatus
268 | if columnIndex == 7:
269 | return logEntry._enfocementStatusUnauthorized
270 | return ""
271 |
272 | class TableSelectionListener(ListSelectionListener):
273 | """Class Responsible for the multi-row deletion"""
274 | def __init__(self, extender):
275 | self._extender = extender
276 |
277 | def valueChanged(self, e):
278 | rows = [i for i in self._table.getSelectedRows()]
279 | self._extender.tableModel.removeRows(rows)
280 |
281 | class Table(JTable):
282 | def __init__(self, extender):
283 | self._extender = extender
284 | self._extender.tableModel = TableModel(extender)
285 | self.setModel(self._extender.tableModel)
286 | self.addMouseListener(Mouseclick(self._extender))
287 | self.getColumnModel().getColumn(0).setPreferredWidth(450)
288 | self.setRowSelectionAllowed(True)
289 | # Enables multi-row selection
290 | self.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION)
291 |
292 | def prepareRenderer(self, renderer, row, col):
293 | comp = JTable.prepareRenderer(self, renderer, row, col)
294 | value = self._extender.tableModel.getValueAt(self._extender.logTable.convertRowIndexToModel(row), col)
295 | if col == 6 or col == 7:
296 | if value == self._extender.BYPASSSED_STR:
297 | comp.setBackground(Color(255, 153, 153))
298 | comp.setForeground(Color.BLACK)
299 | elif value == self._extender.IS_ENFORCED_STR:
300 | comp.setBackground(Color(255, 204, 153))
301 | comp.setForeground(Color.BLACK)
302 | elif value == self._extender.ENFORCED_STR:
303 | comp.setBackground(Color(204, 255, 153))
304 | comp.setForeground(Color.BLACK)
305 | else:
306 | comp.setForeground(Color.BLACK)
307 | comp.setBackground(Color.WHITE)
308 |
309 | selectedRows = self._extender.logTable.getSelectedRows()
310 | if row in selectedRows:
311 | comp.setBackground(Color(201, 215, 255))
312 | comp.setForeground(Color.BLACK)
313 |
314 | return comp
315 |
316 | def changeSelection(self, row, col, toggle, extend):
317 | # show the log entry for the selected row
318 | logEntry = self._extender._log.get(self._extender.logTable.convertRowIndexToModel(row))
319 | self._extender._requestViewer.setMessage(logEntry._requestResponse.getRequest(), True)
320 | self._extender._responseViewer.setMessage(logEntry._requestResponse.getResponse(), False)
321 | self._extender._originalrequestViewer.setMessage(logEntry._originalrequestResponse.getRequest(), True)
322 | self._extender._originalresponseViewer.setMessage(logEntry._originalrequestResponse.getResponse(), False)
323 |
324 | if logEntry._unauthorizedRequestResponse is not None:
325 | self._extender._unauthorizedrequestViewer.setMessage(logEntry._unauthorizedRequestResponse.getRequest(), True)
326 | self._extender._unauthorizedresponseViewer.setMessage(logEntry._unauthorizedRequestResponse.getResponse(), False)
327 | else:
328 | self._extender._unauthorizedrequestViewer.setMessage("Request disabled", True)
329 | self._extender._unauthorizedresponseViewer.setMessage("Response disabled", False)
330 |
331 | self._extender._currentlyDisplayedItem = logEntry
332 |
333 | if col == 3:
334 | collapse(self._extender, self._extender.modified_requests_tabs)
335 | collapse(self._extender, self._extender.unauthenticated_requests_tabs)
336 | expand(self._extender, self._extender.original_requests_tabs)
337 | elif col == 4 or col == 6:
338 | collapse(self._extender, self._extender.original_requests_tabs)
339 | collapse(self._extender, self._extender.unauthenticated_requests_tabs)
340 | expand(self._extender, self._extender.modified_requests_tabs)
341 | elif col == 5 or col == 7:
342 | collapse(self._extender, self._extender.original_requests_tabs)
343 | collapse(self._extender, self._extender.modified_requests_tabs)
344 | expand(self._extender, self._extender.unauthenticated_requests_tabs)
345 | else:
346 | collapse(self._extender, self._extender.original_requests_tabs)
347 | collapse(self._extender, self._extender.modified_requests_tabs)
348 | collapse(self._extender, self._extender.unauthenticated_requests_tabs)
349 |
350 | JTable.changeSelection(self, row, col, toggle, extend)
351 | return
352 |
353 | class LogEntry:
354 | def __init__(self, id, requestResponse, method, url, originalrequestResponse, enforcementStatus, unauthorizedRequestResponse, enforcementStatusUnauthorized):
355 | self._id = id
356 | self._requestResponse = requestResponse
357 | self._originalrequestResponse = originalrequestResponse
358 | self._method = method
359 | self._url = url
360 | self._enfocementStatus = enforcementStatus
361 | self._unauthorizedRequestResponse = unauthorizedRequestResponse
362 | self._enfocementStatusUnauthorized = enforcementStatusUnauthorized
363 | return
364 |
365 | class Mouseclick(MouseAdapter):
366 | def __init__(self, extender):
367 | self._extender = extender
368 |
369 | def mouseReleased(self, evt):
370 | if evt.button == 3:
371 | self._extender.menu.show(evt.getComponent(), evt.getX(), evt.getY())
372 |
373 | class TableRowFilter(RowFilter):
374 | def __init__(self, extender):
375 | self._extender = extender
376 |
377 | def include(self, entry):
378 | if self._extender.showAuthBypassModified.isSelected() and self._extender.BYPASSSED_STR == entry.getValue(6):
379 | return True
380 | elif self._extender.showAuthPotentiallyEnforcedModified.isSelected() and self._extender.IS_ENFORCED_STR == entry.getValue(6):
381 | return True
382 | elif self._extender.showAuthEnforcedModified.isSelected() and self._extender.ENFORCED_STR == entry.getValue(6):
383 | return True
384 | elif self._extender.showAuthBypassUnauthenticated.isSelected() and self._extender.BYPASSSED_STR == entry.getValue(7):
385 | return True
386 | elif self._extender.showAuthPotentiallyEnforcedUnauthenticated.isSelected() and self._extender.IS_ENFORCED_STR == entry.getValue(7):
387 | return True
388 | elif self._extender.showAuthEnforcedUnauthenticated.isSelected() and self._extender.ENFORCED_STR == entry.getValue(7):
389 | return True
390 | elif self._extender.showDisabledUnauthenticated.isSelected() and "Disabled" == entry.getValue(7):
391 | return True
392 | else:
393 | return False
394 |
395 | class UpdateTableEDT(Runnable):
396 | def __init__(self,extender,action,firstRow,lastRow):
397 | self._extender=extender
398 | self._action=action
399 | self._firstRow=firstRow
400 | self._lastRow=lastRow
401 |
402 | def run(self):
403 | if self._action == "insert":
404 | self._extender.tableModel.fireTableRowsInserted(self._firstRow, self._lastRow)
405 | elif self._action == "update":
406 | self._extender.tableModel.fireTableRowsUpdated(self._firstRow, self._lastRow)
407 | elif self._action == "delete":
408 | self._extender.tableModel.fireTableRowsDeleted(self._firstRow, self._lastRow)
409 | else:
410 | print("Invalid action in UpdateTableEDT")
411 |
412 |
--------------------------------------------------------------------------------
/gui/enforcement_detector.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | import sys
5 | sys.path.append("..")
6 |
7 | from javax.swing import JLabel
8 | from javax.swing import JList
9 | from javax.swing import JPanel
10 | from javax.swing import JButton
11 | from javax.swing import JTextArea
12 | from javax.swing import JComboBox
13 | from javax.swing import GroupLayout
14 | from javax.swing import JScrollPane
15 | from javax.swing import DefaultListModel
16 | from javax.swing.border import LineBorder
17 |
18 | from helpers.filters import addFilterHelper, delFilterHelper, modFilterHelper
19 |
20 | class EnforcementDetectors():
21 | def __init__(self, extender):
22 | self._extender = extender
23 |
24 | def draw(self):
25 | """
26 | init enforcement detector tab
27 | """
28 |
29 | EDLType = JLabel("Type:")
30 | EDLType.setBounds(10, 10, 140, 30)
31 |
32 | EDLContent = JLabel("Content:")
33 | EDLContent.setBounds(10, 50, 140, 30)
34 |
35 | EDLabelList = JLabel("Filter List:")
36 | EDLabelList.setBounds(10, 165, 140, 30)
37 |
38 | EDStrings = [
39 | "Headers (simple string): (enforced message headers contain)",
40 | "Headers NOT (simple string): (enforced message headers NOT contain)",
41 | "Headers (regex): (enforced message headers contain)",
42 | "Headers NOT (regex): (enforced message headers NOT contain)",
43 | "Body (simple string): (enforced message body contains)",
44 | "Body NOT (simple string): (enforced message body NOT contains)",
45 | "Body (regex): (enforced message body contains)",
46 | "Body NOT (regex): (enforced message body NOT contains)",
47 | "Full response (simple string): (enforced message contains)",
48 | "Full response NOT (simple string): (enforced message NOT contains)",
49 | "Full response (regex): (enforced message contains)",
50 | "Full response NOT (regex): (enforced message NOT contains)",
51 | "Full response length: (of enforced response)",
52 | "Full response NOT length: (of enforced response)",
53 | "Status code equals: (numbers only)",
54 | "Status code NOT equals: (numbers only)"
55 | ]
56 | self._extender.EDType = JComboBox(EDStrings)
57 | self._extender.EDType.setBounds(80, 10, 430, 30)
58 |
59 | self._extender.EDText = JTextArea("", 5, 30)
60 |
61 | scrollEDText = JScrollPane(self._extender.EDText)
62 | scrollEDText.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED)
63 | scrollEDText.setBounds(80, 50, 300, 110)
64 |
65 | self._extender.EDModel = DefaultListModel()
66 | self._extender.EDList = JList(self._extender.EDModel)
67 | self._extender.EDList.setPrototypeCellValue("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
68 | scrollEDList = JScrollPane(self._extender.EDList)
69 | scrollEDList.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED)
70 | scrollEDList.setBounds(80, 175, 300, 110)
71 |
72 | self._extender.EDAdd = JButton("Add filter", actionPerformed=self.addEDFilter)
73 | self._extender.EDAdd.setBounds(390, 85, 120, 30)
74 | self._extender.EDDel = JButton("Remove filter", actionPerformed=self.delEDFilter)
75 | self._extender.EDDel.setBounds(390, 210, 120, 30)
76 | self._extender.EDMod = JButton("Modify filter", actionPerformed=self.modEDFilter)
77 | self._extender.EDMod.setBounds(390, 250, 120, 30)
78 |
79 | AndOrStrings = ["And", "Or"]
80 | self._extender.AndOrType = JComboBox(AndOrStrings)
81 | self._extender.AndOrType.setBounds(390, 170, 120, 30)
82 |
83 | self._extender.EDPnl = JPanel()
84 | layout = GroupLayout(self._extender.EDPnl)
85 | self._extender.EDPnl.setLayout(layout)
86 | layout.setAutoCreateGaps(True)
87 | layout.setAutoCreateContainerGaps(True)
88 |
89 | layout.setHorizontalGroup(
90 | layout.createSequentialGroup()
91 | .addGroup(
92 | layout.createParallelGroup()
93 | .addComponent(
94 | EDLType,
95 | GroupLayout.PREFERRED_SIZE,
96 | GroupLayout.PREFERRED_SIZE,
97 | GroupLayout.PREFERRED_SIZE,
98 | )
99 | .addComponent(
100 | EDLContent,
101 | GroupLayout.PREFERRED_SIZE,
102 | GroupLayout.PREFERRED_SIZE,
103 | GroupLayout.PREFERRED_SIZE,
104 | )
105 | .addComponent(
106 | EDLabelList,
107 | GroupLayout.PREFERRED_SIZE,
108 | GroupLayout.PREFERRED_SIZE,
109 | GroupLayout.PREFERRED_SIZE,
110 | )
111 | )
112 | .addGroup(
113 | layout.createParallelGroup()
114 | .addComponent(
115 | self._extender.EDType,
116 | GroupLayout.PREFERRED_SIZE,
117 | GroupLayout.PREFERRED_SIZE,
118 | GroupLayout.PREFERRED_SIZE,
119 | )
120 | .addComponent(
121 | scrollEDText,
122 | GroupLayout.PREFERRED_SIZE,
123 | GroupLayout.PREFERRED_SIZE,
124 | GroupLayout.PREFERRED_SIZE,
125 | )
126 | .addComponent(
127 | scrollEDList,
128 | GroupLayout.PREFERRED_SIZE,
129 | GroupLayout.PREFERRED_SIZE,
130 | GroupLayout.PREFERRED_SIZE,
131 | )
132 | .addComponent(
133 | self._extender.EDAdd,
134 | GroupLayout.PREFERRED_SIZE,
135 | GroupLayout.PREFERRED_SIZE,
136 | GroupLayout.PREFERRED_SIZE,
137 | )
138 | .addComponent(
139 | self._extender.AndOrType,
140 | GroupLayout.PREFERRED_SIZE,
141 | GroupLayout.PREFERRED_SIZE,
142 | GroupLayout.PREFERRED_SIZE,
143 | )
144 | .addComponent(
145 | self._extender.EDDel,
146 | GroupLayout.PREFERRED_SIZE,
147 | GroupLayout.PREFERRED_SIZE,
148 | GroupLayout.PREFERRED_SIZE,
149 | )
150 | .addComponent(
151 | self._extender.EDMod,
152 | GroupLayout.PREFERRED_SIZE,
153 | GroupLayout.PREFERRED_SIZE,
154 | GroupLayout.PREFERRED_SIZE,
155 | )
156 | )
157 | )
158 |
159 | layout.setVerticalGroup(
160 | layout.createSequentialGroup()
161 | .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
162 | .addComponent(
163 | EDLType,
164 | GroupLayout.PREFERRED_SIZE,
165 | GroupLayout.PREFERRED_SIZE,
166 | GroupLayout.PREFERRED_SIZE,
167 | )
168 | .addComponent(
169 | self._extender.EDType,
170 | GroupLayout.PREFERRED_SIZE,
171 | GroupLayout.PREFERRED_SIZE,
172 | GroupLayout.PREFERRED_SIZE,
173 | )
174 | )
175 | .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
176 | .addComponent(
177 | EDLContent,
178 | GroupLayout.PREFERRED_SIZE,
179 | GroupLayout.PREFERRED_SIZE,
180 | GroupLayout.PREFERRED_SIZE,
181 | )
182 | .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
183 | .addComponent(
184 | scrollEDText,
185 | GroupLayout.PREFERRED_SIZE,
186 | GroupLayout.PREFERRED_SIZE,
187 | GroupLayout.PREFERRED_SIZE,
188 | )
189 |
190 | )
191 | )
192 | .addComponent(
193 | self._extender.EDAdd,
194 | GroupLayout.PREFERRED_SIZE,
195 | GroupLayout.PREFERRED_SIZE,
196 | GroupLayout.PREFERRED_SIZE,
197 | )
198 | .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
199 | .addComponent(
200 | EDLabelList,
201 | GroupLayout.PREFERRED_SIZE,
202 | GroupLayout.PREFERRED_SIZE,
203 | GroupLayout.PREFERRED_SIZE,
204 | )
205 | .addComponent(
206 | self._extender.AndOrType,
207 | GroupLayout.PREFERRED_SIZE,
208 | GroupLayout.PREFERRED_SIZE,
209 | GroupLayout.PREFERRED_SIZE,
210 | )
211 | )
212 | .addComponent(
213 | scrollEDList,
214 | GroupLayout.PREFERRED_SIZE,
215 | GroupLayout.PREFERRED_SIZE,
216 | GroupLayout.PREFERRED_SIZE,
217 | )
218 | .addComponent(
219 | self._extender.EDDel,
220 | GroupLayout.PREFERRED_SIZE,
221 | GroupLayout.PREFERRED_SIZE,
222 | GroupLayout.PREFERRED_SIZE,
223 | )
224 | .addComponent(
225 | self._extender.EDMod,
226 | GroupLayout.PREFERRED_SIZE,
227 | GroupLayout.PREFERRED_SIZE,
228 | GroupLayout.PREFERRED_SIZE,
229 | )
230 | )
231 |
232 |
233 | def draw_unauthenticated(self):
234 | """ init enforcement detector tab
235 | """
236 |
237 | EDLType = JLabel("Type:")
238 | EDLType.setBounds(10, 10, 140, 30)
239 |
240 | EDLContent = JLabel("Content:")
241 | EDLContent.setBounds(10, 50, 140, 30)
242 |
243 | EDLabelList = JLabel("Filter List:")
244 | EDLabelList.setBounds(10, 165, 140, 30)
245 |
246 | EDStrings = [
247 | "Headers (simple string): (enforced message headers contain)",
248 | "Headers NOT (simple string): (enforced message headers NOT contain)",
249 | "Headers (regex): (enforced message headers contain)",
250 | "Headers NOT (regex): (enforced message headers NOT contain)",
251 | "Body (simple string): (enforced message body contains)",
252 | "Body NOT (simple string): (enforced message body NOT contains)",
253 | "Body (regex): (enforced message body contains)",
254 | "Body NOT (regex): (enforced message body NOT contains)",
255 | "Full response (simple string): (enforced message contains)",
256 | "Full response NOT (simple string): (enforced message NOT contains)",
257 | "Full response (regex): (enforced message contains)",
258 | "Full response NOT (regex): (enforced message NOT contains)",
259 | "Full response length: (of enforced response)",
260 | "Full response NOT length: (of enforced response)",
261 | "Status code equals: (numbers only)",
262 | "Status code NOT equals: (numbers only)"
263 | ]
264 | self._extender.EDTypeUnauth = JComboBox(EDStrings)
265 | self._extender.EDTypeUnauth.setBounds(80, 10, 430, 30)
266 |
267 | self._extender.EDTextUnauth = JTextArea("", 5, 30)
268 |
269 | scrollEDTextUnauth = JScrollPane(self._extender.EDTextUnauth)
270 | scrollEDTextUnauth.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED)
271 | scrollEDTextUnauth.setBounds(80, 50, 300, 110)
272 |
273 | self._extender.EDModelUnauth = DefaultListModel()
274 | self._extender.EDListUnauth = JList(self._extender.EDModelUnauth)
275 | self._extender.EDListUnauth.setPrototypeCellValue("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
276 | scrollEDListUnauth = JScrollPane(self._extender.EDListUnauth)
277 | scrollEDListUnauth.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED)
278 | scrollEDListUnauth.setBounds(80, 175, 300, 110)
279 |
280 | self._extender.EDAddUnauth = JButton("Add filter",
281 | actionPerformed=self.addEDFilterUnauth)
282 | self._extender.EDAddUnauth.setBounds(390, 85, 120, 30)
283 | self._extender.EDDelUnauth = JButton("Remove filter",
284 | actionPerformed=self.delEDFilterUnauth)
285 | self._extender.EDDelUnauth.setBounds(390, 210, 120, 30)
286 | self._extender.EDModUnauth = JButton("Modify filter",
287 | actionPerformed=self.modEDFilterUnauth)
288 | self._extender.EDModUnauth.setBounds(390, 250, 120, 30)
289 |
290 | AndOrStrings = ["And", "Or"]
291 | self._extender.AndOrTypeUnauth = JComboBox(AndOrStrings)
292 | self._extender.AndOrTypeUnauth.setBounds(390, 170, 120, 30)
293 |
294 | self._extender.EDPnlUnauth = JPanel()
295 | layout = GroupLayout(self._extender.EDPnlUnauth)
296 | self._extender.EDPnlUnauth.setLayout(layout)
297 | layout.setAutoCreateGaps(True)
298 | layout.setAutoCreateContainerGaps(True)
299 |
300 | layout.setHorizontalGroup(
301 | layout.createSequentialGroup()
302 | .addGroup(
303 | layout.createParallelGroup()
304 | .addComponent(
305 | EDLType,
306 | GroupLayout.PREFERRED_SIZE,
307 | GroupLayout.PREFERRED_SIZE,
308 | GroupLayout.PREFERRED_SIZE,
309 | )
310 | .addComponent(
311 | EDLContent,
312 | GroupLayout.PREFERRED_SIZE,
313 | GroupLayout.PREFERRED_SIZE,
314 | GroupLayout.PREFERRED_SIZE,
315 | )
316 | .addComponent(
317 | EDLabelList,
318 | GroupLayout.PREFERRED_SIZE,
319 | GroupLayout.PREFERRED_SIZE,
320 | GroupLayout.PREFERRED_SIZE,
321 | )
322 | )
323 | .addGroup(
324 | layout.createParallelGroup()
325 | .addComponent(
326 | self._extender.EDTypeUnauth,
327 | GroupLayout.PREFERRED_SIZE,
328 | GroupLayout.PREFERRED_SIZE,
329 | GroupLayout.PREFERRED_SIZE,
330 | )
331 | .addComponent(
332 | scrollEDTextUnauth,
333 | GroupLayout.PREFERRED_SIZE,
334 | GroupLayout.PREFERRED_SIZE,
335 | GroupLayout.PREFERRED_SIZE,
336 | )
337 | .addComponent(
338 | scrollEDListUnauth,
339 | GroupLayout.PREFERRED_SIZE,
340 | GroupLayout.PREFERRED_SIZE,
341 | GroupLayout.PREFERRED_SIZE,
342 | )
343 | .addComponent(
344 | self._extender.EDAddUnauth,
345 | GroupLayout.PREFERRED_SIZE,
346 | GroupLayout.PREFERRED_SIZE,
347 | GroupLayout.PREFERRED_SIZE,
348 | )
349 | .addComponent(
350 | self._extender.AndOrTypeUnauth,
351 | GroupLayout.PREFERRED_SIZE,
352 | GroupLayout.PREFERRED_SIZE,
353 | GroupLayout.PREFERRED_SIZE,
354 | )
355 | .addComponent(
356 | self._extender.EDDelUnauth,
357 | GroupLayout.PREFERRED_SIZE,
358 | GroupLayout.PREFERRED_SIZE,
359 | GroupLayout.PREFERRED_SIZE,
360 | )
361 | .addComponent(
362 | self._extender.EDModUnauth,
363 | GroupLayout.PREFERRED_SIZE,
364 | GroupLayout.PREFERRED_SIZE,
365 | GroupLayout.PREFERRED_SIZE,
366 | )
367 | )
368 | )
369 |
370 |
371 |
372 | layout.setVerticalGroup(
373 | layout.createSequentialGroup()
374 | .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
375 | .addComponent(
376 | EDLType,
377 | GroupLayout.PREFERRED_SIZE,
378 | GroupLayout.PREFERRED_SIZE,
379 | GroupLayout.PREFERRED_SIZE,
380 | )
381 | .addComponent(
382 | self._extender.EDTypeUnauth,
383 | GroupLayout.PREFERRED_SIZE,
384 | GroupLayout.PREFERRED_SIZE,
385 | GroupLayout.PREFERRED_SIZE,
386 | )
387 | )
388 | .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
389 | .addComponent(
390 | EDLContent,
391 | GroupLayout.PREFERRED_SIZE,
392 | GroupLayout.PREFERRED_SIZE,
393 | GroupLayout.PREFERRED_SIZE,
394 | )
395 | .addComponent(
396 | scrollEDTextUnauth,
397 | GroupLayout.PREFERRED_SIZE,
398 | GroupLayout.PREFERRED_SIZE,
399 | GroupLayout.PREFERRED_SIZE,
400 | )
401 | )
402 | .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
403 | .addComponent(
404 | self._extender.EDAddUnauth,
405 | GroupLayout.PREFERRED_SIZE,
406 | GroupLayout.PREFERRED_SIZE,
407 | GroupLayout.PREFERRED_SIZE,
408 | )
409 | )
410 | .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
411 | .addComponent(
412 | EDLabelList,
413 | GroupLayout.PREFERRED_SIZE,
414 | GroupLayout.PREFERRED_SIZE,
415 | GroupLayout.PREFERRED_SIZE,
416 | )
417 | .addComponent(
418 | self._extender.AndOrTypeUnauth,
419 | GroupLayout.PREFERRED_SIZE,
420 | GroupLayout.PREFERRED_SIZE,
421 | GroupLayout.PREFERRED_SIZE,
422 | )
423 | )
424 | .addComponent(
425 | scrollEDListUnauth,
426 | GroupLayout.PREFERRED_SIZE,
427 | GroupLayout.PREFERRED_SIZE,
428 | GroupLayout.PREFERRED_SIZE,
429 | )
430 | .addComponent(
431 | self._extender.EDDelUnauth,
432 | GroupLayout.PREFERRED_SIZE,
433 | GroupLayout.PREFERRED_SIZE,
434 | GroupLayout.PREFERRED_SIZE,
435 | )
436 | .addComponent(
437 | self._extender.EDModUnauth,
438 | GroupLayout.PREFERRED_SIZE,
439 | GroupLayout.PREFERRED_SIZE,
440 | GroupLayout.PREFERRED_SIZE,
441 | )
442 | )
443 |
444 | def addEDFilter(self, event):
445 | addFilterHelper(self._extender.EDType, self._extender.EDModel, self._extender.EDText)
446 |
447 | def delEDFilter(self, event):
448 | delFilterHelper(self._extender.EDList)
449 |
450 | def modEDFilter(self, event):
451 | modFilterHelper(self._extender.EDList, self._extender.EDType, self._extender.EDText)
452 |
453 | def addEDFilterUnauth(self, event):
454 | addFilterHelper(self._extender.EDTypeUnauth, self._extender.EDModelUnauth, self._extender.EDTextUnauth)
455 |
456 | def delEDFilterUnauth(self, event):
457 | delFilterHelper(self._extender.EDListUnauth)
458 |
459 | def modEDFilterUnauth(self, event):
460 | modFilterHelper(self._extender.EDListUnauth, self._extender.EDTypeUnauth, self._extender.EDTextUnauth)
461 |
--------------------------------------------------------------------------------
/gui/export.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | import sys
5 | sys.path.append("..")
6 |
7 | from java.io import File
8 | from java.awt import Font
9 | from javax.swing import JLabel
10 | from javax.swing import JLabel
11 | from javax.swing import JPanel
12 | from javax.swing import JFrame
13 | from javax.swing import JButton
14 | from javax.swing import JCheckBox
15 | from javax.swing import JComboBox
16 | from javax.swing import GroupLayout
17 | from javax.swing import JFileChooser
18 | from java.awt.event import ItemListener
19 |
20 | from save_restore import SaveRestore
21 |
22 | class RemoveDups(ItemListener):
23 | def __init__(self, extender):
24 | self._extender = extender
25 |
26 | def itemStateChanged(self, e):
27 | return True
28 |
29 | class Export():
30 | def __init__(self, extender):
31 | self._extender = extender
32 | self.BYPASSSED_STR = extender.BYPASSSED_STR
33 | self.ENFORCED_STR = extender.ENFORCED_STR
34 | self.IS_ENFORCED_STR = extender.IS_ENFORCED_STR
35 | self._log = extender._log
36 | self.save_restore = SaveRestore(extender)
37 |
38 | def draw(self):
39 | """ init Save/Restore
40 | """
41 |
42 | exportLabel = JLabel("Export:")
43 | exportLabel.setBounds(10, 10, 100, 30)
44 | labelFont = exportLabel.getFont()
45 | boldFont = Font(labelFont.getFontName(), Font.BOLD, labelFont.getSize())
46 | exportLabel.setFont(boldFont)
47 |
48 | exportLType = JLabel("File Type:")
49 | exportLType.setBounds(10, 50, 100, 30)
50 |
51 | exportFileTypes = ["HTML", "CSV"]
52 | self.exportType = JComboBox(exportFileTypes)
53 | self.exportType.setBounds(100, 50, 200, 30)
54 |
55 | exportES = ["All Statuses", "As table filter",
56 | self._extender.BYPASSSED_STR,
57 | self._extender.IS_ENFORCED_STR,
58 | self._extender.ENFORCED_STR]
59 | self.exportES = JComboBox(exportES)
60 | self.exportES.setBounds(100, 90, 200, 30)
61 |
62 | exportLES = JLabel("Statuses:")
63 | exportLES.setBounds(10, 90, 100, 30)
64 |
65 | self.removeDuplicates = JCheckBox("Remove Duplicates")
66 | self.removeDuplicates.setBounds(8, 120, 300, 30)
67 | self.removeDuplicates.setSelected(True)
68 | self.removeDuplicates.addItemListener(RemoveDups(self._extender))
69 |
70 | self.exportButton = JButton("Export",
71 | actionPerformed=self.export)
72 | self.exportButton.setBounds(390, 50, 100, 30)
73 |
74 | saveRestoreLabel = JLabel("State (incl. Configuration):")
75 | saveRestoreLabel.setBounds(10, 160, 250, 30)
76 | saveRestoreLabel.setFont(boldFont)
77 |
78 | self.saveStateButton = JButton("Save",
79 | actionPerformed=self.saveStateAction)
80 | self.saveStateButton.setBounds(10, 200, 100, 30)
81 |
82 | self.restoreStateButton = JButton("Restore",
83 | actionPerformed=self.restoreStateAction)
84 | self.restoreStateButton.setBounds(390, 200, 100, 30)
85 |
86 | self._extender.exportPnl = JPanel()
87 | layout = GroupLayout(self._extender.exportPnl)
88 | self._extender.exportPnl.setLayout(layout)
89 | layout.setAutoCreateGaps(True)
90 | layout.setAutoCreateContainerGaps(True)
91 |
92 | layout.setHorizontalGroup(layout.createSequentialGroup()
93 | .addGroup(layout.createParallelGroup()
94 | .addComponent(
95 | exportLabel,
96 | GroupLayout.PREFERRED_SIZE,
97 | GroupLayout.PREFERRED_SIZE,
98 | GroupLayout.PREFERRED_SIZE,
99 | )
100 | .addComponent(
101 | exportLType,
102 | GroupLayout.PREFERRED_SIZE,
103 | GroupLayout.PREFERRED_SIZE,
104 | GroupLayout.PREFERRED_SIZE,
105 | )
106 | .addComponent(
107 | exportLES,
108 | GroupLayout.PREFERRED_SIZE,
109 | GroupLayout.PREFERRED_SIZE,
110 | GroupLayout.PREFERRED_SIZE,
111 | )
112 | .addComponent(
113 | self.removeDuplicates,
114 | GroupLayout.PREFERRED_SIZE,
115 | GroupLayout.PREFERRED_SIZE,
116 | GroupLayout.PREFERRED_SIZE,
117 | )
118 | .addComponent(
119 | saveRestoreLabel,
120 | GroupLayout.PREFERRED_SIZE,
121 | GroupLayout.PREFERRED_SIZE,
122 | GroupLayout.PREFERRED_SIZE,
123 | )
124 | .addComponent(
125 | self.saveStateButton,
126 | GroupLayout.PREFERRED_SIZE,
127 | GroupLayout.PREFERRED_SIZE,
128 | GroupLayout.PREFERRED_SIZE,
129 | )
130 | )
131 | .addGroup(layout.createParallelGroup()
132 | .addComponent(
133 | self.exportES,
134 | GroupLayout.PREFERRED_SIZE,
135 | GroupLayout.PREFERRED_SIZE,
136 | GroupLayout.PREFERRED_SIZE,
137 | )
138 | .addComponent(
139 | self.exportType,
140 | GroupLayout.PREFERRED_SIZE,
141 | GroupLayout.PREFERRED_SIZE,
142 | GroupLayout.PREFERRED_SIZE,
143 | )
144 | )
145 | .addGroup(layout.createParallelGroup()
146 | .addComponent(
147 | self.exportButton,
148 | GroupLayout.PREFERRED_SIZE,
149 | GroupLayout.PREFERRED_SIZE,
150 | GroupLayout.PREFERRED_SIZE,
151 | )
152 | .addComponent(
153 | self.restoreStateButton,
154 | GroupLayout.PREFERRED_SIZE,
155 | GroupLayout.PREFERRED_SIZE,
156 | GroupLayout.PREFERRED_SIZE,
157 | )
158 | )
159 | )
160 |
161 | layout.setVerticalGroup(layout.createSequentialGroup()
162 | .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
163 | .addComponent(
164 | exportLabel,
165 | GroupLayout.PREFERRED_SIZE,
166 | GroupLayout.PREFERRED_SIZE,
167 | GroupLayout.PREFERRED_SIZE,
168 | )
169 | )
170 | .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
171 | .addComponent(
172 | exportLType,
173 | GroupLayout.PREFERRED_SIZE,
174 | GroupLayout.PREFERRED_SIZE,
175 | GroupLayout.PREFERRED_SIZE,
176 | )
177 | .addComponent(
178 | self.exportType,
179 | GroupLayout.PREFERRED_SIZE,
180 | GroupLayout.PREFERRED_SIZE,
181 | GroupLayout.PREFERRED_SIZE,
182 | )
183 | .addComponent(
184 | self.exportButton,
185 | GroupLayout.PREFERRED_SIZE,
186 | GroupLayout.PREFERRED_SIZE,
187 | GroupLayout.PREFERRED_SIZE,
188 | )
189 | )
190 | .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
191 | .addComponent(
192 | exportLES,
193 | GroupLayout.PREFERRED_SIZE,
194 | GroupLayout.PREFERRED_SIZE,
195 | GroupLayout.PREFERRED_SIZE,
196 | )
197 | .addComponent(
198 | self.exportES,
199 | GroupLayout.PREFERRED_SIZE,
200 | GroupLayout.PREFERRED_SIZE,
201 | GroupLayout.PREFERRED_SIZE,
202 | )
203 | )
204 | .addGroup(layout.createSequentialGroup()
205 | .addComponent(
206 | self.removeDuplicates,
207 | GroupLayout.PREFERRED_SIZE,
208 | GroupLayout.PREFERRED_SIZE,
209 | GroupLayout.PREFERRED_SIZE,
210 | )
211 | )
212 | .addGroup(layout.createSequentialGroup()
213 | .addComponent(
214 | saveRestoreLabel,
215 | GroupLayout.PREFERRED_SIZE,
216 | GroupLayout.PREFERRED_SIZE,
217 | GroupLayout.PREFERRED_SIZE,
218 | )
219 | )
220 | .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
221 | .addComponent(
222 | self.saveStateButton,
223 | GroupLayout.PREFERRED_SIZE,
224 | GroupLayout.PREFERRED_SIZE,
225 | GroupLayout.PREFERRED_SIZE,
226 | )
227 | .addComponent(
228 | self.restoreStateButton,
229 | GroupLayout.PREFERRED_SIZE,
230 | GroupLayout.PREFERRED_SIZE,
231 | GroupLayout.PREFERRED_SIZE,
232 | )
233 | )
234 | )
235 |
236 |
237 |
238 | def export(self, event):
239 | if self.exportType.getSelectedItem() == "HTML":
240 | self.exportToHTML()
241 | else:
242 | self.exportToCSV()
243 |
244 | def saveStateAction(self, event):
245 | self.save_restore.saveState()
246 |
247 | def restoreStateAction(self, event):
248 | self.save_restore.restoreState()
249 |
250 | def exportToHTML(self):
251 | parentFrame = JFrame()
252 | fileChooser = JFileChooser()
253 | fileChooser.setSelectedFile(File("AutorizeReport.html"))
254 | fileChooser.setDialogTitle("Save Autorize Report")
255 | userSelection = fileChooser.showSaveDialog(parentFrame)
256 | if userSelection == JFileChooser.APPROVE_OPTION:
257 | fileToSave = fileChooser.getSelectedFile()
258 |
259 | enforcementStatusFilter = self.exportES.getSelectedItem()
260 | htmlContent = """Autorize Report by Barak Tawily
261 |
284 |
285 | Autorize Report
286 |
287 | | ID | Method | URL | Original length | Modified length | Unauthorized length | Authorization Enforcement Status | Authorization Unauthenticated Status |
288 | """
289 | unique_HTML_lines = set() # set to keep track of unique values
290 | for i in range(0,self._log.size()):
291 | if self.removeDuplicates.isSelected():
292 | # line data only looks for method, url, and authorized status. Does not factor in size of request during comparision
293 | lineData = "\t%s\t%s\t%s\t%s\n" % (self._log.get(i)._method, self._log.get(i)._url, self._log.get(i)._enfocementStatus,self._log.get(i)._enfocementStatusUnauthorized)
294 | if lineData in unique_HTML_lines: # Skip if line is already in set
295 | continue
296 | else: # Add line to set and continue with execution
297 | unique_HTML_lines.add(lineData)
298 | color_modified = ""
299 | if self._log.get(i)._enfocementStatus == self.BYPASSSED_STR:
300 | color_modified = "red"
301 | elif self._log.get(i)._enfocementStatus == self.IS_ENFORCED_STR:
302 | color_modified = "yellow"
303 | elif self._log.get(i)._enfocementStatus == self.ENFORCED_STR:
304 | color_modified = "LawnGreen"
305 |
306 | color_unauthorized = ""
307 | if self._log.get(i)._enfocementStatusUnauthorized == self.BYPASSSED_STR:
308 | color_unauthorized = "red"
309 | elif self._log.get(i)._enfocementStatusUnauthorized == self.IS_ENFORCED_STR:
310 | color_unauthorized = "yellow"
311 | elif self._log.get(i)._enfocementStatusUnauthorized == self.ENFORCED_STR:
312 | color_unauthorized = "LawnGreen"
313 |
314 | if enforcementStatusFilter == "All Statuses":
315 | htmlContent += "| %d | %s | %s | %d | %d | %d | %s | %s |
" % (self._log.get(i)._id, self._log.get(i)._method, self._log.get(i)._url, self._log.get(i)._url, len(self._log.get(i)._originalrequestResponse.getResponse()) if self._log.get(i)._originalrequestResponse is not None else 0, len(self._log.get(i)._requestResponse.getResponse()) if self._log.get(i)._requestResponse is not None else 0, len(self._log.get(i)._unauthorizedRequestResponse.getResponse()) if self._log.get(i)._unauthorizedRequestResponse is not None else 0, color_modified, self._log.get(i)._enfocementStatus, color_unauthorized, self._log.get(i)._enfocementStatusUnauthorized)
316 | elif enforcementStatusFilter == "As table filter":
317 | if ((self._extender.showAuthBypassModified.isSelected() and self.BYPASSSED_STR == self._log.get(i)._enfocementStatus) or
318 | (self._extender.showAuthPotentiallyEnforcedModified.isSelected() and "Is enforced???" == self._log.get(i)._enfocementStatus) or
319 | (self._extender.showAuthEnforcedModified.isSelected() and self.ENFORCED_STR == self._log.get(i)._enfocementStatus) or
320 | (self._extender.showAuthBypassUnauthenticated.isSelected() and self.BYPASSSED_STR == self._log.get(i)._enfocementStatusUnauthorized) or
321 | (self._extender.showAuthPotentiallyEnforcedUnauthenticated.isSelected() and "Is enforced???" == self._log.get(i)._enfocementStatusUnauthorized) or
322 | (self._extender.showAuthEnforcedUnauthenticated.isSelected() and self.ENFORCED_STR == self._log.get(i)._enfocementStatusUnauthorized) or
323 | (self._extender.showDisabledUnauthenticated.isSelected() and "Disabled" == self._log.get(i)._enfocementStatusUnauthorized)):
324 | htmlContent += "| %d | %s | %s | %d | %d | %d | %s | %s |
" % (self._log.get(i)._id, self._log.get(i)._method, self._log.get(i)._url, self._log.get(i)._url, len(self._log.get(i)._originalrequestResponse.getResponse()) if self._log.get(i)._originalrequestResponse is not None else 0, len(self._log.get(i)._requestResponse.getResponse()) if self._log.get(i)._requestResponse is not None else 0, len(self._log.get(i)._unauthorizedRequestResponse.getResponse()) if self._log.get(i)._unauthorizedRequestResponse is not None else 0, color_modified, self._log.get(i)._enfocementStatus, color_unauthorized, self._log.get(i)._enfocementStatusUnauthorized)
325 | else:
326 | if (enforcementStatusFilter == self._log.get(i)._enfocementStatus) or (enforcementStatusFilter == self._log.get(i)._enfocementStatusUnauthorized):
327 | htmlContent += "| %d | %s | %s | %d | %d | %d | %s | %s |
" % (self._log.get(i)._id, self._log.get(i)._method, self._log.get(i)._url, self._log.get(i)._url, len(self._log.get(i)._originalrequestResponse.getResponse()) if self._log.get(i)._originalrequestResponse is not None else 0, len(self._log.get(i)._requestResponse.getResponse()) if self._log.get(i)._requestResponse is not None else 0, len(self._log.get(i)._unauthorizedRequestResponse.getResponse()) if self._log.get(i)._unauthorizedRequestResponse is not None else 0, color_modified, self._log.get(i)._enfocementStatus, color_unauthorized, self._log.get(i)._enfocementStatusUnauthorized)
328 |
329 | htmlContent += "
"
330 | f = open(fileToSave.getAbsolutePath(), 'w')
331 | f.writelines(htmlContent)
332 | f.close()
333 |
334 | def exportToCSV(self):
335 | parentFrame = JFrame()
336 | fileChooser = JFileChooser()
337 | fileChooser.setSelectedFile(File("AutorizeReport.csv"))
338 | fileChooser.setDialogTitle("Save Autorize Report")
339 | userSelection = fileChooser.showSaveDialog(parentFrame)
340 | if userSelection == JFileChooser.APPROVE_OPTION:
341 | fileToSave = fileChooser.getSelectedFile()
342 |
343 | enforcementStatusFilter = self.exportES.getSelectedItem()
344 | csvContent = "id\tMethod\tURL\tOriginal length\tModified length\tUnauthorized length\tAuthorization Enforcement Status\tAuthorization Unauthenticated Status\n"
345 |
346 | unique_CVS_lines = set()
347 | for i in range(0, self._log.size()):
348 | if self.removeDuplicates.isSelected():
349 | # line data only looks for method, url, and authorized status. Does not factor in size of request during comparision
350 | lineData = "\t%s\t%s\t%s\t%s\n" % (self._log.get(i)._method, self._log.get(i)._url, self._log.get(i)._enfocementStatus,self._log.get(i)._enfocementStatusUnauthorized)
351 | if lineData in unique_CVS_lines: # Skip if line is already in set
352 | continue
353 | else: # Add line to set and continue with execution
354 | unique_CVS_lines.add(lineData)
355 | if enforcementStatusFilter == "All Statuses":
356 | csvContent += "%d\t%s\t%s\t%d\t%d\t%d\t%s\t%s\n" % (self._log.get(i)._id, self._log.get(i)._method, self._log.get(i)._url, len(self._log.get(i)._originalrequestResponse.getResponse()) if self._log.get(i)._originalrequestResponse is not None else 0, len(self._log.get(i)._requestResponse.getResponse()) if self._log.get(i)._requestResponse is not None else 0, len(self._log.get(i)._unauthorizedRequestResponse.getResponse()) if self._log.get(i)._unauthorizedRequestResponse is not None else 0, self._log.get(i)._enfocementStatus, self._log.get(i)._enfocementStatusUnauthorized)
357 | elif enforcementStatusFilter == "As table filter":
358 | if ((self._extender.showAuthBypassModified.isSelected() and self.BYPASSSED_STR == self._log.get(i)._enfocementStatus) or
359 | (self._extender.showAuthPotentiallyEnforcedModified.isSelected() and "Is enforced???" == self._log.get(i)._enfocementStatus) or
360 | (self._extender.showAuthEnforcedModified.isSelected() and self.ENFORCED_STR == self._log.get(i)._enfocementStatus) or
361 | (self._extender.showAuthBypassUnauthenticated.isSelected() and self.BYPASSSED_STR == self._log.get(i)._enfocementStatusUnauthorized) or
362 | (self._extender.showAuthPotentiallyEnforcedUnauthenticated.isSelected() and "Is enforced???" == self._log.get(i)._enfocementStatusUnauthorized) or
363 | (self._extender.showAuthEnforcedUnauthenticated.isSelected() and self.ENFORCED_STR == self._log.get(i)._enfocementStatusUnauthorized) or
364 | (self._extender.showDisabledUnauthenticated.isSelected() and "Disabled" == self._log.get(i)._enfocementStatusUnauthorized)):
365 | csvContent += "%d\t%s\t%s\t%d\t%d\t%d\t%s\t%s\n" % (self._log.get(i)._id, self._log.get(i)._method, self._log.get(i)._url, len(self._log.get(i)._originalrequestResponse.getResponse()) if self._log.get(i)._originalrequestResponse is not None else 0, len(self._log.get(i)._requestResponse.getResponse()) if self._log.get(i)._requestResponse is not None else 0, len(self._log.get(i)._unauthorizedRequestResponse.getResponse()) if self._log.get(i)._unauthorizedRequestResponse is not None else 0, self._log.get(i)._enfocementStatus, self._log.get(i)._enfocementStatusUnauthorized)
366 | else:
367 | if (enforcementStatusFilter == self._log.get(i)._enfocementStatus) or (enforcementStatusFilter == self._log.get(i)._enfocementStatusUnauthorized):
368 | csvContent += "%d\t%s\t%s\t%d\t%d\t%d\t%s\t%s\n" % (self._log.get(i)._id, self._log.get(i)._method, self._log.get(i)._url, len(self._log.get(i)._originalrequestResponse.getResponse()) if self._log.get(i)._originalrequestResponse is not None else 0, len(self._log.get(i)._requestResponse.getResponse()) if self._log.get(i)._requestResponse is not None else 0, len(self._log.get(i)._unauthorizedRequestResponse.getResponse()) if self._log.get(i)._unauthorizedRequestResponse is not None else 0, self._log.get(i)._enfocementStatus, self._log.get(i)._enfocementStatusUnauthorized)
369 |
370 |
371 | f = open(fileToSave.getAbsolutePath(), 'w')
372 | f.writelines(csvContent)
373 | f.close()
374 |
--------------------------------------------------------------------------------