예제 #1
0
    def custom_severity(self, sev_level):
        """Sets or removed the custom severity for this report.

        Arguments:
            sev_level (int): The new severity, or None to remove the custom severity.

        Returns:
            ReportSeverity (ReportSeverity): The new custom severity.
            None: If the custom severity was removed.

        Raises:
            InvalidObjectError: If `id` is missing or this Report is from a Watchlist.
        """
        if not self.id:
            raise InvalidObjectError("missing report ID")
        if self._from_watchlist:
            raise InvalidObjectError(
                "watchlist reports don't have custom severities")

        url = "/threathunter/watchlistmgr/v3/orgs/{}/reports/{}/severity".format(
            self._cb.credentials.org_key, self.id)

        if sev_level is None:
            self._cb.delete_object(url)
            return

        args = {
            "report_id": self.id,
            "severity": sev_level,
        }

        resp = self._cb.put_object(url, args).json()
        return ReportSeverity(self._cb, initial_data=resp)
예제 #2
0
    def validate(self):
        """Validates this IOC structure's state.

        Raises:
            InvalidObjectError: If the IOC structure's state is invalid.
        """
        super(IOC, self).validate()

        for md5 in self.md5:
            if not validators(md5):
                raise InvalidObjectError(
                    "invalid MD5 checksum: {}".format(md5))
        for ipv4 in self.ipv4:
            if not validators(ipv4):
                raise InvalidObjectError(
                    "invalid IPv4 address: {}".format(ipv4))
        for ipv6 in self.ipv6:
            if not validators(ipv6):
                raise InvalidObjectError(
                    "invalid IPv6 address: {}".format(ipv6))
        for dns in self.dns:
            if not validators(dns):
                raise InvalidObjectError("invalid domain: {}".format(dns))
        for query in self.query:
            if not self._cb.validate(query["search_query"]):
                raise InvalidObjectError("invalid search query: {}".format(
                    query["search_query"]))
예제 #3
0
    def ignored(self):
        """Returns the ignore status for this report.

        Only watchlist reports have an ignore status.

        Returns:
            (bool): True if this Report is ignored, False otherwise.

        Raises:
            InvalidObjectError: If `id` is missing or this Report is not from a Watchlist.

        Example:

        >>> if report.ignored:
        ...     report.unignore()
        """
        if not self.id:
            raise InvalidObjectError("missing Report ID")
        if not self._from_watchlist:
            raise InvalidObjectError(
                "ignore status only applies to watchlist reports")

        url = "/threathunter/watchlistmgr/v3/orgs/{}/reports/{}/ignore".format(
            self._cb.credentials.org_key, self.id)
        resp = self._cb.get_object(url)
        return resp["ignored"]
예제 #4
0
    def update(self, **kwargs):
        """Update this Report with the given arguments.

        Arguments:
            **kwargs (dict(str, str)): The Report fields to update.

        Returns:
            Report (Report): The updated Report.

        Raises:
            InvalidObjectError: If `id` is missing, or `feed_id` is missing
                and this report is a Feed Report, or Report.validate() fails.

        Note:
            The report's timestamp is always updated, regardless of whether
            passed explicitly.

        >>> report.update(title="My new report title")
        """
        if not self.id:
            raise InvalidObjectError("missing Report ID")

        if self._from_watchlist:
            url = "/threathunter/watchlistmgr/v3/orgs/{}/reports/{}".format(
                self._cb.credentials.org_key, self.id)
        else:
            if not self._feed_id:
                raise InvalidObjectError("missing Feed ID")
            url = "/threathunter/feedmgr/v2/orgs/{}/feeds/{}/reports/{}".format(
                self._cb.credentials.org_key, self._feed_id, self.id)

        for key, value in kwargs.items():
            if key in self._info:
                self._info[key] = value

        if self.iocs:
            self._iocs = IOC(self._cb,
                             initial_data=self.iocs,
                             report_id=self.id)
        if self.iocs_v2:
            self._iocs_v2 = [
                IOC_V2(self._cb, initial_data=ioc, report_id=self.id)
                for ioc in self.iocs_v2
            ]

        # NOTE(ww): Updating reports on the watchlist API appears to require
        # updated timestamps.
        self.timestamp = int(time.time())
        self.validate()

        new_info = self._cb.put_object(url, self._info).json()
        self._info.update(new_info)
        return self
예제 #5
0
    def update(self, **kwargs):
        """Update this feed's metadata with the given arguments.

        Arguments:
            **kwargs (dict(str, str)): The fields to update.

        Raises:
            InvalidObjectError: If `id` is missing or Feed.validate() fails.
            ApiError: If an invalid field is specified.

        Example:

        >>> feed.update(access="private")
        """
        if not self.id:
            raise InvalidObjectError("missing feed ID")

        for key, value in kwargs.items():
            if key in self._info:
                self._info[key] = value

        self.validate()

        url = "/threathunter/feedmgr/v2/orgs/{}/feeds/{}/feedinfo".format(
            self._cb.credentials.org_key,
            self.id,
        )
        new_info = self._cb.put_object(url, self._info).json()
        self._info.update(new_info)

        return self
예제 #6
0
    def validate(self):
        """Validates this feed's state.

        Raises:
            InvalidObjectError: If the Feed's state is invalid.
        """
        super(Feed, self).validate()

        if self.access not in ["public", "private"]:
            raise InvalidObjectError("access should be public or private")

        if not validators.url(self.provider_url):
            raise InvalidObjectError("provider_url should be a valid URL")

        for report in self._reports:
            report.validate()
예제 #7
0
    def download_url(self, expiration_seconds=3600):
        """Returns a URL that can be used to download the file for this binary. Returns None if no download found.

        Arguments:
            expiration_seconds (int): How long the download should be valid for.

        Returns:
            URL (str): A pre-signed AWS download URL.
            None: If no download is found.

        Raises:
            InvalidObjectError: If the URL retrieval should be retried.
        """
        downloads = self._cb.select(Downloads, [self.sha256],
                                    expiration_seconds=expiration_seconds)

        if self.sha256 in downloads.not_found:
            return None
        elif self.sha256 in downloads.error:
            raise InvalidObjectError("{} should be retried".format(
                self.sha256))
        else:
            return next(
                (item.url
                 for item in downloads.found if self.sha256 == item.sha256),
                None)
예제 #8
0
    def unignore(self):
        """Removes the ignore status on this IOC.

        Only watchlist IOCs have an ignore status.

        Raises:
            InvalidObjectError: If `id` is missing or this IOC is not from a Watchlist.
        """
        if not self.id:
            raise InvalidObjectError("missing Report ID")
        if not self._report_id:
            raise InvalidObjectError("ignoring only applies to watchlist IOCs")

        url = "/threathunter/watchlistmgr/v3/orgs/{}/reports/{}/iocs/{}/ignore".format(
            self._cb.credentials.org_key, self._report_id, self.id)
        self._cb.delete_object(url)
예제 #9
0
    def update(self, **kwargs):
        """Updates this watchlist with the given arguments.

        Arguments:
            **kwargs (dict(str, str)): The fields to update.

        Raises:
            InvalidObjectError: If `id` is missing or Watchlist.validate() fails.
            ApiError: If `report_ids` is given and is empty.

        Example:

        >>> watchlist.update(name="New Name")


        """
        if not self.id:
            raise InvalidObjectError("missing Watchlist ID")

        # NOTE(ww): Special case, according to the docs.
        if "report_ids" in kwargs and not kwargs["report_ids"]:
            raise ApiError(
                "can't update a watchlist to have an empty report list")

        for key, value in kwargs.items():
            if key in self._info:
                self._info[key] = value

        self.validate()

        url = "/threathunter/watchlistmgr/v3/orgs/{}/watchlists/{}".format(
            self._cb.credentials.org_key, self.id)
        new_info = self._cb.put_object(url, self._info).json()
        self._info.update(new_info)
예제 #10
0
    def ignore(self):
        """Sets the ignore status on this report.

        Only watchlist reports have an ignore status.

        Raises:
            InvalidObjectError: If `id` is missing or this Report is not from a Watchlist.
        """
        if not self.id:
            raise InvalidObjectError("missing Report ID")

        if not self._from_watchlist:
            raise InvalidObjectError(
                "ignoring only applies to watchlist reports")

        url = "/threathunter/watchlistmgr/v3/orgs/{}/reports/{}/ignore".format(
            self._cb.credentials.org_key, self.id)
        self._cb.put_object(url, None)
예제 #11
0
    def validate(self):
        """Validates this IOC_V2's state.

        Raises:
            InvalidObjectError: If the IOC_V2's state is invalid.
        """
        super(IOC_V2, self).validate()

        if self.link and not validators.url(self.link):
            raise InvalidObjectError("link should be a valid URL")
예제 #12
0
    def custom_severity(self):
        """Returns the custom severity for this report.

        Returns:
            ReportSeverity (ReportSeverity): The custom severity for this Report,
                if it exists.

        Raises:
            InvalidObjectError: If `id` ismissing or this Report is from a Watchlist.
        """
        if not self.id:
            raise InvalidObjectError("missing report ID")
        if self._from_watchlist:
            raise InvalidObjectError(
                "watchlist reports don't have custom severities")

        url = "/threathunter/watchlistmgr/v3/orgs/{}/reports/{}/severity".format(
            self._cb.credentials.org_key, self.id)
        resp = self._cb.get_object(url)
        return ReportSeverity(self._cb, initial_data=resp)
예제 #13
0
    def enable_alerts(self):
        """Enable alerts for this watchlist. Alerts are not retroactive.

        Raises:
            InvalidObjectError: If `id` is missing.
        """
        if not self.id:
            raise InvalidObjectError("missing Watchlist ID")

        url = "/threathunter/watchlistmgr/v3/orgs/{}/watchlists/{}/alert".format(
            self._cb.credentials.org_key, self.id)
        self._cb.put_object(url, None)
예제 #14
0
    def delete(self):
        """Deletes this feed from the Enterprise EDR server.

        Raises:
            InvalidObjectError: If `id` is missing.
        """
        if not self.id:
            raise InvalidObjectError("missing feed ID")

        url = "/threathunter/feedmgr/v2/orgs/{}/feeds/{}".format(
            self._cb.credentials.org_key, self.id)
        self._cb.delete_object(url)
예제 #15
0
    def disable_tags(self):
        """Disable tagging for this watchlist.

        Raises:
            InvalidObjectError: if `id` is missing.
        """
        if not self.id:
            raise InvalidObjectError("missing Watchlist ID")

        url = "/threathunter/watchlistmgr/v3/orgs/{}/watchlists/{}/tag".format(
            self._cb.credentials.org_key, self.id)
        self._cb.delete_object(url)
예제 #16
0
    def validate(self):
        """Validates this report's state.

        Raises:
            InvalidObjectError: If the report's state is invalid
        """
        super(Report, self).validate()

        if self.link and not validators.url(self.link):
            raise InvalidObjectError("link should be a valid URL")

        if self.iocs_v2:
            [ioc.validate() for ioc in self._iocs_v2]
예제 #17
0
    def ignored(self):
        """Returns whether or not this IOC is ignored

        Returns:
            (bool): True if the IOC is ignore, False otherwise.

        Raises:
            InvalidObjectError: If this IOC is missing an `id` or is not a Watchlist IOC.

        Example:

        >>> if ioc.ignored:
        ...     ioc.unignore()
        """
        if not self.id:
            raise InvalidObjectError("missing IOC ID")
        if not self._report_id:
            raise InvalidObjectError(
                "ignore status only applies to watchlist IOCs")

        url = "/threathunter/watchlistmgr/v3/orgs/{}/reports/{}/iocs/{}/ignore".format(
            self._cb.credentials.org_key, self._report_id, self.id)
        resp = self._cb.get_object(url)
        return resp["ignored"]
예제 #18
0
    def delete(self):
        """Deletes this report from the Enterprise EDR server.

        Raises:
            InvalidObjectError: If `id` is missing, or `feed_id` is missing
                and this report is a Feed Report.

        Example:

        >>> report.delete()
        """
        if not self.id:
            raise InvalidObjectError("missing Report ID")

        if self._from_watchlist:
            url = "/threathunter/watchlistmgr/v3/orgs/{}/reports/{}".format(
                self._cb.credentials.org_key, self.id)
        else:
            if not self._feed_id:
                raise InvalidObjectError("missing Feed ID")
            url = "/threathunter/feedmgr/v2/orgs/{}/feeds/{}/reports/{}".format(
                self._cb.credentials.org_key, self._feed_id, self.id)

        self._cb.delete_object(url)
예제 #19
0
    def replace_reports(self, reports):
        """Replace this Feed's Reports with the given Reports.

        Arguments:
            reports ([Report]): List of Reports to replace existing Reports with.

        Raises:
            InvalidObjectError: If `id` is missing.
        """
        if not self.id:
            raise InvalidObjectError("missing feed ID")

        rep_dicts = [report._info for report in reports]
        body = {"reports": rep_dicts}

        url = "/threathunter/feedmgr/v2/orgs/{}/feeds/{}/reports".format(
            self._cb.credentials.org_key, self.id)
        self._cb.post_object(url, body)
예제 #20
0
    def append_reports(self, reports):
        """Append the given Reports to this Feed's current Reports.

        Arguments:
            reports ([Report]): List of Reports to append to Feed.

        Raises:
            InvalidObjectError: If `id` is missing.
        """
        if not self.id:
            raise InvalidObjectError("missing feed ID")

        rep_dicts = [report._info for report in reports]
        rep_dicts += [report._info for report in self.reports]
        body = {"reports": rep_dicts}

        url = "/threathunter/feedmgr/v2/orgs/{}/feeds/{}/reports".format(
            self._cb.credentials.org_key, self.id)
        self._cb.post_object(url, body)