def test_zap(zapconfig): parser = SafeConfigParser() parser.read(zapconfig) zapUrl = parser.get("Proxy", "url"); zap = ZAP(proxies={'http': zapUrl, 'https': zapUrl}) if (parser.getboolean("Actions", "start")): # print "platform=" + platform.system() if (platform.system() == "Windows"): zapScript = "start /b zap.bat" else: zapScript = "zap.sh" zapInstall = parser.get("Proxy", "install"); if (len(zapInstall) == 0): if (platform.system() == "Windows"): # Win 7 default path zapInstall = "C:\Program Files (x86)\OWASP\Zed Attack Proxy"; if ( not os.path.exists(zapInstall)): # Win XP default path zapInstall = "C:\Program Files\OWASP\Zed Attack Proxy"; else: # No default path for Mac OS or Linux print "Installation directory must be set in " + zapconfig if (len(parser.get("Proxy", "home")) > 0): zapScript = zapScript + " -d " + parser.get("Proxy", "home") os.chdir(zapInstall); os.system(zapScript); time.sleep(20); spiderUrls = parser.get("Actions", "spider"); if (len(spiderUrls) > 0): for spiderUrl in spiderUrls.split(','): zap.urlopen(spiderUrl) # Give the sites tree a chance to get updated time.sleep(2) print 'Spidering %s' % spiderUrl zap.start_spider(spiderUrl) # Give the Spider a chance to start time.sleep(2) while (int(zap.spider_status[0]) < 100): #print 'Spider progress %: ' + zap.spider_status[0] time.sleep(5) print 'Finished spidering %s' % spiderUrl print 'Spider completed' # Give the passive scanner a chance to finish time.sleep(5) scanUrls = parser.get("Actions", "scan"); if (len(scanUrls) > 0): for scanUrl in scanUrls.split(','): print 'Scanning %s' % scanUrl zap.start_scan(scanUrl) while (int(zap.scan_status[0]) < 100): #print 'Scan progress %: ' + zap.scan_status[0] time.sleep(5) print 'Finished scanning %s' % scanUrl print 'Scanner completed' saveSession = parser.get("Actions", "savesession"); if (len(saveSession) > 0): time.sleep(5) # Will this help?? zap.save_session(saveSession) #zapAlerts = zap.alerts # Save for later, in case ZAP is stopped.. zapAlerts = copy.deepcopy(zap.alerts) # Save for later, in case ZAP is stopped.. if (parser.getboolean("Actions", "stop")): # TODO: this is causing problems right now :( zap.shutdown() requireAlertsStr = parser.get("Alerts", "require") if (len(requireAlertsStr) > 0): for requireAlertStr in requireAlertsStr.split("\n"): requireAlert = ast.literal_eval(requireAlertStr) # Check at least one match found in the alerts found = False for alert in zapAlerts: if ( match_alerts(alert, requireAlert)): found = True break if (not found): # No match, fail the test print "Required alert not present: " + requireAlertStr assert 0 ignoreAlertsStr = parser.get("Alerts", "ignore") ignoreAlerts = [] if (len(ignoreAlertsStr) > 0): for ignoreAlertStr in ignoreAlertsStr.split("\n"): ignoreAlerts.append(ast.literal_eval(ignoreAlertStr)) strippedAlerts = strip_alerts(zapAlerts, ignoreAlerts) saveAlerts = parser.get("Alerts", "savealerts") if (len(saveAlerts) > 0): alertsFile = open(saveAlerts, 'w') for alert in strippedAlerts: alertsFile.write(alert_to_str(alert)) alertsFile.write("\n") alertsFile.close() assert len(strippedAlerts) == 0
def test_zap(zapconfig): parser = SafeConfigParser() parser.read(zapconfig) zapUrl = parser.get("Proxy", "url") zap = ZAP(proxies={'http': zapUrl, 'https': zapUrl}) if (parser.getboolean("Actions", "start")): # print "platform=" + platform.system() if (platform.system() == "Windows"): zapScript = "start /b zap.bat" else: zapScript = "zap.sh" zapInstall = parser.get("Proxy", "install") if (len(zapInstall) == 0): if (platform.system() == "Windows"): # Win 7 default path zapInstall = "C:\Program Files (x86)\OWASP\Zed Attack Proxy" if (not os.path.exists(zapInstall)): # Win XP default path zapInstall = "C:\Program Files\OWASP\Zed Attack Proxy" else: # No default path for Mac OS or Linux print "Installation directory must be set in " + zapconfig if (len(parser.get("Proxy", "home")) > 0): zapScript = zapScript + " -d " + parser.get("Proxy", "home") os.chdir(zapInstall) os.system(zapScript) time.sleep(20) spiderUrls = parser.get("Actions", "spider") if (len(spiderUrls) > 0): for spiderUrl in spiderUrls.split(','): zap.urlopen(spiderUrl) # Give the sites tree a chance to get updated time.sleep(2) print 'Spidering %s' % spiderUrl zap.start_spider(spiderUrl) # Give the Spider a chance to start time.sleep(2) while (int(zap.spider_status[0]) < 100): #print 'Spider progress %: ' + zap.spider_status[0] time.sleep(5) print 'Finished spidering %s' % spiderUrl print 'Spider completed' # Give the passive scanner a chance to finish time.sleep(5) scanUrls = parser.get("Actions", "scan") if (len(scanUrls) > 0): for scanUrl in scanUrls.split(','): print 'Scanning %s' % scanUrl zap.start_scan(scanUrl) while (int(zap.scan_status[0]) < 100): #print 'Scan progress %: ' + zap.scan_status[0] time.sleep(5) print 'Finished scanning %s' % scanUrl print 'Scanner completed' saveSession = parser.get("Actions", "savesession") if (len(saveSession) > 0): time.sleep(5) # Will this help?? zap.save_session(saveSession) #zapAlerts = zap.alerts # Save for later, in case ZAP is stopped.. zapAlerts = copy.deepcopy( zap.alerts) # Save for later, in case ZAP is stopped.. if (parser.getboolean("Actions", "stop")): # TODO: this is causing problems right now :( zap.shutdown() requireAlertsStr = parser.get("Alerts", "require") if (len(requireAlertsStr) > 0): for requireAlertStr in requireAlertsStr.split("\n"): requireAlert = ast.literal_eval(requireAlertStr) # Check at least one match found in the alerts found = False for alert in zapAlerts: if (match_alerts(alert, requireAlert)): found = True break if (not found): # No match, fail the test print "Required alert not present: " + requireAlertStr assert 0 ignoreAlertsStr = parser.get("Alerts", "ignore") ignoreAlerts = [] if (len(ignoreAlertsStr) > 0): for ignoreAlertStr in ignoreAlertsStr.split("\n"): ignoreAlerts.append(ast.literal_eval(ignoreAlertStr)) strippedAlerts = strip_alerts(zapAlerts, ignoreAlerts) saveAlerts = parser.get("Alerts", "savealerts") if (len(saveAlerts) > 0): alertsFile = open(saveAlerts, 'w') for alert in strippedAlerts: alertsFile.write(alert_to_str(alert)) alertsFile.write("\n") alertsFile.close() assert len(strippedAlerts) == 0
class ZAPPlugin(ExternalProcessPlugin): PLUGIN_NAME = "ZAP" PLUGIN_VERSION = "0.1" ZAP_NAME = "zap.sh" def do_configure(self): logging.debug("ZAPPlugin.do_configure") self.zap_path = self.locate_program(self.ZAP_NAME) if self.zap_path is None: raise Exception("Cannot find %s in PATH" % self.ZAP_NAME) # Validate the configuration if self.configuration.get('target') is None or len(self.configuration['target']) == 0: raise Exception("Missing or invalid target in configuration") def do_process_ended(self, status): logging.debug("ZAPPlugin.do_process_ended") self.callbacks.report_finish() def do_start(self): logging.debug("ZAPPlugin.do_start") # Start ZAP in daemon mode self.zap_port = self._random_port() args = ['-daemon', '-port', str(self.zap_port), '-dir', self.work_directory] self.spawn(self.zap_path, args) self.report_artifacts("ZAP Output", ["zap.log"]) # Start the main code in a thread return deferToThread(self._blocking_zap_main) def _random_port(self): return random.randint(8192, 16384) def _blocking_zap_main(self): logging.debug("ZAPPlugin._blocking_zap_main") self.report_progress(15, 'Starting ZAP') try: self.zap = ZAP(proxies={'http': 'http://127.0.0.1:%d' % self.zap_port, 'https': 'http://127.0.0.1:%d' % self.zap_port}) target = self.configuration['target'] time.sleep(5) logging.info('Accessing target %s' % target) while (True): try: self.zap.urlopen(target) break except IOError as e: time.sleep(2) # Give the sites tree a chance to get updated time.sleep(2) logging.info('Spidering target %s' % target) self.report_progress(34, 'Spidering target') self.zap.start_spider(target) # Give the Spider a chance to start time.sleep(2) while True: spider_progress = int(self.zap.spider_status[0]) logging.debug('Spider progress %d' % spider_progress) progress = 34 + (spider_progress / 3) self.report_progress(progress, 'Spidering target') if spider_progress == 100: break time.sleep(5) logging.debug('Spider completed') self.report_progress(67, 'Scanning target') if self.configuration.get('scan'): # Give the passive scanner a chance to finish time.sleep(5) logging.debug('Scanning target %s' % target) self.zap.start_scan(target) time.sleep(5) while True: scan_progress = int(self.zap.spider_status[0]) logging.debug('Scan progress %d' % scan_progress) progress = 67 + (scan_progress / 3) self.report_progress(progress, 'Scanning target') if scan_progress == 100: break time.sleep(5) self.report_progress(100, 'Completing scan') logging.debug('Scan completed? %s' % self.zap.scan_status[0]) self.report_issues(self.get_results()) logging.info('Scan completed, shutting down') self.zap.shutdown() self.report_finish() except Exception as e: logging.exception("Error while executing zap plugin") def get_results(self): alerts = self.zap.alerts issues = [] for alert in alerts: found = False for issue in issues: # TODO should test other values here as well if alert.get('alert') == issue['Summary']: if len(issue['URLs']) < 25: issue['URLs'].append(alert.get('url')) found = True break if found: break if not found: issues.append({ "Summary" : alert.get('alert'), "Description" : alert.get('description'), "Further-Info" : alert.get('other'), "Severity" : alert.get('risk'), "Confidence" : alert.get('reliability'), "Solution" : alert.get('solution'), "URLs" : [alert.get('url')]}); return issues