def context_list(zap_helper): """List the available contexts.""" contexts = zap_helper.zap.context.context_list if len(contexts): console.info('Available contexts: {0}'.format(contexts[1:-1])) else: console.info('No contexts available in the current session')
def context_exclude(zap_helper, name, pattern): """Exclude a pattern from a given context.""" console.info('Excluding regex {0} from context with name: {1}'.format(pattern, name)) with zap_error_handler(): result = zap_helper.zap.context.exclude_from_context(contextname=name, regex=pattern) if result != 'OK': raise ZAPError('Excluding regex from context failed: {}'.format(result))
def set_scanner_threshold(zap_helper, scanners, threshold): """Set the alert threshold for scanners.""" if not scanners or 'all' in scanners: scanners = _get_all_scanner_ids(zap_helper) with zap_error_handler(): zap_helper.set_scanner_alert_threshold(scanners, threshold) console.info('Set alert threshold to {0}.'.format(threshold))
def set_scanner_strength(zap_helper, scanners, strength): """Set the attack strength for scanners.""" if not scanners or 'all' in scanners: scanners = _get_all_scanner_ids(zap_helper) with zap_error_handler(): zap_helper.set_scanner_attack_strength(scanners, strength) console.info('Set attack strength to {0}.'.format(strength))
def set_policy_strength(zap_helper, policy_ids, strength): """Set the attack strength for policies.""" if not policy_ids: policy_ids = _get_all_policy_ids(zap_helper) with zap_error_handler(): zap_helper.set_policy_attack_strength(policy_ids, strength) console.info('Set attack strength to {0}.'.format(strength))
def set_policy_threshold(zap_helper, policy_ids, threshold): """Set the alert threshold for policies.""" if not policy_ids: policy_ids = _get_all_policy_ids(zap_helper) with zap_error_handler(): zap_helper.set_policy_alert_threshold(policy_ids, threshold) console.info('Set alert threshold to {0}.'.format(threshold))
def context_import(zap_helper, file_path): """Import a saved context file.""" with zap_error_handler(): result = zap_helper.zap.context.import_context(file_path) if not result.isdigit(): raise ZAPError('Importing context from file failed: {}'.format(result)) console.info('Imported context from {}'.format(file_path))
def context_export(zap_helper, name, file_path): """Export a given context to a file.""" with zap_error_handler(): result = zap_helper.zap.context.export_context(name, file_path) if result != 'OK': raise ZAPError('Exporting context to file failed: {}'.format(result)) console.info('Exported context {0} to {1}'.format(name, file_path))
def context_info(zap_helper, context_name): """Get info about the given context.""" with zap_error_handler(): info = zap_helper.get_context_info(context_name) console.info('ID: {}'.format(info['id'])) console.info('Name: {}'.format(info['name'])) console.info('Authentication type: {}'.format(info['authType'])) console.info('Included regexes: {}'.format(info['includeRegexs'])) console.info('Excluded regexes: {}'.format(info['excludeRegexs']))
def context_export(zap_helper, name, file_path): """Export a given context to a file.""" with zap_error_handler(): result = zap_helper.zap.context.export_context(name, file_path) if result != 'OK': raise ZAPError( 'Exporting context to file failed: {}'.format(result)) console.info('Exported context {0} to {1}'.format(name, file_path))
def context_import(zap_helper, file_path): """Import a saved context file.""" with zap_error_handler(): result = zap_helper.zap.context.import_context(file_path) if not result.isdigit(): raise ZAPError( 'Importing context from file failed: {}'.format(result)) console.info('Imported context from {}'.format(file_path))
def report(zap_helper, output, output_format): """Generate XML, MD or HTML report.""" if output_format == 'html': zap_helper.html_report(output) elif output_format == 'md': zap_helper.md_report(output) else: zap_helper.xml_report(output) console.info('Report saved to "{0}"'.format(output))
def disable_script(zap_helper, script_name): """Disable a script.""" with zap_error_handler(): console.debug('Disabling script "{0}"'.format(script_name)) result = zap_helper.zap.script.disable(script_name) if result != 'OK': raise ZAPError('Error disabling script: {0}'.format(result)) console.info('Script "{0}" disabled'.format(script_name))
def remove_script(zap_helper, script_name): """Remove a script.""" with zap_error_handler(): console.debug('Removing script "{0}"'.format(script_name)) result = zap_helper.zap.script.remove(script_name) if result != 'OK': raise ZAPError('Error removing script: {0}'.format(result)) console.info('Script "{0}" removed'.format(script_name))
def context_list_users(zap_helper, context_name): """List the users available for a given context.""" with zap_error_handler(): info = zap_helper.get_context_info(context_name) users = zap_helper.zap.users.users_list(info['id']) if len(users): user_list = ', '.join([user['name'] for user in users]) console.info('Available users for the context {0}: {1}'.format(context_name, user_list)) else: console.info('No users configured for the context {}'.format(context_name))
def context_exclude(zap_helper, name, pattern): """Exclude a pattern from a given context.""" console.info('Excluding regex {0} from context with name: {1}'.format( pattern, name)) with zap_error_handler(): result = zap_helper.zap.context.exclude_from_context(contextname=name, regex=pattern) if result != 'OK': raise ZAPError( 'Excluding regex from context failed: {}'.format(result))
def report_alerts(alerts, output_format='table'): """ Print our alerts in the given format. """ num_alerts = len(alerts) if output_format == 'json': click.echo(json.dumps(alerts, indent=4)) else: console.info('Issues found: {0}'.format(num_alerts)) if num_alerts > 0: click.echo(tabulate([[a['alert'], a['risk'], a['cweid'], a['url']] for a in alerts], headers=['Alert', 'Risk', 'CWE ID', 'URL'], tablefmt='grid'))
def active_scan(zap_helper, url, scanners, recursive): """ Run an Active Scan against a URL. The URL to be scanned must be in ZAP's site tree, i.e. it should have already been opened using the open-url command or found by running the spider command. """ console.info('Running an active scan...') with helpers.zap_error_handler(): if scanners: zap_helper.set_enabled_scanners(scanners) zap_helper.run_active_scan(url, recursive=recursive)
def active_scan(zap_helper, url, scanners, recursive, context_name, user_name): """ Run an Active Scan against a URL. The URL to be scanned must be in ZAP's site tree, i.e. it should have already been opened using the open-url command or found by running the spider command. """ console.info('Running an active scan...') with helpers.zap_error_handler(): if scanners: zap_helper.set_enabled_scanners(scanners) zap_helper.run_active_scan(url, recursive, context_name, user_name)
def load_script(zap_helper, **options): """Load a script from a file.""" with zap_error_handler(): if not os.path.isfile(options['file_path']): raise ZAPError('No file found at "{0}", cannot load script.'.format(options['file_path'])) if not _is_valid_script_engine(zap_helper.zap, options['engine']): engines = zap_helper.zap.script.list_engines raise ZAPError('Invalid script engine provided. Valid engines are: {0}'.format(', '.join(engines))) console.debug('Loading script "{0}" from "{1}"'.format(options['name'], options['file_path'])) result = zap_helper.zap.script.load(options['name'], options['script_type'], options['engine'], options['file_path'], scriptdescription=options['description']) if result != 'OK': raise ZAPError('Error loading script: {0}'.format(result)) console.info('Script "{0}" loaded'.format(options['name']))
def check_status(zap_helper, timeout): """ Check if ZAP is running and able to receive API calls. You can provide a timeout option which is the amount of time in seconds the command should wait for ZAP to start if it is not currently running. This is useful to run before calling other commands if ZAP was started outside of zap-cli. For example: zap-cli status -t 60 && zap-cli open-url "http://127.0.0.1/" Exits with code 1 if ZAP is either not running or the command timed out waiting for ZAP to start. """ with helpers.zap_error_handler(): if zap_helper.is_running(): console.info('ZAP is running') elif timeout is not None: zap_helper.wait_for_zap(timeout) console.info('ZAP is running') else: console.error('ZAP is not running') sys.exit(2)
def check_status(zap_helper, timeout): """ Check if ZAP is running and able to receive API calls. You can provide a timeout option which is the amount of time in seconds the command should wait for ZAP to start if it is not currently running. This is useful to run before calling other commands if ZAP was started outside of zap-cli. For example: zap-cli status -t 60 && zap-cli open-url "http://127.0.0.1/" Exits with code 1 if ZAP is either not running or the command timed out waiting for ZAP to start. """ with helpers.zap_error_handler(): if zap_helper.is_running(): console.info('ZAP is running') elif timeout is not None: zap_helper.wait_for_zap(timeout) console.info('ZAP is running') else: console.error('ZAP is not running') sys.exit(1)
def quick_scan(zap_helper, url, **options): """ Run a quick scan of a site by opening a URL, optionally spidering the URL, running an Active Scan, and reporting any issues found. This command contains most scan options as parameters, so you can do everything in one go. If any alerts are found for the given alert level, this command will exit with a status code of 1. """ if options['self_contained']: console.info('Starting ZAP daemon') with helpers.zap_error_handler(): zap_helper.start(options['start_options']) console.info('Running a quick scan for {0}'.format(url)) with helpers.zap_error_handler(): if options['scanners']: zap_helper.set_enabled_scanners(options['scanners']) if options['exclude']: zap_helper.exclude_from_all(options['exclude']) zap_helper.open_url(url) if options['spider']: zap_helper.run_spider(url, options['context_name'], options['user_name']) if options['ajax_spider']: zap_helper.run_ajax_spider(url) zap_helper.run_active_scan(url, options['recursive'], options['context_name'], options['user_name']) alerts = zap_helper.alerts(options['alert_level']) helpers.report_alerts(alerts, options['output_format']) if options['self_contained']: console.info('Shutting down ZAP daemon') with helpers.zap_error_handler(): zap_helper.shutdown() # Customization: Soft fail for error codes if len(alerts) > 0 and not options.get("soft_fail") and not os.getenv( "SOFT_FAIL"): exit_code = 1 else: exit_code = 0 # exit_code = 1 if len(alerts) > 0 else 0 sys.exit(exit_code)
def quick_scan(zap_helper, urls, **options): """ Run a quick scan of a site by opening a URL, optionally spidering the URL, running an Active Scan, and reporting any issues found. This command contains most scan options as parameters, so you can do everything in one go. """ if options['self_contained']: console.info('Starting ZAP daemon') with helpers.zap_error_handler(): zap_helper.start(options['start_options']) console.info('Running a quick scan for {0}'.format(', '.join(urls))) with helpers.zap_error_handler(): if options['scanners']: zap_helper.set_enabled_scanners(options['scanners']) if options['exclude']: zap_helper.exclude_from_all(options['exclude']) _ = [zap_helper.open_url(url) for url in urls] if options['spider']: _ = [zap_helper.run_spider(url) for url in urls] if options['ajax_spider']: _ = [zap_helper.run_ajax_spider(url) for url in urls] _ = [ zap_helper.run_active_scan(url, recursive=options['recursive']) for url in urls ] alerts = zap_helper.alerts(options['alert_level']) num_alerts = len(alerts) helpers.report_alerts(alerts, options['output_format']) if options['self_contained']: console.info('Shutting down ZAP daemon') with helpers.zap_error_handler(): zap_helper.shutdown() sys.exit(num_alerts)
def quick_scan(zap_helper, url, **options): """ Run a quick scan of a site by opening a URL, optionally spidering the URL, running an Active Scan, and reporting any issues found. This command contains most scan options as parameters, so you can do everything in one go. If any alerts are found for the given alert level, this command will exit with a status code of 1. """ if options['self_contained']: console.info('Starting ZAP daemon') with helpers.zap_error_handler(): zap_helper.start(options['start_options']) console.info('Running a quick scan for {0}'.format(url)) with helpers.zap_error_handler(): if options['scanners']: zap_helper.set_enabled_scanners(options['scanners']) if options['exclude']: zap_helper.exclude_from_all(options['exclude']) zap_helper.open_url(url) if options['spider']: zap_helper.run_spider(url, options['context_name'], options['user_name']) if options['ajax_spider']: zap_helper.run_ajax_spider(url) zap_helper.run_active_scan(url, options['recursive'], options['context_name'], options['user_name']) alerts = zap_helper.alerts(options['alert_level']) helpers.report_alerts(alerts, options['output_format']) if options['self_contained']: console.info('Shutting down ZAP daemon') with helpers.zap_error_handler(): zap_helper.shutdown() exit_code = 1 if len(alerts) > 0 else 0 sys.exit(exit_code)
def start_zap_daemon(zap_helper, start_options): """Helper to start the daemon using the current config.""" console.info('Starting ZAP daemon') with helpers.zap_error_handler(): zap_helper.start(options=start_options)
def remove_script(zap_helper, script_name): """Remove a script.""" with zap_error_handler(): zap_helper.remove_script(script_name) console.info('Script "{0}" removed'.format(script_name))
def ajax_spider_url(zap_helper, url): """Run the AJAX Spider against a URL.""" console.info('Running AJAX Spider...') zap_helper.run_ajax_spider(url)
def context_include(zap_helper, name, pattern): """Include a pattern in a given context.""" console.info('Including regex {0} in context with name: {1}'.format(pattern, name)) with zap_error_handler(): zap_helper.include_in_context(name, pattern)
def context_new(zap_helper, name): """Create a new context.""" console.info('Creating context with name: {0}'.format(name)) res = zap_helper.zap.context.new_context(contextname=name) console.info('Context "{0}" created with ID: {1}'.format(name, res))
def list_engines(zap_helper): """List engines that can be used to run scripts.""" engines = zap_helper.zap.script.list_engines console.info('Available engines: {}'.format(', '.join(engines)))
def shutdown_zap_daemon(zap_helper): """Shutdown the ZAP daemon.""" console.info('Shutting down ZAP daemon') with helpers.zap_error_handler(): zap_helper.shutdown()
def context_export(zap_helper, name, file_path): """Export a given context to a file.""" with zap_error_handler(): zap_helper.export_context(name, file_path) console.info('Exported context {0} to {1}'.format(name, file_path))
def open_url(zap_helper, url): """Open a URL using the ZAP proxy.""" console.info('Accessing URL {0}'.format(url)) zap_helper.open_url(url)
def load_script(zap_helper, **options): """Load a script from a file.""" with zap_error_handler(): zap_helper.load_script(**options) console.info('Script "{0}" loaded'.format(options['name']))
def disable_script(zap_helper, script_name): """Disable a script.""" with zap_error_handler(): zap_helper.disable_script(script_name) console.info('Script "{0}" disabled'.format(script_name))
def spider_url(zap_helper, url): """Run the spider against a URL.""" console.info('Running spider...') with helpers.zap_error_handler(): zap_helper.run_spider(url)
def context_exclude(zap_helper, name, pattern): """Exclude a pattern from a given context.""" console.info('Excluding regex {0} from context with name: {1}'.format(pattern, name)) with zap_error_handler(): zap_helper.exclude_from_context(name, pattern)
def context_import(zap_helper, file_path): """Import a saved context file.""" with zap_error_handler(): zap_helper.import_context(file_path) console.info('Imported context from {}'.format(file_path))
def spider_url(zap_helper, url, context_name, user_name): """Run the spider against a URL.""" console.info('Running spider...') with helpers.zap_error_handler(): zap_helper.run_spider(url, context_name, user_name)