Пример #1
0
 def delete(self):
     self.api.call(
         'POST', 'JSON/context/action/removeContext', {
             'zapapiformat': 'JSON',
             'formMethod': 'POST',
             'contextName': self.context
         })
     report_to_cli("Removed ZAP context %s" % self.context)
Пример #2
0
 def store(self):
     report_to_cli('Storing context %s' % self.context)
     self.api.call(
         'POST', 'JSON/context/action/exportContext', {
             'zapapiformat': 'JSON',
             'formMethod': 'POST',
             'contextName': self.context,
             'contextFile': '%s.context' % self.context
         })
Пример #3
0
 def active(self, target, context_id):
     report_to_cli("Starting active scan")
     scan_id = self.api.call('POST', 'JSON/ascan/action/scan/', {
         'zapapiformat': 'JSON',
         'formMethod': 'POST',
         'contextId': context_id
     }).json()['scan']
     progress = self.active_progress(scan_id)
     while progress < 100:
         print("Active scan %i%% completed" % progress, end="\r")
         sleep(10)
         progress = self.active_progress(scan_id)
     print("", end="\r")
     report_to_cli("Active scan complete")
Пример #4
0
    def alerts(self, target):
        report_to_cli("The following alerts were found for target %s:" %
                      target)

        alerts = []
        for target_site in self.target_sites(target):
            target_site = "%s://%s" % (urlparse(target_site).scheme,
                                       urlparse(target_site).netloc)
            alerts += self.api.call(
                'POST', 'JSON/core/view/alerts', {
                    'zapapiformat': 'JSON',
                    'formMethod': 'POST',
                    'baseurl': target_site
                }).json()['alerts']

        alert_dict = {'High': [], 'Medium': [], 'Low': [], 'Informational': []}
        for alert in alerts:
            print(
                " -", "%s (CONFIDENCE: %s) - %s)" %
                (alert['risk'], alert['confidence'], alert['alert']))
            alert_dict[alert['risk']].append(alert)

        self.build_html_header(target, alert_dict)
        if len(alert_dict['High']) > 0:
            store('     <h3 id="high"> High findings </h3>', 'report.html',
                  'a')
        for alert in alert_dict['High']:
            self.build_html_alert(alert)

        if len(alert_dict['Medium']) > 0:
            store('     <h3 id="medium"> Medium findings </h3>', 'report.html',
                  'a')
        for alert in alert_dict['Medium']:
            self.build_html_alert(alert)

        if len(alert_dict['Low']) > 0:
            store('     <h3 id="low"> Low findings </h3>', 'report.html', 'a')
        for alert in alert_dict['Low']:
            self.build_html_alert(alert)

        if len(alert_dict['Informational']) > 0:
            store('     <h3 id="info"> Informational findings </h3>',
                  'report.html', 'a')
        for alert in alert_dict['Informational']:
            self.build_html_alert(alert)
        self.build_html_footer()
Пример #5
0
    def passive(self):
        report_to_cli("Starting passive scan")
        passive_scan_items_remaining = self.passive_progress()
        i = 0

        # Give the passive scan time to pop things in queue
        if not passive_scan_items_remaining:
            sleep(30)

        # While there are items to scan and ~10 minutes have not elapsed yet
        while passive_scan_items_remaining and i < 60:
            print("%i items remaining to scan" % passive_scan_items_remaining,
                  end="\r")
            i += 1
            sleep(10)
            passive_scan_items_remaining = self.passive_progress()
        print("", end="\r")
        report_to_cli("Passive scan complete")
Пример #6
0
    def spider(self, target, context):
        report_to_cli("Starting spider")
        spider = self.api.call(
            'POST', 'JSON/spider/action/scan', {
                'zapapiformat': 'JSON',
                'formMethod': 'POST',
                'contextName': context,
                'url': target
            }).json()
        spider_id = spider['scan']

        progress = self.spider_progress(spider_id)
        while progress < 100:
            print("Spider %i%% completed" % progress, end="\r")
            sleep(10)
            progress = self.spider_progress(spider_id)
        print("", end="\r")
        report_to_cli("Spider complete")
Пример #7
0
def init():
    """
    The initialisation of the Zapper automated scanning process.
    """
    parser = argparse.ArgumentParser(
        description='ZAP control unit for DAST scanning')
    config = configparser.ConfigParser()

    parser.add_argument('--config',
                        help='Path to ZAP config',
                        default='/etc/zapper/zapper.config')
    parser.add_argument(
        '--target', help='ZAP target (full URL. Example: https://google.nl)')
    parser.add_argument('--host',
                        help='ZAP host (Hostname only. Example: localhost)')
    parser.add_argument('--port', help='ZAP port')
    parser.add_argument('--proto', help='ZAP protocol (Either HTTP or HTTPS)')
    parser.add_argument(
        '--scope',
        nargs='+',
        help=
        'URLS in scope of attack. Only the target will be attacked, but if URLS in scope are found at the target, these will also be scanned. By default, only the target is in scope.'
    )
    parser.add_argument(
        '--overwrite',
        help=
        "Force overwrite of sessions. This forces ZAP to start a scan even if another scan on the same target is already running.",
        action='store_true',
        default=False)
    parser.add_argument(
        '--no-passivescan',
        help=
        "Dont run the passive scan. Use this if you dont proxy traffic through ZAP before running the scans.",
        action='store_true',
        default=False)
    parser.add_argument(
        '--no-activescan',
        help=
        "Dont run the active scan. ZAP will not interact with the server and only interpet traffic proxied through it",
        action='store_true',
        default=False)
    parser.add_argument(
        '--no-spider',
        help=
        "Dont run the spider. This will prevent ZAP from trying to find new URLs on the web page it has not seen before through the proxy",
        action='store_true',
        default=False)
    parser.add_argument(
        '--report',
        help="Dont scan just report the outcome of a previous scan",
        action='store_true',
        default=False)

    args = parser.parse_args()
    optional_args = [
        'scope',
    ]
    config.read(args.config)

    for arg in vars(args):
        if getattr(args, arg) is None and arg not in optional_args:
            setattr(args, arg, config['zap'][arg])

    if not args.scope and path.exists(args.config):
        args.scope = [urlparse(
            args.target).netloc] if not config['zap']['scope'] else set(
                [urlparse(args.target).netloc] +
                [x.strip().lower() for x in config['zap']['scope'].split(',')])
    elif not args.scope:
        args.scope = [urlparse(args.target).netloc]
    else:
        args.scope = set([urlparse(args.target).netloc] +
                         [x.lower() for x in args.scope])

    if not check_args(parser, args, 'host', 'port', 'proto', 'target'):
        exit(1)

    zap_url = "%s://%s:%s" % (args.proto, args.host, args.port)
    zapper_api = api(zap_url)
    zapper_scanner = scanner(zapper_api)
    zapper_report = report(zapper_api)

    report_to_cli("Starting Zapper using ZAP host %s" % zap_url)

    target_host = urlparse(args.target).netloc
    target_sub_dir = urlparse(args.target).path
    if args.report:
        zapper_report.alerts(args.target)
    else:
        scan_context = context(args.target, args.scope, zapper_api,
                               args.overwrite)

        if not args.no_spider:
            zapper_scanner.spider(args.target, scan_context.name())
        if not args.no_passivescan:
            zapper_scanner.passive()
        if not args.no_activescan:
            zapper_scanner.active(args.target, scan_context.id())
        scan_context.store()
        scan_context.delete()
    report_to_cli("Zapper finished, exiting.")
Пример #8
0
    def __init__(self, target, scope, api, force=False):
        """
        Control one Context entry of ZAP. A context has the following properties:

        Attributes:
            target: The target of the scan
            scope: The scope that is allowed to scan
            api: The ZAP api that it can call. Expectes the zapper.api class
            force: Overwrite the context if a current scan is going
        """

        # Remove special chars from target so it can be set as context name
        self.context = target.replace('/', '')

        self.scope = scope
        self.api = api
        self.force = force

        try:
            self.api.call(
                'POST', 'JSON/context/action/importContext', {
                    'zapapiformat': 'JSON',
                    'formMethod': 'POST',
                    'contextFile': '%s.context' % self.context
                })
            report_to_cli("Found existing context %s, importing" %
                          self.context)
            self.context_id = context_info['contextId']
            return True

        except:
            contexts = self.api.call(
                'GET',
                'JSON/context/view/contextList/?zapapiformat=JSON&formMethod=GET'
            ).json()
            if self.context in contexts['contextList']:
                if self.force:
                    self.delete()
                else:
                    report_to_cli('ZAP is already scanning %s, exiting.' %
                                  self.context)
                    exit(1)

            context_info = self.api.call(
                'POST', 'JSON/context/action/newContext', {
                    'zapapiformat': 'JSON',
                    'formMethod': 'POST',
                    'contextName': self.context
                }).json()
            self.context_id = context_info['contextId']
            report_to_cli("Created new ZAP context %s with context ID %s" %
                          (self.context, self.context_id))

            # Include the domain(s) into the context
            for scope_url in self.scope:
                self.api.call(
                    'POST', 'JSON/context/action/includeInContext', {
                        'zapapiformat': 'JSON',
                        'formMethod': 'POST',
                        'contextName': self.context,
                        'regex': ".*" + scope_url + ".*"
                    })