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)
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)