Projects STRLCPY autorize Commits 9b484925
🤬
  • ■ ■ ■ ■ ■ ■
    BappManifest.bmf
    skipped 1 lines
    2 2  ExtensionType: 2
    3 3  Name: Autorize
    4 4  RepoName: autorize
    5  -ScreenVersion: 1.5
    6  -SerialVersion: 20
     5 +ScreenVersion: 1.6
     6 +SerialVersion: 21
    7 7  MinPlatformVersion: 0
    8 8  ProOnly: False
    9  -Author: Barak Tawily
     9 +Author: Barak Tawily, AppSec Labs
    10 10  ShortDescription: Automatically detects authorization enforcement.
    11 11  EntryPoint: Autorize.py
    12 12  BuildCommand:
    skipped 2 lines
  • ■ ■ ■ ■
    README.md
    skipped 51 lines
    52 52   
    53 53   
    54 54  # Authors
    55  -- Barak Tawily, CTO @ [enso.security](https://enso.security/) by day, [Application Security Researcher](https://quitten.github.io/) by night
     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 56   
  • ■ ■ ■ ■ ■ ■
    authorization/authorization.py
    1 1  #!/usr/bin/env python
    2 2  # -*- coding: utf-8 -*-
    3 3   
     4 +from operator import truediv
    4 5  import sys
    5 6  reload(sys)
    6 7   
    7  -sys.setdefaultencoding('utf8')
     8 +if (sys.version_info[0] == 2):
     9 + sys.setdefaultencoding('utf8')
     10 + 
    8 11  sys.path.append("..")
    9 12   
    10  -from helpers.http import get_authorization_header_from_message, get_cookie_header_from_message, isStatusCodesReturned, makeMessage, makeRequest, getResponseContentLength, IHttpRequestResponseImplementation
     13 +from helpers.http import get_authorization_header_from_message, get_cookie_header_from_message, isStatusCodesReturned, makeMessage, makeRequest, getResponseBody, IHttpRequestResponseImplementation
    11 14  from gui.table import LogEntry, UpdateTableEDT
    12 15  from javax.swing import SwingUtilities
    13 16  from java.net import URL
    skipped 123 lines
    137 140   if not re.search(regex_string, resStr, re.IGNORECASE) is None:
    138 141   message_passed_filters = False
    139 142   
     143 + if self.IFList.getModel().getElementAt(i).split(":")[0] == "Header contains":
     144 + for header in list(resInfo.getHeaders()):
     145 + if self.IFList.getModel().getElementAt(i)[17:] in header:
     146 + message_passed_filters = False
     147 + 
     148 + if self.IFList.getModel().getElementAt(i).split(":")[0] == "Header doesn't contain":
     149 + for header in list(resInfo.getHeaders()):
     150 + if not self.IFList.getModel().getElementAt(i)[17:] in header:
     151 + message_passed_filters = False
     152 + 
    140 153   if self.IFList.getModel().getElementAt(i).split(":")[0] == "Only HTTP methods (newline separated)":
    141 154   filterMethods = self.IFList.getModel().getElementAt(i)[39:].split("\n")
    142 155   filterMethods = [x.lower() for x in filterMethods]
    skipped 6 lines
    149 162   filterMethods = [x.lower() for x in filterMethods]
    150 163   reqMethod = str(self._helpers.analyzeRequest(messageInfo).getMethod())
    151 164   if reqMethod.lower() in filterMethods:
     165 + message_passed_filters = False
     166 + 
     167 + if self.IFList.getModel().getElementAt(i).split(":")[0] == "Ignore OPTIONS requests":
     168 + reqMethod = str(self._helpers.analyzeRequest(messageInfo).getMethod())
     169 + if reqMethod == "OPTIONS":
    152 170   message_passed_filters = False
    153 171   
    154 172   return message_passed_filters
    skipped 46 lines
    201 219   andEnforcementCheck = False
    202 220   auth_enforced = False
    203 221   
    204  - response = requestResponse.getResponse()
    205 222   for filter in filters:
    206 223   filter = self._helpers.bytesToString(bytes(filter))
     224 + inverse = "NOT" in filter
     225 + filter = filter.replace(" NOT", "")
     226 + 
    207 227   if filter.startswith("Status code equals: "):
    208 228   statusCode = filter[20:]
    209  - if andEnforcementCheck:
    210  - if auth_enforced and not isStatusCodesReturned(self, requestResponse, statusCode):
    211  - auth_enforced = False
    212  - else:
    213  - if not auth_enforced and isStatusCodesReturned(self, requestResponse, statusCode):
    214  - auth_enforced = True
     229 + filterMatched = inverse ^ isStatusCodesReturned(self, requestResponse, statusCode)
    215 230   
    216  - if filter.startswith("Headers (simple string): "):
    217  - if andEnforcementCheck:
    218  - if auth_enforced and not filter[25:] in self._helpers.bytesToString(requestResponse.getResponse()[0:analyzedResponse.getBodyOffset()]):
    219  - auth_enforced = False
    220  - else:
    221  - if not auth_enforced and filter[25:] in self._helpers.bytesToString(requestResponse.getResponse()[0:analyzedResponse.getBodyOffset()]):
    222  - auth_enforced = True
     231 + elif filter.startswith("Headers (simple string): "):
     232 + filterMatched = inverse ^ (filter[25:] in self._helpers.bytesToString(requestResponse.getResponse()[0:analyzedResponse.getBodyOffset()]))
    223 233   
    224  - if filter.startswith("Headers (regex): "):
     234 + elif filter.startswith("Headers (regex): "):
    225 235   regex_string = filter[17:]
    226 236   p = re.compile(regex_string, re.IGNORECASE)
    227  - if andEnforcementCheck:
    228  - if auth_enforced and not p.search(self._helpers.bytesToString(requestResponse.getResponse()[0:analyzedResponse.getBodyOffset()])):
    229  - auth_enforced = False
    230  - else:
    231  - if not auth_enforced and p.search(self._helpers.bytesToString(requestResponse.getResponse()[0:analyzedResponse.getBodyOffset()])):
    232  - auth_enforced = True
     237 + filterMatched = inverse ^ bool(p.search(self._helpers.bytesToString(requestResponse.getResponse()[0:analyzedResponse.getBodyOffset()])))
    233 238   
    234  - if filter.startswith("Body (simple string): "):
    235  - if andEnforcementCheck:
    236  - if auth_enforced and not filter[22:] in self._helpers.bytesToString(requestResponse.getResponse()[analyzedResponse.getBodyOffset():]):
    237  - auth_enforced = False
    238  - else:
    239  - if not auth_enforced and filter[22:] in self._helpers.bytesToString(requestResponse.getResponse()[analyzedResponse.getBodyOffset():]):
    240  - auth_enforced = True
     239 + elif filter.startswith("Body (simple string): "):
     240 + filterMatched = inverse ^ (filter[22:] in self._helpers.bytesToString(requestResponse.getResponse()[analyzedResponse.getBodyOffset():]))
    241 241   
    242  - if filter.startswith("Body (regex): "):
     242 + elif filter.startswith("Body (regex): "):
    243 243   regex_string = filter[14:]
    244 244   p = re.compile(regex_string, re.IGNORECASE)
    245  - if andEnforcementCheck:
    246  - if auth_enforced and not p.search(self._helpers.bytesToString(requestResponse.getResponse()[analyzedResponse.getBodyOffset():])):
    247  - auth_enforced = False
    248  - else:
    249  - if not auth_enforced and p.search(self._helpers.bytesToString(requestResponse.getResponse()[analyzedResponse.getBodyOffset():])):
    250  - auth_enforced = True
     245 + filterMatched = inverse ^ bool(p.search(self._helpers.bytesToString(requestResponse.getResponse()[analyzedResponse.getBodyOffset():])))
    251 246   
    252  - if filter.startswith("Full response (simple string): "):
    253  - if andEnforcementCheck:
    254  - if auth_enforced and not filter[31:] in self._helpers.bytesToString(requestResponse.getResponse()):
    255  - auth_enforced = False
    256  - else:
    257  - if not auth_enforced and filter[31:] in self._helpers.bytesToString(requestResponse.getResponse()):
    258  - auth_enforced = True
     247 + elif filter.startswith("Full response (simple string): "):
     248 + filterMatched = inverse ^ (filter[31:] in self._helpers.bytesToString(requestResponse.getResponse()))
    259 249   
    260  - if filter.startswith("Full response (regex): "):
     250 + elif filter.startswith("Full response (regex): "):
    261 251   regex_string = filter[23:]
    262 252   p = re.compile(regex_string, re.IGNORECASE)
    263  - if andEnforcementCheck:
    264  - if auth_enforced and not p.search(self._helpers.bytesToString(requestResponse.getResponse())):
    265  - auth_enforced = False
    266  - else:
    267  - if not auth_enforced and p.search(self._helpers.bytesToString(requestResponse.getResponse())):
    268  - auth_enforced = True
     253 + filterMatched = inverse ^ bool(p.search(self._helpers.bytesToString(requestResponse.getResponse())))
    269 254   
    270  - if filter.startswith("Full response length: "):
    271  - if andEnforcementCheck:
    272  - if auth_enforced and not str(len(response)) == filter[22:].strip():
    273  - auth_enforced = False
    274  - else:
    275  - if not auth_enforced and str(len(response)) == filter[22:].strip():
    276  - auth_enforced = True
    277  - return auth_enforced
     255 + elif filter.startswith("Full response length: "):
     256 + filterMatched = inverse ^ (str(len(response)) == filter[22:].strip())
    278 257   
    279  -def checkBypass(self, oldStatusCode, newStatusCode, oldContentLen,
    280  - newContentLen, filters, requestResponse, andOrEnforcement):
     258 + if andEnforcementCheck:
     259 + if auth_enforced and not filterMatched:
     260 + auth_enforced = False
     261 + else:
     262 + if not auth_enforced and filterMatched:
     263 + auth_enforced = True
     264 + 
     265 + return auth_enforced
     266 + 
     267 +def checkBypass(self, oldStatusCode, newStatusCode, oldContent,
     268 + newContent, filters, requestResponse, andOrEnforcement):
    281 269   if oldStatusCode == newStatusCode:
    282 270   auth_enforced = 0
    283 271   if len(filters) > 0:
    284 272   auth_enforced = auth_enforced_via_enforcement_detectors(self, filters, requestResponse, andOrEnforcement)
    285 273   if auth_enforced:
    286 274   return self.ENFORCED_STR
    287  - elif oldContentLen == newContentLen:
     275 + elif oldContent == newContent:
    288 276   return self.BYPASSSED_STR
    289 277   else:
    290 278   return self.IS_ENFORCED_STR
    skipped 1 lines
    292 280   return self.ENFORCED_STR
    293 281   
    294 282  def checkAuthorization(self, messageInfo, originalHeaders, checkUnauthorized):
    295  - oldResponse = messageInfo.getResponse()
    296 283   message = makeMessage(self, messageInfo, True, True)
    297 284   requestResponse = makeRequest(self, messageInfo, message)
    298 285   newResponse = requestResponse.getResponse()
    skipped 1 lines
    300 287   
    301 288   oldStatusCode = originalHeaders[0]
    302 289   newStatusCode = analyzedResponse.getHeaders()[0]
    303  - oldContentLen = getResponseContentLength(self, oldResponse)
    304  - newContentLen = getResponseContentLength(self, newResponse)
     290 + oldContent = getResponseBody(self, messageInfo)
     291 + newContent = getResponseBody(self, requestResponse)
    305 292   
    306 293   # Check unauthorized request
    307 294   if checkUnauthorized:
    skipped 2 lines
    310 297   unauthorizedResponse = requestResponseUnauthorized.getResponse()
    311 298   analyzedResponseUnauthorized = self._helpers.analyzeResponse(unauthorizedResponse)
    312 299   statusCodeUnauthorized = analyzedResponseUnauthorized.getHeaders()[0]
    313  - contentLenUnauthorized = getResponseContentLength(self, unauthorizedResponse)
     300 + contentUnauthorized = getResponseBody(self, requestResponseUnauthorized)
    314 301   
    315 302   EDFilters = self.EDModel.toArray()
    316 303   
    317  - impression = checkBypass(self, oldStatusCode,newStatusCode,oldContentLen,newContentLen,EDFilters,requestResponse,self.AndOrType.getSelectedItem())
     304 + impression = checkBypass(self, oldStatusCode, newStatusCode, oldContent, newContent, EDFilters, requestResponse, self.AndOrType.getSelectedItem())
    318 305   
    319 306   if checkUnauthorized:
    320 307   EDFiltersUnauth = self.EDModelUnauth.toArray()
    321  - impressionUnauthorized = checkBypass(self, oldStatusCode,statusCodeUnauthorized,oldContentLen,contentLenUnauthorized,EDFiltersUnauth,requestResponseUnauthorized,self.AndOrTypeUnauth.getSelectedItem())
     308 + impressionUnauthorized = checkBypass(self, oldStatusCode, statusCodeUnauthorized, oldContent, contentUnauthorized, EDFiltersUnauth, requestResponseUnauthorized, self.AndOrTypeUnauth.getSelectedItem())
    322 309   
    323 310   self._lock.acquire()
    324 311   
    skipped 13 lines
    338 325   checkAuthorization(self, messageInfo, self._extender._helpers.analyzeResponse(messageInfo.getResponse()).getHeaders(), self._extender.doUnauthorizedRequest.isSelected())
    339 326   
    340 327  def retestAllRequests(self):
     328 + self.logTable.setAutoCreateRowSorter(True)
    341 329   for i in range(self.tableModel.getRowCount()):
    342 330   logEntry = self._log.get(self.logTable.convertRowIndexToModel(i))
    343 331   handle_message(self, "AUTORIZE", False, logEntry._originalrequestResponse)
     332 + 
  • gui/configuration_tab.py
    Content is identical
  • ■ ■ ■ ■ ■ ■
    gui/enforcement_detector.py
    skipped 34 lines
    35 35   EDLabelList = JLabel("Filter List:")
    36 36   EDLabelList.setBounds(10, 165, 140, 30)
    37 37   
    38  - EDStrings = ["Headers (simple string): (enforced message headers contains)",
    39  - "Headers (regex): (enforced message headers contains)",
    40  - "Body (simple string): (enforced message body contains)",
    41  - "Body (regex): (enforced message body contains)",
    42  - "Full response (simple string): (enforced message contains)",
    43  - "Full response (regex): (enforced message contains)",
    44  - "Full response length: (of enforced response)",
    45  - "Status code equals: (numbers only)"]
     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 + ]
    46 56   self._extender.EDType = JComboBox(EDStrings)
    47 57   self._extender.EDType.setBounds(80, 10, 430, 30)
    48 58   
    skipped 50 lines
    99 109   EDLabelList = JLabel("Filter List:")
    100 110   EDLabelList.setBounds(10, 165, 140, 30)
    101 111   
    102  - EDStrings = ["Headers (simple string): (enforced message headers contains)",
    103  - "Headers (regex): (enforced message headers contains)",
    104  - "Body (simple string): (enforced message body contains)",
    105  - "Body (regex): (enforced message body contains)",
    106  - "Full response (simple string): (enforced message contains)",
    107  - "Full response (regex): (enforced message contains)",
    108  - "Full response length: (of enforced response)",
    109  - "Status code equals: (numbers only)"]
     112 + EDStrings = [
     113 + "Headers (simple string): (enforced message headers contain)",
     114 + "Headers NOT (simple string): (enforced message headers NOT contain)",
     115 + "Headers (regex): (enforced message headers contain)",
     116 + "Headers NOT (regex): (enforced message headers NOT contain)",
     117 + "Body (simple string): (enforced message body contains)",
     118 + "Body NOT (simple string): (enforced message body NOT contains)",
     119 + "Body (regex): (enforced message body contains)",
     120 + "Body NOT (regex): (enforced message body NOT contains)",
     121 + "Full response (simple string): (enforced message contains)",
     122 + "Full response NOT (simple string): (enforced message NOT contains)",
     123 + "Full response (regex): (enforced message contains)",
     124 + "Full response NOT (regex): (enforced message NOT contains)",
     125 + "Full response length: (of enforced response)",
     126 + "Full response NOT length: (of enforced response)",
     127 + "Status code equals: (numbers only)",
     128 + "Status code NOT equals: (numbers only)"
     129 + ]
    110 130   self._extender.EDTypeUnauth = JComboBox(EDStrings)
    111 131   self._extender.EDTypeUnauth.setBounds(80, 10, 430, 30)
    112 132   
    skipped 60 lines
  • ■ ■ ■ ■ ■
    gui/export.py
    skipped 12 lines
    13 13  from javax.swing import JFrame
    14 14  from java.awt import Font
    15 15  from java.io import File
     16 +from javax.swing import JCheckBox
     17 +from java.awt.event import ItemListener
     18 + 
    16 19   
    17 20  from save_restore import SaveRestore
    18 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 + 
    19 30  class Export():
     31 + 
    20 32   def __init__(self, extender):
    21 33   self._extender = extender
    22 34   self.BYPASSSED_STR = extender.BYPASSSED_STR
    skipped 2 lines
    25 37   self._log = extender._log
    26 38   self.save_restore = SaveRestore(extender)
    27 39   
     40 + 
    28 41   def draw(self):
    29 42   """ init Save/Restore
    30 43   """
    skipped 21 lines
    52 65   exportLES = JLabel("Statuses:")
    53 66   exportLES.setBounds(10, 90, 100, 30)
    54 67   
     68 + self.removeDuplicates = JCheckBox("Remove Duplicates")
     69 + self.removeDuplicates.setBounds(8, 120, 300, 30)
     70 + self.removeDuplicates.setSelected(True)
     71 + self.removeDuplicates.addItemListener(RemoveDups(self._extender))
     72 + 
    55 73   self.exportButton = JButton("Export",
    56 74   actionPerformed=self.export)
    57 75   self.exportButton.setBounds(390, 50, 100, 30)
    58 76   
    59  - saveRestoreLabel = JLabel("Save / Restore:")
    60  - saveRestoreLabel.setBounds(10, 250, 100, 30)
     77 + saveRestoreLabel = JLabel("State (incl. Configuration):")
     78 + saveRestoreLabel.setBounds(10, 160, 250, 30)
    61 79   saveRestoreLabel.setFont(boldFont)
    62 80   
    63  - self.saveStateButton = JButton("Save state",
     81 + self.saveStateButton = JButton("Save",
    64 82   actionPerformed=self.saveStateAction)
    65 83   self.saveStateButton.setBounds(10, 200, 100, 30)
    66 84   
    67  - self.restoreStateButton = JButton("Restore state",
     85 + self.restoreStateButton = JButton("Restore",
    68 86   actionPerformed=self.restoreStateAction)
    69 87   self.restoreStateButton.setBounds(390, 200, 100, 30)
    70 88   
    skipped 10 lines
    81 99   exportPnl.add(saveRestoreLabel)
    82 100   exportPnl.add(self.saveStateButton)
    83 101   exportPnl.add(self.restoreStateButton)
     102 + exportPnl.add(self.removeDuplicates)
    84 103   
    85 104   def export(self, event):
    86 105   if self.exportType.getSelectedItem() == "HTML":
    skipped 46 lines
    133 152   <div class="datagrid"><table>
    134 153   <thead><tr><th width=\"3%\">ID</th><th width=\"5%\">Method</th><th width=\"43%\">URL</th><th width=\"9%\">Original length</th><th width=\"9%\">Modified length</th><th width=\"9%\">Unauthorized length</th><th width=\"11%\">Authorization Enforcement Status</th><th width=\"11%\">Authorization Unauthenticated Status</th></tr></thead>
    135 154   <tbody>"""
    136  - 
     155 + unique_HTML_lines = set() # set to keep track of unique values
    137 156   for i in range(0,self._log.size()):
     157 + if self.removeDuplicates.isSelected():
     158 + # line data only looks for method, url, and authorized status. Does not factor in size of request during comparision
     159 + 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)
     160 + if lineData in unique_HTML_lines: # Skip if line is already in set
     161 + continue
     162 + else: # Add line to set and continue with execution
     163 + unique_HTML_lines.add(lineData)
    138 164   color_modified = ""
    139 165   if self._log.get(i)._enfocementStatus == self.BYPASSSED_STR:
    140 166   color_modified = "red"
    skipped 42 lines
    183 209   enforcementStatusFilter = self.exportES.getSelectedItem()
    184 210   csvContent = "id\tMethod\tURL\tOriginal length\tModified length\tUnauthorized length\tAuthorization Enforcement Status\tAuthorization Unauthenticated Status\n"
    185 211   
    186  - for i in range(0,self._log.size()):
    187  - 
     212 + unique_CVS_lines = set()
     213 + for i in range(0, self._log.size()):
     214 + if self.removeDuplicates.isSelected():
     215 + # line data only looks for method, url, and authorized status. Does not factor in size of request during comparision
     216 + 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)
     217 + if lineData in unique_CVS_lines: # Skip if line is already in set
     218 + continue
     219 + else: # Add line to set and continue with execution
     220 + unique_CVS_lines.add(lineData)
    188 221   if enforcementStatusFilter == "All Statuses":
    189 222   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)
    190 223   elif enforcementStatusFilter == "As table filter":
    skipped 8 lines
    199 232   else:
    200 233   if (enforcementStatusFilter == self._log.get(i)._enfocementStatus) or (enforcementStatusFilter == self._log.get(i)._enfocementStatusUnauthorized):
    201 234   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)
     235 + 
    202 236   
    203 237   f = open(fileToSave.getAbsolutePath(), 'w')
    204 238   f.writelines(csvContent)
    skipped 2 lines
  • ■ ■ ■ ■ ■
    gui/interception_filters.py
    skipped 40 lines
    41 41   "Response Body contains (regex): ",
    42 42   "Response Body NOT contains (simple string): ",
    43 43   "Response Body Not contains (regex): ",
     44 + "Header contains: ",
     45 + "Header doesn't contain: ",
    44 46   "Only HTTP methods (newline separated): ",
    45 47   "Ignore HTTP methods (newline separated): ",
    46 48   "Ignore spider requests: (Content is not required)",
    47 49   "Ignore proxy requests: (Content is not required)",
    48  - "Ignore target requests: (Content is not required)"]
     50 + "Ignore target requests: (Content is not required)",
     51 + "Ignore OPTIONS requests: (Content is not required)"
     52 + ]
    49 53   self._extender.IFType = JComboBox(IFStrings)
    50 54   self._extender.IFType.setBounds(80, 10, 430, 30)
    51 55  
    skipped 7 lines
    59 63   
    60 64   # Adding some default interception filters
    61 65   # self.IFModel.addElement("Scope items only: (Content is not required)") # commented for better first impression.
    62  - self._extender.IFModel.addElement("URL Not Contains (regex): \\.js|\\.css|\\.png|\\.jpg|\\.svg|\\.jpeg|\\.gif|\\.woff|\\.map|\\.bmp|\\.ico$")
     66 + self._extender.IFModel.addElement("URL Not Contains (regex): (\\.js|\\.css|\\.png|\\.jpg|\\.svg|\\.jpeg|\\.gif|\\.woff|\\.map|\\.bmp|\\.ico)(?![a-z]+)[?]*[\S]*$")
    63 67   self._extender.IFModel.addElement("Ignore spider requests: ")
    64 68  
    65 69   self._extender.IFText = JTextArea("", 5, 30)
    skipped 43 lines
  • ■ ■ ■ ■ ■ ■
    gui/match_replace.py
    skipped 32 lines
    33 33   column1X = 10
    34 34   column2X = column1X + labelWidth + padding
    35 35   column3X = column2X + editWidth + padding
    36  - MRStrings = ["Headers (simple string):" ,
     36 + MRStrings = ["Headers (simple string):",
    37 37   "Headers (regex):",
    38 38   "Body (simple string):",
    39 39   "Body (regex):"]
    skipped 77 lines
    117 117   
    118 118   regexMatch = None
    119 119   try:
    120  - if "(regex)" in typeName :
     120 + if "(regex)" in typeName:
    121 121   regexMatch = re.compile(match)
    122 122   except re.error:
    123 123   self._extender.MRFeedback.setText("ERROR: Invalid regex")
    skipped 23 lines
  • ■ ■ ■ ■
    gui/menu.py
    skipped 21 lines
    22 22   ret = LinkedList()
    23 23   requestMenuItem = JMenuItem("Send request to Autorize")
    24 24   cookieMenuItem = JMenuItem("Send Cookie header to Autorize")
    25  - authMenuItem = JMenuItem("Send Authorziation header to Autorize")
     25 + authMenuItem = JMenuItem("Send Authorization header to Autorize")
    26 26   
    27 27   for response in responses:
    28 28   requestMenuItem.addActionListener(HandleMenuItems(self._extender,response, "request"))
    skipped 24 lines
  • ■ ■ ■ ■ ■ ■
    gui/save_restore.py
    skipped 6 lines
    7 7  from java.io import File
    8 8   
    9 9  from table import LogEntry, UpdateTableEDT
    10  -from helpers.http import IHttpRequestResponseImplementation
     10 +from helpers.http import get_cookie_header_from_message, get_authorization_header_from_message, IHttpRequestResponseImplementation
    11 11   
    12  -import csv, base64, sys
     12 +import csv, base64, json, re, sys
    13 13   
    14 14  # This code is necessary to maximize the csv field limit for the save and
    15 15  # restore functionality
    skipped 10 lines
    26 26  class SaveRestore():
    27 27   def __init__(self, extender):
    28 28   self._extender = extender
     29 + self._checkBoxes = [
     30 + "autoScroll",
     31 + "ignore304",
     32 + "prevent304",
     33 + "interceptRequestsfromRepeater",
     34 + "doUnauthorizedRequest",
     35 + "replaceQueryParam",
     36 + "showAuthBypassModified",
     37 + "showAuthPotentiallyEnforcedModified",
     38 + "showAuthEnforcedModified",
     39 + "showAuthBypassUnauthenticated",
     40 + "showAuthPotentiallyEnforcedUnauthenticated",
     41 + "showAuthEnforcedUnauthenticated",
     42 + "showDisabledUnauthenticated"
     43 + ]
    29 44   
    30 45   def saveState(self):
    31 46   parentFrame = JFrame()
    skipped 5 lines
    37 52   exportFile = fileChooser.getSelectedFile()
    38 53   with open(exportFile.getAbsolutePath(), 'wb') as csvfile:
    39 54   csvwriter = csv.writer(csvfile, delimiter='\t', quotechar='|', quoting=csv.QUOTE_MINIMAL)
     55 + 
     56 + # Configuration
     57 + tempRow = ["ReplaceString", base64.b64encode(self._extender.replaceString.getText())]
     58 + csvwriter.writerow(tempRow)
     59 + 
     60 + for EDFilter in self._extender.EDModel.toArray():
     61 + tempRow = ["EDFilter", base64.b64encode(EDFilter)]
     62 + csvwriter.writerow(tempRow)
     63 + 
     64 + for EDFilterUnauth in self._extender.EDModelUnauth.toArray():
     65 + tempRow = ["EDFilterUnauth", base64.b64encode(EDFilterUnauth)]
     66 + csvwriter.writerow(tempRow)
     67 + 
     68 + for IFFilter in self._extender.IFModel.toArray():
     69 + tempRow = ["IFFilter", base64.b64encode(IFFilter)]
     70 + csvwriter.writerow(tempRow)
     71 + 
     72 + for t in ["AndOrType", "AndOrTypeUnauth"]:
     73 + tempRow = [t, getattr(self._extender, t).getSelectedItem()]
     74 + csvwriter.writerow(tempRow)
     75 + 
     76 + for key in self._extender.badProgrammerMRModel:
     77 + d = dict(self._extender.badProgrammerMRModel[key])
     78 + d["regexMatch"] = d["regexMatch"] is not None
     79 + tempRow = ["MatchReplace", base64.b64encode(json.dumps(d))]
     80 + csvwriter.writerow(tempRow)
     81 + 
     82 + d = dict((c, getattr(self._extender, c).isSelected()) for c in self._checkBoxes)
     83 + tempRow = ["CheckBoxes", json.dumps(d)]
     84 + csvwriter.writerow(tempRow)
     85 + 
     86 + isSelected = self._extender.exportPnl.getComponents()[-1].isSelected()
     87 + tempRow = ["RemoveDuplicates", json.dumps(isSelected)]
     88 + csvwriter.writerow(tempRow)
     89 + 
     90 + # Request/response list
    40 91   for i in range(0,self._extender._log.size()):
    41 92   tempRequestResponseHost = self._extender._log.get(i)._requestResponse.getHttpService().getHost()
    42 93   tempRequestResponsePort = self._extender._log.get(i)._requestResponse.getHttpService().getPort()
    skipped 5 lines
    48 99   tempOriginalRequestResponsePort = self._extender._log.get(i)._originalrequestResponse.getHttpService().getPort()
    49 100   tempOriginalRequestResponseProtocol = self._extender._log.get(i)._originalrequestResponse.getHttpService().getProtocol()
    50 101   tempOriginalRequestResponseRequest = base64.b64encode(self._extender._log.get(i)._originalrequestResponse.getRequest())
    51  - tempOriginalRequestResponseResponse = base64.b64encode(self._extender._log.get(i)._originalrequestResponse.getResponse())
     102 + tempOriginalRequestResponseResponse = base64.b64encode(self._extender._log.get(i)._originalrequestResponse.getResponse())
    52 103   
    53 104   if self._extender._log.get(i)._unauthorizedRequestResponse is not None:
    54 105   tempUnauthorizedRequestResponseHost = self._extender._log.get(i)._unauthorizedRequestResponse.getHttpService().getHost()
    skipped 9 lines
    64 115   tempUnauthorizedRequestResponseResponse = None
    65 116   
    66 117   tempEnforcementStatus = self._extender._log.get(i)._enfocementStatus
    67  - tempEnforcementStatusUnauthorized = self._extender._log.get(i)._enfocementStatusUnauthorized
     118 + tempEnforcementStatusUnauthorized = self._extender._log.get(i)._enfocementStatusUnauthorized
    68 119   
    69 120   tempRow = [tempRequestResponseHost,tempRequestResponsePort,tempRequestResponseProtocol,tempRequestResponseRequest,tempRequestResponseResponse]
    70 121   tempRow.extend([tempOriginalRequestResponseHost,tempOriginalRequestResponsePort,tempOriginalRequestResponseProtocol,tempOriginalRequestResponseRequest,tempOriginalRequestResponseResponse])
    skipped 6 lines
    77 128   parentFrame = JFrame()
    78 129   fileChooser = JFileChooser()
    79 130   fileChooser.setDialogTitle("State import file")
    80  - userSelection = fileChooser.showDialog(parentFrame,"Restore")
     131 + userSelection = fileChooser.showDialog(parentFrame, "Restore")
     132 + modelMap = {
     133 + "IFFilter": self._extender.IFModel,
     134 + "EDFilter": self._extender.EDModel,
     135 + "EDFilterUnauth": self._extender.EDModelUnauth
     136 + }
    81 137   
    82 138   if userSelection == JFileChooser.APPROVE_OPTION:
    83 139   importFile = fileChooser.getSelectedFile()
    skipped 3 lines
    87 143   csvreader = csv.reader(csvfile, delimiter='\t', quotechar='|')
    88 144   
    89 145   for row in csvreader:
     146 + # Configuration
     147 + if row[0] == "ReplaceString":
     148 + self._extender.replaceString.setText(base64.b64decode(row[1]))
     149 + continue
    90 150   
     151 + if row[0] in modelMap:
     152 + f = base64.b64decode(row[1])
     153 + if f not in modelMap[row[0]].toArray():
     154 + modelMap[row[0]].addElement(f)
     155 + continue
     156 + 
     157 + if row[0] in {"AndOrType", "AndOrTypeUnauth"}:
     158 + getattr(self._extender, row[0]).setSelectedItem(row[1])
     159 + continue
     160 + 
     161 + if row[0] == "MatchReplace":
     162 + d = json.loads(base64.b64decode(row[1]))
     163 + key = d["type"] + " " + d["match"] + "->" + d["replace"]
     164 + if key in self._extender.badProgrammerMRModel:
     165 + continue
     166 + regexMatch = None
     167 + if d["regexMatch"]:
     168 + try:
     169 + d["regexMatch"] = re.compile(d["match"])
     170 + except re.error:
     171 + print("ERROR: Regex to restore is invalid:", d["match"])
     172 + continue
     173 + self._extender.badProgrammerMRModel[key] = d
     174 + self._extender.MRModel.addElement(key)
     175 + continue
     176 + 
     177 + if row[0] == "CheckBoxes":
     178 + d = json.loads(row[1])
     179 + for k in d:
     180 + getattr(self._extender, k).setSelected(d[k])
     181 + continue
     182 + 
     183 + if row[0] == "RemoveDuplicates":
     184 + isSelected = json.loads(row[1])
     185 + try:
     186 + self._extender.exportPnl.getComponents()[-1].setSelected(isSelected)
     187 + except TypeError: # suppress TypeError: None required for void return
     188 + pass
     189 + continue
     190 + 
     191 + # Request/response list
    91 192   tempRequestResponseHost = row[0]
    92 193   tempRequestResponsePort = row[1]
    93 194   tempRequestResponseProtocol = row[2]
    skipped 7 lines
    101 202   tempOriginalRequestResponsePort = row[6]
    102 203   tempOriginalRequestResponseProtocol = row[7]
    103 204   tempOriginalRequestResponseRequest = base64.b64decode(row[8])
    104  - tempOriginalRequestResponseResponse = base64.b64decode(row[9])
     205 + tempOriginalRequestResponseResponse = base64.b64decode(row[9])
    105 206   
    106 207   tempOriginalRequestResponseHttpService = self._extender._helpers.buildHttpService(tempOriginalRequestResponseHost,int(tempOriginalRequestResponsePort),tempOriginalRequestResponseProtocol)
    107 208   tempOriginalRequestResponse = IHttpRequestResponseImplementation(tempOriginalRequestResponseHttpService,tempOriginalRequestResponseRequest,tempOriginalRequestResponseResponse)
    skipped 12 lines
    120 221   tempUnauthorizedRequestResponse = None
    121 222   
    122 223   tempEnforcementStatus = row[15]
    123  - tempEnforcementStatusUnauthorized = row[16]
     224 + tempEnforcementStatusUnauthorized = row[16]
    124 225   
    125 226   self._extender._lock.acquire()
    126 227   
    skipped 24 lines
    151 252   
    152 253   lastRow = self._extender._log.size()
    153 254   if lastRow > 0:
    154  - cookiesHeader = self._extender.get_cookie_header_from_message(self._extender._log.get(lastRow - 1)._requestResponse)
     255 + cookiesHeader = get_cookie_header_from_message(self._extender, self._extender._log.get(lastRow - 1)._requestResponse)
    155 256   if cookiesHeader:
    156 257   self._extender.lastCookiesHeader = cookiesHeader
    157 258   self._extender.fetchCookiesHeaderButton.setEnabled(True)
    158  - authorizationHeader = self._extender.get_authorization_header_from_message(self._extender._log.get(lastRow - 1)._requestResponse)
     259 + authorizationHeader = get_authorization_header_from_message(self._extender, self._extender._log.get(lastRow - 1)._requestResponse)
    159 260   if authorizationHeader:
    160 261   self._extender.lastAuthorizationHeader = authorizationHeader
    161 262   self._extender.fetchAuthorizationHeaderButton.setEnabled(True)
    162 263   
    163  - 
  • ■ ■ ■ ■ ■ ■
    gui/tabs.py
    skipped 24 lines
    25 25   
    26 26  from table import Table, LogEntry, TableRowFilter
    27 27  from helpers.filters import expand, collapse
     28 +from javax.swing import KeyStroke
     29 +from javax.swing import JTable
     30 +from javax.swing import AbstractAction
     31 +from java.awt.event import KeyEvent
     32 +from java.awt.event import InputEvent
     33 + 
    28 34   
    29 35  class ITabImpl(ITab):
    30 36   def __init__(self, extender):
    skipped 44 lines
    75 81   
    76 82   sendRequestMenu2 = JMenuItem("Send Modified Request to Repeater")
    77 83   sendRequestMenu2.addActionListener(SendRequestRepeater(self._extender, self._extender._callbacks, False))
     84 + 
     85 + # Define the key combination for the shortcut
     86 + 
     87 + # The keystroke combo is: Mac -> Command + r / Windows control + r
     88 + # This is used to send to the repeater function in burp
     89 + controlR = KeyStroke.getKeyStroke(KeyEvent.VK_R, Toolkit.getDefaultToolkit().getMenuShortcutKeyMaskEx())
     90 + 
     91 + # The keystroke combo is: Mac -> Command + c / Windows control + c
     92 + # This is used to copy the URL to the keyboard.
     93 + controlC = KeyStroke.getKeyStroke(KeyEvent.VK_C, InputEvent.META_DOWN_MASK)
     94 + 
     95 + # Get the input and action maps for the JTable
     96 + inputMap = self._extender.logTable.getInputMap(JTable.WHEN_FOCUSED)
     97 + actionMap = self._extender.logTable.getActionMap()
     98 + 
     99 + # Bind the key combination to the action
     100 + inputMap.put(controlR, "SendRequestToRepeaterAction")
     101 + actionMap.put("SendRequestToRepeaterAction", SendRequestToRepeaterAction(self._extender, self._extender._callbacks))
     102 + 
     103 + # Bind the key combination to the action
     104 + inputMap.put(controlC, "copyToClipBoard")
     105 + actionMap.put("copyToClipBoard",
     106 + CopySelectedURLToClipBoard(self._extender, self._extender._callbacks))
    78 107   
    79 108   sendResponseMenu = JMenuItem("Send Responses to Comparer")
    80 109   sendResponseMenu.addActionListener(SendResponseComparer(self._extender, self._extender._callbacks))
    skipped 76 lines
    157 186   proto = request.getHttpService().getProtocol()
    158 187   secure = True if proto == "https" else False
    159 188   
    160  - self._callbacks.sendToRepeater(host, port, secure, request.getRequest(), "Autorize");
     189 + self._callbacks.sendToRepeater(host, port, secure, request.getRequest(), "Autorize")
    161 190   
    162 191  class SendResponseComparer(ActionListener):
    163 192   def __init__(self, extender, callbacks):
    skipped 74 lines
    238 267   else:
    239 268   collapse(self._extender, evt.getComponent())
    240 269   
     270 +class SendRequestToRepeaterAction(AbstractAction):
     271 + def __init__(self, extender, callbacks):
     272 + self._extender = extender
     273 + self._callbacks = callbacks
    241 274   
     275 + def actionPerformed(self, e):
     276 + # Get the selected row of the JTable
     277 + row = self._extender.logTable.getSelectedRow()
     278 + 
     279 + # Get the LogEntry object for the selected row
     280 + rowModelIndex = self._extender.logTable.convertRowIndexToModel(row)
     281 + entry = self._extender.tableModel.getValueAt(rowModelIndex, 0)
     282 + 
     283 + # Get the modified request
     284 + request = self._extender._currentlyDisplayedItem._requestResponse
     285 + host = request.getHttpService().getHost()
     286 + port = request.getHttpService().getPort()
     287 + proto = request.getHttpService().getProtocol()
     288 + secure = True if proto == "https" else False
     289 + 
     290 + self._callbacks.sendToRepeater(host, port, secure, request.getRequest(), "Autorize")
     291 + 
     292 +class CopySelectedURLToClipBoard(AbstractAction):
     293 + def __init__(self, extender, callbacks):
     294 + self._extender = extender
     295 + self._callbacks = callbacks
     296 + 
     297 + def actionPerformed(self, e):
     298 + stringSelection = StringSelection(str(self._extender._helpers.analyzeRequest(
     299 + self._extender._currentlyDisplayedItem._requestResponse).getUrl()))
     300 + clpbrd = Toolkit.getDefaultToolkit().getSystemClipboard()
     301 + clpbrd.setContents(stringSelection, None)
  • ■ ■ ■ ■ ■ ■
    helpers/http.py
    skipped 49 lines
    50 50   if authorizeOrNot:
    51 51   # simple string replace
    52 52   for k, v in self.badProgrammerMRModel.items():
    53  - if(v["type"] == "Headers (simple string):") :
     53 + if(v["type"] == "Headers (simple string):"):
    54 54   headers = map(lambda h: h.replace(v["match"], v["replace"]), headers)
    55 55   if(v["type"] == "Headers (regex):") :
    56 56   headers = map(lambda h: re.sub(v["regexMatch"], v["replace"], h), headers)
    skipped 1 lines
    58 58   if not queryFlag:
    59 59   # fix missing carriage return on *NIX systems
    60 60   replaceStringLines = self.replaceString.getText().split("\n")
    61  -
    62 61   for h in replaceStringLines:
    63  - headers.append(h)
     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)
    64 66   
    65 67   msgBody = messageInfo.getRequest()[requestInfo.getBodyOffset():]
    66 68   
    skipped 5 lines
    72 74   if(v["type"] == "Body (simple string):") :
    73 75   msgBody = msgBody.replace(v["match"], v["replace"])
    74 76   if(v["type"] == "Body (regex):") :
    75  - msgBody = re.sub(v["regexMatch"], v["replace"],msgBody)
     77 + msgBody = re.sub(v["regexMatch"], v["replace"], msgBody)
    76 78   msgBody = self._helpers.stringToBytes(msgBody)
    77 79   return self._helpers.buildHttpMessage(headers, msgBody)
    78 80   
    skipped 3 lines
    82 84   
    83 85  def getResponseBody(self, requestResponse):
    84 86   analyzedResponse = self._helpers.analyzeResponse(requestResponse.getResponse())
    85  - self._helpers.bytesToString(requestResponse.getResponse()[analyzedResponse.getBodyOffset():])
     87 + return self._helpers.bytesToString(requestResponse.getResponse()[analyzedResponse.getBodyOffset():])
    86 88   
    87 89  def getResponseContentLength(self, response):
    88 90   return len(response) - self._helpers.analyzeResponse(response).getBodyOffset()
    skipped 53 lines
  • ■ ■ ■ ■ ■
    helpers/initiator.py
    skipped 17 lines
    18 18   self._extender = extender
    19 19  
    20 20   def init_constants(self):
    21  - self.contributors = ["Federico Dotta", "mgeeky", "Marcin Woloszyn", "jpginc"]
    22  - self._extender.version = 1.5
     21 + self.contributors = ["Federico Dotta", "mgeeky", "Marcin Woloszyn", "jpginc", "Eric Harris"]
     22 + self._extender.version = 1.6
    23 23   self._extender._log = ArrayList()
    24 24   self._extender._lock = Lock()
    25 25   
    skipped 52 lines
    78 78  Contributors: {}
    79 79   
    80 80  Github:\nhttps://github.com/Quitten/Autorize""".format(self._extender.version, ", ".join(self.contributors)))
     81 + 
Please wait...
Page is in error, reload to recover