Beispiel #1
0
    def process_vts(self, vts):
        """ Add single VTs and their parameters. """
        vts_list = []
        vts_params = []
        vtgroups = vts.pop('vt_groups')

        ctx = openvas_db.db_find(nvti.NVTICACHE_STR)
        openvas_db.set_global_redisctx(ctx)
        if vtgroups:
            vts_list = self.get_vts_in_groups(ctx, vtgroups)

        for vtid, vt_params in vts.items():
            vts_list.append(vtid)
            nvt_name = self.vts[vtid].get('name')
            for vt_param_id, vt_param_value in vt_params.items():
                param_type = self.get_vt_param_type(vtid, vt_param_id)
                if vt_param_id == 'timeout':
                    type_aux = 'integer'
                else:
                    type_aux = param_type
                if self.check_param_type(vt_param_value, type_aux):
                    logger.debug(
                        'Expected {} type for parameter value {}'.format(
                            type_aux, str(vt_param_value)))
                param = [
                    "{0}[{1}]:{2}".format(nvt_name, param_type, vt_param_id),
                    str(vt_param_value)
                ]
                vts_params.append(param)
        return vts_list, vts_params
Beispiel #2
0
 def redis_nvticache_init(self):
     """ Loads NVT's metadata into Redis DB. """
     try:
         logger.debug('Loading NVTs in Redis DB')
         subprocess.check_call(['openvassd', '-C'])
     except subprocess.CalledProcessError as err:
         logger.error('OpenVAS Scanner failed to load NVTs.')
         raise err
Beispiel #3
0
 def stop_scan(self, global_scan_id):
     """ Set a key in redis to indicate the wrapper is stopped.
     It is done through redis because it is a new multiprocess
     instance and it is not possible to reach the variables
     of the grandchild process. Send SIGUSR2 to openvas to stop
     each running scan."""
     ctx = self.openvas_db.kb_connect()
     for current_kbi in range(0, self.openvas_db.max_dbindex):
         self.openvas_db.select_kb(ctx, str(current_kbi), set_global=True)
         scan_id = self.openvas_db.get_single_item(
             'internal/%s/globalscanid' % global_scan_id)
         if scan_id:
             self.openvas_db.set_single_item('internal/%s' % scan_id, [
                 'stop_all',
             ])
             ovas_pid = self.openvas_db.get_single_item('internal/ovas_pid')
             parent = psutil.Process(int(ovas_pid))
             self.openvas_db.release_db(current_kbi)
             parent.send_signal(signal.SIGUSR2)
             logger.debug('Stopping process: {0}'.format(parent))
Beispiel #4
0
 def stop_scan(global_scan_id):
     """ Set a key in redis to indicate the wrapper is stopped.
     It is done through redis because it is a new multiprocess
     instance and it is not possible to reach the variables
     of the grandchild process. Send SIGUSR2 to openvas to stop
     each running scan."""
     ctx = openvas_db.kb_connect()
     for current_kbi in range(0, openvas_db.MAX_DBINDEX):
         ctx.execute_command('SELECT ' + str(current_kbi))
         openvas_db.set_global_redisctx(ctx)
         scan_id = openvas_db.item_get_single(
             ('internal/%s/globalscanid' % global_scan_id))
         if scan_id:
             openvas_db.item_set_single(('internal/%s' % scan_id), [
                 'stop_all',
             ])
             ovas_pid = openvas_db.item_get_single('internal/ovas_pid')
             parent = psutil.Process(int(ovas_pid))
             openvas_db.release_db(current_kbi)
             parent.send_signal(signal.SIGUSR2)
             logger.debug('Stopping process: {0}'.format(parent))
Beispiel #5
0
    def check_feed(self):
        """ Check if there is a feed update. Wait until all the running
        scans finished. Set a flag to anounce there is a pending feed update,
        which avoid to start a new scan.
        """
        _running_scan = False
        for scan_id in self.scan_processes:
            if self.scan_processes[scan_id].is_alive():
                _running_scan = True

        if self.pending_feed:
            _pending_feed = True
        else:
            _pending_feed = self.get_vts_version() != nvti.get_feed_version()

        if _running_scan and _pending_feed:
            if not self.pending_feed:
                self.pending_feed = True
                logger.debug('There is a running scan. Therefore the feed '
                             'update will be performed later.')
        elif not _running_scan and _pending_feed:
            self.vts = dict()
            self.load_vts()
Beispiel #6
0
    def exec_scan(self, scan_id, target):
        """ Starts the OpenVAS scanner for scan_id scan. """
        if self.pending_feed:
            logger.info('%s: There is a pending feed update. '
                        'The scan can not be started.' % scan_id)
            self.add_scan_error(
                scan_id,
                name='',
                host=target,
                value=('It was not possible to start the scan,'
                       'because a pending feed update. Please try later'))
            return 2

        global MAIN_KBINDEX
        ports = self.get_scan_ports(scan_id, target)
        if not ports:
            self.add_scan_error(scan_id,
                                name='',
                                host=target,
                                value='No port list defined.')
            return 2

        # Get scan options
        options = self.get_scan_options(scan_id)
        prefs_val = []
        ctx = openvas_db.kb_new()
        openvas_db.set_global_redisctx(ctx)
        MAIN_KBINDEX = openvas_db.DB_INDEX

        # To avoid interference between scan process during a parallel scanning
        # new uuid is used internally for each scan.
        openvas_scan_id = str(uuid.uuid4())
        openvas_db.item_add_single(('internal/%s' % openvas_scan_id), [
            'new',
        ])
        openvas_db.item_add_single(('internal/%s/globalscanid' % scan_id), [
            openvas_scan_id,
        ])

        # Set scan preferences
        for item in options.items():
            item_type = ''
            if item[0] in OSPD_PARAMS:
                item_type = OSPD_PARAMS[item[0]].get('type')
            if item_type == 'boolean' and item[1] == 1:
                val = 'yes'
            else:
                val = str(item[1])
            prefs_val.append(item[0] + "|||" + val)
        openvas_db.item_add_single(
            str('internal/%s/scanprefs' % (openvas_scan_id)), prefs_val)

        # Store MAIN_KBINDEX as global preference
        ov_maindbid = ('ov_maindbid|||%d' % MAIN_KBINDEX)
        openvas_db.item_add_single(('internal/%s/scanprefs' % openvas_scan_id),
                                   [
                                       ov_maindbid,
                                   ])

        # Set target
        target_aux = ('TARGET|||%s' % target)
        openvas_db.item_add_single(('internal/%s/scanprefs' % openvas_scan_id),
                                   [
                                       target_aux,
                                   ])
        # Set port range
        port_range = ('port_range|||%s' % ports)
        openvas_db.item_add_single(('internal/%s/scanprefs' % openvas_scan_id),
                                   [
                                       port_range,
                                   ])

        # Set credentials
        credentials = self.get_scan_credentials(scan_id, target)
        if credentials:
            cred_prefs = self.build_credentials_as_prefs(credentials)
            openvas_db.item_add_single(
                str('internal/%s/scanprefs' % openvas_scan_id), cred_prefs)

        # Set plugins to run
        nvts = self.get_scan_vts(scan_id)
        if nvts != '':
            nvts_list, nvts_params = self.process_vts(nvts)
            # Select the scan KB again.
            ctx.execute_command('SELECT ' + str(MAIN_KBINDEX))
            openvas_db.set_global_redisctx(ctx)
            # Add nvts list
            separ = ';'
            plugin_list = ('plugin_set|||%s' % separ.join(nvts_list))
            openvas_db.item_add_single(
                ('internal/%s/scanprefs' % openvas_scan_id), [
                    plugin_list,
                ])
            # Add nvts parameters
            for elem in nvts_params:
                item = ('%s|||%s' % (elem[0], elem[1]))
                openvas_db.item_add_single(
                    ('internal/%s/scanprefs' % openvas_scan_id), [
                        item,
                    ])
        else:
            openvas_db.release_db(MAIN_KBINDEX)
            self.add_scan_error(scan_id,
                                name='',
                                host=target,
                                value='No VTS to run.')
            return 2

        # Create a general log entry about executing OpenVAS
        # It is important to send at least one result, otherwise
        # the host details won't be stored.
        self.add_scan_log(scan_id,
                          host=target,
                          name='OpenVAS summary',
                          value='An OpenVAS Scanner was started for %s.' %
                          target)

        self.add_scan_log(scan_id,
                          host=target,
                          name='KB location Found',
                          value='KB location path was found: %s.' %
                          openvas_db.DB_ADDRESS)

        self.add_scan_log(scan_id,
                          host=target,
                          name='Feed Update',
                          value='Feed version: %s.' % nvti.get_feed_version())

        cmd = ['openvassd', '--scan-start', openvas_scan_id]
        try:
            result = subprocess.Popen(cmd, shell=False)
        except OSError:
            # the command is not available
            return False

        ovas_pid = result.pid
        logger.debug('pid = {0}'.format(ovas_pid))
        openvas_db.item_add_single(('internal/ovas_pid'), [
            ovas_pid,
        ])

        # Wait until the scanner starts and loads all the preferences.
        while openvas_db.item_get_single('internal/' +
                                         openvas_scan_id) == 'new':
            time.sleep(1)

        no_id_found = False
        while True:
            time.sleep(3)

            # Check if the client stopped the whole scan
            if self.scan_is_stopped(openvas_scan_id):
                return 1

            ctx = openvas_db.kb_connect(MAIN_KBINDEX)
            openvas_db.set_global_redisctx(ctx)
            dbs = openvas_db.item_get_set('internal/dbindex')
            for i in list(dbs):
                if i == MAIN_KBINDEX:
                    continue
                ctx.execute_command('SELECT ' + str(i))
                openvas_db.set_global_redisctx(ctx)
                id_aux = ctx.execute_command('srandmember internal/scan_id')
                if not id_aux:
                    continue
                if id_aux == openvas_scan_id:
                    no_id_found = False
                    self.get_openvas_timestamp_scan_host(scan_id, target)
                    self.get_openvas_result(scan_id)
                    self.get_openvas_status(scan_id, target)
                    if self.scan_is_finished(openvas_scan_id):
                        ctx.execute_command('SELECT ' + str(MAIN_KBINDEX))
                        openvas_db.remove_set_member('internal/dbindex', i)
                        openvas_db.release_db(i)

            # Scan end. No kb in use for this scan id
            if no_id_found:
                break
            no_id_found = True

        # Delete keys from KB related to this scan task.
        openvas_db.release_db(MAIN_KBINDEX)
        return 1
Beispiel #7
0
    def load_vts(self):
        """ Load the NVT's metadata into the vts
        global  dictionary. """
        logger.debug('Loading vts in memory.')
        oids = dict(nvti.get_oids())
        for filename, vt_id in oids.items():
            _vt_params = nvti.get_nvt_params(vt_id)
            _vt_refs = nvti.get_nvt_refs(vt_id)
            _custom = nvti.get_nvt_metadata(vt_id)
            _name = _custom.pop('name')
            _vt_creation_time = _custom.pop('creation_date')
            _vt_modification_time = _custom.pop('last_modification')

            _summary = None
            _impact = None
            _affected = None
            _insight = None
            _solution = None
            _solution_t = None
            _vuldetect = None
            _qod_t = None
            _qod_v = None

            if 'summary' in _custom:
                _summary = _custom.pop('summary')
            if 'impact' in _custom:
                _impact = _custom.pop('impact')
            if 'affected' in _custom:
                _affected = _custom.pop('affected')
            if 'insight' in _custom:
                _insight = _custom.pop('insight')
            if 'solution' in _custom:
                _solution = _custom.pop('solution')
                if 'solution_type' in _custom:
                    _solution_t = _custom.pop('solution_type')

            if 'vuldetect' in _custom:
                _vuldetect = _custom.pop('vuldetect')
            if 'qod_type' in _custom:
                _qod_t = _custom.pop('qod_type')
            elif 'qod' in _custom:
                _qod_v = _custom.pop('qod')

            _severity = dict()
            if 'severity_base_vector' in _custom:
                _severity_vector = _custom.pop('severity_base_vector')
            else:
                _severity_vector = _custom.pop('cvss_base_vector')
            _severity['severity_base_vector'] = _severity_vector
            if 'severity_type' in _custom:
                _severity_type = custom.pop('severity_type')
            else:
                _severity_type = 'cvss_base_v2'
            _severity['severity_type'] = _severity_type
            if 'severity_origin' in _custom:
                _severity['severity_origin'] = _custom.pop('severity_origin')

            _vt_dependencies = list()
            if 'dependencies' in _custom:
                _deps = _custom.pop('dependencies')
                _deps_list = _deps.split(', ')
                for dep in _deps_list:
                    _vt_dependencies.append(oids.get('filename:' + dep))

            ret = self.add_vt(vt_id,
                              name=_name,
                              vt_params=_vt_params,
                              vt_refs=_vt_refs,
                              custom=_custom,
                              vt_creation_time=_vt_creation_time,
                              vt_modification_time=_vt_modification_time,
                              vt_dependencies=_vt_dependencies,
                              summary=_summary,
                              impact=_impact,
                              affected=_affected,
                              insight=_insight,
                              solution=_solution,
                              solution_t=_solution_t,
                              detection=_vuldetect,
                              qod_t=_qod_t,
                              qod_v=_qod_v,
                              severities=_severity)
            if ret == -1:
                logger.info("Dupplicated VT with OID: {0}".format(vt_id))
            if ret == -2:
                logger.info("{0}: Invalid OID.".format(vt_id))

        _feed_version = nvti.get_feed_version()
        self.set_vts_version(vts_version=_feed_version)
        self.pending_feed = False
        logger.debug('Finish loading up vts.')