Exemplo n.º 1
0
class OpenvasRemote:
    def __init__(self, path, connection, transform):
        self.path = path
        self.connection = connection
        self.gmp = Gmp(connection=connection, transform=transform)
        
    def create_task(self, task_name, config_id, target_id, scanner_id, username, password):
        try:
            with self.gmp:
                self.gmp.authenticate(username, password)
                response = self.gmp.create_task(
                    task_name, config_id, target_id, scanner_id)
                pretty_print(response)
                id = response.xpath('@id')
                return id[0]
        except GvmError as e:
            print(e)
            return 'bad'

    def create_target(self, target_name, targets_list, username, password):
        try:
            with self.gmp:
                self.gmp.authenticate(username, password)
                response = self.gmp.create_target(
                    target_name, hosts=targets_list,alive_test=AliveTest.CONSIDER_ALIVE)
                pretty_print(response)
                if(response.xpath("@status_text")[0] == 'Target exists already'):
                    with self.gmp:
                        self.gmp.authenticate(username, password)
                        response = self.gmp.get_targets(
                            filter="name={0}".format(target_name))
                        target_id = response.xpath('target/@id')[0]
                        return target_id
                else:
                    id = response.xpath('@id')[0]
                    return id
        except GvmError as e:
            print(e)
            return 'bad'

    #this also delete all the reports
    def delete_all_tasks(self, username, password):
        try:
            with self.gmp:
                self.gmp.authenticate(username, password)
                response = self.gmp.get_tasks()
                for task in response.xpath('task'):
                    task_id = task.xpath('@id')[0]
                    response = self.gmp.delete_task(task_id)
                    pretty_print(response)
                result = {'status': 'good'}
                return result
        except GvmError as e:
            print(e)
            result = {'status': 'bad'}
            return result

    def delete_all_targets(self, username, password):
        try:
            with self.gmp:
                self.gmp.authenticate(username, password)
                response = self.gmp.get_targets()
                for target in response.xpath('target'):
                    target_id = target.xpath('@id')[0]
                    response = self.gmp.delete_target(target_id)
                    pretty_print(response)
                result = {'status': 'good'}
                return result
        except GvmError as e:
            print(e)
            result = {'status': 'bad'}
            return result

    @staticmethod
    def get_full_and_fast_config_id():
        return 'daba56c8-73ec-11df-a475-002264764cea'

    @staticmethod
    def get_default_openvas_scanner_id():
        return '08b69003-5fc2-4037-a479-93b440211c73'

    def get_report(self, id, target_list, username, password):
        try:
            with self.gmp:
                self.gmp.authenticate(username, password)
                response = self.gmp.get_report(id)
                running_status = response.xpath(
                    'report/report/scan_run_status/text()')[0]
                if(running_status == 'Done'):
                    print(response.xpath('report/@id')[0])
                    report = {}
                    hosts = []
                    for IP_address in target_list:
                        host = {}
                        host['ip_address'] = IP_address
                        host['results'] = []
                        host['results_count'] = 0
                        hosts.append(host)

                    for report_result in response.xpath('report/report/results/result'):
                        print(
                            '=======================================================================')
                        result = {}
                        result['report_id'] = report_result.xpath('@id')[0]
                        result['description'] = report_result.xpath(
                            'description/text()')[0]
                        result['name'] = report_result.xpath('name/text()')[0]
                        result['port'] = report_result.xpath('port/text()')[0]
                        result['nvt_bid'] = report_result.xpath(
                            'nvt/bid/text()')[0]
                        result['nvt_cve'] = report_result.xpath(
                            'nvt/cve/text()')[0]
                        result['nvt_cvss_base'] = report_result.xpath(
                            'nvt/cvss_base/text()')[0]
                        result['nvt_family'] = report_result.xpath(
                            'nvt/family/text()')[0]
                        result['nvt_oid'] = report_result.xpath('nvt/@oid')[0]
                        result['nvt_tags'] = report_result.xpath(
                            'nvt/tags/text()')[0]
                        result['nvt_type'] = report_result.xpath(
                            'nvt/type/text()')[0]
                        result['nvt_xref'] = report_result.xpath(
                            'nvt/xref/text()')[0]
                        result['quality_of_detection_value'] = report_result.xpath(
                            'qod/value/text()')[0]
                        result['quality_of_detection_type'] = report_result.xpath(
                            'qod/type/text()')[0]
                        result['threat'] = report_result.xpath(
                            'threat/text()')[0]
                        result['severity'] = report_result.xpath(
                            'severity/text()')[0]
                        for host in hosts:
                            if(host['ip_address'] == report_result.xpath('host/text()')[0]):
                                host['results'].append(result)
                    report['hosts'] = hosts
                    report['ip_address_count'] = len(target_list)
                    report['status'] = 'received'
                    
                    print(json.dumps(report))
                    return report
                else:
                    report = {'status': 'running'}
                    return report
        except GvmError as e:
            no_report = {'status': 'bad'}
            print(e)
            return no_report

    def get_reports(self, id, username, password):
        try:
            with self.gmp:
                self.gmp.authenticate(username, password)
                response = self.gmp.get_reports()
                pretty_print(response)
        except GvmError as e:
            print(e)

    def get_full_report(self, id, username, password):
        try:
            with self.gmp:
                self.gmp.authenticate(username, password)
                response = self.gmp.get_report(id)
                pretty_print(response)
        except GvmError as e:
            print(e)

    def get_targets(self, username, password):
        try:
            with self.gmp:
                self.gmp.authenticate(username, password)
                response = self.gmp.get_targets()
                pretty_print(response)
                for target in response.xpath('target'):
                    pretty_print(target.xpath('@id'))
        except GvmError as e:
            print(e)

    def get_task(self, id, username, password):
        try:
            with self.gmp:
                self.gmp.authenticate(username, password)
                reponse = self.gmp.get_task(id)
                pretty_print(reponse)
        except GvmError as e:
            print(e)

    def get_tasks(self, username, password):
        try:
            with self.gmp:
                self.gmp.authenticate(username, password)
                response = self.gmp.get_tasks()
                for task in response.xpath('task'):
                    pretty_print(task.xpath('@id'))
        except GvmError as e:
            print(e)

    def scan_target(self, task_name, target_name, targets_list, username, password):
        try:
            target_id = self.create_target(
                target_name, targets_list, username, password)
            if(target_id == 'bad'):
                return ('bad','bad','bad','bad')
            task_id = self.create_task(task_name, self.get_full_and_fast_config_id(), target_id,
                self.get_default_openvas_scanner_id(), username, password)
            if(task_id == 'bad'):
                return ('bad','bad','bad','bad')
            task_tuple = self.start_task(task_id, username, password)
            if(task_tuple[0] =='bad'):
                return ('bad','bad','bad','bad')
            report_id = task_tuple[0]
            status = task_tuple[1]
            return (target_id,task_id,report_id, status)
        except GvmError as e:
            print(e)
            return ('bad','bad','bad','bad')

    def start_task(self, id, username, password):
        try:
            with self.gmp:
                print(id)
                self.gmp.authenticate(username, password)
                reponse = self.gmp.start_task(id)
                report_id = reponse.xpath('report_id/text()')
                status = 'start'
                if(len(report_id) == 0):
                    return ('bad','bad')
                return (report_id[0], status)
        except GvmError as e:
            print(e)
            return ('bad', 'bad')
    def test1(self, task_name, target_name,ip_address_list,ip_address_count_per_report,username,password):
        
        run_task_name = task_name + '_' + str(uuid4())
        total_ip_addresses = len(ip_address_list)
        remainder = total_ip_addresses % ip_address_count_per_report
        chopped_ip_addresses = total_ip_addresses - remainder
        count = 0
        left_index = 0
        right_index = ip_address_count_per_report
        for batch in range(chopped_ip_addresses//ip_address_count_per_report):
            slice_object = slice(left_index,right_index)
            sub_ip_address_list = ip_address_list[slice_object]
            left_index = left_index + ip_address_count_per_report
            right_index = right_index + ip_address_count_per_report
            run_task_name_id = run_task_name + '_batch_number_' + str(batch)
            run_target_name_id = run_task_name_id + '_target_' + target_name
            count = count + 1
            report_tuple = self.scan_target(run_task_name_id,run_target_name_id, sub_ip_address_list, username, password)
        if( remainder > 0):
            slice_object = slice(-remainder,total_ip_addresses)
            sub_ip_address_list = ip_address_list[slice_object]
            run_task_name_id = run_task_name + '_batch_number_' + str(count)
            run_target_name_id = run_task_name_id + '_target_' + target_name
            report_tuple = self.scan_target(run_task_name_id,run_target_name_id, sub_ip_address_list, username, password)
Exemplo n.º 2
0
class OpenVASScanner(Scanner):

    name = 'OpenVAS'

    def __init__(self):
        connection = TLSConnection(hostname=config['HOST_NAME'],
                                   port=config['PORT'],
                                   certfile=None,
                                   cafile=None,
                                   keyfile=None,
                                   password=None,
                                   timeout=25)
        transform = EtreeTransform()
        self.gmp = Gmp(connection, transform=transform)
        self.storage_service = StorageService()

        # Login
        try:
            self.gmp.authenticate(config['OPENVAS_USERNAME'],
                                  config['OPENVAS_PASSWORD'])
        except:
            print(f'[{self.name}] Not able to connect to the {self.name}: ',
                  sys.exc_info())
            return

    def start(self, scan_name, target):
        print(f'[{self.name}] Starting Scan for Target: {target}')

        try:
            return self.scan(scan_name, target)
        except:
            print(f'[{self.name}] Not able to connect to the {self.name}: ',
                  sys.exc_info())
            return False

    def scan(self, scan_name, target):
        print(f'[{self.name}] Scan Name: {scan_name}')

        address = self._get_address(target)

        # Creating Target
        target_response = self.gmp.create_target(
            name=scan_name,
            hosts=[address],
            port_list_id='33d0cd82-57c6-11e1-8ed1-406186ea4fc5')
        # print('target_response')
        #pretty_print(target_response)
        target_id = target_response.get('id')

        if not target_id:
            print(f'[{self.name}] could not able to create target: ',
                  target_response.get('status_text'))
            return False

        # target_id = '69ca3c65-af09-48b8-bb3a-59e2e6cccb96'

        print(f'[{self.name}] Target Created: {target_id}')

        scan_data = self.storage_service.get_by_name(scan_name)

        if not scan_data:
            scan_data = {
                'scan_name': scan_name,
                'scan_id': '',
                'target': target,
                'status': ''
            }
            self.storage_service.add(scan_data)

        scan_data['OPENVAS'] = {
            'openvas_id': target_id,
            'target_id': target_id,
            'scan_status': {
                'status': 'INPROGRESS'
            }
        }
        self.storage_service.update_by_name(scan_name, scan_data)

        time.sleep(4)
        self._create_task(scan_name)

        return scan_data

    def _create_task(self, scan_name):

        scan_data = self.storage_service.get_by_name(scan_name)
        openvas_id = scan_data['OPENVAS']['openvas_id']

        scan_config_id = config['SCAN_CONFIG_ID']
        scanner_id = config['SCANNER_ID']
        report_format_id = config['REPORT_FORMAT_ID']

        # Creating Task
        task_response = self.gmp.create_task(name=scan_name,
                                             config_id=scan_config_id,
                                             target_id=openvas_id,
                                             scanner_id=scanner_id)
        # print('task_response')
        # pretty_print(task_response)
        task_id = task_response.get('id')
        print(f'[{self.name}] Created Task:  with : {task_id}')
        # Starting Task
        start_task_response = self.gmp.start_task(task_id)
        # print('start_task_response')
        # pretty_print(start_task_response)
        report_id = start_task_response[0].text

        scan_data['OPENVAS']['report_id'] = report_id
        scan_data['OPENVAS']['report_format_id'] = report_format_id
        scan_data['OPENVAS']['scan_config_id'] = scan_config_id
        scan_data['OPENVAS']['scanner_id'] = scanner_id
        scan_data['OPENVAS']['task_id'] = task_id

        self.storage_service.update_by_name(scan_name, scan_data)

        return scan_data

    def get_scan_status(self, scan_name, scan_status_list=[]):

        if not self.is_valid_scan(scan_name):
            return False

        scan_data = self.storage_service.get_by_name(scan_name)
        scan_status = scan_data.get('OPENVAS', {}).get('scan_status', {})
        openvas_id = scan_data.get('OPENVAS', {})['openvas_id']
        target = scan_data['target']
        task_id = scan_data.get('OPENVAS', {})['task_id']

        print(f'[{self.name}] Getting Scan Status for Target: {target}')
        print(f'[{self.name}] Scan Name: {scan_name}')
        print(f'[{self.name}] Scan Id: {openvas_id}')

        try:
            scan_info = self.gmp.get_task(task_id)

            status = scan_info.xpath('task/status/text()')
            progress = scan_info.xpath('task/progress/text()')

        except:
            print(f'[{self.name}] Could not get the scan {openvas_id}: ',
                  sys.exc_info())
            return False

        scan_status['status'] = 'COMPLETE' if status[
            0] == 'Done' else 'INPROGRESS' if status[
                0] == 'Running' else status[0]
        scan_status['progress'] = progress[0]
        scan_data['OPENVAS']['scan_status'] = scan_status
        self.storage_service.update_by_name(scan_name, scan_data)

        if scan_status['status'] is 'COMPLETE':
            print(f'[{self.name}] Scan {scan_name} Completed')

        scan_status_list.append({
            'scanner':
            self.name,
            'status':
            f'{scan_status["status"]} {progress[0]}%'
        })
        return scan_status_list

    def get_scan_results(self, scan_name, oscan_results={}):

        if not self.is_valid_scan(scan_name):
            return False

        scan_data = self.storage_service.get_by_name(scan_name)

        # if scan_data.get('OPENVAS', {}).get('scan_status').get('status', None) != 'COMPLETE':
        #     print(f'[{self.name}] Scan is in progress')
        #     return False

        openvas_id = scan_data.get('OPENVAS', {})['openvas_id']
        report_id = scan_data.get('OPENVAS', {})['report_id']
        report_format_id = scan_data.get('OPENVAS', {})['report_format_id']

        try:
            report_response = self.gmp.get_report(
                report_id=report_id, report_format_id=report_format_id)
            # print('report_response')
            #pretty_print(report_response)
        except:
            print(f'[{self.name}] Could not get the scan {openvas_id}: ',
                  sys.exc_info())
            return False

        self._process_results(report_response, oscan_results)

        return oscan_results

    def _process_results(self, report_response, oscan_results={}):
        report_response_str = ElementTree.tostring(report_response,
                                                   encoding='unicode')
        report_response_dict = xmltodict.parse(report_response_str)

        report_results = report_response_dict.get(
            'get_reports_response',
            {}).get('report', {}).get('report', {}).get('results',
                                                        {}).get('result', [])

        # print(json.dumps(report_results, indent=2))
        # print('report_results', report_results)

        for vuln in report_results:
            name = vuln.get('name')
            #print('name: ', name)
            if oscan_results.get(name):
                # print('--- Duplicate name: ', name)
                continue
            nvt = vuln.get('nvt', {})
            scan_result = {}
            scan_result['name'] = name
            scan_result['severity'] = float(nvt.get('cvss_base', 0))
            scan_result['risk'] = vuln.get('threat')
            scan_result['cve_id'] = nvt.get(
                'cve', 'N/A') if nvt.get('cve') != 'NOCVE' else 'N/A'
            scan_result['description'] = vuln.get('description')
            scan_result['solution'] = 'N/A'
            scan_result['reported_by'] = 'OpenVAS'
            oscan_results[name] = scan_result

        return oscan_results

    def is_valid_scan(self, scan_name):

        scan_data = self.storage_service.get_by_name(scan_name)
        if not scan_data:
            print(f'[{self.name}] Invalid Scan Name: {scan_name}')
            return False

        if not scan_data.get('OPENVAS'):
            print(f'[{self.name}] No Scan Details found for {scan_name}')
            return False

        return True

    def pause(self, scan_name):
        if not self.is_valid_scan(scan_name):
            return False

        scan = self.storage_service.get_by_name(scan_name)

        task_id = scan['OPENVAS']['task_id']

        response = self.gmp.stop_task(task_id)  #GMP does not support pause

        print(f'[{self.name}]  scan paused ')
        return response

    def resume(self, scan_name):
        if not self.is_valid_scan(scan_name):
            return False

        scan = self.storage_service.get_by_name(scan_name)

        task_id = scan['OPENVAS']['task_id']

        response = self.gmp.resume_task(task_id)

        print(f'[{self.name}]  scan resumed ')

        return response

    def stop(self, scan_name):
        if not self.is_valid_scan(scan_name):
            return False

        scan = self.storage_service.get_by_name(scan_name)

        task_id = scan['OPENVAS']['task_id']

        response = self.gmp.stop_task(task_id)

        print(f'[{self.name}]  scan stopped ')

        return response

    def remove(self, scan_name):
        if not self.is_valid_scan(scan_name):
            return False

        scan = self.storage_service.get_by_name(scan_name)

        task_id = scan['OPENVAS']['task_id']

        response = self.gmp.delete_task(task_id, ultimate=False)

        print(f'[{self.name}]  scan removed ')

        return response

    def list_scans(self):

        self.tasks = self.gmp.get_tasks()
        task_names = self.tasks.xpath('task/name/text()')
        print("Available scan names from openvas")
        pretty_print(task_names)
        return task_names

    def start_sp(self, scan_name):
        if not self.is_valid_scan(scan_name):
            return False
        scan_data = self.storage_service.get_by_name(scan_name)
        print(f'[{self.name}] Starting Scan: {scan_name}')
        task_id = scan_data['OPENVAS']['task_id']
        start_task_response = self.gmp.start_task(task_id)
        print(f'[{self.name}] Task started')
        report_id = start_task_response[0].text

        scan_data['OPENVAS'] = {
            'report_id': report_id,
            'scan_status': {
                'status': 'INPROGRESS'
            }
        }
        self.storage_service.update_by_name(scan_name, scan_data)
Exemplo n.º 3
0
class OpenVASScanner(Scanner):

    name = 'OpenVAS'

    def __init__(self):
        connection = UnixSocketConnection(path=config['OPENVAS_SOCKET'])
        transform = EtreeTransform()
        self.gmp = Gmp(connection, transform=transform)
        self.storage_service = StorageService()

        # Login
        try:
            self.gmp.authenticate(config['OPENVAS_USERNAME'],
                                  config['OPENVAS_PASSWORD'])
        except:
            print(f'[{self.name}] Not able to connect to the {self.name}: ',
                  sys.exc_info())
            return

        # Getting Version
        # version = self.gmp.get_version()
        # pretty_print(version)

    def start(self, scan_name, target):
        print(f'[{self.name}] Starting Scan for Target: {target}')

        try:
            return self.scan(scan_name, target)
        except:
            print(f'[{self.name}] Not able to connect to the {self.name}: ',
                  sys.exc_info())
            return False

    def scan(self, scan_name, target):
        print(f'[{self.name}] Scan Name: {scan_name}')

        address = self._get_address(target)

        # Creating Target
        target_response = self.gmp.create_target(name=scan_name,
                                                 hosts=[address])
        # print('target_response')
        pretty_print(target_response)
        target_id = target_response.get('id')

        if not target_id:
            print(f'[{self.name}] could not able to create target: ',
                  target_response.get('status_text'))
            return False

        # target_id = '69ca3c65-af09-48b8-bb3a-59e2e6cccb96'

        print(f'[{self.name}] Target Created: {target_id}')

        scan_data = self.storage_service.get_by_name(scan_name)

        if not scan_data:
            scan_data = {
                'scan_name': scan_name,
                'scan_id': '',
                'target': target,
                'status': ''
            }
            self.storage_service.add(scan_data)

        scan_data['OPENVAS'] = {
            'openvas_id': target_id,
            'target_id': target_id,
            'scan_status': {
                'status': 'INPROGRESS'
            }
        }
        self.storage_service.update_by_name(scan_name, scan_data)

        time.sleep(4)
        self._create_report(scan_name)

        return scan_data

    def _create_report(self, scan_name):

        scan_data = self.storage_service.get_by_name(scan_name)
        openvas_id = scan_data['OPENVAS']['openvas_id']

        scan_config_id = config['SCAN_CONFIG_ID']
        scanner_id = config['SCANNER_ID']
        report_format_id = config['REPORT_FORMAT_ID']

        # Creating Task
        task_response = self.gmp.create_task(name=scan_name,
                                             config_id=scan_config_id,
                                             target_id=openvas_id,
                                             scanner_id=scanner_id)
        # print('task_response')
        # pretty_print(task_response)
        task_id = task_response.get('id')

        # Starting Task
        start_task_response = self.gmp.start_task(task_id)
        # print('start_task_response')
        # pretty_print(start_task_response)
        report_id = start_task_response[0].text

        scan_data['OPENVAS']['report_id'] = report_id
        scan_data['OPENVAS']['report_format_id'] = report_format_id
        scan_data['OPENVAS']['scan_config_id'] = scan_config_id
        scan_data['OPENVAS']['scanner_id'] = scanner_id
        scan_data['OPENVAS']['task_id'] = task_id

        print(
            f'[{self.name}] Created Report: {report_id} with Task: {task_id}')

        self.storage_service.update_by_name(scan_name, scan_data)

        return scan_data

    def get_scan_status(self, scan_name, scan_status_list=[]):

        if not self.is_valid_scan(scan_name):
            return False

        scan_data = self.storage_service.get_by_name(scan_name)
        scan_status = scan_data.get('OPENVAS', {}).get('scan_status', {})
        openvas_id = scan_data.get('OPENVAS', {})['openvas_id']
        target = scan_data['target']

        print(f'[{self.name}] Getting Scan Status for Target: {target}')
        print(f'[{self.name}] Scan Name: {scan_name}')
        print(f'[{self.name}] Scan Id: {openvas_id}')

        try:
            scan_info = self.get_scan_results(scan_name)
            # print('scan_info')
            # pretty_print(scan_info)
        except:
            print(f'[{self.name}] Could not get the scan {openvas_id}: ',
                  sys.exc_info())
            return False

        scan_status['status'] = 'COMPLETE' if scan_info else 'INPROGRESS'
        scan_data['OPENVAS']['scan_status'] = scan_status

        self.storage_service.update_by_name(scan_name, scan_data)

        if scan_status['status'] is 'COMPLETE':
            print(f'[{self.name}] Scan {scan_name} Completed')

        scan_status_list.append({
            'scanner': self.name,
            'status': scan_status['status']
        })

        return scan_status_list

    def get_scan_results(self, scan_name, scan_results={}):

        if not self.is_valid_scan(scan_name):
            return False

        scan_data = self.storage_service.get_by_name(scan_name)

        # if scan_data.get('OPENVAS', {}).get('scan_status').get('status', None) != 'COMPLETE':
        #     print(f'[{self.name}] Scan is in progress')
        #     return False

        openvas_id = scan_data.get('OPENVAS', {})['openvas_id']
        report_id = scan_data.get('OPENVAS', {})['report_id']
        report_format_id = scan_data.get('OPENVAS', {})['report_format_id']
        # report_id = '79bf4984-9a0e-435a-807b-9dd530fb532f'

        try:
            report_response = self.gmp.get_report(
                report_id=report_id, report_format_id=report_format_id)
            # print('report_response')
            # pretty_print(report_response)
        except:
            print(f'[{self.name}] Could not get the scan {openvas_id}: ',
                  sys.exc_info())
            return False

        self._process_results(report_response, scan_results)

        return scan_results

    def _process_results(self, report_response, scan_results={}):
        report_response_str = ElementTree.tostring(report_response,
                                                   encoding='unicode')
        report_response_dict = xmltodict.parse(report_response_str)

        report_results = report_response_dict.get(
            'get_reports_response',
            {}).get('report', {}).get('report', {}).get('results',
                                                        {}).get('result', [])

        # print(json.dumps(report_results, indent=2))
        # print('report_results', report_results)

        for vuln in report_results:
            name = vuln.get('name')
            print('name: ', name)
            if scan_results.get(name):
                print('--- Duplicate name: ', name)
                continue
            nvt = vuln.get('nvt', {})
            scan_result = {}
            scan_result['name'] = name
            scan_result['severity'] = float(nvt.get('cvss_base', 0))
            scan_result['risk'] = vuln.get('threat')
            scan_result['cve_id'] = nvt.get(
                'cve', 'N/A') if nvt.get('cve') != 'NOCVE' else 'N/A'
            scan_result['description'] = vuln.get('description')
            scan_result['solution'] = 'N/A'
            scan_result['reported_by'] = 'OpenVAS'
            scan_results[name] = scan_result
        return scan_results

    def is_valid_scan(self, scan_name):

        scan_data = self.storage_service.get_by_name(scan_name)
        if not scan_data:
            print(f'[{self.name}] Invalid Scan Name: {scan_name}')
            return False

        if not scan_data.get('OPENVAS'):
            print(f'[{self.name}] No Scan Details found for {scan_name}')
            return False

        return True

    def pause(self, scan_name):
        if not self.is_valid_scan(scan_name):
            return False

        # scan = self.storage_service.get_by_name(scan_name)
        # nexpose_id = scan['nexpose_id']

        # response = self.nexpose.set_scan_status(nexpose_id, 'pause')
        # pprint(response)
        # return response

    def resume(self, scan_name):
        if not self.is_valid_scan(scan_name):
            return False

        # scan = self.storage_service.get_by_name(scan_name)
        # nexpose_id = scan['nexpose_id']

        # response = self.nexpose.set_scan_status(nexpose_id, 'resume')
        # pprint(response)
        # return response

    def stop(self, scan_name):
        if not self.is_valid_scan(scan_name):
            return False

        # scan = self.storage_service.get_by_name(scan_name)
        # nexpose_id = scan['nexpose_id']

        # response = self.nexpose.set_scan_status(nexpose_id, 'stop')
        # pprint(response)
        # return response

    def remove(self, scan_name):
        if not self.is_valid_scan(scan_name):
            return False

        # scan = self.storage_service.get_by_name(scan_name)
        # nexpose_id = scan['nexpose_id']

        # response = self.nexpose.set_scan_status(nexpose_id, 'remove')
        # pprint(response)
        # return response

    def list_scans(self):
        pass
Exemplo n.º 4
0
class GVM_client:
  def __init__(self, password, socket_path='/var/run/gvmd.sock', user='******', timeout=10, loglevel=logging.ERROR):
    logging.basicConfig(level=loglevel)
    self.connection_errors = 0
    self.container_tasks = {}
    self.password = password
    self.user = user
    self.socketconnection = UnixSocketConnection(path=socket_path, timeout=timeout)
    self.connection = DebugConnection(self.socketconnection)
    self.transform = EtreeCheckCommandTransform()
    self.gmp = Gmp(connection=self.connection, transform=self.transform)
    self.connect()

  def authenticate(self):
    try:
      self.gmp.authenticate(self.user, self.password)
    except Exception as ex:
      logging.error('Unable to authenticate: {}'.format(ex))

  def connect(self):
    try:
      self.authenticate()
      return self.gmp._connected
    except Exception as ex:
      self.connection_errors += 1
      logging.error('Can\'t connect to service: {}'.format(ex))
      return False

  def get_xmls(self, directory):
    results = []
    for file_name in os.listdir(directory):
      if file_name.lower().endswith(".xml"):
        file_path = os.path.join(directory, file_name)
        logging.info('Reading file {}'.format(file_path))

        with io.open(file_path, 'r', encoding='utf-8') as file:
          results.append(''.join(file.readlines()))
    return results

  def wait_connection(self, connection_tries=10, secs_before_attempt=5):
    while not self.connect():
      if self.connection_errors <= connection_tries:
        sleep(secs_before_attempt)
      else:
        raise Exception('Can\'t connect to gvmd in {} sec'.format(connection_tries*secs_before_attempt))

  def wait_sync(self, interval=15):
    logging.info('Waiting for NVTs/Feeds sync to complete')
    while True:
      if self.connect():
        families = self.gmp.get_nvt_families().xpath('families/family')
        feeds = self.gmp.get_feeds().xpath('feed/currently_syncing')
        if len(families) != 0 and len(feeds) == 0:
          break
        else:
          sleep(interval)

  def import_configs(self, directory):
    for config in self.get_xmls(directory):
      if self.connect():
        try:
          response = self.gmp.import_config(config)
          if response.attrib['status'] == '201':
            config_root = ET.fromstring(config)
            config_name = config_root.findtext('config/name')
            logging.info('Importing config OK: {}'.format(config_name))

        except Exception as ex:
          logging.error('Importing config error: {}'.format(ex))

  def create_target(self, target:Target):
    if self.connect():
      try:
        response = self.gmp.create_target(
          name=target.name,
          make_unique=target.make_unique,
          hosts=target.hosts,
          exclude_hosts=target.exclude_hosts,
          comment=target.comment,
          alive_tests=target.alive_tests,
          reverse_lookup_only=target.reverse_lookup_only,
          reverse_lookup_unify=target.reverse_lookup_unify,
          port_range=target.port_range,
          port_list_id=target.port_list_id,
          asset_hosts_filter=target.asset_hosts_filter,
          ssh_credential_id=target.ssh_credential_id,
          ssh_credential_port=target.ssh_credential_port,
          smb_credential_id=target.smb_credential_id,
          snmp_credential_id=target.snmp_credential_id,
          esxi_credential_id=target.esxi_credential_id)

        if response.attrib['status'] == '201':
          logging.info('Importing target OK: {}'.format(target.name))

      except Exception as ex:
        logging.error('Importing target error: {}'.format(ex))

  def import_targets(self, directory:str):
    '''
      directory: path to exported targets in XML
    '''
    for target_config in self.get_xmls(directory):
      if self.connect():
        try:
          target = Target(target_config)
          self.create_target(target)
        except Exception as ex:
          logging.error('Importing target error: {}'.format(ex))

  def create_task(self, task:Task):
    if self.connect():
      try:
        response = self.gmp.create_task(
          name=task.name,
          target_id=task.target_id,
          scanner_id=task.scanner_id,
          config_id=task.config_id,
          comment=task.comment,
          alterable=task.alterable,
          alert_ids=task.alert_ids,
          hosts_ordering=task.hosts_ordering,
          schedule_id=task.schedule_id,
          schedule_periods=task.schedule_periods,
          observers=task.observers)

        if response.attrib['status'] == '201':
          logging.info('Importing task OK: {}'.format(task.name))

      except Exception as ex:
        logging.error('Importing task error: {}'.format(ex))

  def create_override(self, override:Override):
    if self.connect():
      try:
        response = self.gmp.create_override(
          text=override.text,
          nvt_oid=override.nvt_oid,
          seconds_active=override.seconds_active,
          comment=override.comment,
          hosts=override.hosts,
          port=override.port,
          result_id=override.result_id,
          severity=override.severity,
          new_severity=override.new_severity,
          task_id=override.task_id,
          threat=override.threat,
          new_threat=override.new_threat)

        if response.attrib['status'] == '201':
          logging.info('Creating override OK: {}'.format(override.text))

      except Exception as ex:
        logging.error('Creating override error: {}'.format(ex))

  def import_overrides(self, directory:str):
    for override_xml in self.get_xmls(directory):
      if self.connect():
        try:
          override = Override(override_xml)
          self.create_override(override)

        except Exception as ex:
          logging.error('Importing override error: {}'.format(ex))

  def import_tasks(self, directory:str):
    for task_config in self.get_xmls(directory):
      if self.connect():
        try:
          task = Task(task_config)

          task.target_id = None
          for target in self.gmp.get_targets().xpath('target'):
            target_name = target.find('name').text
            if target_name == task.name:
              task.target_id = target.attrib['id']
              logging.log(logging.DEBUG, 'Importing task - target_id: {}'.format(task.target_id))

          if task.target_id == None:
            logging.log(logging.DEBUG, 'Importing task - {}. No target_id found'.format(task.name))
            continue

          task.config_id = None
          for config in self.gmp.get_configs().xpath('config'):
            if config.find('name').text == task.config['name']:
              task.config_id = config.attrib['id']
              logging.log(logging.DEBUG, 'Importing task - config_id: {}'.format(task.config_id))
              break

          self.create_task(task)

        except Exception as ex:
          logging.error('Importing task error: {}'.format(ex))

  def import_reports(self, directory):
    for report_xml in self.get_xmls(directory):
      if self.connect():
        try:
          report = Report(report_xml)

          if report.task_name not in self.container_tasks.keys():
            response = self.gmp.import_report(report_xml, task_name=report.task_name, task_comment=report.task_comment)

            if response.attrib['status'] == '201':
              logging.info('Importing report OK: {}'.format(report.task_name))
              tasks = self.gmp.get_tasks().xpath('task')
              for task in tasks:
                if task.find('name').text == report.task_name and self._is_container_task(task):
                  logging.log(logging.DEBUG, 'Found container task: {}[{}]'.format(report.task_name, task.attrib['id']))
                  self.container_tasks[report.task_name] = task.attrib['id']
                  break
          else:
            response = self.gmp.import_report(report_xml, task_id=self.container_tasks[report.task_name])
            if response.attrib['status'] == '201':
              logging.info('Importing report OK: {}'.format(report.task_name))
        except Exception as ex:
          logging.error('Importing report error: {}'.format(ex))

  def get_task(self, task_id):
    if self.connect():
      try:
        response = self.gmp.get_task(task_id=task_id)
        if response.attrib['status'] == '200':
          task = Task(response.find('task'))
          logging.debug('Getting task OK: {} [{}]'.format(task.name, task_id))
          return task
        else:
          return None
      except Exception as ex:
        logging.error('Getting task error: {}'.format(ex))

  def get_task_status(self, task_id):
    if self.connect():
      try:
        response = self.gmp.get_task(task_id=task_id)
        if response.attrib['status'] == '200':
          task_status = response.find('task/status').text
          logging.info('Getting task status OK: {} [{}]'.format(task_id, task_status))
          return task_status
        else:
          return None
      except Exception as ex:
        logging.error('Getting task status error: {}'.format(ex))

  def run_task(self, task_id:str):
    if self.connect():
      try:
        response = self.gmp.start_task(task_id=task_id)
        if response.attrib['status'] == '202':
          logging.info('Running task OK: {}'.format(task_id))
          return True
        else:
          return False
      except Exception as ex:
        logging.error('Running task error: {}'.format(ex))
        return False

  def _is_container_task(self, task):
    return task.find('target').attrib['id'] == ''

  def get_targets(self):
    if self.connect():
      try:
        targets = [Target(target) for target in self.gmp.get_targets().xpath('target')]
        logging.info('Targets found in DB: {}'.format(', '.join([target.name for target in targets])))
        return targets
      except Exception as ex:
        logging.error('Getting targets error: {}'.format(ex))
        return False

  def get_tasks(self, exclude_containers=True):
    if self.connect():
      try:
        tasks = self.gmp.get_tasks().xpath('task')
        logging.info('Tasks found in DB: {}'.format(', '.join([task.find('name').text for task in tasks])))
        if exclude_containers:
          return [Task(task) for task in tasks if not self._is_container_task(task)]
        else:
          return [Task(task) for task in tasks]
      except Exception as ex:
        logging.error('Getting tasks error: {}'.format(ex))
        return False

  def save_report(self, report_id:str, directory:str):
    if self.connect():
      try:
        raw_report = self.gmp.get_report(report_id).find('report')
        report = Report(raw_report)
        logging.info('Got report: {}'.format(report.name))

        file_name = '{}-{}.xml'.format(report.task_name, report.name)
        file_path = os.path.join(directory, file_name)
        logging.info('Saving report to file {}'.format(file_path))

        if os.path.isfile(file_path):
          raise Exception('File exists: {}'.format(file_path))

        with io.open(file_path, 'wb') as file:
          file.write(ET.tostring(raw_report, encoding='utf-8', method='xml', pretty_print=True))

        return True
      except Exception as ex:
        logging.error('Getting targets error: {}'.format(ex))
        return False