コード例 #1
0
ファイル: api.py プロジェクト: rapid7/insightconnect-plugins
    def call_api(self, path: str, params: dict = None) -> dict:
        if params is None:
            params = {}

        api_url = self.base_url + path

        headers = {"Authorization": f"basic {self.token}"}

        try:
            response = request("GET",
                               self.base_url + path,
                               params=komand.helper.clean(params),
                               headers=headers)
            response.raise_for_status()
            return komand.helper.clean(response.json())
        except HTTPError as httpError:
            raise PluginException(
                cause=
                f"Failed to get a valid response from AttackerKB at endpoint {api_url}",
                assistance=f"Response was {httpError.response.text}",
                data=httpError,
            )
コード例 #2
0
    def run(self, params={}):
        try:
            issue = {
                'title':
                params.get(Input.TITLE),
                'priority': ('major' if params.get(Input.PRIORITY) == 'None'
                             else params.get(Input.PRIORITY)),
                'kind': ('bug' if params.get(Input.KIND) == 'None' else
                         params.get(Input.KIND)),
                'state': ('new' if params.get(Input.STATE) == 'None' else
                          params.get(Input.STATE))
            }
            issue = dict((keys, v.lower()) for keys, v in issue.items())

            if params.get(Input.CONTENT):
                issue['content'] = {'raw': params.get(Input.CONTENT)}
            if params.get(Input.COMPONENT):
                issue['components'] = {'name': params.get(Input.COMPONENT)}
            if params.get(Input.ASSIGNEE):
                issue['assignee'] = {'username': params.get(Input.ASSIGNEE)}
            if params.get(Input.VERSION):
                issue['versions'] = {'name': params.get(Input.VERSION)}
            if params.get(Input.MILESTONE):
                issue['milestones'] = {'name': params.get(Input.MILESTONE)}

            self.connection.bucket_session.headers.update(
                {'Content-Type': 'application/json'})
            api_call = f'{self.connection.base_api}/repositories/{self.connection.username}/{params.get(Input.REPOSITORY).lower()}/issues'
            response = self.connection.bucket_session.post(
                api_call, data=json.dumps(issue))
            if response.status_code == 201:
                self.logger.info('Issue Successfully created')
                return {'status': 'Issue Successfully created'}
            else:
                resp_obj = response.json()
                return {'error': resp_obj['error']['message']}

        except requests.exceptions.RequestException as e:
            raise PluginException(cause='User repository error', data=e)
コード例 #3
0
    def run(self, params={}):
        endpoint = f"https://{self.connection.host}/api/v2/cmdb/firewall/address"
        filter_ = params.get(Input.NAME_FILTER, "")

        params = None
        if filter_:
            params = {"filter": f"name=@{filter_}"}

        result = self.connection.session.get(endpoint,
                                             verify=self.connection.ssl_verify,
                                             params=params)

        try:
            result.raise_for_status()
        except Exception as e:
            raise PluginException(
                cause=f"Get address objects failed for {endpoint}\n",
                assistance=result.text,
                data=e)

        results = result.json().get("results")
        return {Output.ADDRESS_OBJECTS: komand.helper.clean(results)}
コード例 #4
0
    def run(self, params={}):
        formatter = ADUtils()
        conn = self.connection.conn
        dn = params.get("distinguished_name")
        dn = formatter.format_dn(dn)[0]
        dn = formatter.unescape_asterisk(dn)
        self.logger.info(f"Escaped DN {dn}")

        password_expire = {"pwdLastSet": ("MODIFY_REPLACE", [0])}

        try:
            conn.raise_exceptions = True
            conn.modify(dn=dn, changes=password_expire)
        except LDAPException as e:
            raise PluginException(
                cause="LDAP returned an error.",
                assistance=
                "Error was returned when trying to force password reset for this user.",
                data=e,
            )

        return {"success": True}
コード例 #5
0
    def _check_and_compile_query(self,
                                 description_query: str) -> Optional[object]:
        """
        This takes a regex string and compiles it to regex. If no string is given it will return None

        :param description_query: regex as string
        :return: re.Pattern (re.compile()) OR None if no string was given
        """
        compiled_query = None

        if description_query:
            try:
                compiled_query = re.compile(description_query)
            except re.error as e:
                raise PluginException(
                    cause=
                    f"Invalid regex used for Description Query: {description_query}",
                    assistance=
                    "Please check your input for Description Query for errors"
                ) from e

        return compiled_query
コード例 #6
0
    def run(self, params={}):
        short_url = params.get(Input.URL)
        try:
            r = requests.get('https://unshorten.me/json/' + short_url)
            r.raise_for_status()
            out = r.json()
        except Exception as e:
            self.logger.error(e)
            raise PluginException(cause='Internal server error',
                                  assistance='Unshorten.me is unable to resolve the URL',
                                  data=e)

        try:
            if out[Output.ERROR]:
                if out[Output.ERROR] == "Connection Error":
                    out[Output.ERROR] = "Unshorten.me is unable to resolve the URL"
                self.logger.error(out.get(Output.ERROR))
        except KeyError:
            # All good, no error key is present
            self.logger.info('No errors')

        return out
コード例 #7
0
    def maybe_get_log_entries(self, log_id: str, query: str, time_from: int,
                              time_to: int) -> (str, [object]):
        """
        Make a call to the API and ask politely for log results.

        If the query runs exceptionally fast the API will return results immediately. In this case, we will return the
        results as the second return entry in the return tuple. The first element of the tuple will be None

        Usually, the API will return a 202 with callback URL to poll for results. If this is the case, we
        return the URL as the first entry in the tuple return. The second element in the return tuple will be None

        @param log_id: str
        @param query: str
        @param time_from: int
        @param time_to: int
        @return: (callback url, list of log entries)
        """
        endpoint = f"{self.connection.url}log_search/query/logs/{log_id}"
        params = {"query": query, "from": time_from, "to": time_to}

        self.logger.info(f"Getting logs from: {endpoint}")
        self.logger.info(f"Using parameters: {params}")
        response = self.connection.session.get(endpoint, params=params)
        try:
            response.raise_for_status()
        except Exception:
            raise PluginException(
                cause="Failed to get logs from InsightIDR\n",
                assistance=f"Could not get logs from: {endpoint}\n",
                data=response.text)

        results_object = response.json()
        potential_results = results_object.get("events")
        if potential_results:
            self.logger.info("Got results immediately, returning.")
            return None, potential_results
        else:
            self.logger.info("Got a callback url. Polling results...")
            return results_object.get("links")[0].get("href"), None
コード例 #8
0
    def make_request(action, logger, *args, **kwargs):
        try:
            response = action(*args, **kwargs)
            return response.data()
        except BadRequestException as e:
            cause = "DomainToolsAPI: Bad Request:"
            assistance = f"code {e.code}, reason {e.reason}"
        except ServiceUnavailableException as e:
            cause = "DomainToolsAPI: Service Unavailable:"
            assistance = f"code {e.code}, reason {e.reason}"
        except NotAuthorizedException as e:
            cause = "DomainToolsAPI: Authorization Failed:"
            assistance = f"code {e.code}, reason {e.reason}"
        except NotFoundException as e:
            cause = "DomainToolsAPI: Action Not Found:"
            assistance = f"code {e.code}, reason {e.reason}"
        except InternalServerErrorException as e:
            cause = "DomainToolsAPI: Internal Server Error:"
            assistance = f"code {e.code}, reason {e.reason}"

        logger.error(f"DomainToolsAPI: {cause} {assistance}")
        raise PluginException(cause=cause, assistance=assistance)
コード例 #9
0
    def run(self, params={}):
        #
        # Note: ID is not a required payload parameter despite the API docs saying it is
        # Providing it actually causes the request to fail
        #
        resource_helper = ResourceRequests(self.connection.session,
                                           self.logger)
        endpoint = endpoints.ScanEnginePool.scan_engine_pools(
            self.connection.console_url)

        if ("engines" not in params) or (("engines" in params) and
                                         (len(params["engines"]) == 0)):
            error = "At least 1 scan engine must be assigned to the scan engine pool for creation."
            raise PluginException(preset=PluginException.Preset.UNKNOWN,
                                  data=error)

        self.logger.info("Creating scan engine pool...")
        response = resource_helper.resource_request(endpoint=endpoint,
                                                    method="post",
                                                    payload=params)

        return response
コード例 #10
0
    def get_token(self):
        self.logger.info("Updating Auth Token...")
        token_url = f"https://login.microsoftonline.com/{self.tenant_id}/oauth2/token"

        body = {
            "resource": "https://graph.microsoft.com",
            "grant_type": "password",
            "client_id": self.app_id,
            "client_secret": self.app_secret,
            "username": self.username,
            "password": self.password
        }

        if self.refresh_token:
            body["refresh_token"] = self.refresh_token

        self.logger.info(f"Getting token from: {token_url}")
        result = requests.post(token_url, data=body)

        try:
            result.raise_for_status()
        except Exception as e:
            raise PluginException(
                cause="Authentication to Microsoft Graph failed.",
                assistance=
                f"Some common causes for this error include an invalid username, password, or connection settings."
                f"Verify you are using the correct domain name for your user, and verify that user has access to "
                f"the target tenant. Verify you can log into Office365 with the user account as well.\n"
                f"The result returned was:\n{result.text}",
                data=e) from e

        result_json = result.json()
        self.api_token = result_json.get("access_token")
        self.refresh_token = result_json.get("refresh_token")

        self.logger.info(
            f"Authentication was successful, token is: ******************{self.api_token[-5:]}"
        )
        self.logger.info(f"Detected Permissions: {result_json.get('scope')}")
コード例 #11
0
    def commit(self, action: str, cmd: str) -> dict:
        querystring = {
            "type": "commit",
            "action": action,
            "key": self.key,
            "cmd": cmd
        }

        response = requests.get(self.url,
                                params=querystring,
                                verify=self.verify_cert)
        try:
            output = xmltodict.parse(response.text)
        except TypeError:
            raise ServerException(
                cause='The response from PAN-OS was not the correct data type.',
                assistance='Contact support for help.',
                data=response.text)
        except SyntaxError:
            raise ServerException(
                cause='The response from PAN-OS was malformed.',
                assistance='Contact support for help.',
                data=response.text)
        except BaseException as e:
            raise PluginException(
                cause=
                'An unknown error occurred when parsing the PAN-OS response.',
                assistance='Contact support for help.',
                data=f'{response.text}, error {e}')

        if output['response']['@status'] == 'error':
            error = output['response']['msg']
            error = json.dumps(error)
            raise ServerException(
                cause='PAN-OS returned an error in response to the request.',
                assistance=
                'Double that check inputs are valid. Contact support if this issue persists.',
                data=error)
        return output
コード例 #12
0
    def run(self, params={}):
        endpoint = f"https://{self.connection.host}/api/v2/cmdb/firewall/policy"

        filter_ = params.get(Input.NAME_FILTER, "")
        get_params = {}
        if filter_:
            get_params = {"filter": f"name=@{filter_}"}

        result = self.connection.session.get(endpoint,
                                             params=get_params,
                                             verify=self.connection.ssl_verify)

        try:
            result.raise_for_status()
        except Exception as e:
            raise PluginException(cause=f"Get policy failed for {endpoint}\n",
                                  assistance=result.text,
                                  data=e)

        policies = result.json().get("results")

        return {Output.POLICIES: komand.helper.clean(policies)}
コード例 #13
0
    def run(self, params={}):
        saved_search_name = params.get(Input.SAVED_SEARCH_NAME)
        properties = params.get(Input.PROPERTIES)

        try:
            param_dict = json.loads(
                json.dumps(properties,
                           default=lambda o: o.__dict__,
                           indent=4,
                           sort_keys=True))

            saved_search_to_update = self.connection.client.saved_searches[
                saved_search_name]
            saved_search_to_update.update(**param_dict).refresh()
        except JSONDecodeError as e:
            raise PluginException(
                preset=PluginException.Preset.INVALID_JSON) from e
        except KeyError as error:
            self.logger.error(error)
            return {Output.SUCCESS: False}

        return {Output.SUCCESS: True}
コード例 #14
0
    def run(self, params={}):
        """Add label to issue"""

        issue = self.connection.client.issue(id=params['id'])

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

        labels = params['label'].split(',')

        for label in labels:
            if label not in issue.fields.labels:
                issue.fields.labels.append(label)

        self.logger.info('Adding labels to issue %s: %s', params['id'],
                         issue.fields.labels)

        issue.update(fields={'labels': issue.fields.labels})

        return {'success': True}
コード例 #15
0
    def run(self, params={}):
        query = params.get(Input.QUERY)
        days_back = params.get(Input.DAYS_BACK, None)

        if query not in self.connection.terms:
            raise PluginException(
                cause="Query term not enabled in PhishEye product.",
                assistance=
                f"Add term to PhishEye and try again, or use one of the allowed terms: {self.connection.terms}."
            )

        response = Helper.make_request(self.connection.api.phisheye,
                                       self.logger, query, days_back)
        output = {
            Output.DOMAINS: response["response"]["domains"],
            Output.TERM: response["response"]["term"]
        }

        if "date" in response["response"]:
            output["date"] = response["response"]["date"]

        return output
コード例 #16
0
    def _create_client(self, is_enterprise_license: bool) -> Service:
        """
        Creates a Splunk client based on the Splunk license input
        :param is_enterprise_license: Whether or not the Splunk client should be configured for an Enterprise license
        :return: Splunk client
        """
        try:
            if is_enterprise_license:
                self.logger.info("Connect: Connecting with Enterprise license configuration...")
                splunk_client = client.connect(
                    host=self.host,
                    port=self.port,
                    username=self.username,
                    password=self.password,
                    scheme=self.scheme,
                    verify=self.verify,
                )
            else:
                self.logger.info("Connect: Connecting with Free license configuration...")
                # We need to pass 'admin' as the username for the free license
                splunk_client = client.connect(
                    host=self.host,
                    port=self.port,
                    username="******",
                    scheme=self.scheme,
                    verify=self.verify,
                )
        except Exception as e:
            # noinspection PyTypeChecker
            raise self._EXCEPTIONS.get(
                type(e),
                PluginException(
                    cause="An unhandled exception occurred!",
                    assistance="Check the logs for more details.",
                    data=e,
                ),
            )

        return splunk_client
コード例 #17
0
    def get_site_scans(self, params):
        # Generate unique identifier for report names
        identifier = uuid.uuid4()

        # Gather site IDs of sites that match regular expression
        site_ids = NewScans.get_sites_within_scope(self, params.get(Input.SITE_NAME_FILTER))

        # Gather sites and corresponding site IDs in scope
        report_payload = {
            'name': f"Rapid7-InsightConnect-NewScans-{identifier}",
            'format': 'sql-query',
            'query': NewScans.scans_query(map(lambda x: "'" + x + "'", params.get(Input.STATUS_FILTER)),
                                          [str(site_id) for site_id in site_ids]),
            'version': '2.3.0',
        }

        # Run report to get scans based on sites in scope
        # This is preferred over API endpoints due to endpoints returning all scans for agent site
        self.logger.info("Pulling scans")
        report_contents = util.adhoc_sql_report(self.connection, self.logger, report_payload)

        site_scans = defaultdict(list)
        try:
            csv_report = csv.DictReader(io.StringIO(report_contents['raw'].decode('utf-8')))
        except Exception as e:
            raise PluginException(cause="Error: Failed to process query response while fetching site scans.",
                                  assistance=f"Exception returned was {e}")

        # Identify all scans that match sites from regular expression and status filter
        for row in csv_report:
            site_scan = {
                "scan_id": int(row["scan_id"]),
                "status": row["status"],
                "site_id": int(row["site_id"]),
                "site_name": row["site_name"]
            }
            site_scans[row["site_id"]].append(site_scan)

        return site_scans
コード例 #18
0
    def run(self, params={}):
        try:
            domain = params.get(Input.DOMAIN)
            fields = params.get(Input.FIELDS)
            comment = params.get(Input.COMMENT)

            if not fields or not len(fields):
                fields = None

            if not comment:
                comment = None
            domain_report = self.connection.client.lookup_domain(
                domain, fields=fields, comment=comment)
            if domain_report.get("warnings", False):
                self.logger.warning(
                    f"Warning: {domain_report.get('warnings')}")
                self.logger.info(
                    'Option for fields are: ["sightings","threatLists","analystNotes","counts","entity","hashAlgorithm","intelCard","metrics", "relatedEntities" ,"risk" ,"timestamps"]'
                )
            return komand.helper.clean(domain_report["data"])
        except Exception as e:
            PluginException(cause=f"Error: {e}", assistance="Review exception")
コード例 #19
0
    def run(self, params={}):
        # Import variables from connection
        url = self.connection.url
        access_key = self.connection.access_key
        secret_key = self.connection.secret_key
        app_id = self.connection.app_id
        app_key = self.connection.app_key

        query = params.get(Input.QUERY)
        source = params.get(Input.SOURCE)
        if query:
            data = {"query": query, "source": source}
        else:
            data = {"source": source}

        # Mimecast request
        mimecast_request = util.MimecastRequests()
        response = mimecast_request.mimecast_post(
            url=url,
            uri=FindGroups._URI,
            access_key=access_key,
            secret_key=secret_key,
            app_id=app_id,
            app_key=app_key,
            data=data,
        )

        try:
            output = response["data"][0]["folders"]
        except KeyError:
            self.logger.error(response)
            raise PluginException(
                cause="Unexpected output format.",
                assistance=
                "The output from Mimecast was not in the expected format. Please contact support for help.",
                data=response,
            )

        return {Output.GROUPS: output}
コード例 #20
0
def send_html_message(
    logger: Logger,
    connection: komand.connection,
    message: str,
    team_id: str,
    channel_id: str,
    thread_id: str = None,
) -> dict:
    """
    Send HTML content as a message to Teams

    :param logger: object (logging.logger)
    :param connection: object (komand.connection)
    :param message: String (HTML)
    :param team_id: String
    :param channel_id: String
    :param thread_id: string
    :return: dict
    """
    send_message_url = f"https://graph.microsoft.com/beta/teams/{team_id}/channels/{channel_id}/messages"

    if thread_id:
        send_message_url = send_message_url + f"/{thread_id}/replies"

    logger.info(f"Sending message to: {send_message_url}")
    headers = connection.get_headers()

    body = {"body": {"contentType": "html", "content": message}}

    result = requests.post(send_message_url, headers=headers, json=body)
    try:
        result.raise_for_status()
    except Exception as e:
        raise PluginException(cause="Send message failed.",
                              assistance=result.text) from e

    message = result.json()
    return message
コード例 #21
0
    def run(self, params={}):
        job_id = params.get(Input.JOB_ID)
        timeout = params.get(Input.TIMEOUT)
        timer_step = 0.2  # What we should increment the timeout counter by

        try:
            search_job = self.connection.client.jobs[job_id]
        except KeyError as error:
            self.logger.error(error)
            raise PluginException(
                cause="Unable to find job.",
                assistance="Ensure the provided job ID input is valid.",
                data=f"Job ID: {job_id}",
            )

        timer = 0  # Keep track of the timeout

        self.logger.info("Streaming results")
        while not search_job.is_done() and timer < timeout:
            sleep(timer_step)
            timer += timer_step
            self.logger.info("Search not complete, sleeping for %s seconds" %
                             timer_step)
        if timer > timeout:
            self.logger.info(
                "Timeout occurred, finalizing and attempting to retrieve results..."
            )
            search_job.finalize()

        rr = results.ResultsReader(search_job.results())

        gathered_results = []

        for result in rr:
            if isinstance(result, dict):
                gathered_results.append(result)

        return {Output.SEARCH_RESULTS: gathered_results}
コード例 #22
0
    def run(self, params={}):
        group_name = params[Input.GROUP_NAME]
        address_name = params[Input.ADDRESS_OBJECT_NAME]

        group = self.connection.get_address_group(group_name)
        group_members = group.get("member")

        group_members.append({"name": address_name})
        group["member"] = group_members

        endpoint = f"https://{self.connection.host}/api/v2/cmdb/firewall/addrgrp/{group.get('name')}"

        response = self.connection.session.put(
            endpoint, json=group, verify=self.connection.ssl_verify)

        try:
            response.raise_for_status()
        except Exception as e:
            json_obj = {}
            try:
                json_obj = response.json()
            except Exception as err:
                self.throw_unknown_error(err, endpoint, response)
            if json_obj.get("error", 0) == -3:
                raise PluginException(
                    cause=
                    f"Add address object to address group failed: {endpoint}\n",
                    assistance=
                    "The error code returned was -3. This usually indicates"
                    "that the address object specified could not be found.",
                    data=e)

            self.throw_unknown_error(e, endpoint, response)

        json_response = response.json()
        success = json_response.get("status", "").lower() == "success"

        return {Output.SUCCESS: success, Output.RESULT_OBJECT: json_response}
コード例 #23
0
def handle_exceptions(e: pyodbc.Error, query: str):
    """
    This method takes a pyodbc.Error object and raises a specific error type Along with appropriate messaging
    :param e: A pyodbc.Error object to be raised and give context
    :param query: The query that the plugin attempted to run
    """
    _ASSISTANCE = 'Double-check the query string and refer to the error code for additional information.'
    _DATA = f'Error code: {e}\nQuery string: {query}'

    cause = {
        pyodbc.OperationalError:
        'An operational error occurred. This can be related to the database\'s operation'
        ' and not necessarily under the control of the programmer, e.g. an unexpected disconnect occurs,'
        ' the data source name is not found, a transaction could not be processed,'
        ' a memory allocation error occurred during processing, etc.',
        pyodbc.ProgrammingError:
        'A programing error occurred. This can be caused by \'table not found\' or \'already exists\','
        ' syntax error in the SQL statement, wrong number of parameters specified, etc.',
        pyodbc.DataError:
        'A data error occurred. This can be caused by problems with the processed data such as division by zero,'
        ' numeric value out of range, etc.',
        pyodbc.IntegrityError:
        'An integrity error occurred. This can happen'
        ' when the relational integrity of the database is affected, e.g. a foreign key check fails.',
        pyodbc.InternalError:
        'An internal error occurred. This can be caused when the database encounters an internal error, e.g. the '
        'cursor is invalid, the transaction is out of sync, etc.',
        pyodbc.NotSupportedError:
        'A \'not supported\' error occurred. This can be caused by a method or database API was used'
        ' which is not supported by the database, e.g.'
        ' requesting a .rollback() on a connection that does not support transactions or has transactions turned off.',
        pyodbc.InterfaceError:
        'An interface error occurred. This is an error related to the database interface rather than the database itself.'
    }

    raise PluginException(cause=cause[type(e)],
                          assistance=_ASSISTANCE,
                          data=_DATA)
コード例 #24
0
    def search(self, pattern, start=None, limit=None, include_category=None):
        '''Searches for domains that match a given pattern'''

        params = dict()

        if start is None:
            start = datetime.timedelta(days=30)

        if isinstance(start, datetime.timedelta):
            params['start'] = int(time.mktime((datetime.datetime.utcnow() - start).timetuple()) * 1000)
        elif isinstance(start, datetime.datetime):
            params['start'] = int(time.mktime(start.timetuple()) * 1000)
        else:
            raise PluginException(cause='Unable to retrieve domains for search.', assistance=Investigate.SEARCH_ERR)

        if limit is not None and isinstance(limit, int):
            params['limit'] = limit
        if include_category is not None and isinstance(include_category, bool):
            params['includeCategory'] = str(include_category).lower()

        uri = self._uris['search'].format(urllib.parse.quote_plus(pattern))

        return self.get_parse(uri, params)
コード例 #25
0
    def run(self, params={}):
        endpoint = f"https://{self.connection.host}/api/v2/cmdb/firewall/address"
        filter_ = params.get(Input.NAME_FILTER, "")
        helper = Helpers(self.logger)

        params = None
        if filter_:
            params = {"filter": f"name=@{filter_}"}

        response = self.connection.session.get(
            endpoint, verify=self.connection.ssl_verify, params=params)

        try:
            json_response = response.json()
        except ValueError:
            raise PluginException(
                cause="Data sent by FortiGate was not in JSON format.\n",
                assistance="Contact support for help.",
                data=response.text)
        helper.http_errors(json_response, response.status_code)

        results = response.json().get("results")
        return {Output.ADDRESS_OBJECTS: komand.helper.clean(results)}
コード例 #26
0
    def run(self, params={}):
        url = f"https://{self.connection.server_ip}:{self.connection.server_port}/web_api/show-access-rulebase"
        headers = self.connection.get_headers()
        payload = {
            "offset": 0,
            "limit": params.get(Input.LIMIT, 1),
            "name": params.get(Input.LAYER_NAME),
            "details-level": "full",
            "use-object-dictionary": True,
        }

        result = requests.post(url, headers=headers, json=payload, verify=self.connection.ssl_verify)

        try:
            result.raise_for_status()
        except Exception as e:
            raise PluginException(
                cause=f"Show Access Rules from {url} failed.\n",
                assistance=f"{result.text}\n",
                data=e,
            )

        return {Output.ACCESS_RULES: komand.helper.clean(result.json())}
コード例 #27
0
    def run(self, params={}):
        # Note: ID is not a required payload parameter despite the API docs saying it is
        # Providing it actually causes the request to fail
        resource_helper = ResourceRequests(self.connection.session, self.logger)
        endpoint = endpoints.ScanEngine.scan_engines(self.connection.console_url)
        payload = params

        self.logger.info("Creating scan engine...")
        try:
            response = resource_helper.resource_request(endpoint=endpoint, method="post", payload=payload)
        except Exception as e:
            if "An unexpected error occurred." in str(e):
                error = "Security console failed to connect to scan engine"
            elif "errors with the input or parameters supplied" in str(e):
                error = (
                    f"{str(e)} - "
                    f"This may be due to an engine with this IP or name already existing in the Security Console."
                )
            else:
                error = e
            raise PluginException(preset=PluginException.Preset.UNKNOWN, data=error)

        return response
コード例 #28
0
    def get_address_object(self, address_name):
        try:
            response_ipv4_json = self.call_api(
                path=f"firewall/address/{address_name}").json()

            if response_ipv4_json["http_status"] == 200:
                return response_ipv4_json
        except (PluginException, json.decoder.JSONDecodeError,
                requests.exceptions.HTTPError):
            pass

        response_ipv6 = self.call_api(path=f"firewall/address6/{address_name}")
        response_ipv6_json = response_ipv6.json()

        if response_ipv6_json["http_status"] == 200:
            return response_ipv6_json

        raise PluginException(
            cause=
            f"Get address object failed. Address object '{address_name}' does not exists.\n",
            assistance="Contact support for assistance.",
            data=response_ipv6.text,
        )
コード例 #29
0
    def run(self, params={}):
        group_ids = params.get(Input.GROUP_ID)
        user_id = params.get(Input.USER_ID)

        self.logger.info(f"Getting user info: {user_id}")
        user_response = get_user_info(self.connection, user_id, self.logger)
        user_object = user_response.json()
        user = {"@odata.id": f"https://graph.microsoft.com/v1.0/{self.connection.tenant}/users/{user_object.get('id')}"}

        headers = self.connection.get_headers(self.connection.get_auth_token())

        for group_id in group_ids:
            add_to_group_endpoint = (
                f"https://graph.microsoft.com/v1.0/{self.connection.tenant}/groups/{group_id}/members/$ref"
            )
            result = requests.post(add_to_group_endpoint, json=user, headers=headers)
            if not result.status_code == 204:
                raise PluginException(
                    cause=f"Add User to Group call returned an unexpected response: {result.status_code}",
                    assistance=f"Check that the group id {group_id} and user id {user_id} are correct.",
                    data=result.text,
                )
        return {Output.SUCCESS: True}
コード例 #30
0
 def run(self, params={}):
     name = params.get(Input.NAME)
     resource_records = params.get(Input.RESOURCE_RECORDS)
     record_type = params.get(Input.RECORDTYPE)
     if record_type:
         record_type = record_type.replace(" ", "")
     try:
         response = self.connection.investigate.get_dns(
             name,
             resource_records=resource_records,
             record_type=record_type
         )
     except Exception as e:
         raise PluginException(
             preset=PluginException.Preset.UNKNOWN,
             data=e
         )
     if resource_records == "Timeline":
         return {
             Output.TIMELINE_DATA: response
         }
     else:
         return response