예제 #1
0
def health():
    credentials = get_jwt()
    url = 'https://api.securitycenter.windows.com/api/exposureScore'
    client = Client(credentials)
    client.open_session()
    client.call_api(url)
    client.close_session()
    return jsonify_data({'status': 'ok'})
def respond_observables():
    observables, error = get_observables()
    if error:
        return jsonify_errors(error)

    observables = group_observables(observables, 'respond')

    if not observables:
        return jsonify_data([])

    g.actions = []

    credentials = get_jwt()
    client = Client(credentials)
    client.open_session()

    for observable in observables:

        query_params = {
            'observable_type': observable['type'],
            'observable_value': observable['value']
        }

        if observable['type'] == 'ms_machine_id':

            _actions = get_supported_actions(client, observable['value'])
            _actions = get_reverse_actions(client, observable['value'],
                                           _actions)

            actions = []
            for item in _actions:
                action = {}
                action['id'] = \
                    f'microsoft-defender-{_TR_SUPPORTED_ACTIONS[item]}'

                action['title'] = item
                action['description'] = item

                action['categories'] = [
                    'Microsoft Defender for Endpoint', 'Machine Actions'
                ]
                action['query-params'] = query_params

                actions.append(action)

        else:

            params = "$filter=indicatorValue+eq+'{value}'&$top=1".format(
                value=observable['value']).encode('utf-8')

            response, error = client.call_api(
                current_app.config['INDICATOR_URL'], params=params)

            if response and response.get('value'):
                obj = response['value'][0]
                human_action = 'Alert and Block' \
                    if obj['action'] == 'AlertAndBlock' else obj['action']
                query_params['indicator_id'] = obj['id']
                actions = [
                    {
                        'id':
                        'microsoft-defender-remove-indicator',
                        'title':
                        'Remove indicator: {action} - {title}'.format(
                            action=human_action, title=obj['title']),
                        'description':
                        f'Remove indicator with {human_action} '
                        f'action for {observable["value"]}',
                        'categories': [
                            'Microsoft Defender for Endpoint',
                            'Remove Indicator'
                        ],
                        'query-params':
                        query_params
                    },
                ]
            else:
                actions = [{
                    'id':
                    'microsoft-defender-add-indicator-alert',
                    'title':
                    'Add indicator: Alert',
                    'description':
                    f'Add indicator with Alert action '
                    f'for {observable["value"]}',
                    'categories':
                    ['Microsoft Defender for Endpoint', 'Add Indicator'],
                    'query-params':
                    query_params
                }, {
                    'id':
                    'microsoft-defender-'
                    'add-indicator-alert-and-block',
                    'title':
                    'Add indicator: Alert and Block',
                    'description':
                    f'Add indicator with '
                    f'Alert and Block action'
                    f' for {observable["value"]}',
                    'categories':
                    ['Microsoft Defender for Endpoint', 'Add Indicator'],
                    'query-params':
                    query_params
                }, {
                    'id':
                    'microsoft-defender-add-indicator-allowed',
                    'title':
                    'Add indicator: Allow',
                    'description':
                    f'Add indicator with Allow action '
                    f'for {observable["value"]}',
                    'categories':
                    ['Microsoft Defender for Endpoint', 'Add Indicator'],
                    'query-params':
                    query_params
                }]
        g.actions.extend(actions)

    client.close_session()

    return jsonify_data(g.actions)
def respond_trigger():
    mapping_by_type = {
        'sha1': 'FileSha1',
        'sha256': 'FileSha256',
        'ip': 'IpAddress',
        'ipv6': 'IpAddress',
        'domain': 'DomainName'
    }
    data, error = get_action_form_params()

    if error:
        return jsonify_errors(error)

    title = 'From SecureX Threat Response'
    description = 'This indicator was added via SecureX Threat Response ' \
                  'by the UI or API response actions'

    if data['observable_type'] == 'ms_machine_id':
        comment = 'Performed via SecureX Threat Response'

        actions = {
            'microsoft-defender-FullIsolation': {
                'url':
                '{base_url}/machines/{machine_id}/isolate'.format(
                    base_url=current_app.config['BASE_URL'],
                    machine_id=data['observable_value']),
                'method':
                'POST',
                'data': {
                    'Comment': comment,
                    'IsolationType': 'Full'
                }
            },
            'microsoft-defender-SelectiveIsolation': {
                'url':
                '{base_url}/machines/{machine_id}/isolate'.format(
                    base_url=current_app.config['BASE_URL'],
                    machine_id=data['observable_value']),
                'method':
                'POST',
                'data': {
                    'Comment': comment,
                    'IsolationType': 'Selective'
                }
            },
            'microsoft-defender-Unisolate': {
                'url':
                '{base_url}/machines/{machine_id}/unisolate'.format(
                    base_url=current_app.config['BASE_URL'],
                    machine_id=data['observable_value']),
                'method':
                'POST',
                'data': {
                    'Comment': comment
                }
            },
            'microsoft-defender-RestrictCodeExecution': {
                'url':
                '{base_url}/machines/{machine_id}'
                '/restrictCodeExecution'.format(
                    base_url=current_app.config['BASE_URL'],
                    machine_id=data['observable_value']),
                'method':
                'POST',
                'data': {
                    'Comment': comment
                }
            },
            'microsoft-defender-UnrestrictCodeExecution': {
                'url':
                '{base_url}/machines/{machine_id}'
                '/unrestrictCodeExecution'.format(
                    base_url=current_app.config['BASE_URL'],
                    machine_id=data['observable_value']),
                'method':
                'POST',
                'data': {
                    'Comment': comment
                }
            },
            'microsoft-defender-RunAntiVirusScanQuick': {
                'url':
                '{base_url}/machines/{machine_id}'
                '/runAntiVirusScan'.format(
                    base_url=current_app.config['BASE_URL'],
                    machine_id=data['observable_value']),
                'method':
                'POST',
                'data': {
                    'Comment': comment,
                    'ScanType': 'Quick'
                }
            },
            'microsoft-defender-RunAntiVirusScanFull': {
                'url':
                '{base_url}/machines/{machine_id}'
                '/runAntiVirusScan'.format(
                    base_url=current_app.config['BASE_URL'],
                    machine_id=data['observable_value']),
                'method':
                'POST',
                'data': {
                    'Comment': comment,
                    'ScanType': 'Full'
                }
            },
            'microsoft-defender-CollectInvestigationPackage': {
                'url':
                '{base_url}/machines/{machine_id}'
                '/collectInvestigationPackage'.format(
                    base_url=current_app.config['BASE_URL'],
                    machine_id=data['observable_value']),
                'method':
                'POST',
                'data': {
                    'Comment': comment
                }
            },
            'microsoft-defender-InitiateInvestigation': {
                'url':
                '{base_url}/machines/{machine_id}'
                '/startInvestigation'.format(
                    base_url=current_app.config['BASE_URL'],
                    machine_id=data['observable_value']),
                'method':
                'POST',
                'data': {
                    'Comment': comment
                }
            }
        }

    else:
        actions = {
            'microsoft-defender-add-indicator-alert': {
                'url': current_app.config['INDICATOR_URL'],
                'method': 'POST',
                'data': {
                    'indicatorValue': data['observable_value'],
                    'indicatorType':
                    mapping_by_type.get(data['observable_type']),
                    'action': 'Alert',
                    'title': title,
                    'description': description,
                    'severity': 'High'
                }
            },
            'microsoft-defender-add-indicator-alert-and-block': {
                'url': current_app.config['INDICATOR_URL'],
                'method': 'POST',
                'data': {
                    'indicatorValue': data['observable_value'],
                    'indicatorType':
                    mapping_by_type.get(data['observable_type']),
                    'action': 'AlertAndBlock',
                    'title': title,
                    'description': description,
                    'severity': 'High'
                }
            },
            'microsoft-defender-add-indicator-allowed': {
                'url': current_app.config['INDICATOR_URL'],
                'method': 'POST',
                'data': {
                    'indicatorValue': data['observable_value'],
                    'indicatorType':
                    mapping_by_type.get(data['observable_type']),
                    'action': 'Allowed',
                    'title': title,
                    'description': description
                }
            },
            'microsoft-defender'
            '-remove-indicator': {
                'url':
                current_app.config['INDICATOR_URL'] + '/' +
                str(data.get('indicator_id', '')),
                'method':
                'DELETE',
                'data': {}
            }
        }

    result = {'data': {'status': 'success'}}

    item = actions.get(data['action-id'])
    if not item:
        result['data']['status'] = 'failure'
        result['errors'] = [
            CTRBadRequestError("Unsupported action.").json,
        ]
        return jsonify(result)

    if data['observable_type'] != 'ms_machine_id' and \
            not item['data']['indicatorType']:
        raise UnsupportedTypeError(data['observable_type'])

    if item['data']:
        action = json.dumps(item['data']).encode('utf-8')
    else:
        action = None
    credentials = get_jwt()
    client = Client(credentials)
    client.open_session()
    response, error = client.call_api(item['url'], item['method'], data=action)
    client.close_session()

    if error is not None:
        result['data']['status'] = 'failure'
        result['errors'] = [
            CTRBadRequestError(error).json,
        ]

    return jsonify(result)
예제 #4
0
def observe_observables():
    observables, error = get_observables()
    if error:
        return jsonify_errors(error)

    observables = group_observables(observables)

    if not observables:
        return jsonify_data({})

    data = {}
    g.sightings = []

    credentials = get_jwt()
    client = Client(credentials)
    for observable in observables:
        client.open_session()

        response = get_alert(client, observable)

        if not response or not response.get('value'):
            alerts = []
        else:
            alerts = response['value']
            alerts.sort(key=lambda x: x['alertCreationTime'], reverse=True)

        count = len(alerts)

        if count >= current_app.config['CTR_ENTITIES_LIMIT']:
            alerts = alerts[:current_app.config['CTR_ENTITIES_LIMIT']]
            events = []
        else:
            events = call_advanced_hunting(
                client, observable['value'], observable['type'],
                current_app.config['CTR_ENTITIES_LIMIT'] - count)
            count = count + len(events)
            events.sort(key=lambda x: x['Timestamp'], reverse=True)

        mapping = Mapping(client, observable, count)

        if alerts:
            with ThreadPoolExecutor(max_workers=min(len(alerts),
                                                    cpu_count() or 1) *
                                    5) as executor:
                alerts = executor.map(mapping.build_sighting_from_alert,
                                      alerts)

            [g.sightings.append(alert) for alert in alerts if alert]

        if events:
            with ThreadPoolExecutor(max_workers=min(len(events),
                                                    cpu_count() or 1) *
                                    5) as executor:
                events = executor.map(mapping.build_sighting_from_ah, events)

            [g.sightings.append(event) for event in events if event]

    client.close_session()

    if g.sightings:
        data['sightings'] = format_docs(g.sightings)

    return jsonify_data(data)