Example #1
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
Example #2
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
Example #3
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