Exemplo n.º 1
0
def _update_duplicate_chain(api: RESTConfig, label: AlertLabel, email: Email,
                            ids: types.List[str]) -> bool:
    url = "{}/alerttriagechain".format(api.url)

    payload = {
        "alert": label.value,
        "user": email,
        "identifiers": ids,
    }

    jwt_auth = None

    if api.token is not None:
        jwt_auth = JWTAuth(api.token)
        jwt_auth.set_header_format("Bearer %s")

    try:
        resp = requests.put(url, json=payload, auth=jwt_auth)
    except requests.exceptions.RequestException as ex:
        raise APIError("Failed to make request: {}".format(ex))

    error = resp.json().get("error")

    if error is not None:
        raise APIError(error)

    return True
Exemplo n.º 2
0
def update_alert_status(msg: UserResponseMessage, api: RESTConfig):
    """Invoke the MozDef REST API to update the status of an alert.
    """

    url = "{}/alertstatus".format(api.url)

    status = new_status(msg.response)

    payload = {
        "alert": msg.identifier,
        "status": status.value,
        "user": {
            "email": msg.user.email,
            "slack": msg.user.slack
        },
        "identityConfidence": msg.identityConfidence.value,
        "response": msg.response.value,
    }

    jwt_auth = None

    if api.token is not None:
        jwt_auth = JWTAuth(api.token)
        jwt_auth.set_header_format("Bearer %s")

    try:
        logger.debug("Sending request to REST API")
        resp = requests.post(url, json=payload, auth=jwt_auth)
    except Exception as ex:
        logger.exception("Request failed: {}".format(ex))
        return False

    return resp.status_code < 300
Exemplo n.º 3
0
class message(object):
    def __init__(self):
        '''
        takes an incoming alert
        and triggers the block ip rest api endpoint
        '''

        self.configfile = os.path.join(os.path.dirname(__file__),
                                       'block_ip.conf')
        self.options = None
        if os.path.exists(self.configfile):
            self.initConfiguration()
        if self.options.jwt_token is not None:
            self._restapi_jwt = JWTAuth(self.options.jwt_token)
            self._restapi_jwt.set_header_format('Bearer %s')
        else:
            self._restapi_jwt = None

        self.registration = self.options.keywords.split(" ")
        # Block for 1 day
        self.DEFAULT_BLOCK_LENGTH = "1d"
        self.priority = 1

    def initConfiguration(self):
        myparser = OptionParser()
        (self.options, args) = myparser.parse_args([])

        self.options.keywords = getConfig('alert_names', [], self.configfile)
        self.options.restapi_url = getConfig('restapi_url', '',
                                             self.configfile)
        self.options.jwt_token = getConfig('jwt_token', None, self.configfile)

    def onMessage(self, alert):
        message = alert['_source']
        post_data = [{
            'ipaddress':
            "{0}/32".format(message['details']['sourceipaddress'])
        }, {
            'duration': self.DEFAULT_BLOCK_LENGTH
        }, {
            'comment': 'Automatic Block'
        }, {
            'referenceid': ''
        }, {
            'IPBlockList': True
        }, {
            'userid': "MozDef"
        }]
        headers = {'Content-type': 'application/json'}
        resp = requests.post(url=self.options.restapi_url + "/blockip",
                             data=json.dumps(post_data),
                             auth=self._restapi_jwt,
                             headers=headers)
        if not resp.ok:
            raise Exception(
                "Received error {0} from rest api when updating alerts schedules {1}"
                .format(resp.status_code, resp.data))
        return message
Exemplo n.º 4
0
    def test_custom_header_text(self):
        httpretty.register_uri(httpretty.GET, 'http://example.com/', body='[]')
        secret = 's33333krit'

        auth = JWTAuth(secret)
        auth.add_field('path', requests_jwt.payload_path)
        auth.set_header_format('Bearer: "%s"')

        resp = requests.get('http://example.com/',
                            params={'Hope this': 'Is signed'},
                            auth=auth)

        req = httpretty.last_request()
        auth_hdr = req.headers['Authorization']

        self.assertTrue(auth_hdr.startswith('Bearer: "'))
Exemplo n.º 5
0
def _retrieve_duplicate_chain(api: RESTConfig, label: AlertLabel,
                              email: Email) -> types.Optional[DuplicateChain]:
    url = "{}/alerttriagechain".format(api.url)

    payload = {
        "alert": label.value,
        "user": email,
    }

    jwt_auth = None

    if api.token is not None:
        jwt_auth = JWTAuth(api.token)
        jwt_auth.set_header_format("Bearer %s")

    try:
        resp = requests.get(url, params=payload, auth=jwt_auth)
        resp_data = resp.json()
    except json.JSONDecodeError as ex:
        raise APIError("Did not receive JSON response: {}".format(ex))
    except requests.exceptions.RequestException as ex:
        raise APIError("Failed to make request: {}".format(ex))

    error = resp_data.get("error")

    if error is not None:
        if resp.status_code != 200:
            raise APIError(error)

        return None  # No duplicate chain found

    ids = resp_data.get("identifiers", [])

    if len(ids) == 0:
        return None

    try:
        created = toUTC(resp_data["created"])
        modified = toUTC(resp_data["modified"])
    except KeyError:
        raise APIError(
            "Duplicate chain data missing created or modified field")
    except ValueError:
        raise APIError("Duplicate chain data contains unexpected timestamps")

    return DuplicateChain(ids, created, modified)
Exemplo n.º 6
0
    def main(self):
        self.parse_config('get_watchlist.conf', ['api_url', 'jwt_secret', 'use_auth'])

        jwt_token = None
        if self.config.use_auth.lower() != 'false':
            jwt_token = JWTAuth(self.config.jwt_secret)
            jwt_token.set_header_format('Bearer %s')

        r = requests.get(self.config.api_url, auth=jwt_token)
        # Connect to rest api and grab response
        if r.ok:
            response = r.text
            terms_list = json.loads(response)
            for term in terms_list:
                self.watchterm = term
                self.process_alert()
        else:
            logger.error('The watchlist request failed. Status {0}.\n'.format(r))
Exemplo n.º 7
0
    def main(self):
        self.parse_config('get_watchlist.conf', ['api_url', 'jwt_secret', 'use_auth'])

        jwt_token = None
        if self.config.use_auth.lower() != 'false':
            jwt_token = JWTAuth(self.config.jwt_secret)
            jwt_token.set_header_format('Bearer %s')

        r = requests.get(self.config.api_url, auth=jwt_token)
        # Connect to rest api and grab response
        if r.ok:
            response = r.text
            terms_list = json.loads(response)
            for term in terms_list:
                self.watchterm = term
                self.process_alert()
        else:
            logger.error('The watchlist request failed. Status {0}.\n'.format(r))
Exemplo n.º 8
0
    def main(self):
        self.parse_config('get_watchlist.conf', ['api_url', 'jwt_secret'])

        jwt_token = JWTAuth(self.config.jwt_secret)
        jwt_token.set_header_format('Bearer %s')

        # Connect to rest api and grab response
        r = requests.get(self.config.api_url, auth=jwt_token)
        status = r.status_code
        index = 0
        if status == 200:
            status = r.status_code
            response = r.text
            terms_list = json.loads(response)
            while index < len(terms_list):
                term = terms_list[index]
                term = '"{}"'.format(term)
                self.watchterm = term
                index += 1
                self.process_alert(term)
        else:
            logger.error('The watchlist request failed. Status {0}.\n'.format(status))
Exemplo n.º 9
0
class CeleryRestClient():
    def __init__(self):
        if hasattr(current_app.conf, "CELERY_RESTAPI_JWT"
                   ) and current_app.conf.CELERY_RESTAPI_JWT != "":
            self._restapi_jwt = JWTAuth(current_app.conf.CELERY_RESTAPI_JWT)
            self._restapi_jwt.set_header_format('Bearer %s')
            get_logger(__name__).info("setting JWT value")
        else:
            self._restapi_jwt = None

        if hasattr(current_app.conf, "CELERY_RESTAPI_URL"):
            self._restapi_url = current_app.conf.CELERY_RESTAPI_URL
            get_logger(__name__).info("alert scheduler using {0}".format(
                self._restapi_url))
        else:
            raise Exception("Need to define CELERY_RESTAPI_URL")

    def fetch_schedule_dict(self):
        resp = requests.get(self._restapi_url + "/alertschedules",
                            auth=self._restapi_jwt)
        if not resp.ok:
            raise Exception(
                "Received error {0} from rest api when fetching alert schedules: {1}"
                .format(resp.status_code, resp.text))
        return json.loads(resp.text)

    def sync_schedules(self, current_schedule):
        resp = requests.post(url=RESTAPI_URL + "/syncalertschedules",
                             data=json.dumps(current_schedule),
                             auth=self._restapi_jwt)
        if not resp.ok:
            raise Exception(
                "Received error {0} from rest api when updating alerts schedules {1}"
                .format(resp.status_code, resp.data))

    def update_schedules(self, current_schedule):
        resp = requests.post(url=RESTAPI_URL + "/updatealertschedules",
                             data=json.dumps(current_schedule),
                             auth=self._restapi_jwt)
        if not resp.ok:
            raise Exception(
                "Received error {0} from rest api when updating alerts schedules {1}"
                .format(resp.status_code, resp.data))

    def load_and_register_alerts(self):
        existing_alert_schedules = self.fetch_schedule_dict()
        alert_schedules = {}
        for alert_name, params in ALERTS.items():
            # Register alerts in celery
            try:
                alert_tokens = alert_name.split(".")
                alert_module_name = alert_tokens[0]
                alert_classname = alert_tokens[-1]
                alert_module = import_module(alert_module_name)
                alert_class = getattr(alert_module, alert_classname)
                current_app.register_task(alert_class())
            except ImportError as e:
                logger.exception("Error importing {0}: {1}".format(
                    alert_name, e))
                pass
            except Exception as e:
                logger.exception("Generic error registering {0}: {1}".format(
                    alert_name, e))
                pass
            alert_schedule = {
                "name": alert_name,
                "task": alert_name,
                "enabled": True,
            }
            if 'args' in params:
                alert_schedule['args'] = params['args']
            if 'kwargs' in params:
                alert_schedule['kwargs'] = params['kwargs']

            if isinstance(params['schedule'], timedelta):
                alert_schedule['schedule_type'] = 'interval'
                alert_schedule['celery_schedule'] = {
                    "every": params['schedule'].total_seconds(),
                    "period": "seconds"
                }
            elif isinstance(params['schedule'], crontab):
                alert_schedule['schedule_type'] = 'crontab'
                alert_schedule['celery_schedule'] = {
                    "minute": params['schedule']._orig_minute,
                    "hour": params['schedule']._orig_hour,
                    "day_of_week": params['schedule']._orig_day_of_week,
                    "day_of_month": params['schedule']._orig_day_of_month,
                    "month_of_year": params['schedule']._orig_month_of_year,
                }

            if alert_name not in existing_alert_schedules:
                logger.debug("Inserting schedule for {0} into mongodb".format(
                    alert_name))
                updated_alert_schedule = alert_schedule
            else:
                existing_schedule = existing_alert_schedules[alert_name]
                logger.debug(
                    "Updating existing schedule ({0}) with new information into mongodb"
                    .format(alert_name))
                existing_schedule['schedule_type'] = alert_schedule[
                    'schedule_type']
                existing_schedule['celery_schedule'] = alert_schedule[
                    'celery_schedule']
                updated_alert_schedule = existing_schedule

            alert_schedules[alert_name] = PeriodicTask(
                **updated_alert_schedule).to_dict()
        self.update_schedules(alert_schedules)
Exemplo n.º 10
0
class CeleryRestClient(object):
    def __init__(self):
        if hasattr(current_app.conf, "CELERY_RESTAPI_JWT"
                   ) and current_app.conf.CELERY_RESTAPI_JWT != "":
            self._restapi_jwt = JWTAuth(current_app.conf.CELERY_RESTAPI_JWT)
            self._restapi_jwt.set_header_format('Bearer %s')
            get_logger(__name__).info("setting JWT value")
        else:
            self._restapi_jwt = None

        if hasattr(current_app.conf, "CELERY_RESTAPI_URL"):
            self._restapi_url = current_app.conf.CELERY_RESTAPI_URL
            get_logger(__name__).info("alert scheduler using {0}".format(
                self._restapi_url))
        else:
            raise Exception("Need to define CELERY_RESTAPI_URL")

    def fetch_schedule_dict(self):
        resp = requests.get(self._restapi_url + "/alertschedules",
                            auth=self._restapi_jwt)
        if not resp.ok:
            raise Exception(
                "Received error {0} from rest api when fetching alert schedules"
                .format(resp.status_code))
        api_results = json.loads(resp.text)
        return api_results

    def print_schedule(self):
        schedule = self.fetch_schedule_dict()
        get_logger(__name__).info("**** Current Alert Schedule ****")
        for alert_name, details in schedule.items():
            get_logger(__name__).info("\t{0}: {1} (enabled={2})".format(
                alert_name, details['schedule_string'], details['enabled']))

    def load_and_register_alerts(self):
        existing_alert_schedules = self.fetch_schedule_dict()
        alert_schedules = {}
        for alert_name, params in ALERTS.items():
            # Register alerts in celery
            try:
                alert_tokens = alert_name.split(".")
                alert_module_name = alert_tokens[0]
                alert_classname = alert_tokens[-1]
                alert_module = import_module(alert_module_name)
                alert_class = getattr(alert_module, alert_classname)
                current_app.register_task(alert_class())
            except ImportError as e:
                logger.exception("Error importing {0}: {1}".format(
                    alert_name, e))
                pass
            except Exception as e:
                logger.exception("Generic error registering {0}: {1}".format(
                    alert_name, e))
                pass

            full_path_name = "{0}.{1}".format(alert_module_name,
                                              alert_classname)
            alert_schedule = {
                "_id": str(ObjectId()),
                "_cls": "PeriodicTask",
                "name": full_path_name,
                "task": full_path_name,
                "enabled": True,
                "args": [],
                "kwargs": {},
            }
            if 'args' in params:
                alert_schedule['args'] = params['args']
            if 'kwargs' in params:
                alert_schedule['kwargs'] = params['kwargs']

            if isinstance(params['schedule'], timedelta):
                alert_schedule['schedule_type'] = 'interval'
                alert_schedule['interval'] = {
                    "every": params['schedule'].total_seconds(),
                    "period": "seconds"
                }
                alert_schedule['schedule_string'] = "{0} {1}".format(
                    params['schedule'].total_seconds(), "seconds")
            elif isinstance(params['schedule'], crontab):
                alert_schedule['schedule_type'] = 'crontab'
                alert_schedule['crontab'] = {
                    "minute": params['schedule']._orig_minute,
                    "hour": params['schedule']._orig_hour,
                    "day_of_week": params['schedule']._orig_day_of_week,
                    "day_of_month": params['schedule']._orig_day_of_month,
                    "month_of_year": params['schedule']._orig_month_of_year,
                }
                alert_schedule[
                    'schedule_string'] = "{0} {1} {2} {3} {4}".format(
                        params['schedule']._orig_minute,
                        params['schedule']._orig_hour,
                        params['schedule']._orig_day_of_week,
                        params['schedule']._orig_day_of_month,
                        params['schedule']._orig_month_of_year,
                    )

            if alert_name not in existing_alert_schedules:
                logger.debug("Inserting schedule for {0} into mongodb".format(
                    full_path_name))
                updated_alert_schedule = alert_schedule
            else:
                # Update schedule if it differs from file to api
                del existing_alert_schedules[alert_name][
                    existing_alert_schedules[alert_name]['schedule_type']]
                existing_alert_schedules[alert_name][
                    'schedule_type'] = alert_schedule['schedule_type']
                existing_alert_schedules[alert_name][
                    alert_schedule['schedule_type']] = alert_schedule[
                        alert_schedule['schedule_type']]
                existing_alert_schedules[alert_name][
                    'schedule_string'] = alert_schedule['schedule_string']
                updated_alert_schedule = existing_alert_schedules[alert_name]

            alert_schedules[alert_name] = updated_alert_schedule
        resp = requests.post(url=RESTAPI_URL + "/updatealertschedules",
                             data=json.dumps(alert_schedules),
                             auth=self._restapi_jwt)
        if not resp.ok:
            raise Exception(
                "Received error {0} from rest api when updating alerts schedules"
                .format(resp.status_code))