├── scr.JPG ├── README.md ├── jslinkfinder_community.py └── jslinkfinder.py /scr.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phlmox/BurpJSLinkFinderv2/HEAD/scr.JPG -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # BurpJSLinkFinderV2 2 | Burp Extension for passive scanning of JS files to find endpoint links. 3 | 4 | ![Screenshot](https://github.com/phlmox/BurpJSLinkFinderv2/assets/62145317/f4f61bd9-f25d-445a-b91a-75b851821d5c) 5 | 6 | # Installation 7 | 8 | 1) Go to the Burp Suite Extender Tab -> Click 'Add'. 9 | 2) Set Extension Type to Python, then click the 'Select File' button and select `jslinkfinder.py`, and click 'Next'. 10 | 3) Done! 11 | 12 | # Changelog 13 | 14 | ## V2.3 15 | - Added 'Referer' tab. Thanks to @Giftedboy 16 | 17 | ## V2.2 18 | - Updated the regex used for scanning. 19 | 20 | ## V2.1 21 | - Added 'Delete selected items' feature. 22 | 23 | ## V2 24 | - Added 'Only scope' feature. 25 | - Replaced Textbox with JTable. 26 | - Added a blacklist filter for various extensions (jpg, png, gif, css, etc.). 27 | - Added 'Export endpoints' feature. 28 | 29 | Original repo: https://github.com/InitRoot/BurpJSLinkFinder 30 | -------------------------------------------------------------------------------- /jslinkfinder_community.py: -------------------------------------------------------------------------------- 1 | # 2 | # BurpLinkFinder Community - Find links within JS files. 3 | # 4 | # Copyright (c) 2019 Frans Hendrik Botes, 5 | # Copyright (c) 2024 v2.3 Enes Saltik, 6 | # Credit to https://github.com/GerbenJavado/LinkFinder for the idea and regex 7 | # 8 | from burp import IBurpExtender, IScannerCheck, IScanIssue, ITab,IContextMenuFactory, IHttpRequestResponse 9 | from java.io import PrintWriter 10 | from java.util import ArrayList 11 | import binascii 12 | import base64 13 | import re 14 | from javax import swing 15 | from java.awt import Font, Color 16 | from threading import Thread 17 | from java.awt import EventQueue,Dimension 18 | from java.lang import Runnable 19 | from javax.swing import JFileChooser, JMenuItem 20 | from javax.swing.table import DefaultTableModel 21 | 22 | # Using the Runnable class for thread-safety with Swing 23 | class Run(Runnable): 24 | def __init__(self, runner): 25 | self.runner = runner 26 | 27 | def run(self): 28 | self.runner() 29 | 30 | # Needed params 31 | 32 | JSExclusionList = ['jquery', 'google-analytics','gpt.js'] 33 | 34 | class BurpExtender(IBurpExtender, IScannerCheck, ITab,IContextMenuFactory, IHttpRequestResponse): 35 | def registerExtenderCallbacks(self, callbacks): 36 | self.callbacks = callbacks 37 | self.helpers = callbacks.getHelpers() 38 | callbacks.setExtensionName("BurpJSLinkFinder Community") 39 | callbacks.registerContextMenuFactory(self) 40 | 41 | callbacks.registerScannerCheck(self) 42 | self.initUI() 43 | self.callbacks.addSuiteTab(self) 44 | 45 | self.blacklist_ext = ["jpg","png","jpeg","gif","css","svg","pdf","woff","woff2","ttf","eot"] 46 | 47 | print ("Burp JS LinkFinder V2 loaded.") 48 | print ("Copyright (c) 2019 Frans Hendrik Botes") 49 | print ("Copyright (c) 2024 V2.3 (Current) Enes Saltik") 50 | 51 | def initUI(self): 52 | self.tab = swing.JPanel() 53 | 54 | # UI for Output 55 | self.outputLabel = swing.JLabel("LinkFinder V2 Log:") 56 | self.outputLabel.setFont(Font("Tahoma", Font.BOLD, 14)) 57 | self.outputLabel.setForeground(Color(142, 68, 173)) 58 | self.tableData = [] 59 | colNames = ('ID','URL','Referer','Found Path') 60 | self.dataModel = DefaultTableModel(self.tableData, colNames) 61 | self.outputList = swing.JTable(self.dataModel) 62 | self.outputList.setAutoCreateRowSorter(True) 63 | self.scrollPane = swing.JScrollPane() 64 | self.scrollPane.setPreferredSize(Dimension(300,100)) 65 | self.scrollPane.getViewport().setView((self.outputList)) 66 | 67 | self.clearBtn = swing.JButton("Clear Log", actionPerformed=self.clearLog) 68 | self.DeleteSelectedBtn = swing.JButton("Delete Selected Items", actionPerformed=self.deleteSelected) 69 | self.exportBtn = swing.JButton("Export Endpoints", actionPerformed=self.saveBtn) 70 | 71 | # Layout 72 | layout = swing.GroupLayout(self.tab) 73 | layout.setAutoCreateGaps(True) 74 | layout.setAutoCreateContainerGaps(True) 75 | self.tab.setLayout(layout) 76 | 77 | layout.setHorizontalGroup( 78 | layout.createParallelGroup() 79 | .addGroup(layout.createSequentialGroup() 80 | .addGroup(layout.createParallelGroup() 81 | .addComponent(self.outputLabel) 82 | .addComponent(self.scrollPane) 83 | .addGroup(layout.createSequentialGroup() 84 | .addComponent(self.clearBtn) 85 | .addComponent(self.DeleteSelectedBtn) 86 | .addComponent(self.exportBtn) 87 | ) 88 | ) 89 | ) 90 | ) 91 | 92 | layout.setVerticalGroup( 93 | layout.createSequentialGroup() 94 | .addComponent(self.outputLabel) 95 | .addComponent(self.scrollPane) 96 | .addGroup(layout.createParallelGroup() 97 | .addComponent(self.clearBtn) 98 | .addComponent(self.DeleteSelectedBtn) 99 | .addComponent(self.exportBtn) 100 | ) 101 | ) 102 | 103 | def getTabCaption(self): 104 | return "BurpJSLinkFinder Community" 105 | 106 | def getUiComponent(self): 107 | return self.tab 108 | 109 | def clearLog(self, event): 110 | self.dataModel.setRowCount(0) 111 | 112 | def deleteSelected(self, event): 113 | selected = self.outputList.getSelectedRows() 114 | Idel=0 115 | for i in selected: 116 | self.outputList.getModel().removeRow(i-Idel) 117 | Idel+=1 118 | 119 | def createMenuItems(self, invocation): 120 | items = [] 121 | item = JMenuItem("Run Scan", actionPerformed=lambda _: self.linkfinderWorker(invocation)) 122 | items.append(item) 123 | return items 124 | 125 | def saveBtn(self,e): 126 | chooseFile = JFileChooser() 127 | chooseFile.setDialogTitle('Select Export Location') 128 | chooseFile.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY) 129 | 130 | txt="" 131 | for i in range(self.outputList.getModel().getRowCount()): 132 | txt+=str(self.outputList.getModel().getValueAt(i,0))+"\t"+self.outputList.getModel().getValueAt(i,1)+"\t"+self.outputList.getModel().getValueAt(i,2)+"\t"+self.outputList.getModel().getValueAt(i,3)+"\n" 133 | ret = chooseFile.showSaveDialog(self.tab) 134 | if ret == JFileChooser.APPROVE_OPTION: 135 | if chooseFile.getSelectedFile().isDirectory(): 136 | file_name = str(chooseFile.getSelectedFile()) 137 | f=open(file_name+"/export.txt","wb") 138 | f.write(txt) 139 | f.close() 140 | 141 | 142 | def linkfinderWorker(self, invocation): 143 | messages=invocation.getSelectedMessages() 144 | for ihrr in messages: 145 | try: 146 | urlReq = ihrr.getUrl() 147 | testString = str(urlReq) 148 | print("Scanning "+testString) 149 | linkA = linkAnalyse(ihrr,self.helpers) 150 | 151 | # Exclude casual JS files 152 | if any(x in testString.split("/")[-1] for x in JSExclusionList): 153 | print("[-] URL excluded " + str(urlReq)) 154 | else: 155 | issueText = linkA.analyseURL() 156 | for counter, issueText in enumerate(issueText): 157 | if "." in issueText['link']: 158 | if issueText['link'].split("?")[0].split(".")[-1] in self.blacklist_ext: 159 | continue 160 | 161 | headers = self.helpers.analyzeRequest(ihrr.getHttpService(),ihrr.getRequest()).getHeaders() 162 | referer = "No Referer" 163 | for h in headers: 164 | if h.split(":")[0]=="Referer": 165 | referer = h.split("Referer:")[1].strip() 166 | break 167 | 168 | self.outputList.getModel().addRow([self.outputList.getModel().getRowCount(),str(urlReq),referer,issueText['link']]) 169 | 170 | except UnicodeEncodeError: 171 | print ("Error in URL decode.") 172 | print("Scan ended.") 173 | return None 174 | 175 | 176 | def consolidateDuplicateIssues(self, isb, isa): 177 | return -1 178 | 179 | def extensionUnloaded(self): 180 | print("BurpJSLinkFinder Community unloaded") 181 | return 182 | 183 | class linkAnalyse(): 184 | 185 | def __init__(self, reqres, helpers): 186 | self.helpers = helpers 187 | self.reqres = reqres 188 | 189 | 190 | regex_str = r""" 191 | 192 | (?:"|') # Start newline delimiter 193 | 194 | ( 195 | ((?:[a-zA-Z]{1,10}://|//) # Match a scheme [a-Z]*1-10 or // 196 | [^"'/]{1,}\. # Match a domainname (any character + dot) 197 | [a-zA-Z]{2,}[^"']{0,}) # The domainextension and/or path 198 | 199 | | 200 | 201 | ((?:/|\.\./|\./) # Start with /,../,./ 202 | [^"'><,;| *()(%%$^/\\\[\]] # Next character can't be... 203 | [^"'><,;|()]{1,}) # Rest of the characters can't be 204 | 205 | | 206 | 207 | ([a-zA-Z0-9_\-/]{1,}/ # Relative endpoint with / 208 | [a-zA-Z0-9_\-/.]{1,} # Resource name 209 | \.(?:[a-zA-Z]{1,4}|action) # Rest + extension (length 1-4 or action) 210 | (?:[\?|#][^"|']{0,}|)) # ? or # mark with parameters 211 | 212 | | 213 | 214 | ([a-zA-Z0-9_\-/]{1,}/ # REST API (no extension) with / 215 | [a-zA-Z0-9_\-/]{3,} # Proper REST endpoints usually have 3+ chars 216 | (?:[\?|#][^"|']{0,}|)) # ? or # mark with parameters 217 | 218 | | 219 | 220 | ([a-zA-Z0-9_\-]{1,} # filename 221 | \.(?:php|asp|aspx|jsp|json| 222 | action|html|js|txt|xml) # . + extension 223 | (?:[\?|#][^"|']{0,}|)) # ? or # mark with parameters 224 | 225 | ) 226 | 227 | (?:"|') # End newline delimiter 228 | 229 | """ 230 | 231 | def parser_file(self, content, regex_str, mode=1, more_regex=None, no_dup=1): 232 | regex = re.compile(regex_str, re.VERBOSE) 233 | items = [{"link": m.group(1)} for m in re.finditer(regex, content)] 234 | if no_dup: 235 | # Remove duplication 236 | all_links = set() 237 | no_dup_items = [] 238 | for item in items: 239 | if item["link"] not in all_links: 240 | all_links.add(item["link"]) 241 | no_dup_items.append(item) 242 | items = no_dup_items 243 | 244 | # Match Regex 245 | filtered_items = [] 246 | for item in items: 247 | # Remove other capture groups from regex results 248 | if more_regex: 249 | if re.search(more_regex, item["link"]): 250 | #print ("TEST parselfile #3") 251 | filtered_items.append(item) 252 | else: 253 | filtered_items.append(item) 254 | return filtered_items 255 | 256 | # Potential for use in the future... 257 | def threadAnalysis(self): 258 | thread = Thread(target=self.analyseURL(), args=(session,)) 259 | thread.daemon = True 260 | thread.start() 261 | 262 | def analyseURL(self): 263 | endpoints = "" 264 | try: 265 | encoded_resp=binascii.b2a_base64(self.reqres.getResponse()) 266 | decoded_resp=base64.b64decode(encoded_resp) 267 | endpoints=self.parser_file(decoded_resp, self.regex_str) 268 | except: 269 | pass 270 | return endpoints 271 | 272 | 273 | if __name__ in ('__main__', 'main'): 274 | EventQueue.invokeLater(Run(BurpExtender)) 275 | -------------------------------------------------------------------------------- /jslinkfinder.py: -------------------------------------------------------------------------------- 1 | # 2 | # BurpLinkFinder - Find links within JS files. 3 | # 4 | # Copyright (c) 2019 Frans Hendrik Botes, 5 | # Copyright (c) 2024 v2.3 Enes Saltik, 6 | # Credit to https://github.com/GerbenJavado/LinkFinder for the idea and regex 7 | # 8 | from burp import IBurpExtender, IScannerCheck, IScanIssue, ITab 9 | from java.io import PrintWriter 10 | from java.net import URL 11 | from java.util import ArrayList, List 12 | from java.util.regex import Matcher, Pattern 13 | import binascii 14 | import base64 15 | import re 16 | from javax import swing 17 | from java.awt import Font, Color 18 | from threading import Thread 19 | from array import array 20 | from java.awt import EventQueue,Dimension 21 | from java.lang import Runnable 22 | from thread import start_new_thread 23 | from javax.swing import JFileChooser 24 | from javax.swing.table import DefaultTableModel 25 | 26 | # Using the Runnable class for thread-safety with Swing 27 | class Run(Runnable): 28 | def __init__(self, runner): 29 | self.runner = runner 30 | 31 | def run(self): 32 | self.runner() 33 | 34 | # Needed params 35 | 36 | JSExclusionList = ['jquery', 'google-analytics','gpt.js'] 37 | 38 | class BurpExtender(IBurpExtender, IScannerCheck, ITab): 39 | def registerExtenderCallbacks(self, callbacks): 40 | self.callbacks = callbacks 41 | self.helpers = callbacks.getHelpers() 42 | callbacks.setExtensionName("BurpJSLinkFinder") 43 | callbacks.issueAlert("BurpJSLinkFinder Passive Scanner enabled") 44 | 45 | self.onlyScope = False 46 | 47 | stdout = PrintWriter(callbacks.getStdout(), True) 48 | stderr = PrintWriter(callbacks.getStderr(), True) 49 | callbacks.registerScannerCheck(self) 50 | self.initUI() 51 | self.callbacks.addSuiteTab(self) 52 | 53 | self.blacklist_ext = ["jpg","png","jpeg","gif","css","svg","pdf","woff","woff2","ttf","eot"] 54 | 55 | print ("Burp JS LinkFinder V2 loaded.") 56 | print ("Copyright (c) 2019 Frans Hendrik Botes") 57 | print ("Copyright (c) 2024 V2.3 (Current) Enes Saltik") 58 | 59 | def initUI(self): 60 | self.tab = swing.JPanel() 61 | 62 | # UI for Output 63 | self.outputLabel = swing.JLabel("LinkFinder V2 Log:") 64 | self.outputLabel.setFont(Font("Tahoma", Font.BOLD, 14)) 65 | self.outputLabel.setForeground(Color(255,102,52)) 66 | self.tableData = [] 67 | colNames = ('ID','URL','Referer','Found Path') 68 | self.dataModel = DefaultTableModel(self.tableData, colNames) 69 | self.outputList = swing.JTable(self.dataModel) 70 | self.outputList.setAutoCreateRowSorter(True) 71 | self.scrollPane = swing.JScrollPane() 72 | self.scrollPane.setPreferredSize(Dimension(300,100)) 73 | self.scrollPane.getViewport().setView((self.outputList)) 74 | 75 | self.clearBtn = swing.JButton("Clear Log", actionPerformed=self.clearLog) 76 | self.DeleteSelectedBtn = swing.JButton("Delete Selected Items", actionPerformed=self.deleteSelected) 77 | self.exportBtn = swing.JButton("Export Endpoints", actionPerformed=self.saveBtn) 78 | 79 | self.onlyScopeCheckbox = swing.JCheckBox("Only In-Scope Items",actionPerformed=self.checkBoxScope) 80 | 81 | # Layout 82 | layout = swing.GroupLayout(self.tab) 83 | layout.setAutoCreateGaps(True) 84 | layout.setAutoCreateContainerGaps(True) 85 | self.tab.setLayout(layout) 86 | 87 | layout.setHorizontalGroup( 88 | layout.createParallelGroup() 89 | .addGroup(layout.createSequentialGroup() 90 | .addGroup(layout.createParallelGroup() 91 | .addComponent(self.outputLabel) 92 | .addComponent(self.scrollPane) 93 | .addGroup(layout.createSequentialGroup() 94 | .addComponent(self.clearBtn) 95 | .addComponent(self.DeleteSelectedBtn) 96 | .addComponent(self.exportBtn) 97 | .addComponent(self.onlyScopeCheckbox) 98 | ) 99 | ) 100 | ) 101 | ) 102 | 103 | layout.setVerticalGroup( 104 | layout.createSequentialGroup() 105 | .addComponent(self.outputLabel) 106 | .addComponent(self.scrollPane) 107 | .addGroup(layout.createParallelGroup() 108 | .addComponent(self.clearBtn) 109 | .addComponent(self.DeleteSelectedBtn) 110 | .addComponent(self.exportBtn) 111 | .addComponent(self.onlyScopeCheckbox) 112 | ) 113 | ) 114 | 115 | def checkBoxScope(self,_x): 116 | self.onlyScope=not self.onlyScope 117 | 118 | def getTabCaption(self): 119 | return "BurpJSLinkFinder" 120 | 121 | def getUiComponent(self): 122 | return self.tab 123 | 124 | def clearLog(self, event): 125 | self.dataModel.setRowCount(0) 126 | 127 | def deleteSelected(self, event): 128 | selected = self.outputList.getSelectedRows() 129 | Idel=0 130 | for i in selected: 131 | self.outputList.getModel().removeRow(i-Idel) 132 | Idel+=1 133 | 134 | def saveBtn(self,e): 135 | chooseFile = JFileChooser() 136 | chooseFile.setDialogTitle('Select Export Location') 137 | chooseFile.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY) 138 | 139 | txt="" 140 | for i in range(self.outputList.getModel().getRowCount()): 141 | txt+=str(self.outputList.getModel().getValueAt(i,0))+"\t"+self.outputList.getModel().getValueAt(i,1)+"\t"+self.outputList.getModel().getValueAt(i,2)+"\t"+self.outputList.getModel().getValueAt(i,3)+"\n" 142 | ret = chooseFile.showSaveDialog(self.tab) 143 | if ret == JFileChooser.APPROVE_OPTION: 144 | if chooseFile.getSelectedFile().isDirectory(): 145 | file_name = str(chooseFile.getSelectedFile()) 146 | f=open(file_name+"/export.txt","wb") 147 | f.write(txt) 148 | f.close() 149 | 150 | def scanJS(self,ihrr): 151 | try: 152 | urlReq = ihrr.getUrl() 153 | testString = str(urlReq) 154 | linkA = linkAnalyse(ihrr,self.helpers) 155 | # check if JS file 156 | if ".js" in str(urlReq): 157 | # Exclude casual JS files 158 | if any(x in testString.split("/")[-1] for x in JSExclusionList): 159 | print("\n" + "[-] URL excluded " + str(urlReq)) 160 | else: 161 | if self.onlyScope and not self.callbacks.isInScope(urlReq): 162 | return 163 | issueText = linkA.analyseURL() 164 | for counter, issueText in enumerate(issueText): 165 | if "." in issueText['link']: 166 | if issueText['link'].split("?")[0].split(".")[-1] in self.blacklist_ext: 167 | continue 168 | 169 | headers = self.helpers.analyzeRequest(ihrr.getHttpService(),ihrr.getRequest()).getHeaders() 170 | referer = "No Referer" 171 | for h in headers: 172 | if h.split(":")[0]=="Referer": 173 | referer = h.split("Referer:")[1].strip() 174 | break 175 | 176 | self.outputList.getModel().addRow([self.outputList.getModel().getRowCount(),str(urlReq),referer,issueText['link']]) 177 | issues = ArrayList() 178 | issues.add(SRI(ihrr, self.helpers)) 179 | return issues 180 | except UnicodeEncodeError: 181 | print ("Error in URL decode.", urlReq) 182 | except: 183 | pass 184 | return None 185 | 186 | def doActiveScan(self, brr, _): 187 | return self.scanJS(brr) 188 | 189 | def doPassiveScan(self, ihrr): 190 | return self.scanJS(ihrr) 191 | 192 | def consolidateDuplicateIssues(self, isb, isa): 193 | return -1 194 | 195 | def extensionUnloaded(self): 196 | print("Burp JS LinkFinder unloaded") 197 | return 198 | 199 | class linkAnalyse(): 200 | 201 | def __init__(self, reqres, helpers): 202 | self.helpers = helpers 203 | self.reqres = reqres 204 | 205 | 206 | regex_str = r""" 207 | 208 | (?:"|') # Start newline delimiter 209 | 210 | ( 211 | ((?:[a-zA-Z]{1,10}://|//) # Match a scheme [a-Z]*1-10 or // 212 | [^"'/]{1,}\. # Match a domainname (any character + dot) 213 | [a-zA-Z]{2,}[^"']{0,}) # The domainextension and/or path 214 | 215 | | 216 | 217 | ((?:/|\.\./|\./) # Start with /,../,./ 218 | [^"'><,;| *()(%%$^/\\\[\]] # Next character can't be... 219 | [^"'><,;|()]{1,}) # Rest of the characters can't be 220 | 221 | | 222 | 223 | ([a-zA-Z0-9_\-/]{1,}/ # Relative endpoint with / 224 | [a-zA-Z0-9_\-/.]{1,} # Resource name 225 | \.(?:[a-zA-Z]{1,4}|action) # Rest + extension (length 1-4 or action) 226 | (?:[\?|#][^"|']{0,}|)) # ? or # mark with parameters 227 | 228 | | 229 | 230 | ([a-zA-Z0-9_\-/]{1,}/ # REST API (no extension) with / 231 | [a-zA-Z0-9_\-/]{3,} # Proper REST endpoints usually have 3+ chars 232 | (?:[\?|#][^"|']{0,}|)) # ? or # mark with parameters 233 | 234 | | 235 | 236 | ([a-zA-Z0-9_\-]{1,} # filename 237 | \.(?:php|asp|aspx|jsp|json| 238 | action|html|js|txt|xml) # . + extension 239 | (?:[\?|#][^"|']{0,}|)) # ? or # mark with parameters 240 | 241 | ) 242 | 243 | (?:"|') # End newline delimiter 244 | 245 | """ 246 | 247 | def parser_file(self, content, regex_str, mode=1, more_regex=None, no_dup=1): 248 | regex = re.compile(regex_str, re.VERBOSE) 249 | items = [{"link": m.group(1)} for m in re.finditer(regex, content)] 250 | if no_dup: 251 | # Remove duplication 252 | all_links = set() 253 | no_dup_items = [] 254 | for item in items: 255 | if item["link"] not in all_links: 256 | all_links.add(item["link"]) 257 | no_dup_items.append(item) 258 | items = no_dup_items 259 | 260 | # Match Regex 261 | filtered_items = [] 262 | for item in items: 263 | # Remove other capture groups from regex results 264 | if more_regex: 265 | if re.search(more_regex, item["link"]): 266 | #print ("TEST parselfile #3") 267 | filtered_items.append(item) 268 | else: 269 | filtered_items.append(item) 270 | return filtered_items 271 | 272 | # Potential for use in the future... 273 | def threadAnalysis(self): 274 | thread = Thread(target=self.analyseURL(), args=(session,)) 275 | thread.daemon = True 276 | thread.start() 277 | 278 | def analyseURL(self): 279 | endpoints = "" 280 | mime_type=self.helpers.analyzeResponse(self.reqres.getResponse()).getStatedMimeType() 281 | if mime_type.lower() == 'script': 282 | url = self.reqres.getUrl() 283 | encoded_resp=binascii.b2a_base64(self.reqres.getResponse()) 284 | decoded_resp=base64.b64decode(encoded_resp) 285 | endpoints=self.parser_file(decoded_resp, self.regex_str) 286 | return endpoints 287 | return endpoints 288 | 289 | 290 | class SRI(IScanIssue,ITab): 291 | def __init__(self, reqres, helpers): 292 | self.helpers = helpers 293 | self.reqres = reqres 294 | 295 | def getHost(self): 296 | return self.reqres.getHost() 297 | 298 | def getPort(self): 299 | return self.reqres.getPort() 300 | 301 | def getProtocol(self): 302 | return self.reqres.getProtocol() 303 | 304 | def getUrl(self): 305 | return self.reqres.getUrl() 306 | 307 | def getIssueName(self): 308 | return "Linkfinder Analysed JS files" 309 | 310 | def getIssueType(self): 311 | return 0x08000000 # See http:#portswigger.net/burp/help/scanner_issuetypes.html 312 | 313 | def getSeverity(self): 314 | return "Information" # "High", "Medium", "Low", "Information" or "False positive" 315 | 316 | def getConfidence(self): 317 | return "Certain" # "Certain", "Firm" or "Tentative" 318 | 319 | def getIssueBackground(self): 320 | return str("JS files holds links to other parts of web applications. Refer to TAB for results.") 321 | 322 | def getRemediationBackground(self): 323 | return "This is an informational finding only.
" 324 | 325 | def getIssueDetail(self): 326 | return str("Burp Scanner has analysed the following JS file for links: " 327 | "%s

" % (self.reqres.getUrl().toString())) 328 | 329 | def getRemediationDetail(self): 330 | return None 331 | 332 | def getHttpMessages(self): 333 | #print ("................raising issue................") 334 | rra = [self.reqres] 335 | return rra 336 | 337 | def getHttpService(self): 338 | return self.reqres.getHttpService() 339 | 340 | 341 | if __name__ in ('__main__', 'main'): 342 | EventQueue.invokeLater(Run(BurpExtender)) 343 | --------------------------------------------------------------------------------