Ejemplo n.º 1
0
    def __init__(self, status_code, message):
        self.status_code = status_code
        self.message = message["message"]

        raise PluginException(
            cause=
            "Received HTTP %d status code from GreyNoise. Verify your input and try again."
            % self.status_code,
            assistance=
            "If the issue persists please contact GreyNoise support.",
            data=f"{self.status_code}, {self.message}",
        )
Ejemplo n.º 2
0
    def run(self, params={}):
        equation = params.get(Input.EQUATION)
        result = Calculate.execute_equation(equation)

        if result is None:
            raise PluginException(
                cause="Calculation error",
                assistance="Error occurred while calculating the equation. Check to make sure it is valid and try "
                "again. ",
            )

        return {Output.RESULT: result}
Ejemplo n.º 3
0
def get_json(response):
    json_ = response.json()
    if "errors" in json_:
        details = ''
        if len(json_['errors']) > 0 and 'details' in json_['errors'][0]:
            details = json_['errors'][0]["detail"]

        raise PluginException(
            cause='Received an error response from AbuseIPDB.',
            assistance=details)

    return json_
Ejemplo n.º 4
0
    def _get_kind(address: str):
        if validators.ipv4(address):
            return "IPv4Address"
        elif validators.ipv6(address):
            return "IPv6Address"
        elif validators.ipv4_cidr(address):
            return "IPv4Network"

        raise PluginException(
            cause=f"Kind not detected from address: {address}",
            assistance="Check address input and try again. Allowed kind are: " "IPv4Address, IPv6Address, IPv4Network.",
        )
Ejemplo n.º 5
0
    def get_group_type(self, name):
        group = self.get_group(name)
        for groups in group.get("address_group", {}):
            if "ipv4" in groups:
                return "ipv4"
            if "ipv6" in groups:
                return "ipv6"

        raise PluginException(
            cause="The address group does not exist in SonicWall.",
            assistance="Please enter valid names and try again.",
        )
Ejemplo n.º 6
0
    def search_service_request_template(self, identifier: str) -> dict:
        template = self._call_api(
            "GET",
            f"odata/businessobject/servicereqtemplates?$search={identifier}"
        ).get("value")

        if template and len(template) > 1:
            raise PluginException(
                cause="Multiple employees found.",
                assistance=
                f"Search for {template} returned more than 1 result. Please provide a unique identifier.",
            )

        if template:
            return template[0]

        raise PluginException(
            cause="No service request templates found.",
            assistance=
            f"No service request templates found using data provided - {identifier}. Please validate and try again.",
        )
Ejemplo n.º 7
0
    def run(self, params={}):
        decoded = base64.b64decode(params[Input.CSV]).decode()

        validation = params.get(Input.VALIDATION)
        if validation:
            csv_good = utils.csv_syntax_good(decoded)
            if not csv_good:
                raise PluginException(cause="Malformed CSV",
                                      assistance="Wrong CSV syntax")

        list_of_dicts = utils.csv_to_dict(decoded, self)
        return {Output.JSON: list_of_dicts}
Ejemplo n.º 8
0
 def __find_in_whitelist(agent_obj: dict, whitelist: list):
     for key, value in agent_obj.items():
         if key in ["externalIp", "computerName", "id", "uuid"]:
             if value in whitelist:
                 raise PluginException(
                     cause="Agent found in the whitelist.",
                     assistance=
                     f"If you would like to block this host, remove {value} from the whitelist and try again.",
                 )
         if key == "networkInterfaces":
             network_dict = value[0]
             for network_key, network_val in network_dict.items():
                 if network_key in ["inet", "inet6"]:
                     for ip_address in network_val:
                         if ip_address in whitelist:
                             raise PluginException(
                                 cause="Agent found in the whitelist.",
                                 assistance=
                                 f"If you would like to block this host, remove {ip_address} from the whitelist and try again.",
                             )
     return
Ejemplo n.º 9
0
    def search_employee(self, identifier: str) -> dict:
        employees = self._call_api(
            "GET", f"odata/businessobject/employees?$search={identifier}").get(
                "value")

        if employees and len(employees) > 1:
            raise PluginException(
                cause="Multiple employees found.",
                assistance=
                f"Search for {identifier} returned more than 1 result. "
                "Please provide a unique identifier.",
            )

        if employees:
            return employees[0]

        raise PluginException(
            cause="No employees found.",
            assistance=
            f"No employees found using data provided - {identifier}. Please validate and try again.",
        )
Ejemplo n.º 10
0
    def run(self, params={}):
        start, end = params.get(Input.START), params.get(Input.END)
        try:
            agents = self.connection.client.agents.list(start=start, end=end)
        except (ThreatStackAPIError, ThreatStackClientError,
                APIRateLimitError) as e:
            raise PluginException(cause="An error occurred!", assistance=e)

        # Consume the generator
        agents = [clean(agent) for agent in agents]

        return {Output.AGENTS: agents, Output.COUNT: len(agents)}
Ejemplo n.º 11
0
 def valdate_patch_group_ids(self, patch_group_ids: list):
     invalid_ids = []
     for patch_group_id in patch_group_ids:
         if not self.connection.ivanti_api.get_patch_group(patch_group_id):
             invalid_ids.append(patch_group_id)
     if len(invalid_ids) >= 1:
         raise PluginException(
             cause="Invalid Patch Group ID provided.",
             assistance=
             f"Following Patch Group IDs do not exist: {str(invalid_ids)[1:-1]}.",
         )
     return
Ejemplo n.º 12
0
    def run(self, params={}):
        files = None
        if params.get(Input.OBJ_TYPE) and \
                params.get(Input.OBJ_TYPE) != 'file' and \
                Input.FILE in params and params.get(Input.FILE).get('content'):
            raise PluginException(
                cause='Missing file content.',
                assistance='Complete the file input with base64 file content.')
        if params.get(Input.OBJ_TYPE) == 'file' and Input.OBJ_URL in params:
            raise PluginException(
                cause='Invalid input.',
                assistance=
                'File submission from URL only possible with type "url" or "download".'
            )
        if params.get(
                Input.OBJ_TYPE) != 'url' and Input.OBJ_EXT_BROWSER in params:
            raise PluginException(
                cause='Invalid input.',
                assistance='Browser name only possible with type "url".')
        if params.get(Input.OBJ_TYPE) != 'download' and (
                Input.OBJ_EXT_USERAGENT in params
                or Input.OPT_PRIVACY_HIDESOURCE in params):
            raise PluginException(
                cause='Invalid input.',
                assistance='User agent only possible with type "download".')

        if params.get(Input.OBJ_TYPE
                      ) == 'file' and Input.FILE in params and params.get(
                          Input.FILE).get('content'):
            file = params.get(Input.FILE)
            files = {
                'file':
                (file.get('filename'),
                 base64.decodebytes(file.get('content').encode('ascii')))
            }

        if params.get(Input.FILE):
            params.pop(Input.FILE)
        task_result = self.connection.any_run_api.run_analysis(params, files)
        return {Output.UUID: task_result.get("data", {}).get('taskid', None)}
    def make_json_request(self,
                          method,
                          path,
                          params=None,
                          data=None,
                          headers=None,
                          files=None,
                          full_response: bool = False):
        response = {"text": ""}

        try:
            response = requests.request(method,
                                        f"{self.url}/{path}",
                                        data=data,
                                        params=params,
                                        files=files,
                                        headers=headers,
                                        verify=self.verify_ssl)

            if response.status_code == 403:
                raise PluginException(preset=PluginException.Preset.API_KEY)
            if response.status_code >= 400:
                raise PluginException(preset=PluginException.Preset.UNKNOWN,
                                      data=response.text)
            if 200 <= response.status_code < 300:
                if full_response:
                    return response

                return response.json()

            raise PluginException(preset=PluginException.Preset.UNKNOWN,
                                  data=response.text)
        except json.decoder.JSONDecodeError as e:
            self.logger.info(f"Invalid JSON: {e}")
            raise PluginException(preset=PluginException.Preset.INVALID_JSON,
                                  data=response.text)
        except requests.exceptions.HTTPError as e:
            self.logger.info(f"Call to McAfee ATD API failed: {e}")
            raise PluginException(preset=PluginException.Preset.UNKNOWN,
                                  data=response.text)
Ejemplo n.º 14
0
    def run(self, params={}):
        bl_name = params.get(Input.NAME)
        bl_desc = params.get(Input.DESCRIPTION)
        domain_id = params.get(Input.DOMAIN_ID, "")
        hashes = params.get(Input.HASHES)

        if not hashes:
            raise PluginException(cause="At least one hash must be provided for the blacklist!",
                                  assistance="Ensure at least one hash is provided as step input.")

        # Verify hashes are of the same type
        self._verify_hash_input(hashes=hashes)

        # Get the hash type
        hash_type = self._is_md5_or_sha256(hashes[0])
        if hash_type is HashType.sha256:
            raise PluginException(cause="SHA256 hashes are not supported!",
                                  assistance="Ensure only MD5 hashes are being used for input!")

        # If no domain_id specified, then blacklist should be global. Get all domain IDs the connection can access
        if not domain_id:
            self.logger.info("No domain IDs were specified, defaulting to global blacklisting!")
            domains = self.connection.api_client.get_all_accessible_domains()
            domains_to_blacklist = [domain["id"] for domain in domains]
        else:
            domains_to_blacklist = [domain_id]

        self.logger.info("Starting hash blacklisting...")
        try:
            blacklist_ids = self.connection.api_client.blacklist_files(blacklist_data=hashes,
                                                                       blacklist_description=bl_desc,
                                                                       domain_ids=domains_to_blacklist,
                                                                       hash_type=hash_type,
                                                                       name=bl_name)
        except APIException as e:
            raise PluginException(cause="An error occurred while attempting to blacklist hashes!",
                                  assistance=e.message)

        self.logger.info("Hash blacklisting complete!")
        return {Output.BLACKLIST_IDS: blacklist_ids}
Ejemplo n.º 15
0
    def run(self, params={}):
        success = False
        hash_input = params.get(Input.HASH)
        if not validators.sha256(hash_input):
            raise PluginException(
                cause="An invalid hash was provided.",
                assistance="Please enter a SHA256 hash and try again.",
            )

        if params.get(Input.BLACKLIST_STATE):
            action = self.connection.client.blacklist(
                hash_input, params.get(Input.DESCRIPTION))
            success = action.get("id") is not None
        else:
            for page in range(1, 9999):
                list_of_blacklist_item = self.connection.client.get_blacklists(
                    page)

                uuid = None
                for e in list_of_blacklist_item.get("items", []):
                    if e.get("properties", {}).get("sha256") == hash_input:
                        uuid = e.get("id")
                        break

                if uuid is None:
                    raise PluginException(
                        cause=
                        "Unable to unblacklist a hash that is not in the blacklist.",
                        assistance=
                        "Please provide a hash that is already blacklisted.",
                    )

                action = self.connection.client.unblacklist(uuid)
                success = action.get("deleted") is not None

                if page + 1 > list_of_blacklist_item.get("pages",
                                                         {}).get("total"):
                    break

        return {Output.SUCCESS: success}
Ejemplo n.º 16
0
    def _call_api(self, method: str, endpoint: str, params: dict = None, data: dict = None, json: dict = None):

        _url = self.base_url + endpoint

        response = requests.request(url=_url, method=method, params=params, data=data, json=json, headers=self.headers)
        if response.status_code == 401:
            raise PluginException(preset=PluginException.Preset.API_KEY)
        if response.status_code == 403:
            raise PluginException(preset=PluginException.Preset.UNAUTHORIZED)
        if response.status_code == 404:
            raise PluginException(
                cause="No results found.\n",
                assistance="Please provide valid inputs or verify the endpoint/URL/hostname configured in your plugin.\n",
                data=f"{response.text}\nurl: {_url}",
            )
        if 400 <= response.status_code < 500:
            raise PluginException(preset=PluginException.Preset.UNKNOWN, data=response.text)
        if response.status_code >= 500:
            raise PluginException(preset=PluginException.Preset.SERVER_ERROR, data=response.text)
        if endpoint.endswith("risklist"):
            return dict(xmltodict.parse(response.text))
        try:
            return response.json()
        except JSONDecodeError:
            raise PluginException(preset=PluginException.Preset.INVALID_JSON, data=response.text)
Ejemplo n.º 17
0
    def _call_api(self, method: str, endpoint: str, json: dict = None):

        response = requests.request(
            url=self.base_url + endpoint,
            method=method,
            json=json,
            auth=HTTPBasicAuth(self.username, self.password),
        )
        if response.status_code == 401:
            raise PluginException(
                preset=PluginException.Preset.USERNAME_PASSWORD)
        if response.status_code == 403:
            raise PluginException(preset=PluginException.Preset.UNAUTHORIZED)
        if response.status_code == 404:
            raise PluginException(
                cause=
                "No results found. Invalid or unreachable endpoint provided.",
                assistance=
                "Please provide valid inputs or verify the endpoint/URL/hostname configured in your plugin"
                " connection is correct.",
            )
        if 400 <= response.status_code < 500:
            raise PluginException(preset=PluginException.Preset.UNKNOWN,
                                  data=response.text)
        if response.status_code >= 500:
            raise PluginException(preset=PluginException.Preset.SERVER_ERROR,
                                  data=response.text)
        try:
            return response.json()
        except JSONDecodeError:
            raise PluginException(preset=PluginException.Preset.INVALID_JSON,
                                  data=response.text)
Ejemplo n.º 18
0
    def _call_api(self,
                  method,
                  url,
                  params=None,
                  json_data=None,
                  full_response: bool = False):
        response = {"text": ""}
        try:
            response = requests.request(
                method,
                url,
                json=json_data,
                params=params,
                auth=(self.username, self.password),
                verify=self.ssl_verify,
            )

            if response.status_code == 403:
                raise PluginException(preset=PluginException.Preset.API_KEY)
            if response.status_code >= 400:
                response_data = response.json()
                raise PluginException(preset=PluginException.Preset.UNKNOWN,
                                      data=response_data.message)

            if 200 <= response.status_code < 300:
                if full_response:
                    return response

                return response.json()

            raise PluginException(preset=PluginException.Preset.UNKNOWN,
                                  data=response.text)
        except json.decoder.JSONDecodeError as e:
            self.logger.info(f"Invalid json: {e}")
            raise PluginException(preset=PluginException.Preset.INVALID_JSON,
                                  data=response.text)
        except requests.exceptions.HTTPError as e:
            self.logger.info(f"Call to Palo Alto MineMeld failed: {e}")
            raise PluginException(preset=PluginException.Preset.UNKNOWN,
                                  data=response.text)
    def _call_api(self, method, url, params=None, json_data=None, files=None):
        response = {"text": ""}
        try:
            response = requests.request(
                method,
                url,
                files=files,
                json=json_data,
                params=params,
                headers=self.authentication_header,
            )

            if response.status_code == 403:
                raise PluginException(preset=PluginException.Preset.API_KEY)
            if response.status_code == 429:
                raise PluginException(preset=PluginException.Preset.RATE_LIMIT)
            if response.status_code >= 400:
                raise PluginException(preset=PluginException.Preset.UNKNOWN,
                                      data=response.text)
            if 200 <= response.status_code < 300:
                return response.json()

            raise PluginException(preset=PluginException.Preset.UNKNOWN,
                                  data=response.text)
        except json.decoder.JSONDecodeError as e:
            self.logger.info(f"Invalid json: {e}")
            raise PluginException(preset=PluginException.Preset.INVALID_JSON,
                                  data=response.text)
        except requests.exceptions.HTTPError as e:
            self.logger.info(f"Call to Any Run failed: {e}")
            raise PluginException(preset=PluginException.Preset.UNKNOWN,
                                  data=response.text)
Ejemplo n.º 20
0
    def run(self, params={}):
        threat_id = params.get(Input.THREAT_ID)
        campaign_id = params.get(Input.CAMPAIGN_ID)
        include_campaign_forensics = params.get(
            Input.INCLUDE_CAMPAIGN_FORENSICS, False)

        if not threat_id:
            threat_id = None
        if not campaign_id:
            campaign_id = None

        if threat_id and campaign_id:
            raise PluginException(
                cause="Both Campaign ID and Threat ID were provided.",
                assistance=
                "Only one of the following two parameters can be used: Campaign ID or Threat ID.",
            )
        elif not threat_id and not campaign_id:
            raise PluginException(
                cause="One of the following inputs must be provided.",
                assistance="Please enter either Threat ID or Campaign ID.",
            )

        if not threat_id:
            include_campaign_forensics = None

        result = insightconnect_plugin_runtime.helper.clean(
            self.connection.client.get_forensics({
                "threatId":
                threat_id,
                "campaignId":
                campaign_id,
                "includeCampaignForensics":
                include_campaign_forensics,
            }))

        return {
            Output.GENERATED: result.get("generated"),
            Output.REPORTS: result.get("reports")
        }
Ejemplo n.º 21
0
    def _call_api(self, method: str, path: str, token: str = None, json_data: dict = None, params: dict = None):
        response = {"text": ""}
        headers_list = [('Accept', 'application/json')]
        if token:
            headers_list.append(('Authorization', token))

        try:
            response = requests.request(method, self.url + path,
                                        json=json_data,
                                        params=params,
                                        headers=OrderedDict(headers_list),
                                        verify=self.verify_ssl)

            if response.status_code == 401:
                raise PluginException(preset=PluginException.Preset.USERNAME_PASSWORD)
            if response.status_code == 403:
                raise PluginException(preset=PluginException.Preset.UNAUTHORIZED)
            if response.status_code >= 400:
                response_data = response.text
                raise PluginException(preset=PluginException.Preset.UNKNOWN, data=response_data)
            if 200 <= response.status_code < 300:
                return response.json()

            raise PluginException(preset=PluginException.Preset.UNKNOWN, data=response.text)
        except json.decoder.JSONDecodeError as e:
            self.logger.info(f"Invalid JSON: {e}")
            raise PluginException(preset=PluginException.Preset.INVALID_JSON, data=response.text)
        except requests.exceptions.HTTPError as e:
            self.logger.info(f"Call to SonicWall Capture Client API failed: {e}")
            raise PluginException(preset=PluginException.Preset.UNKNOWN, data=response.text)
Ejemplo n.º 22
0
    def run(self, params={}):
        """ Run action"""
        id_ = params[Input.ID]
        issue = self.connection.client.issue(id=id_)

        if not issue:
            raise PluginException(
                cause=f'No issue found with ID: {id_}.',
                assistance='Please provide a valid issue ID.')

        result = self.connection.client.assign_issue(
            issue=issue, assignee=params[Input.ASSIGNEE])
        return {Output.SUCCESS: result}
Ejemplo n.º 23
0
    def file_search(self, server_filter: dict, file_filter: dict) -> dict:
        if not file_filter:
            raise PluginException(cause="File filter shouldn't be empty.",
                                  assistance="Please check this input.")

        return self.send_request(
            "POST",
            "/rest/sensors/action/fileSearch",
            payload={
                "filters": server_filter,
                "fileFilters": file_filter
            },
        )
Ejemplo n.º 24
0
 def _determine_address_type(address: str) -> str:
     if validators.ipv4(address):
         return "ipv4"
     if validators.ipv6(address):
         return "ipv6"
     if validators.domain(address):
         return "fqdn"
     if re.search('/', address):
         return "cidr"
     raise PluginException(
         cause="Unknown address type provided.",
         assistance=f"{address} is not one of the following: IPv4, IPv6, CIDR or domain name."
     )
Ejemplo n.º 25
0
 def _verify_hash_input(self, hashes: [str]) -> None:
     """
     Checks if multiple types of hashes have been provided as input. If multiple types are found an exception will
     be raised.
     :param hashes: Hashes input
     :return: None
     """
     if len(set(filter(self._is_md5_or_sha256, hashes))) > 1:
         raise PluginException(
             cause=
             "Multiple types of hashes were found in the hashes input!",
             assistance="Only MD5 hashes are allowed as input.",
         )
Ejemplo n.º 26
0
    def run(self, params={}):
        string = params.get(Input.STRING)
        encoding_val = params.get(Input.ENCODING).lower()
        error_handler = params.get(Input.ERROR_HANDLING)

        try:
            output = string.encode(encoding_val, error_handler)
        except UnicodeError:
            raise PluginException(cause="Encoding failed.", assistance="Could not encode given string.")

        output = output.decode(encoding_val, error_handler)

        return {Output.ENCODED: output}
Ejemplo n.º 27
0
    def _make_request(self, method, path, json_data=None):
        self.login()
        try:
            response = self._call_api(method, path, json_data)
            self._call_api("POST", "config/pending")
        except PluginException as e:
            raise PluginException(cause=e.cause,
                                  assistance=e.assistance,
                                  data=e.data)
        finally:
            self.logout()

        return response
Ejemplo n.º 28
0
    def run(self, params={}):
        rule_id, ruleset_id = params.get(Input.RULE_ID), params.get(
            Input.RULESET_ID)

        try:
            rule = clean(
                self.connection.client.rulesets.rules(ruleset_id=ruleset_id,
                                                      rule_id=rule_id))
        except (ThreatStackAPIError, ThreatStackClientError,
                APIRateLimitError) as e:
            raise PluginException(cause="An error occurred!", assistance=e)

        return {Output.RULE: rule}
Ejemplo n.º 29
0
 def ip_check(self, address):
     try:
         socket.inet_aton(address)
         return True
     except socket.error:
         self.logger.error(
             "The IP address is invalid, please provide a valid IPv4 address"
         )
         raise PluginException(
             cause=f"An invalid IPv4 address was provided: {address}.",
             assistance=
             "Please update the action input to include a valid IPv4 address.",
         )
Ejemplo n.º 30
0
    def run(self, params={}):
        agent_input = params.get(Input.AGENT)
        try:
            agent = self.connection.api.get_agent(agent_input)
        except APIException as e:
            raise PluginException(cause=e.cause,
                                  assistance=e.assistance,
                                  data=e.data)

        # Need to rename agent due to bug in yaml typing
        agent["agent_info"] = agent.pop("agent")

        return {Output.AGENT: agent}