def download(self, path, history_id=None, format=ScanExportRequest.FORMAT_PDF,
                 chapter=ScanExportRequest.CHAPTER_EXECUTIVE_SUMMARY, file_open_mode='wb'):
        """Download a scan report.

        :param path: The file path to save the report to.
        :param format: The report format. Default to :class:`tenable_io.api.scans.ScanExportRequest`.FORMAT_PDF.
        :param chapter: The report contents. Default to \
        :class:`tenable_io.api.scans.ScanExportRequest`.CHAPTER_EXECUTIVE_SUMMARY.
        :param file_open_mode: The open mode to the file output. Default to "wb".
        :param history_id: A specific scan history ID, None for the most recent scan history. default to None.
        :return: The same ScanRef instance.
        """
        self.wait_until_stopped(history_id=history_id)

        if format in [ScanExportRequest.FORMAT_HTML, ScanExportRequest.FORMAT_PDF]:
            export_request = ScanExportRequest(format=format, chapters=chapter)
        else:
            export_request = ScanExportRequest(format=format)

        file_id = self._client.scans_api.export_request(
            self.id,
            export_request,
            history_id
        )
        util.wait_until(
            lambda: self._client.scans_api.export_status(self.id, file_id) == ScansApi.STATUS_EXPORT_READY)

        iter_content = self._client.scans_api.export_download(self.id, file_id)
        with open(path, file_open_mode) as fd:
            for chunk in iter_content:
                fd.write(chunk)
        return self
    def wait_until_stopped(self, history_id=None):
        """Blocks until the scan is stopped.

        :param history_id: The scan history to wait for, None for most recent. Default to None.
        :return: The same ScanRef instance.
        """
        util.wait_until(lambda: self.stopped(history_id=history_id))
        return self
    def resume(self, wait=True):
        """Resume the scan.

        :param wait: If True, the method blocks until the scan's status is not \
        :class:`tenable_io.api.models.Scan`.STATUS_RESUMING. Default is False.
        :return: The same ScanRef instance.
        """
        self._client.scans_api.resume(self.id)
        if wait:
            util.wait_until(lambda: self.status() != Scan.STATUS_RESUMING)
        return self
Beispiel #4
0
    def pause(self, wait=True):
        """Pause the scan.

        :param wait: If True, the method blocks until the scan's status is not \
        :class:`tenable_io.api.models.Scan`.STATUS_PAUSING. Default is False.
        :return: The same ScanRef instance.
        """
        self._client.scans_api.pause(schedule_uuid=self.uuid)
        if wait:
            util.wait_until(lambda: self.status() != Scan.STATUS_PAUSING)
        return self
    def wait_or_cancel_after(self, seconds):
        """Blocks until the scan is stopped, or cancel if it isn't stopped within the specified seconds.

        :param seconds: The maximum amount of seconds the method should block before canceling the scan.
        :return: The same ScanRef instance.
        """
        start_time = time.time()
        util.wait_until(lambda: time.time() - start_time > seconds or self.stopped())
        if not self.stopped():
            self.stop()
        return self
    def vulnerabilities_parse(self,
                              date_range=1,
                              asset_id=None,
                              page_size=DEFAULT_PAGE_SIZE):
        """Retrieve recorded vulnerabilities from the workbench nessus report.

        :param date_range: The number of days of data prior to today to return, default to 1.
        :param asset_id: If specified, returns only vulnerabilities for the asset identified by asset_id, default to
            None.
        :param page_size: The page size of the pages returns by the iterator, default to DEFAULT_PAGE_SIZE.
        :raise TenableIOApiException:  When API error is encountered.
        :return: Iterator that yields pages of :class:`Vulnerability`.
        """
        file_id = self._client.workbenches_api.export_request(
            WorkbenchesApi.FORMAT_NESSUS,
            WorkbenchesApi.REPORT_VULNERABILITIES,
            WorkbenchesApi.CHAPTER_VULN_BY_ASSET,
            date_range=date_range,
            asset_id=asset_id,
            filters=[{
                'quality': 'qt',
                'filter': 'severity',
                'value': 'All',
            }])

        wait_until(lambda: self._client.workbenches_api.export_status(file_id)
                   == WorkbenchesApi.STATUS_EXPORT_READY)

        iter_content = self._client.workbenches_api.export_download(file_id)

        with tempfile.NamedTemporaryFile() as temp:

            for chunk in iter_content:
                temp.write(chunk)
                temp.flush()

            vulnerabilities = []
            try:
                gen = WorkbenchParser.parse(temp.name,
                                            tag=WorkbenchParser.REPORT_ITEM)
                while True:
                    report_item = next(gen)
                    vulnerabilities.append(
                        Vulnerability().from_report_item(report_item))
                    if page_size and len(vulnerabilities) >= page_size:
                        yield vulnerabilities
                        vulnerabilities = []
                pass
            except StopIteration:
                pass

        if len(vulnerabilities) > 0:
            yield vulnerabilities
Beispiel #7
0
    def download_vulns(self, path=None, num_assets=50, severity=None, state=None, plugin_family=None, since=None,
                       file_open_mode='wb'):
        """Request the vulns export chunks, poll for status, and download them to disk or load to memory when it's
            available. The chunks will be retrieved in no particular order.

        :param path: The file path to save the report to. Will load to memory if equals `None`
        :param num_assets: Specifies the number of assets per exported chunk. Default is 50. Range is 50-5000. If you
            specify a value outside of that range, the system uses lower or upper bound value.
        :param severity: Defaults to all severity levels. Supported values are [info, low, medium, high,
            critical].
        :param state: The state of the vulnerabilities to include in the export. If not provided, default states are
            OPEN and REOPENED. Acceptable values are [OPEN, REOPENED, FIXED]. Case insensitive.
        :param plugin_family: The plugin family of the exported vulnerabilities. This filter is case sensitive.
        :param since: The start date (in Unix time) for the range of new or updated vulnerability data you want
            to export. If your request omits this parameter, exported data includes all vulnerabilities, regardless of
            date.
        :param file_open_mode: The open mode to the file output. Default to "wb".
        :return: The list of `chunk_id`s.
        """
        # If not parameterized for chunk ID.
        if path is not None and path % {'chunk_id': 1} == path:
            path += '_%(chunk_id)s'

        export_uuid = self._client.exports_api.vulns_request_export(
            ExportsVulnsRequest(
                num_assets=num_assets,
                filters={
                    u'severity': severity,
                    u'state': state,
                    u'plugin_family': plugin_family,
                    u'since': since
                }
            )
        )

        util.wait_until(
            lambda: self._client.exports_api.vulns_export_status(export_uuid).status ==
            ExportsVulnsStatus.STATUS_FINISHED)

        status = self._client.exports_api.vulns_export_status(export_uuid)

        # Retrieve chunks
        vulns = []
        for chunk_id in status.chunks_available:
            if path is None:
                vulns += self._client.exports_api.vulns_chunk(export_uuid, chunk_id)
            else:
                iter_content = self._client.exports_api.vulns_download_chunk(export_uuid, chunk_id)
                with open(path % {'chunk_id': chunk_id}, file_open_mode) as fd:
                    for chunk in iter_content:
                        fd.write(chunk)

        return vulns if path is None else status.chunks_available
    def launch(self, wait=True, alt_targets=None):
        """Launch the scan.

        :param wait: If True, the method blocks until the scan's status is not \
        :class:`tenable_io.api.models.Scan`.STATUS_PENDING. Default is False.

        :param alt_targets: String of comma separated alternative targets or list of alternative target strings.
        :return: The same ScanRef instance.
        """
        if isinstance(alt_targets, six.string_types):
            alt_targets = [alt_targets]

        self._client.scans_api.launch(
            self.id, ScanLaunchRequest(alt_targets=alt_targets))
        if wait:
            util.wait_until(
                lambda: self.status() not in ScanHelper.STATUSES_PENDING)
        return self
Beispiel #9
0
    def download(self, path, history_id=None, format=ScanExportRequest.FORMAT_PDF, file_open_mode='wb'):
        """Download a scan report.

        :param path: The file path to save the report to.
        :param format: The report format. Default to :class:`tenable_io.api.models.ScanDetails`.FORMAT_PDF.
        :param file_open_mode: The open mode to the file output. Default to "wb".
        :param history_id: A specific scan history ID, None for the most recent scan history. default to None.
        :return: The same ScanRef instance.
        """
        self.wait_until_stopped(history_id=history_id)

        file_id = self._client.scans_api.export_request(
            self.id,
            ScanExportRequest(format=format),
            history_id
        )
        wait_until(
            lambda: self._client.scans_api.export_status(self.id, file_id) == ScansApi.STATUS_EXPORT_READY)

        iter_content = self._client.scans_api.export_download(self.id, file_id)
        with open(path, file_open_mode) as fd:
            for chunk in iter_content:
                fd.write(chunk)
        return self
    def download_assets(self,
                        path,
                        chunk_size,
                        created_at=None,
                        updated_at=None,
                        terminated_at=None,
                        deleted_at=None,
                        first_scan_time=None,
                        last_authenticated_scan_time=None,
                        last_assessed=None,
                        servicenow_sysid=None,
                        sources=None,
                        has_plugin_results=None,
                        file_open_mode='wb'):
        """Request the vulns export chunks, poll for status, and download them when it's available. The chunks will be
            downloaded in no particular order.

        :param path: The file path to save the report to.
        :param created_at: Returns all assets created later than the date specified. The specified date must be in the
            Unix timestamp format.
        :param updated_at: Returns all assets updated later than the date specified. The specified date must be in the
            Unix timestamp format.
        :param terminated_at: Returns all assets terminated later than the date specified. The specified date must be in
            the Unix timestamp format.
        :param deleted_at: Returns all assets deleted later than the date specified. The specified date must in the Unix
            timestamp format.
        :param first_scan_time: Returns all assets with a first scan time later than the date specified. The specified
            date must be in the Unix timestamp format.
        :param last_authenticated_scan_time: Returns all assets with a last credentialed scan time later than the date
            specified. The specified date must be in the Unix timestamp format.
        :param last_assessed: Returns all assets with a last assessed time later than the date specified. An asset is
            considered assessed if  it has been scanned by a credentialed or non-credentialed scan. The specified date
            must be in the Unix timestamp format.
        :param servicenow_sysid: If true, returns all assets that have a ServiceNow Sys ID, regardless of value. If
            false, returns all assets that do not have a ServiceNow Sys ID.
        :param sources: Returns assets that have the specified source. An asset source is the entity that reported the
            asset details. Sources can include sensors, connectors, and API imports. If your request specifies multiple
            sources, this request returns all assets that have been seen by any of the specified sources.
        :param has_plugin_results: If true, returns all assets that have plugin results. If false, returns all assets
            that do not have plugin results. An asset may not have plugin results if the asset details originated from a
            connector, an API import, or a discovery scan, rather than a vulnerabilities scan.
        :return: The list of `chunk_id`s.
        """
        # If not parameterized for chunk ID.
        if path % {'chunk_id': 1} == path:
            path += '_%(chunk_id)s'

        export_uuid = self._client.exports_api.assets_request_export(
            ExportsAssetsRequest(chunk_size=chunk_size,
                                 filters={
                                     u'created_at': created_at,
                                     u'updated_at': updated_at,
                                     u'terminated_at': terminated_at,
                                     u'deleted_at': deleted_at,
                                     u'first_scan_time': first_scan_time,
                                     u'last_authenticated_scan_time':
                                     last_authenticated_scan_time,
                                     u'last_assessed': last_assessed,
                                     u'servicenow_sysid': servicenow_sysid,
                                     u'sources': sources,
                                     u'has_plugin_results': has_plugin_results,
                                 }))

        util.wait_until(lambda: self._client.exports_api.assets_export_status(
            export_uuid).status == ExportsAssetsStatus.STATUS_FINISHED)

        status = self._client.exports_api.assets_export_status(export_uuid)

        # Download chunks
        for chunk_id in status.chunks_available:
            iter_content = self._client.exports_api.assets_download_chunk(
                export_uuid, chunk_id)
            with open(path % {'chunk_id': chunk_id}, file_open_mode) as fd:
                for chunk in iter_content:
                    fd.write(chunk)

        return status.chunks_available
    def download_assets(self,
                        path=None,
                        chunk_size=100,
                        created_at=None,
                        updated_at=None,
                        terminated_at=None,
                        deleted_at=None,
                        first_scan_time=None,
                        last_authenticated_scan_time=None,
                        last_assessed=None,
                        servicenow_sysid=None,
                        sources=None,
                        has_plugin_results=None,
                        tags=None,
                        file_open_mode='wb'):
        """Request the vulns export chunks, poll for status, and download them when it's available. The chunks will be
            retrieved in no particular order.

        :param path: The file path to save the report to. Will load in memory if equals `None`
        :param chunk_size: Specifies the number of assets per exported chunk. Default is 100. Range is 100-10000. If you
            specify a value outside of that range, a 400 error is returned.
        :param created_at: Returns all assets created later than the date specified. The specified date must be in the
            Unix timestamp format.
        :param updated_at: Returns all assets updated later than the date specified. The specified date must be in the
            Unix timestamp format.
        :param terminated_at: Returns all assets terminated later than the date specified. The specified date must be in
            the Unix timestamp format.
        :param deleted_at: Returns all assets deleted later than the date specified. The specified date must in the Unix
            timestamp format.
        :param first_scan_time: Returns all assets with a first scan time later than the date specified. The specified
            date must be in the Unix timestamp format.
        :param last_authenticated_scan_time: Returns all assets with a last credentialed scan time later than the date
            specified. The specified date must be in the Unix timestamp format.
        :param last_assessed: Returns all assets with a last assessed time later than the date specified. An asset is
            considered assessed if  it has been scanned by a credentialed or non-credentialed scan. The specified date
            must be in the Unix timestamp format.
        :param servicenow_sysid: If true, returns all assets that have a ServiceNow Sys ID, regardless of value. If
            false, returns all assets that do not have a ServiceNow Sys ID.
        :param sources: Returns assets that have the specified source. An asset source is the entity that reported the
            asset details. Sources can include sensors, connectors, and API imports. If your request specifies multiple
            sources, this request returns all assets that have been seen by any of the specified sources.
        :param has_plugin_results: If true, returns all assets that have plugin results. If false, returns all assets
            that do not have plugin results. An asset may not have plugin results if the asset details originated from a
            connector, an API import, or a discovery scan, rather than a vulnerabilities scan.
        :param tags: Returns all assets with the specified tags. The filter is defined as "tag",
            a period ("."), and the tag category name. Should be specified as a dict of {tag_category_name:[tag_value(s)]}
        :param file_open_mode: The open mode to the file output. Default to "wb".
        :return: The list of exported assets if path is `None` else the list of `chunk_id`s.
        """
        # If not parameterized for chunk ID.
        if path is not None and path % {'chunk_id': 1} == path:
            path += '_%(chunk_id)s'

        filters = {
            u'created_at': created_at,
            u'updated_at': updated_at,
            u'terminated_at': terminated_at,
            u'deleted_at': deleted_at,
            u'first_scan_time': first_scan_time,
            u'last_authenticated_scan_time': last_authenticated_scan_time,
            u'last_assessed': last_assessed,
            u'servicenow_sysid': servicenow_sysid,
            u'sources': sources,
            u'has_plugin_results': has_plugin_results
        }

        # Parse tag filters
        if tags is not None:
            tags = {u'tag.{}'.format(k): v for k, v in tags.items()}
            filters.update(tags)

        export_uuid = self._client.exports_api.assets_request_export(
            ExportsAssetsRequest(chunk_size=chunk_size, filters=filters))

        util.wait_until(lambda: self._client.exports_api.assets_export_status(
            export_uuid).status == ExportsAssetsStatus.STATUS_FINISHED)

        status = self._client.exports_api.assets_export_status(export_uuid)

        # Download chunks
        assets = []
        for chunk_id in status.chunks_available:
            if path is None:
                assets += self._client.exports_api.assets_chunk(
                    export_uuid, chunk_id)
            else:
                iter_content = self._client.exports_api.assets_download_chunk(
                    export_uuid, chunk_id)
                with open(path % {'chunk_id': chunk_id}, file_open_mode) as fd:
                    for chunk in iter_content:
                        fd.write(chunk)

        return assets if path is None else status.chunks_available
    def download_vulns(self,
                       path=None,
                       num_assets=50,
                       severity=None,
                       state=None,
                       plugin_family=None,
                       since=None,
                       tags=None,
                       cidr_range=None,
                       first_found=None,
                       last_found=None,
                       last_fixed=None,
                       file_open_mode='wb'):
        """Request the vulns export chunks, poll for status, and download them to disk or load to memory when it's
            available. The chunks will be retrieved in no particular order.

        :param path: The file path to save the report to. Will load to memory if equals `None`
        :param num_assets: Specifies the number of assets per exported chunk. Default is 50. Range is 50-5000. If you
            specify a value outside of that range, the system uses lower or upper bound value.
        :param severity: Defaults to all severity levels. Supported values are [info, low, medium, high,
            critical].
        :param state: The state of the vulnerabilities to include in the export. If not provided, default states are
            OPEN and REOPENED. Acceptable values are [OPEN, REOPENED, FIXED]. Case insensitive.
        :param plugin_family: The plugin family of the exported vulnerabilities. This filter is case sensitive.
        :param since: The start date (in Unix time) for the range of new or updated vulnerability data you want
            to export. If your request omits this parameter, exported data includes all vulnerabilities, regardless of
            date.
        :param tags: Returns all assets with the specified tags. The filter is defined as "tag",
            a period ("."), and the tag category name. Should be specified as a dict of {tag_category_name:[tag_value(s)]}
        :param cidr_range: Restricts search for vulnerabilities to assets assigned an IP address within the specified
            CIDR range. For example, 0.0.0.0/0 restricts the search to 0.0.0.1 and 255.255.255.254.
        :param first_found: The start date (in Unix time) for the range of vulnerability data you want to export,
            based on when a scan first found a vulnerability on an asset.
        :param last_found: The start date (in Unix time) for the range of vulnerability data you want to export,
            based on when a scan last found a vulnerability on an asset.
        :param last_fixed: 	The start date (in Unix time) for the range of vulnerability data you want to export,
            based on when the vulnerability state was changed to fixed.
        :param file_open_mode: The open mode to the file output. Default to "wb".
        :return: The list of `chunk_id`s.
        """
        # If not parameterized for chunk ID.
        if path is not None and path % {'chunk_id': 1} == path:
            path += '_%(chunk_id)s'

        filters = {
            u'severity': severity,
            u'state': state,
            u'plugin_family': plugin_family,
            u'since': since,
            u'cidr_range': cidr_range,
            u'first_found': first_found,
            u'last_found': last_found,
            u'last_fixed': last_fixed
        }

        # Parse tag filters
        if tags is not None:
            tags = {u'tag.{}'.format(k): v for k, v in tags.items()}
            filters.update(tags)

        export_uuid = self._client.exports_api.vulns_request_export(
            ExportsVulnsRequest(num_assets=num_assets, filters=filters))

        util.wait_until(lambda: self._client.exports_api.vulns_export_status(
            export_uuid).status == ExportsVulnsStatus.STATUS_FINISHED)

        status = self._client.exports_api.vulns_export_status(export_uuid)

        # Retrieve chunks
        vulns = []
        for chunk_id in status.chunks_available:
            if path is None:
                vulns += self._client.exports_api.vulns_chunk(
                    export_uuid, chunk_id)
            else:
                iter_content = self._client.exports_api.vulns_download_chunk(
                    export_uuid, chunk_id)
                with open(path % {'chunk_id': chunk_id}, file_open_mode) as fd:
                    for chunk in iter_content:
                        fd.write(chunk)

        return vulns if path is None else status.chunks_available