Пример #1
0
    def _test_connectivity(self, param):

        action_result = self.add_action_result(phantom.ActionResult(dict(param)))

        ret_val, resp_json = self._make_slack_rest_call(action_result, consts.SLACK_AUTH_TEST, {})

        if not ret_val:
            self.save_progress("Test Connectivity Failed")
            return ret_val

        action_result.add_data(resp_json)

        self.save_progress("Auth check to Slack passed. Configuring app for team, {}".format(resp_json.get('team', 'Unknown Team')))

        bot_username = resp_json.get('user')
        bot_user_id = resp_json.get('user_id')

        self.save_progress("Got username, {0}, and user ID, {1}, for the bot".format(bot_username, bot_user_id))

        self._state['bot_name'] = bot_username
        self._state['bot_id'] = bot_user_id

        self.save_progress("Test Connectivity Passed")

        return action_result.set_status(phantom.APP_SUCCESS)
Пример #2
0
    def _list_channels(self, param):

        self.debug_print("param", param)
        action_result = self.add_action_result(phantom.ActionResult(dict(param)))

        limit = self._validate_integers(action_result, param.get("limit", consts.SLACK_DEFAULT_LIMIT), consts.SLACK_LIMIT_KEY)
        if limit is None:
            return action_result.get_status()

        ret_val, resp_json = self._paginator(action_result, consts.SLACK_LIST_CHANNEL, "channels", limit=limit)

        if not ret_val:
            return action_result.get_status()

        action_result.add_data(resp_json)

        channels = resp_json.get('channels', [])

        for chan in channels:
            name = chan.get('name', 'unknownchannel')
            chan['name'] = '#' + name

        action_result.set_summary({"num_public_channels": len(channels)})

        return action_result.set_status(phantom.APP_SUCCESS)
Пример #3
0
    def _restart_service(self, param):

        action_result = self.add_action_result(phantom.ActionResult(param))
        return action_result.set_status(
            phantom.APP_ERROR,
            "This action has been deprecated. Please use the NetWitness Logs and Packets 'restart device' action instead."
        )
Пример #4
0
    def _list_users(self, param):

        self.debug_print("param", param)
        action_result = self.add_action_result(phantom.ActionResult(dict(param)))

        limit = self._validate_integers(action_result, param.get("limit", consts.SLACK_DEFAULT_LIMIT), consts.SLACK_LIMIT_KEY)
        if limit is None:
            return action_result.get_status()

        ret_val, resp_json = self._paginator(action_result, consts.SLACK_USER_LIST, "members", limit=limit)

        if not ret_val:
            return action_result.get_status()

        action_result.add_data(resp_json)

        users = resp_json.get('members', [])

        for user in users:
            name = user.get('name', 'unknownuser')
            user['name'] = '@' + name

        action_result.set_summary({"num_users": len(users)})

        return action_result.set_status(phantom.APP_SUCCESS)
Пример #5
0
    def _add_reaction(self, param):

        action_result = self.add_action_result(
            phantom.ActionResult(dict(param)))

        emoji = self._handle_py_ver_compat_for_input_str(param['emoji'])

        params = {
            'channel': param['destination'],
            'name': emoji,
            'timestamp': param['message_ts']
        }

        ret_val, resp_json = self._make_slack_rest_call(
            action_result, SLACK_ADD_REACTION, params)

        if not ret_val:
            message = action_result.get_message()
            if message:
                error_message = "{}: {}".format(SLACK_ERR_ADDING_REACTION,
                                                message)
            else:
                error_message = SLACK_ERR_ADDING_REACTION
            return action_result.set_status(phantom.APP_ERROR, error_message)

        action_result.add_data(resp_json)

        return action_result.set_status(phantom.APP_SUCCESS,
                                        SLACK_SUCC_REACTION_ADDED)
Пример #6
0
    def _get_user(self, param):

        self.debug_print("param", param)
        action_result = self.add_action_result(phantom.ActionResult(dict(param)))

        user_id = param['user_id']

        if not user_id.startswith('U'):
            return action_result.set_status(phantom.APP_ERROR, "The user parameter must be a user ID")

        ret_val, resp_json = self._make_slack_rest_call(action_result, consts.SLACK_USER_INFO, {'user': user_id})

        if not ret_val:
            return phantom.APP_ERROR

        action_result.add_data(resp_json)

        user = resp_json.get('user')

        if not user:
            return action_result.set_status(phantom.APP_ERROR, "User data not found in json output")

        name = user.get('name', '')
        user['name'] = '@' + name

        return action_result.set_status(phantom.APP_SUCCESS, "User data successfully retrieved")
Пример #7
0
    def _get_response(self, param):

        action_result = self.add_action_result(
            phantom.ActionResult(dict(param)))

        qid = self._handle_py_ver_compat_for_input_str(param['question_id'])
        state_dir = self.get_state_dir()
        answer_path = '{0}/{1}.json'.format(state_dir, qid)

        self.save_progress(
            'Checking for response to question with ID: {0}'.format(qid))

        try:
            answer_file = open(answer_path, 'r')
        except:
            return action_result.set_status(
                phantom.APP_ERROR, SLACK_ERR_QUESTION_RESPONSE_NOT_AVAILABLE)

        try:
            resp_json = json.loads(answer_file.read())
            answer_file.close()
        except:
            return action_result.set_status(
                phantom.APP_ERROR, SLACK_ERR_UNABLE_TO_PARSE_RESPONSE)

        action_result.add_data(resp_json)
        action_result.set_summary({
            'response_received':
            True,
            'response':
            resp_json.get("actions", [{}])[0].get("value")
        })

        return action_result.set_status(phantom.APP_SUCCESS)
Пример #8
0
    def _send_message(self, param):

        self.debug_print("param", param)
        action_result = self.add_action_result(phantom.ActionResult(dict(param)))

        message = self._handle_py_ver_compat_for_input_str(param['message'])

        if '\\' in message:
            if self._python_version == 2:
                message = message.decode('string_escape')
            else:
                message = bytes(message, "utf-8").decode("unicode_escape")

        if len(message) > consts.SLACK_MESSAGE_LIMIT:
            return (action_result.set_status(phantom.APP_ERROR, "Message too long. Please limit messages to {0} characters.".format(consts.SLACK_MESSAGE_LIMIT)))

        params = {'channel': param['destination'], 'text': message, 'as_user': True}

        ret_val, resp_json = self._make_slack_rest_call(action_result, consts.SLACK_SEND_MESSAGE, params)

        if not ret_val:
            return ret_val

        action_result.add_data(resp_json)

        return action_result.set_status(phantom.APP_SUCCESS, "Message sent successfully")
Пример #9
0
    def _list_events(self, param):

        self.debug_print(param)
        action_result = self.add_action_result(phantom.ActionResult(param))
        alert_id = param['id']
        limit = int(param.get('limit', consts.RSASA_DEFAULT_EVENT_LIMIT))

        ret_val, events = self._get_events(action_result, alert_id, limit)

        if not ret_val:
            return ret_val

        for event in events:
            if event['data'][0]['filename'] and not event['data'][0]['hash']:
                self._extract_device_and_hash(event)

        action_result.add_data(events)
        action_result.set_summary({"num_events": len(events)})

        for event in events:
            for link in event['related_links']:
                if link['type'] == 'investigate_original_event':
                    event['id'] = link['url'].split('/')[-1]

        return action_result.set_status(phantom.APP_SUCCESS)
Пример #10
0
    def _list_devices(self, param):

        self.debug_print(param)
        action_result = self.add_action_result(phantom.ActionResult(param))

        endpoint = '/common/devices'

        query_params = {'page': 1, 'start': 0, 'limit': 0}

        ret_val, data = self._make_rest_call(endpoint,
                                             action_result,
                                             params=query_params)

        if not ret_val:
            return ret_val

        devices = data.get('data')

        if not data:
            return action_result.set_status(phantom.APP_ERROR,
                                            consts.RSASA_ERR_NO_DEVICES)

        action_result.add_data(devices)
        action_result.set_summary({'num_devices': len(devices)})

        return action_result.set_status(phantom.APP_SUCCESS)
Пример #11
0
    def _invite_users(self, param):

        action_result = self.add_action_result(
            phantom.ActionResult(dict(param)))

        user_token = self.get_config().get('user_token')

        if not user_token:
            return action_result.set_status(phantom.APP_ERROR,
                                            SLACK_ERR_USER_TOKEN_NOT_PROVIDED)

        headers = {
            "Authorization": "Bearer {}".format(user_token),
            'Content-Type': 'application/json'
        }

        users = [x.strip() for x in param['users'].split(',')]
        users = list(filter(None, users))
        if not users:
            return action_result.set_status(phantom.APP_ERROR,
                                            SLACK_ERR_INVALID_USER)

        params = {
            'users': users,
            'channel': param['channel_id'],
            'token': user_token
        }

        endpoint = "{}{}".format(SLACK_BASE_URL, SLACK_INVITE_TO_CHANNEL)

        ret_val, resp_json = self._make_rest_call(action_result,
                                                  endpoint,
                                                  False,
                                                  method=requests.post,
                                                  headers=headers,
                                                  body=params)

        if not ret_val:
            return ret_val

        if not resp_json.get('ok', True):
            error = resp_json.get('error', 'N/A')
            error_details = self._handle_py_ver_compat_for_input_str(
                resp_json.get('detail', ''))
            if error_details:
                error_message = "{}: {}\r\nDetails: {}".format(
                    SLACK_ERR_INVITING_CHANNEL, error, error_details)
            else:
                error_message = "{}: {}".format(SLACK_ERR_INVITING_CHANNEL,
                                                error)
            return action_result.set_status(phantom.APP_ERROR, error_message)

        action_result.add_data(resp_json)

        return action_result.set_status(phantom.APP_SUCCESS,
                                        SLACK_SUCC_INVITE_SENT)
Пример #12
0
    def _create_channel(self, param):

        action_result = self.add_action_result(
            phantom.ActionResult(dict(param)))

        user_token = self.get_config().get('user_token')

        if not user_token:
            return action_result.set_status(phantom.APP_ERROR,
                                            SLACK_ERR_USER_TOKEN_NOT_PROVIDED)

        headers = {
            "Authorization": "Bearer {}".format(user_token),
            'Content-Type': 'application/json'
        }

        params = {'name': param['name'], 'token': user_token, 'validate': True}
        endpoint = "{}{}".format(SLACK_BASE_URL, SLACK_CHANNEL_CREATE_ENDPOINT)

        # private channel
        channel_type = param.get("channel_type", "public")
        if channel_type not in ["public", "private"]:
            return action_result.set_status(phantom.APP_ERROR,
                                            SLACK_ERR_INVALID_CHANNEL_TYPE)
        if channel_type == "private":
            params.update({"is_private": True})

        ret_val, resp_json = self._make_rest_call(action_result,
                                                  endpoint,
                                                  False,
                                                  method=requests.post,
                                                  headers=headers,
                                                  body=params)

        if not ret_val:
            return ret_val

        if not resp_json.get('ok', True):
            error = resp_json.get('error', 'N/A')
            error_details = self._handle_py_ver_compat_for_input_str(
                resp_json.get('detail', ''))
            if error_details:
                error_message = "{}: {}\r\nDetails: {}".format(
                    SLACK_ERR_CREATING_CHANNEL, error, error_details)
            else:
                error_message = "{}: {}".format(SLACK_ERR_CREATING_CHANNEL,
                                                error)
            return action_result.set_status(phantom.APP_ERROR, error_message)

        action_result.add_data(resp_json)

        return action_result.set_status(phantom.APP_SUCCESS,
                                        SLACK_SUCC_CHANNEL_CREATED)
Пример #13
0
    def _stop_bot(self, param):

        action_result = self.add_action_result(phantom.ActionResult(dict(param)))

        pid = self._state.get('pid', '')
        if pid:

            self._state.pop('pid')

            try:
                if 'slack_bot.pyc' in sh.ps('ww', pid):  # pylint: disable=E1101
                    sh.kill(pid)  # pylint: disable=E1101
                    action_result.set_status(phantom.APP_SUCCESS, "SlackBot has been stopped.")

            except:
                action_result.set_status(phantom.APP_SUCCESS, "SlackBot isn't running, not going to stop it.")

        else:
            action_result.set_status(phantom.APP_SUCCESS, "SlackBot isn't running, not going to stop it.")

        rest_url = consts.SLACK_PHANTOM_ASSET_INFO_URL.format(url=self.get_phantom_base_url(), asset_id=self.get_asset_id())

        ret_val, resp_json = self._make_rest_call(action_result, rest_url, False)

        if phantom.is_fail(ret_val):
            return ret_val

        asset_config = resp_json.get('configuration', {})

        ingest_config = asset_config.get('ingest', {})

        poll = ingest_config.get('poll')

        if poll is None:
            return action_result.set_status(phantom.APP_SUCCESS, "{} Failed to disable ingestion, please check that ingest settings are correct."
                    .format(action_result.get_message()))

        if not poll:
            return action_result.set_status(phantom.APP_SUCCESS, "{} Ingestion isn't enabled, not going to disable it.".format(action_result.get_message()))

        ingest_config['poll'] = False

        body = {'configuration': asset_config}

        ret_val, resp_json = self._make_rest_call(action_result, rest_url, False, method=requests.post, body=body)

        if phantom.is_fail(ret_val):
            return ret_val

        return action_result.set_status(phantom.APP_SUCCESS, "{} Ingestion has been disabled.".format(action_result.get_message()))
Пример #14
0
    def _on_poll(self, param):
        """
        Keep phantom containers up-to-date with data from redmine
        """

        # Add action result
        action_result = self.add_action_result(phantom.ActionResult(dict(param)))

        last_run = self._state.get("last_run")
        max_tickets = None
        backfill = datetime.now() - timedelta(REDMINE_BACKFILL_DAYS)

        if self.is_poll_now():
            self.debug_print("Run Mode: Poll Now")

            # Integer validation for 'maximum containers' configuration parameter
            max_tickets = param[phantom.APP_JSON_CONTAINER_COUNT]
            ret_val, max_tickets = self._validate_integer(action_result, max_tickets, REDMINE_CONTAINER_COUNT_KEY)
            if phantom.is_fail(ret_val):
                return action_result.get_status()
            last_run = backfill
        else:
            if not last_run:
                self.debug_print("Run Mode: First Scheduled Poll")
                last_run = backfill
            else:
                self.debug_print("Run Mode: Scheduled Poll")
                last_run = dateutil.parser.isoparse(last_run)

        self.debug_print(f"Last Run: {last_run}")

        tickets = []
        try:
            ret_val, tickets = self._retrieve_tickets(
                action_result, last_run, max_tickets
            )
            if phantom.is_fail(ret_val):
                return action_result.get_status()
        except Exception as e:
            error_msg = self._get_error_message_from_exception(e)
            return action_result.set_status(
                phantom.APP_ERROR, REDMINE_ERR_FETCHING_TICKETS.format(error=error_msg)
            )

        self.debug_print(f"Total tickets fetched: {len(tickets)}")
        self.save_progress(f"Total tickets fetched: {len(tickets)}")
        for ticket in tickets:
            self._save_ticket_container(action_result, ticket)

        return action_result.set_status(phantom.APP_SUCCESS)
Пример #15
0
    def _list_alerts(self, param):

        self.debug_print(param)
        action_result = self.add_action_result(phantom.ActionResult(param))
        incident_id = param.get('id')
        limit = int(param.get('limit', consts.RSASA_DEFAULT_ALERT_LIMIT))

        ret_val, alerts = self._get_alerts(action_result, incident_id, limit)

        if not ret_val:
            return ret_val

        action_result.add_data(alerts)
        action_result.set_summary({"num_alerts": len(alerts)})

        return action_result.set_status(phantom.APP_SUCCESS)
Пример #16
0
    def _invite_users(self, param):

        action_result = self.add_action_result(phantom.ActionResult(dict(param)))

        user_token = self.get_config().get('user_token')

        if not user_token:
            return action_result.set_status(phantom.APP_ERROR, "user_token is required for this action. Navigate to the asset's configuration and add a token now and try again.")

        headers = {
            "Authorization": "Bearer " + user_token,
            'Content-Type': 'application/json'
        }

        users = [x.strip() for x in param['users'].split(',')]
        users = list(filter(None, users))

        params = {
            'users': users,
            'channel': param['channel_id'],
            'token': user_token
        }

        endpoint = consts.SLACK_BASE_URL + consts.SLACK_INVITE_TO_CHANNEL

        ret_val, resp_json = self._make_rest_call(
            action_result,
            endpoint,
            False,
            method=requests.post,
            headers=headers,
            body=params
        )

        if not ret_val:
            return ret_val

        if not resp_json.get('ok', True):
            return action_result.set_status(
                phantom.APP_ERROR,
                "Error inviting to channel: {}\r\nDetails: {}".format(self._handle_py_ver_compat_for_input_str(resp_json.get('error', 'N/A')),
                self._handle_py_ver_compat_for_input_str(resp_json.get('detail', '')))
            )

        action_result.add_data(resp_json)

        return action_result.set_status(phantom.APP_SUCCESS, "Invite sent to user(s)")
Пример #17
0
    def _create_channel(self, param):

        action_result = self.add_action_result(phantom.ActionResult(dict(param)))

        user_token = self.get_config().get('user_token')

        if not user_token:
            return action_result.set_status(phantom.APP_ERROR, "user_token is required for this action. Navigate to the asset's configuration and add a token now and try again.")

        headers = {
            "Authorization": "Bearer " + user_token,
            'Content-Type': 'application/json'
        }

        params = {
            'name': param['name'],
            'token': user_token,
            'validate': True
        }
        endpoint = consts.SLACK_BASE_URL + consts.SLACK_CHANNEL_CREATE_ENDPOINT

        # private channel
        if param['channel_type'] == "private":
            params.update({"is_private": True})

        ret_val, resp_json = self._make_rest_call(
            action_result,
            endpoint,
            False,
            method=requests.post,
            headers=headers,
            body=params
        )

        if not ret_val:
            return ret_val

        if not resp_json.get('ok', True):
            return action_result.set_status(
                phantom.APP_ERROR,
                "Error creating channel: {}\r\nDetails: {}".format(self._handle_py_ver_compat_for_input_str(resp_json.get('error', 'N/A')),
                self._handle_py_ver_compat_for_input_str(resp_json.get('detail', '')))
            )

        action_result.add_data(resp_json)

        return action_result.set_status(phantom.APP_SUCCESS)
Пример #18
0
    def _list_incidents(self, param):

        self.debug_print(param)
        action_result = self.add_action_result(phantom.ActionResult(param))

        max_incidents = param.get('limit', consts.RSASA_DEFAULT_INCIDENT_LIMIT)
        start_time = param.get('start_time')
        end_time = param.get('end_time')

        epoch = datetime.utcfromtimestamp(0)

        end_epoch = 0
        start_epoch = 0
        if start_time or end_time:

            try:

                if start_time:
                    start_epoch = int(
                        (datetime.strptime(start_time, "%Y-%m-%d %H:%M:%S") -
                         epoch).total_seconds() * 1000)
                else:
                    start_epoch = consts.RSASA_DEFAULT_START_TIME

                if end_time:
                    end_epoch = int(
                        (datetime.strptime(end_time, "%Y-%m-%d %H:%M:%S") -
                         epoch).total_seconds() * 1000)
                else:
                    end_epoch = int(time.time() * 1000)

            except ValueError as e:
                return action_result.set_status(phantom.APP_ERROR, str(e))

        ret_val, incidents = self._get_incidents(action_result,
                                                 max_incidents,
                                                 start_epoch,
                                                 end_epoch,
                                                 sort='DESC')

        if not ret_val:
            return ret_val

        action_result.add_data(incidents)
        action_result.set_summary({"num_incidents": len(incidents)})

        return action_result.set_status(phantom.APP_SUCCESS)
Пример #19
0
    def _send_message(self, param):

        action_result = self.add_action_result(
            phantom.ActionResult(dict(param)))

        message = self._handle_py_ver_compat_for_input_str(param['message'])

        if '\\' in message:
            if self._python_version == 2:
                message = message.decode('string_escape')
            else:
                message = bytes(message, "utf-8").decode("unicode_escape")

        if len(message) > SLACK_MESSAGE_LIMIT:
            return action_result.set_status(
                phantom.APP_ERROR,
                SLACK_ERR_MESSAGE_TOO_LONG.format(limit=SLACK_MESSAGE_LIMIT))

        params = {'channel': param['destination'], 'text': message}

        if 'parent_message_ts' in param:
            # Support for replying in thread
            params['thread_ts'] = param.get('parent_message_ts')

            if 'reply_broadcast' in param:
                params['reply_broadcast'] = param.get('reply_broadcast', False)

        ret_val, resp_json = self._make_slack_rest_call(
            action_result, SLACK_SEND_MESSAGE, params)

        if not ret_val:
            message = action_result.get_message()
            if message:
                error_message = "{}: {}".format(SLACK_ERR_SENDING_MESSAGE,
                                                message)
            else:
                error_message = SLACK_ERR_SENDING_MESSAGE
            return action_result.set_status(phantom.APP_ERROR, error_message)

        action_result.add_data(resp_json)

        return action_result.set_status(phantom.APP_SUCCESS,
                                        SLACK_SUCC_MESSAGE_SENT)
Пример #20
0
    def _get_user(self, param):

        self.debug_print("param", param)
        action_result = self.add_action_result(
            phantom.ActionResult(dict(param)))

        user_id = param['user_id']

        if not user_id.startswith('U'):
            return action_result.set_status(phantom.APP_ERROR,
                                            SLACK_ERR_NOT_A_USER_ID)

        ret_val, resp_json = self._make_slack_rest_call(
            action_result, SLACK_USER_INFO, {'user': user_id})

        if not ret_val:
            message = action_result.get_message()
            if message:
                error_message = "{}: {}".format(SLACK_ERR_FETCHING_USER,
                                                message)
            else:
                error_message = SLACK_ERR_FETCHING_USER
            return action_result.set_status(phantom.APP_ERROR, error_message)

        action_result.add_data(resp_json)

        user = resp_json.get('user')

        if not user:
            return action_result.set_status(
                phantom.APP_ERROR,
                SLACK_ERR_DATA_NOT_FOUND_IN_OUTPUT.format(key="User"))

        name = user.get('name', '')
        user['name'] = '@{}'.format(name)

        return action_result.set_status(phantom.APP_SUCCESS,
                                        SLACK_SUCC_USER_DATA_RETRIEVED)
Пример #21
0
    def _get_response(self, param):

        action_result = self.add_action_result(phantom.ActionResult(dict(param)))

        qid = self._handle_py_ver_compat_for_input_str(param['question_id'])
        state_dir = self.get_state_dir()
        answer_path = '{0}/{1}.json'.format(state_dir, qid)

        self.save_progress('Checking for response to question with ID: {0}'.format(qid))

        try:
            answer_file = open(answer_path, 'r')
        except:
            return action_result.set_status(phantom.APP_ERROR, "Response to question not available")

        try:
            resp_json = json.loads(answer_file.read())
        except:
            return action_result.set_status(phantom.APP_ERROR, "Error occurred while parsing the response")

        action_result.add_data(resp_json)
        action_result.set_summary({'response_received': True, 'response': resp_json.get("actions", [{}])[0].get("value")})

        return action_result.set_status(phantom.APP_SUCCESS)
Пример #22
0
    def _on_poll(self, param):

        action_result = self.add_action_result(phantom.ActionResult(param))

        config = self.get_config()

        # Get the maximum number of tickets that we can poll, same as container count
        if self.is_poll_now():
            try:
                max_containers = int(param[phantom.APP_JSON_CONTAINER_COUNT])
            except:
                return action_result.set_status(phantom.APP_ERROR,
                                                "Invalid Container count")

        else:
            max_containers = config['max_incidents']

        start_time, end_time = self._get_time_range()

        self.save_progress(
            "Getting incident IDs generated\nFrom: {0}\nTo: {1}".format(
                time.strftime("%Y-%m-%dT%H:%M:%SZ",
                              time.gmtime(start_time / 1000)),
                time.strftime("%Y-%m-%dT%H:%M:%SZ",
                              time.gmtime(end_time / 1000))))

        # get the incidents
        ret_val, incidents = self._get_incidents(action_result, max_containers,
                                                 start_time, end_time)

        if phantom.is_fail(ret_val):
            return action_result.get_status()

        if not incidents:
            return action_result.set_status(phantom.APP_SUCCESS,
                                            consts.RSASA_NO_INCIDENTS)

        for incident in incidents:

            ret_val, alerts = self._get_alerts(action_result,
                                               incident.get('id'), 0)

            incident['alerts'] = alerts

            if phantom.is_fail(ret_val):
                self.debug_print("get alert failed with: {0}".format(
                    action_result.get_message()))

            for alert in alerts:

                ret_val, events = self._get_events(action_result,
                                                   alert.get('id'), 0)

                alert['events'] = events

                if phantom.is_fail(ret_val):
                    self.debug_print("get event failed with: {0}".format(
                        action_result.get_message()))

                for event in events:

                    self._extract_device_and_hash(event)

        self.save_progress("Got {0} incidents".format(len(incidents)))

        if not self.is_poll_now():
            if len(incidents) == int(max_containers):
                self._state[
                    consts.
                    RSASA_JSON_LAST_DATE_TIME] = incidents[-1]['created'] + 1
            else:
                self._state[consts.RSASA_JSON_LAST_DATE_TIME] = end_time + 1

        results = pi.parse_incidents(incidents, self)

        self._parse_results(action_result, param, results)

        # blank line to update the last status message
        self.send_progress('')

        return action_result.set_status(phantom.APP_SUCCESS)
Пример #23
0
    def _upload_file(self, param):

        self.debug_print("param", param)
        action_result = self.add_action_result(phantom.ActionResult(dict(param)))

        caption = param.get('caption', '')

        if caption:
            caption += ' -- '

        caption += 'Uploaded from Phantom'

        vault_id = param['file']

        # check the vault for a file with the supplied ID
        try:
            file_info = Vault.get_file_info(vault_id)
            if not file_info:
                return action_result.set_status(phantom.APP_ERROR, consts.SLACK_ERR_UNABLE_TO_FETCH_FILE.format(key="info"))

            file_path = file_info[0].get("path")
            if not file_path:
                return action_result.set_status(phantom.APP_ERROR, consts.SLACK_ERR_UNABLE_TO_FETCH_FILE.format(key="path"))

            file_name = file_info[0].get("name")
            if not file_name:
                return action_result.set_status(phantom.APP_ERROR, consts.SLACK_ERR_UNABLE_TO_FETCH_FILE.format(key="name"))
        except:
            return action_result.set_status(phantom.APP_ERROR, "Could not find the specified Vault ID in vault")

        upfile = open(file_path, 'rb')

        params = {'channels': param['destination'], 'initial_comment': caption, 'filename': file_name}

        ret_val, resp_json = self._make_slack_rest_call(action_result, consts.SLACK_UPLOAD_FILE, params, files={'file': upfile})

        if not ret_val:
            return ret_val

        file_json = resp_json.get('file', {})

        thumbnail_dict = {}
        pop_list = []

        for key, value in list(file_json.items()):

            if key.startswith('thumb'):

                pop_list.append(key)

                name_arr = key.split('_')

                thumb_name = "{0}_{1}".format(name_arr[0], name_arr[1])

                if thumb_name not in thumbnail_dict:
                    thumbnail_dict[thumb_name] = {}

                thumb_dict = thumbnail_dict[thumb_name]

                if len(name_arr) == 2:
                    thumb_dict['img_url'] = value

                elif name_arr[2] == 'w':
                    thumb_dict['width'] = value

                elif name_arr[2] == 'h':
                    thumb_dict['height'] = value

            elif key == 'initial_comment':
                resp_json['caption'] = value
                pop_list.append(key)

            elif key in ['channels', 'ims', 'groups']:

                if 'destinations' not in resp_json:
                    resp_json['destinations'] = []

                resp_json['destinations'] += value

                pop_list.append(key)

            elif key == 'username':
                pop_list.append(key)

            elif key == 'user':
                resp_json['sender'] = value
                pop_list.append(key)

        for poppee in pop_list:
            file_json.pop(poppee)

        resp_json['thumbnails'] = thumbnail_dict

        action_result.add_data(resp_json)

        return action_result.set_status(phantom.APP_SUCCESS, "File uploaded successfully.")
Пример #24
0
    def _ask_question(self, param):

        action_result = self.add_action_result(
            phantom.ActionResult(dict(param)))
        config = self.get_config()

        local_data_state_dir = self.get_state_dir().rstrip('/')
        self._state['local_data_path'] = local_data_state_dir
        # Need to make sure the configured verification token is in the app state so the request_handler can use it to verify POST requests
        if 'token' not in self._state:
            self._state['token'] = config[SLACK_JSON_VERIFICATION_TOKEN]
            self.save_state(self._state)
        elif self._state['token'] != config[SLACK_JSON_VERIFICATION_TOKEN]:
            self._state['token'] = config[SLACK_JSON_VERIFICATION_TOKEN]
            self.save_state(self._state)

        # The default permission of state file in Phantom v4.9 is 600. So when from rest handler method (handle_request) reads this state file,
        # the action fails with "permission denied" error message
        # Adding the data of state file to another temporary file to resolve this issue
        _save_app_state(self._state, self.get_asset_id(), self)

        question = param['question']
        if len(question) > SLACK_MESSAGE_LIMIT:
            return action_result.set_status(
                phantom.APP_ERROR,
                SLACK_ERR_QUESTION_TOO_LONG.format(limit=SLACK_MESSAGE_LIMIT))

        user = param['destination']
        if user.startswith('#') or user.startswith('C'):
            # Don't want to send question to channels because then we would not know who was answering
            return action_result.set_status(
                phantom.APP_ERROR,
                SLACK_ERR_UNABLE_TO_SEND_QUESTION_TO_CHANNEL)

        qid = uuid.uuid4().hex

        answer_filename = '{0}.json'.format(qid)
        answer_path = "{0}/{1}".format(local_data_state_dir, answer_filename)

        path_json = {
            'qid': qid,
            'asset_id': str(self.get_asset_id()),
            'confirmation': param.get('confirmation', ' ')
        }

        callback_id = json.dumps(path_json)
        if len(callback_id) > 255:
            path_json['confirmation'] = ''
            valid_length = 255 - len(json.dumps(path_json))
            return action_result.set_status(
                phantom.APP_ERROR,
                SLACK_ERR_LENGTH_LIMIT_EXCEEDED.format(
                    asset_length=len(self.get_asset_id()),
                    valid_length=valid_length))

        self.save_progress('Asking question with ID: {0}'.format(qid))

        answers = []
        given_answers = [
            x.strip() for x in param.get('responses', 'yes,no').split(',')
        ]
        given_answers = list(filter(None, given_answers))
        for answer in given_answers:
            answer_json = {
                'name': answer,
                'text': answer,
                'value': answer,
                'type': 'button'
            }
            answers.append(answer_json)

        answer_json = [{
            'text': question,
            'fallback': 'Phantom cannot post questions on this channel.',
            'callback_id': callback_id,
            'color': '#422E61',
            'attachment_type': 'default',
            'actions': answers
        }]

        params = {
            'channel': user,
            'attachments': json.dumps(answer_json),
            'as_user': True
        }

        ret_val, resp_json = self._make_slack_rest_call(
            action_result, SLACK_SEND_MESSAGE, params)
        if not ret_val:
            message = action_result.get_message()
            if message:
                error_message = "{}: {}".format(SLACK_ERR_ASKING_QUESTION,
                                                message)
            else:
                error_message = SLACK_ERR_ASKING_QUESTION
            return action_result.set_status(phantom.APP_ERROR, error_message)

        loop_count = (self._timeout * 60) / self._interval
        count = 0

        while True:

            if count >= loop_count:
                action_result.set_summary({
                    'response_received': False,
                    'question_id': qid
                })
                return action_result.set_status(phantom.APP_SUCCESS)

            try:
                answer_file = open(answer_path, 'r')
            except:
                count += 1
                time.sleep(self._interval)
                continue

            try:
                resp_json = json.loads(answer_file.read())
                answer_file.close()
            except:
                return action_result.set_status(
                    phantom.APP_ERROR, SLACK_ERR_UNABLE_TO_PARSE_RESPONSE)

            break

        action_result.add_data(resp_json)
        action_result.set_summary({
            'response_received':
            True,
            'question_id':
            qid,
            'response':
            resp_json.get("actions", [{}])[0].get("value")
        })

        os.remove(answer_path)

        return action_result.set_status(phantom.APP_SUCCESS)
Пример #25
0
    def _upload_file(self, param):

        action_result = self.add_action_result(
            phantom.ActionResult(dict(param)))

        caption = param.get('caption', '')

        if caption:
            caption += ' -- '

        caption += 'Uploaded from Phantom'

        kwargs = {}
        params = {'channels': param['destination'], 'initial_comment': caption}

        if 'filetype' in param:
            params['filetype'] = param.get('filetype')

        if 'filename' in param:
            params['filename'] = param.get('filename')

        if 'parent_message_ts' in param:
            # Support for replying in thread
            params['thread_ts'] = param.get('parent_message_ts')

        if 'file' in param:
            vault_id = param.get('file')

            # check the vault for a file with the supplied ID
            try:
                success, message, vault_meta_info = ph_rules.vault_info(
                    vault_id=vault_id)
                vault_meta_info = list(vault_meta_info)
                if not success or not vault_meta_info:
                    error_msg = " Error Details: {}".format(
                        unquote(message)) if message else ''
                    return action_result.set_status(
                        phantom.APP_ERROR, "{}.{}".format(
                            SLACK_ERR_UNABLE_TO_FETCH_FILE.format(key="info"),
                            error_msg))
            except Exception as e:
                err = self._get_error_message_from_exception(e)
                return action_result.set_status(
                    phantom.APP_ERROR, "{}. {}".format(
                        SLACK_ERR_UNABLE_TO_FETCH_FILE.format(key="info"),
                        err))

            # phantom vault file path
            file_path = vault_meta_info[0].get('path')
            if not file_path:
                return action_result.set_status(
                    phantom.APP_ERROR,
                    SLACK_ERR_UNABLE_TO_FETCH_FILE.format(key="path"))

            # phantom vault file name
            file_name = vault_meta_info[0].get('name')
            if not file_name:
                return action_result.set_status(
                    phantom.APP_ERROR,
                    SLACK_ERR_UNABLE_TO_FETCH_FILE.format(key="name"))

            upfile = open(file_path, 'rb')
            params['filename'] = file_name
            kwargs['files'] = {'file': upfile}
        elif 'content' in param:
            params['content'] = self._handle_py_ver_compat_for_input_str(
                param.get('content'))
        else:
            return action_result.set_status(
                phantom.APP_ERROR, SLACK_ERR_FILE_OR_CONTENT_NOT_PROVIDED)

        ret_val, resp_json = self._make_slack_rest_call(
            action_result, SLACK_UPLOAD_FILE, params, **kwargs)
        if 'files' in kwargs:
            upfile.close()

        if not ret_val:
            message = action_result.get_message()
            if message:
                error_message = "{}: {}".format(SLACK_ERR_UPLOADING_FILE,
                                                message)
            else:
                error_message = SLACK_ERR_UPLOADING_FILE
            return action_result.set_status(phantom.APP_ERROR, error_message)

        file_json = resp_json.get('file', {})

        thumbnail_dict = {}
        pop_list = []

        for key, value in list(file_json.items()):

            if key.startswith('thumb'):

                pop_list.append(key)

                name_arr = key.split('_')

                thumb_name = "{0}_{1}".format(name_arr[0], name_arr[1])

                if thumb_name not in thumbnail_dict:
                    thumbnail_dict[thumb_name] = {}

                thumb_dict = thumbnail_dict[thumb_name]

                if len(name_arr) == 2:
                    thumb_dict['img_url'] = value

                elif name_arr[2] == 'w':
                    thumb_dict['width'] = value

                elif name_arr[2] == 'h':
                    thumb_dict['height'] = value

            elif key == 'initial_comment':
                resp_json['caption'] = value
                pop_list.append(key)

            elif key in ['channels', 'ims', 'groups']:

                if 'destinations' not in resp_json:
                    resp_json['destinations'] = []

                resp_json['destinations'] += value

                pop_list.append(key)

            elif key == 'username':
                pop_list.append(key)

            elif key == 'user':
                resp_json['sender'] = value
                pop_list.append(key)

        for poppee in pop_list:
            file_json.pop(poppee)

        resp_json['thumbnails'] = thumbnail_dict

        action_result.add_data(resp_json)

        return action_result.set_status(phantom.APP_SUCCESS,
                                        SLACK_SUCC_FILE_UPLOAD)
Пример #26
0
    def _handle_get_pcap(self, param):
        """ Request PCAP download, get status, and save to disk.

        Args:
            param (dict): Parameters sent in by a user or playbook

        Returns:
            ActionResult:
                * str: status success/failure
                * str: message
        """

        action_result = self.add_action_result(
            phantom.ActionResult(dict(param)))
        summary_data = action_result.update_summary(
            {'pcap_id': param['pcap_id']})

        endpoint = "datamines/{}/download/download.pcap".format(
            param['pcap_id'])

        self.send_progress('Download starting')
        # Start download of PCAP file
        dl_ret_val, dl_response = self._make_rest_call(endpoint,
                                                       action_result,
                                                       method='get')

        # Check if something went wrong with the request
        if phantom.is_fail(dl_ret_val):
            return action_result.get_status()

        self.send_progress('Checking status of download')
        # Run get_status to check if the download fully completed or if it had been canceled
        endpoint = "datamines/{}".format(param['pcap_id'])
        status_ret_val, status_response = self._make_rest_call(endpoint,
                                                               action_result,
                                                               method='get')

        all_response = {'status': status_response}

        if phantom.is_fail(status_ret_val):
            return action_result.get_status()

        state = status_response.get('datamine', {}).get('status',
                                                        {}).get('state', None)
        summary_data['state'] = state
        if state != 'COMPLETED':
            action_result.add_data(all_response)
            return action_result.set_status(
                phantom.APP_ERROR, 'Error downloading file. {}'.format(state))

        filename = "{}.pcap".format(param['pcap_id'])

        self.send_progress('Saving file to disk')
        # Creating file
        temp_dir = tempfile.mkdtemp()
        try:
            file_path = os.path.join(temp_dir, filename)
            with open(file_path, 'wb') as file_obj:
                file_obj.write(dl_response)
        except Exception as e:
            self.debug_print('Error creating file')
            shutil.rmtree(temp_dir)
            err_msg = self._get_error_message_from_exception(e)
            return action_result.set_status(
                phantom.APP_ERROR,
                'Error creating file. Error Details: {}'.format(err_msg))

        container_id = self.get_container_id()

        # Check if file with same file name and size is available in vault and save only if it is not available
        try:
            vault_list = Vault.vault_info(container_id=container_id)
        except Exception as e:
            err_msg = self._get_error_message_from_exception(e)
            return action_result.set_status(
                phantom.APP_ERROR,
                'Unable to get Vault item details from Phantom. Details: {0}'.
                format(err_msg))

        vault_details = {}
        try:
            # Iterate through each vault item in the container and compare name and size of file
            for vault in vault_list[2]:
                if vault.get('name') == filename and vault.get(
                        'size') == os.path.getsize(file_path):
                    self.send_progress('PCAP already available in Vault')
                    vault_details = {
                        phantom.APP_JSON_SIZE:
                        vault.get('size'),
                        phantom.APP_JSON_VAULT_ID:
                        vault.get(phantom.APP_JSON_VAULT_ID),
                        'filename':
                        filename
                    }
        except Exception as e:
            err_msg = self._get_error_message_from_exception(e)
            return action_result.set_status(
                phantom.APP_ERROR, 'Error details: {}'.format(err_msg))

        if not vault_details:
            vault_ret_val, vault_details = self._move_file_to_vault(
                container_id, os.path.getsize(file_path), 'pcap', file_path,
                action_result)
            # Check if something went wrong while moving file to vault
            if phantom.is_fail(vault_ret_val):
                return action_result.set_status(
                    phantom.APP_ERROR, 'Could not move file to vault')

        shutil.rmtree(temp_dir)

        summary_data['file_availability'] = True
        summary_data[phantom.APP_JSON_VAULT_ID] = vault_details[
            phantom.APP_JSON_VAULT_ID]

        all_response['vault'] = vault_details
        action_result.add_data(all_response)

        message = 'PCAP downloaded to Vault: {0}'.format(
            vault_details[phantom.APP_JSON_VAULT_ID])

        return action_result.set_status(phantom.APP_SUCCESS, message)
Пример #27
0
    def _on_poll(self, param):

        action_result = self.add_action_result(
            phantom.ActionResult(dict(param)))

        ret_val, resp_json = self._make_slack_rest_call(
            action_result, SLACK_AUTH_TEST, {})

        if not ret_val:
            return ret_val

        bot_id = resp_json.get('user_id')

        if not bot_id:
            return action_result.set_status(phantom.APP_ERROR,
                                            SLACK_ERR_COULD_NOT_GET_BOT_ID)

        pid = self._state.get('pid', '')

        if pid:

            try:
                if 'slack_bot.pyc' in sh.ps('ww', pid):  # pylint: disable=E1101
                    self.save_progress(
                        "Detected SlackBot running with pid {0}".format(pid))
                    return action_result.set_status(
                        phantom.APP_SUCCESS, SLACK_SUCC_SLACKBOT_RUNNING)
            except:
                pass

        config = self.get_config()
        bot_token = config.get('bot_token', '')
        ph_auth_token = config.get('ph_auth_token', None)

        if not ph_auth_token:
            return action_result.set_status(phantom.APP_ERROR,
                                            SLACK_ERR_AUTH_TOKEN_NOT_PROVIDED)

        app_version = self.get_app_json().get('app_version', '')

        try:
            ps_out = sh.grep(sh.ps('ww', 'aux'), 'slack_bot.pyc')  # pylint: disable=E1101

            if app_version not in ps_out:

                old_pid = shlex.split(str(ps_out))[1]

                self.save_progress(
                    "Found an old version of slackbot running with pid {}, going to kill it"
                    .format(old_pid))

                sh.kill(old_pid)  # pylint: disable=E1101

        except:
            pass

        try:
            if bot_token in sh.grep(sh.ps('ww', 'aux'), 'slack_bot.pyc'):  # pylint: disable=E1101
                return action_result.set_status(
                    phantom.APP_ERROR,
                    SLACK_ERR_SLACKBOT_RUNNING_WITH_SAME_BOT_TOKEN)

        except:
            pass

        self.save_progress("Starting SlackBot")

        ret_val, base_url = self._get_phantom_base_url_slack(action_result)

        if phantom.is_fail(ret_val):
            return ret_val

        slack_bot_filename = os.path.join(
            os.path.dirname(os.path.realpath(__file__)), 'slack_bot.pyc')

        base_url += '/' if not base_url.endswith('/') else ''

        proc = subprocess.Popen([
            'phenv', 'python2.7', slack_bot_filename, bot_token, bot_id,
            base_url, app_version, ph_auth_token
        ])

        self._state['pid'] = proc.pid

        self.save_progress("Started SlackBot with pid: {0}".format(proc.pid))

        return action_result.set_status(phantom.APP_SUCCESS,
                                        SLACK_SUCC_SLACKBOT_STARTED)
Пример #28
0
    def _on_poll(self, param):

        action_result = self.add_action_result(phantom.ActionResult(dict(param)))

        ret_val, resp_json = self._make_slack_rest_call(action_result, consts.SLACK_AUTH_TEST, {})

        if not ret_val:
            return ret_val

        bot_id = resp_json.get('user_id')

        if not bot_id:
            return action_result.set_status(phantom.APP_ERROR, "Could not get bot ID from Slack")

        pid = self._state.get('pid', '')

        if pid:

            try:
                if 'slack_bot.pyc' in sh.ps('ww', pid):  # pylint: disable=E1101
                    self.save_progress("Detected SlackBot running with pid {0}".format(pid))
                    return action_result.set_status(phantom.APP_SUCCESS, "SlackBot already running")
            except:
                pass

        config = self.get_config()
        bot_token = config.get('bot_token', '')
        ph_auth_token = config.get('ph_auth_token', None)

        if not ph_auth_token:
            return action_result.set_status(phantom.APP_ERROR, "The ph_auth_token asset configuration parameter is required to run the on_poll action.")

        app_version = self.get_app_json().get('app_version', '')

        try:
            ps_out = sh.grep(sh.ps('ww', 'aux'), 'slack_bot.pyc')  # pylint: disable=E1101

            if app_version not in ps_out:

                old_pid = shlex.split(str(ps_out))[1]

                self.save_progress("Found an old version of slackbot running with pid {}, going to kill it".format(old_pid))

                sh.kill(old_pid)  # pylint: disable=E1101

        except:
            pass

        try:
            if bot_token in sh.grep(sh.ps('ww', 'aux'), 'slack_bot.pyc'):  # pylint: disable=E1101
                return action_result.set_status(phantom.APP_ERROR, "Detected an instance of SlackBot running with the same bot token. Not going to start new instance.")

        except:
            pass

        self.save_progress("Starting SlackBot")

        ret_val, base_url = self._get_phantom_base_url_slack(action_result)

        if phantom.is_fail(ret_val):
            return ret_val

        slack_bot_filename = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'slack_bot.pyc')

        base_url += '/' if not base_url.endswith('/') else ''

        proc = subprocess.Popen(['phenv', 'python2.7', slack_bot_filename, bot_token, bot_id, base_url, app_version, ph_auth_token])

        self._state['pid'] = proc.pid

        self.save_progress("Started SlackBot with pid: {0}".format(proc.pid))

        return action_result.set_status(phantom.APP_SUCCESS, "SlackBot started")
Пример #29
0
    def _ask_question(self, param):

        action_result = self.add_action_result(phantom.ActionResult(dict(param)))
        config = self.get_config()

        # Need to make sure the configured verification token is in the app state so the request_handler can use it to verify POST requests
        if 'token' not in self._state:
            self._state['token'] = config[consts.SLACK_JSON_VERIFICATION_TOKEN]
            self.save_state(self._state)
        elif self._state['token'] != config[consts.SLACK_JSON_VERIFICATION_TOKEN]:
            self._state['token'] = config[consts.SLACK_JSON_VERIFICATION_TOKEN]
            self.save_state(self._state)

        # The default permission of state file in Phantom v4.9 is 600. So when from rest handler method (handle_request) reads this state file,
        # the action fails with "permission denied" error message
        # Adding the data of state file to another temporary file to resolve this issue
        _save_app_state(self._state, self.get_asset_id(), self)

        question = param['question']
        if len(question) > consts.SLACK_MESSAGE_LIMIT:
            return action_result.set_status(phantom.APP_ERROR, "Question too long. Please limit questions to {0} characters.".format(consts.SLACK_MESSAGE_LIMIT))

        user = param['destination']
        if user.startswith('#') or user.startswith('C'):
            # Don't want to send question to channels because then we would not know who was answering
            return action_result.set_status(phantom.APP_ERROR, "Questions may only be sent as direct messages to users. They may not be sent to channels.")

        qid = uuid.uuid4().hex
        apps_state_dir = os.path.dirname(os.path.abspath(__file__))
        local_data_state_dir = self.get_state_dir()
        state_dir = "{0},{1}".format(apps_state_dir, local_data_state_dir)

        answer_filename = '{0}.json'.format(qid)
        state_filename = "{0}_state.json".format(self.get_asset_id())

        path_json = {'answer': answer_filename,
                     'state': state_filename,
                     'directory': state_dir,
                     'confirmation': param.get('confirmation', ' ')}

        self.save_progress('Asking question with ID: {0}'.format(qid))

        answers = []
        given_answers = [x.strip() for x in param.get('responses', 'yes,no').split(',')]
        given_answers = list(filter(None, given_answers))
        for answer in given_answers:
            answer_json = {'name': answer, 'text': answer, 'value': answer, 'type': 'button'}
            answers.append(answer_json)

        answer_json = [
                        {
                          'text': question,
                          'fallback': 'Phantom cannot post questions on this channel.',
                          'callback_id': json.dumps(path_json),
                          'color': '#422E61',
                          'attachment_type': 'default',
                          'actions': answers
                        }
                      ]

        params = {'channel': user, 'attachments': json.dumps(answer_json), 'as_user': True}

        ret_val, resp_json = self._make_slack_rest_call(action_result, consts.SLACK_SEND_MESSAGE, params)
        if not ret_val:
            return phantom.APP_ERROR

        answer_path = "{0}/{1}".format(local_data_state_dir, answer_filename)
        loop_count = (self._timeout * 60) / self._interval
        count = 0

        while True:

            if count >= loop_count:
                action_result.set_summary({'response_received': False, 'question_id': qid})
                return action_result.set_status(phantom.APP_SUCCESS)

            try:
                answer_file = open(answer_path, 'r')
            except:
                count += 1
                time.sleep(self._interval)
                continue

            resp_json = json.loads(answer_file.read())

            break

        action_result.add_data(resp_json)
        action_result.set_summary({'response_received': True, 'question_id': qid, 'response': resp_json.get("actions", [{}])[0].get("value")})

        os.remove(answer_path)

        return action_result.set_status(phantom.APP_SUCCESS)
Пример #30
0
    def _stop_bot(self, param):

        action_result = self.add_action_result(
            phantom.ActionResult(dict(param)))

        pid = self._state.get('pid', '')
        if pid:

            self._state.pop('pid')

            try:
                if 'slack_bot.pyc' in sh.ps('ww', pid):  # pylint: disable=E1101
                    sh.kill(pid)  # pylint: disable=E1101
                    action_result.set_status(phantom.APP_SUCCESS,
                                             SLACK_SUCC_SLACKBOT_STOPPED)

            except:
                action_result.set_status(phantom.APP_SUCCESS,
                                         SLACK_SUCC_SLACKBOT_NOT_RUNNING)

        else:
            action_result.set_status(phantom.APP_SUCCESS,
                                     SLACK_SUCC_SLACKBOT_NOT_RUNNING)

        rest_url = SLACK_PHANTOM_ASSET_INFO_URL.format(
            url=self.get_phantom_base_url(), asset_id=self.get_asset_id())

        ret_val, resp_json = self._make_rest_call(action_result, rest_url,
                                                  False)

        if phantom.is_fail(ret_val):
            return ret_val

        asset_config = resp_json.get('configuration', {})

        ingest_config = asset_config.get('ingest', {})

        poll = ingest_config.get('poll')

        if poll is None:
            return action_result.set_status(
                phantom.APP_SUCCESS,
                SLACK_FAILED_TO_DISABLE_INGESTION.format(
                    message=action_result.get_message()))

        if not poll:
            return action_result.set_status(
                phantom.APP_SUCCESS,
                SLACK_INGESTION_NOT_ENABLED.format(
                    message=action_result.get_message()))

        ingest_config['poll'] = False

        body = {'configuration': asset_config}

        ret_val, resp_json = self._make_rest_call(action_result,
                                                  rest_url,
                                                  False,
                                                  method=requests.post,
                                                  body=body)

        if phantom.is_fail(ret_val):
            return ret_val

        return action_result.set_status(
            phantom.APP_SUCCESS,
            SLACK_INGESTION_DISABLED.format(
                message=action_result.get_message()))