def saveHomeOption(self): # If saveHome == True --> Get 'savePath' Path savePath = self.getSavePath() if not FileUtils.exists(savePath): # Check Existence FileUtils.createDirectory(savePath) if FileUtils.exists( savePath) and not FileUtils.isDir(savePath): # Check Status self.output.error( "NOT Available ! {} is a File, Should be a Directory.\nPlease Check Again." .format(savePath)) exit(1) if not FileUtils.canWrite(savePath): # Check Writability self.output.error( "Directory {} is Not Writable.\nPlease Check Again.".format( savePath)) exit(1) return savePath
def setupBatchReports(self): self.batch = True self.batchSession = "Batch-{0}".format( time.strftime('%y-%m-%d_%H-%M-%S')) self.batchDirectoryPath = FileUtils.createPath( self.savePath, "reports", self.batchSession) if not FileUtils.exists(self.batchDirectoryPath): FileUtils.createDirectory(self.batchDirectoryPath) if not FileUtils.exists(self.batchDirectoryPath): self.output.error("Cannot Create Batch Folder {}".format( self.batchDirectoryPath)) sys.exit(1) if FileUtils.canWrite(self.batchDirectoryPath): FileUtils.createDirectory(self.batchDirectoryPath) targetsFile = FileUtils.createPath(self.batchDirectoryPath, "Target-URL-List.txt") FileUtils.writeLines(targetsFile, self.arguments.urlList) else: self.output.error("Cannnot Write Batch Folder {}.".format( self.batchDirectoryPath)) sys.exit(1)
def getReportsPath(self, requester): if self.arguments.autoSave: # Default True basePath = ('/' if requester.basePath is '' else requester.basePath) basePath = basePath.replace(os.path.sep, '.')[1:-1] # Generate File Name & Directory Path fileName = None directoryPath = None if self.batch: fileName = requester.host directoryPath = self.batchDirectoryPath else: fileName = ('{}_'.format(basePath) if basePath is not '' else '') fileName += time.strftime('%y-%m-%d_%H-%M-%S') directoryPath = FileUtils.createPath(self.savePath, 'reports', requester.host) if not FileUtils.exists(directoryPath): FileUtils.createDirectory(directoryPath) if not FileUtils.exists(directoryPath): self.output.error("Cannot Create Reports Folder {}".format( directoryPath)) sys.exit(1) # Generate Reports File Path outputFile = FileUtils.createPath(directoryPath, fileName) # Rename If Duplicate File is Found In Target Directory if FileUtils.exists(outputFile): i = 2 while FileUtils.exists(outputFile + "_" + str(i)): i += 1 outputFile += "_" + str(i) return outputFile, directoryPath
def parseConfig(self): config = DefaultConfigParser() configPath = FileUtils.buildPath(os.path.expanduser('~'), ".dirsearch", "dirsearch.conf") if not FileUtils.exists(configPath): FileUtils.createDirectory(os.path.dirname(configPath)) shutil.copyfile(FileUtils.buildPath(self.script_path, 'default.conf'), configPath) config.read(configPath) # General self.threadsCount = config.safe_getint("general", "threads", 10, list(range(1, 50))) self.excludeStatusCodes = config.safe_get("general", "exclude-status", None) self.redirect = config.safe_getboolean("general", "follow-redirects", False) self.recursive = config.safe_getboolean("general", "recursive", False) self.recursive_level_max = config.safe_getint("general", "recursive-level-max", 1) self.suppressEmpty = config.safe_getboolean("general", "suppress-empty", False) self.testFailPath = config.safe_get("general", "scanner-fail-path", "").strip() self.saveHome = config.safe_getboolean("general", "save-logs-home", False) # Reports self.autoSave = config.safe_getboolean("reports", "autosave-report", False) self.autoSaveFormat = config.safe_get("reports", "autosave-report-format", "plain", ["plain", "json", "simple"]) # Dictionary self.wordlist = config.safe_get("dictionary", "wordlist", FileUtils.buildPath(self.script_path, "db", "dicc.txt")) self.lowercase = config.safe_getboolean("dictionary", "lowercase", False) self.forceExtensions = config.safe_get("dictionary", "force-extensions", False) # Connection self.useRandomAgents = config.safe_get("connection", "random-user-agents", False) self.useragent = config.safe_get("connection", "user-agent", None) self.delay = config.safe_get("connection", "delay", 0) self.timeout = config.safe_getint("connection", "timeout", 30) self.maxRetries = config.safe_getint("connection", "max-retries", 5) self.proxy = config.safe_get("connection", "http-proxy", None) self.httpmethod = config.safe_get("connection", "httpmethod", "get", ["get", "head", "post"]) self.requestByHostname = config.safe_get("connection", "request-by-hostname", False)
def __generate_table_web(self): """ Generate the table with HTTP services registered in the mission """ req = ServicesRequester(self.sqlsession) req.select_mission(self.mission) filter_ = Filter(FilterOperator.AND) filter_.add_condition(Condition('http', FilterData.SERVICE_EXACT)) req.add_filter(filter_) services = req.get_results() if len(services) == 0: html = """ <tr class="notfound"> <td colspan="7">No record found</td> </tr> """ else: html = '' # Unavailable thumbnail with open(REPORT_TPL_DIR + '/../img/unavailable.png', 'rb') as f: unavailable_b64 = base64.b64encode(f.read()).decode('ascii') for service in services: # Results HTML page name results = 'results-{ip}-{port}-{service}-{id}.html'.format( ip=str(service.host.ip), port=service.port, service=service.name, id=service.id) # Encrypted ? (SSL/TLS) enc = '<span class="mdi mdi-lock" title="SSL/TLS encrypted"></span>' \ if service.is_encrypted() else '' # Web technos (in a specific order) # try: # technos = ast.literal_eval(service.web_technos) # except Exception as e: # logger.debug('Error when retrieving "web_technos" field ' \ # 'from db: {exc} for {service}'.format( # exc=e, service=service)) # technos = list() # tmp = list() # for t in technos: # tmp.append('{}{}{}'.format( # t['name'], # ' ' if t['version'] else '', # t['version'] if t['version'] else '')) # webtechnos = ' | '.join(tmp) webtechnos = '' product_types = ('web-server', 'web-appserver', 'web-cms', 'web-language', 'web-framework', 'web-jslib') for t in product_types: product = service.get_product(t) if product: webtechnos += '<span class="badge badge-{type} badge-light">' \ '{name}{version}</span>'.format( type=t, name=product.name, version=' '+str(product.version) \ if product.version else '') # Web Application Firewall product = service.get_product('web-application-firewall') waf = '' if product: waf = '<span class="badge badge-web-application-firewall ' \ 'badge-light">{name}{version}</span>'.format( name=product.name, version=' '+str(product.version) \ if product.version else '') # Screenshot img_name = 'scren-{ip}-{port}-{id}'.format(ip=str( service.host.ip), port=service.port, id=service.id) path = self.output_path + '/screenshots' if service.screenshot is not None \ and service.screenshot.status == ScreenStatus.OK \ and FileUtils.exists(path + '/' + img_name + '.png') \ and FileUtils.exists(path + '/' + img_name + '.thumb.png'): screenshot = """ <a href="{screenlarge}" title="{url} - {title}" class="image-link"> <img src="{screenthumb}" class="border rounded"> </a> """.format(url=service.url, screenlarge='screenshots/' + img_name + '.png', title=service.html_title, screenthumb='screenshots/' + img_name + '.thumb.png') else: screenshot = """ <img src="data:image/png;base64,{unavailable}"> """.format(unavailable=unavailable_b64) # HTML for table row html += """ <tr{clickable}> <td>{url}</td> <td>{enc}</td> <td>{title}</td> <td>{webtechnos}</td> <td>{waf}</td> <td>{screenshot}</td> <td>{checks}</td> </tr> """.format( clickable=' class="clickable-row" data-href="{results}"'.format( results=results) if len(service.results) > 0 else '', url='<a href="{}" title="{}">{}</a>'.format( service.url, service.url, StringUtils.shorten(service.url, 50)) \ if service.url else '', enc=enc, title=StringUtils.shorten(service.html_title, 40), webtechnos=webtechnos, waf=waf, screenshot=screenshot, checks=len(service.results)) return html
def __generate_table_web(self): """ Generate the table with HTTP services registered in the mission """ req = ServicesRequester(self.sqlsession) req.select_mission(self.mission) filter_ = Filter(FilterOperator.AND) filter_.add_condition(Condition('http', FilterData.SERVICE_EXACT)) req.add_filter(filter_) services = req.get_results() if len(services) == 0: html = """ <tr class="notfound"> <td colspan="5">No record found</td> </tr> """ else: html = '' # Unavailable thumbnail with open(REPORT_TPL_DIR + '/../img/unavailable.png', 'rb') as f: unavailable_b64 = base64.b64encode(f.read()).decode('ascii') for service in services: # Results HTML page name results = 'results-{ip}-{port}-{service}-{id}.html'.format( ip=str(service.host.ip), port=service.port, service=service.name, id=service.id) # Web technos try: technos = ast.literal_eval(service.web_technos) except Exception as e: logger.debug('Error when retrieving "web_technos" field ' \ 'from db: {exc} for {service}'.format( exc=e, service=service)) technos = list() tmp = list() for t in technos: tmp.append('{}{}{}'.format( t['name'], ' ' if t['version'] else '', t['version'] if t['version'] else '')) webtechnos = ' | '.join(tmp) # Screenshot img_name = 'scren-{ip}-{port}-{id}'.format(ip=str( service.host.ip), port=service.port, id=service.id) path = self.output_path + '/screenshots' if service.screenshot is not None \ and service.screenshot.status == ScreenStatus.OK \ and FileUtils.exists(path + '/' + img_name + '.png') \ and FileUtils.exists(path + '/' + img_name + '.thumb.png'): screenshot = """ <a href="{screenlarge}" title="{title}" class="image-link"> <img src="{screenthumb}" class="border rounded"> </a> """.format(screenlarge='screenshots/' + img_name + '.png', title=service.html_title, screenthumb='screenshots/' + img_name + '.thumb.png') else: screenshot = """ <img src="data:image/png;base64,{unavailable}"> """.format(unavailable=unavailable_b64) # HTML for table row html += """ <tr{clickable}> <td>{url}</td> <td>{title}</td> <td>{webtechnos}</td> <td>{screenshot}</td> <td>{checks}</td> </tr> """.format( clickable=' class="clickable-row" data-href="{results}"'.format( results=results) if len(service.results) > 0 else '', url='<a href="{}" title="{}">{}</a>'.format( service.url, service.url, StringUtils.shorten(service.url, 50)) \ if service.url else '', title=StringUtils.shorten(service.html_title, 40), webtechnos=webtechnos, screenshot=screenshot, checks=len(service.results)) return html
def exists(self): return FileUtils.exists(self.path)