Preempt Deprecated
Deprecated. No available replacement. Preempt Behavioral Firewall - Detection and enforcement based on user identity
Network Security · Preempt (Deprecated)
Details
| ID | Preempt |
|---|---|
| Provider | CrowdStrike |
| Category | Network Security |
| From Version | 5.0.0 |
| Docker Image | demisto/python:2.7.18.27799 |
| Supported Modules | Agentix XSIAM |
README
Overview
Deprecated. No available replacement.
Use the Preempt integration to eliminate security breaches and internal threats. Preempt is an Adaptive Threat Prevention platform based on identity, behavior, and risk.
This integration was integrated and tested with Preempt v2.3.1086.
Use Cases
- Enable multi-factor authentication (MFA)
- Retrieve user activities and the endpoints used by users
- Retrieve alerts from the Preempt platform.
Prerequisites
You need to obtain the following Preempt information.
- Server address
- API key
Get Your Preempt API Key
- Log in to the Preempt platform.
- Navigate to Administration > System > Settings > API Keys.
- Enable the API Token option.
- Create a token for Cortex XSOAR if one was not already created.
- Click the link icon on the row for the token.
The API key is copied to your clipboard. You will paste this when configuring the integration in Cortex XSOAR.
Configure the Preempt Integration on Cortex XSOAR
- Navigate to Settings > Integrations > Servers & Services.
- Search for Preempt.
- Click Add instance to create and configure a new integration instance.
- Name: a textual name for the integration instance.
- Preempt server address: for example, https://192.168.0.1
- API key: paste the token that you copied.
- Days to look back
- Client Secret
- Refresh Token
- Click Test to validate the URLs and connection.
Commands
You can execute these commands from the Cortex XSOAR CLI, as part of an automation, or in a playbook. After you successfully execute a command, a DBot message appears in the War Room with the command details.
- Add an account to the watch list: preempt-add-to-watch-list
- Remove an account from the watch list: preempt-remove-from-watch-list
- Retrieve User Activities: preempt-get-activities
- Retrieve User Endpoints: preempt-get-user-endpoints
- Retrieve User Alerts: preempt-get-alerts
Add an account to the watch list: preempt-add-to-watch-list
Add a user account to the Preempt watch list.
Input
accountObjectGuid: preempt-get-activities
Ouput
There is no output for this command.
Remove an account from the watch list: preempt-add-to-watch-list
Remove a user account from the Preempt watch list.
Input
accountObjectGuid: preempt-get-activities
Ouput
There is no output for this command.
Retrieve User Activities: preempt-get-activities
Retrieve the activities and the activity data for a specific user.
Command Example
!preempt-get-activities sourceUserId="userID" types="LOGIN" numOfHours="48"
Input
| Parameter | Description |
| sourceUserId | ID of user that you want to retrieve the activities for |
| types | List of specific incident types (comma delimited) |
| endTime | For example: 2012-03-04 12:08:12.354 |
| numOfHours | Number of hours to search back (from the endTime) |
Context Output
| Parameter | Description |
| Preempt.Activities.EndpointHostName | Hostname of the activity's endpoint |
| Preempt.Activities.EventType | Activity type |
| Preempt.Activities.AuthenticationType | Authentication type |
| Preempt.Activities.Timestamp | Activity's date and time |
| Preempt.Activities.Cursor | Cursor of last retrieved activity for pagination |
Human Readable Output

Raw Output
{
"Preeempt":{
"Activities":[
{
"AuthenticationType":"DOMAIN_LOGIN",
"EndpointHostName":"xxxxxx.xxxxx.xxx",
"EventType":"SUCCESSFUL_AUTHENTICATION",
"Timestamp":"2018-03-11T12:41:00.000Z"
}
]
}
}
Retrieve User Endpoints: preempt-get-user-endpoints
Retrieve the endpoints used by a spefic user.
Input
| Parameter | Description |
| sourceUserId | ID of user that you want to retrieve the endpoints for |
Context Output
| Parameter | Description |
| Endpoint.Hostname | Hostname of the endpoint |
| Endpoint.ID | Object GUID of the computer account |
| Endpoint.PrimaryDisplayName | Computer's display name in Active Directory (AD) |
| Endpoint.IsOwnedByUser | Indicates if the user owns this endpoint (boolean) |
| Endpoint.IPAddress | Last IP address associated with the endpoint, detected by the system |
| Endpoint.StaticIpAddresses | Static IP address that has been associated with the endpoint |
Raw Output
{
"Preempt":{
"Endpoint":[
{
"HostName":"xxxxxx.xx.xxx",
"Id":"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxx",
"IsOwnedByUser":T/F,
"LastIpAddress":"xxx.xxx.xxx.xxx",
"PrimaryDisplayName":"xxx-xxxx",
"StaticIpAddresses":[
"xxx.xxx.x.xxx"
]
}
Retrieve User Alerts: preempt-get-alerts
Retrieve the alerts for a specific user.
Command Example
!preempt-get-alerts sourceUserId="userID" numOfHours="48"
Input
| Parameter | Description |
| sourceUserId | ID of user that you want to retrieve the activities for |
| endTime | For example: 2012-03-04 12:08:12.354 |
| numOfHours | Number of hours to search back (from the endTime) |
Context Output
| Parameter | Description |
| Preempt.Alerts.AlertType | Alert type |
| Preempt.Alerts.Timestamp | Alert's date and time |
| Preempt.Alerts.startTime | Date and time the alert started |
| Preempt.Alerts.EndTime | Date and time the alert ended |
| Preempt.Alerts.eventLabel | Alert label |
| Preempt.Alerts.Cursor | Cursor of the last retrieved activity for pagination |
Human Readable Output

Raw Output
{
"Alerts":[
{
"alertType":"AbnormalServiceAccessAlert",
"cursor":"xxxxxxxxxx",
"endTime":"2018-03-27T19:43:00.000Z",
"endpointEntity":{
"_id":"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"hostName":null
},
"eventId":"xxxxxx",
"eventLabel":"Unusual Access to Service",
"incident":{
"_id":"INC-43",
"severity":"INFO",
"state":{
"lifeCycleStage":"NEW"
}
},
"relatedEvents":[
{
"eventType":"SERVICE_ACCESS",
"geoLocation":null,
"ipAddress":"xxx.xxx.xxx.xxx",
"timestamp":"2018-03-27T19:43:00.000Z"
}
]
}
Demisto-Preempt Demo
Configuration parameters
server— Address of Preempt server (e.g. https://192.168.0.1) (required)apiKey— API Key (required)isFetch— Fetch incidentsincidentType— Incident typelookback— Days to look back (required)insecure— Trust any certificate (not secure)proxy— Use system proxy settings
Commands (5)
-
preempt-add-to-watch-listAdds requested user to Preempt's watch list
-
preempt-get-activitiesGet activities from a time frame
-
preempt-get-alertsGet the alerts generated according to given arguments
-
preempt-get-user-endpointsGets the endpoints regularly used by the user account
-
preempt-remove-from-watch-listRemoves requested user from Preempt's watch list
Source
Preempt.ymlcommonfields: id: Preempt version: -1 name: Preempt display: Preempt (Deprecated) category: Network Security provider: CrowdStrike image: data:image/png;base64,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 description: Deprecated. No available replacement. Preempt Behavioral Firewall - Detection and enforcement based on user identity detaileddescription: |- In order to allow the integration to work, the following configurations are required on the Preempt managemnet UI: 1) Login to the UI with an admin of the PBF system 2) Go to Administration -> System -> Settings -> API Keys 3) Verify API tokens are enabled 4) Create a token for Cortex XSOAR 5) Copy the API key to the clipboard by clicking the link icon on the right 6) Paste this value into the apiKey parameter on the integration configuration: - display: Address of Preempt server (e.g. https://192.168.0.1) name: server defaultvalue: https:// type: 0 required: true - display: API Key name: apiKey defaultvalue: "" type: 4 required: true - display: Fetch incidents name: isFetch type: 8 required: false - display: Incident type name: incidentType type: 13 required: false - display: Days to look back name: lookback defaultvalue: "1" type: 0 required: true - display: Trust any certificate (not secure) name: insecure type: 8 required: false - display: Use system proxy settings name: proxy type: 8 required: false script: script: > import json from dateutil.parser import parse as parse_date from datetime import timedelta, datetime import requests from requests.packages.urllib3.exceptions import InsecureRequestWarning # Supress warning about unverified HTTPS requests.packages.urllib3.disable_warnings(InsecureRequestWarning) if not demisto.params().get("proxy", True): # Remove proxy environment variables if they exist for proxy_var in ["HTTP_PROXY", "HTTPS_PROXY", "http_proxy", "https_proxy"]: os.environ.pop(proxy_var, None) API_KEY = str(demisto.params()["apiKey"]) SERVER = str(demisto.params()["server"]) LOOKBACK = timedelta(days=int(demisto.params()["lookback"])) PUBLIC_API_URL = "%s/api/public" % SERVER GRAPHQL_URI = "%s/graphql" % PUBLIC_API_URL ENTITIES_URI = "%s/entities" % PUBLIC_API_URL AUTH_HEADER = { "Authorization": "Bearer %s" % API_KEY } USE_SSL = not demisto.params().get("insecure", False) ''' HELPER FUNCTIONS ''' def api_request(uri, data): data = {} if data is None else data LOG("running request with url=%s\tdata=%s" % (uri, data)) try: res = requests.post(uri, verify=USE_SSL, json=data, headers=AUTH_HEADER) if res.status_code not in (200, 204): raise Exception('Your request failed with the following error: ' + res.reason) except Exception, e: raise return res TIMELINE_LIMIT = 1000 def datetime_to_iso(d): return d.strftime('%Y-%m-%dT%H:%M:%S.000Z') def get_alerts(start_time=None, end_time=None, cursor=None, types=None, source_user_id=None): query = """ query ($cursor: Cursor, $startTime: DateTimeInput, $endTime: DateTimeInput, $types: [String!], $sourceUserId: UUID) { timeline(types: [ALERT], limit: %d, alertQuery: {types: $types}, sourceEntityQuery: {id: $sourceUserId}, startTime: $startTime, endTime: $endTime, after: $cursor) { cursor eventId timestamp ... on TimelineAlertEvent { incident { severity _id state { lifeCycleStage } } alertType timestamp startTime endTime eventLabel userEntity { _id primaryDisplayName primaryAccount { samAccountName domain upn } } endpointEntity { _id hostName } } relatedEvents(startTime: $startTime, limit: 30, types: [SUCCESSFUL_AUTHENTICATION, SERVICE_ACCESS], open: true) { eventType timestamp ... on TimelineAuthenticationEvent { authenticationType geoLocation { cityCode countryCode latitude longitude } ipAddress } ... on TimelineServiceAccessEvent { geoLocation { countryCode country latitude longitude } ipAddress } } } } """ % TIMELINE_LIMIT variables = { "cursor": cursor, "startTime": datetime_to_iso(start_time), "endTime": datetime_to_iso(end_time), "types": types, "sourceUserId": source_user_id } data = { "query": query, "variables": variables } resp = api_request(GRAPHQL_URI, data) alerts = resp.json()["data"]["timeline"] return alerts # The command demisto.command() holds the command sent from the user. if demisto.command() == "test-module": # This is the call made when pressing the integration test button. query = "{ aomActivities(limit: 1) { _id } }" variables = {} data = { "query": query, "variables": variables } res = api_request(GRAPHQL_URI, data) demisto.results('ok') sys.exit(0) if demisto.command() == "fetch-incidents": cursor = demisto.getLastRun().get("cursor") alerts = get_alerts(cursor=cursor, start_time=datetime.utcnow() - LOOKBACK, end_time=datetime.utcnow(), types=["GeoLocationAnomalyAlert", "ForbiddenCountryAlert"]) fixed_alerts = [] # Retrieve geo-location data and external IP from the first relevant activity and put it on the alert JSON for alert in alerts: # Only interested in LOW or MEDIUM severity incidents if alert["incident"]["severity"] not in ["LOW", "MEDIUM"] or alert["incident"]["state"]["lifeCycleStage"] != "NEW": continue alert_start_time = parse_date(alert["startTime"]) try: access = next(event for event in alert["relatedEvents"] if parse_date(event["timestamp"]) >= alert_start_time and event["geoLocation"]) for field in ["geoLocation", "ipAddress"]: alert[field] = access[field] fixed_alerts.append(alert) except StopIteration, e: pass result = [{"Name": "Incident %s" % alert["eventId"], "rawJSON": json.dumps(alert)} for alert in fixed_alerts] # Store the cursor demisto.setLastRun({ "cursor": alerts[-1]["cursor"] if alerts else cursor }) # lastRun is a dictionary, with value "now" for key "time". # JSON of the incident type created by this integration demisto.incidents(result) sys.exit(0) if demisto.command() == "preempt-add-to-watch-list": # The Preempt API receives the same parameters as the command args = { "entityIds": [demisto.args()["accountObjectGuid"]] } resp = api_request("%s/watch" % ENTITIES_URI, args) demisto.results("User added to watch list") sys.exit(0) if demisto.command() == "preempt-remove-from-watch-list": # The Preempt API receives the same parameters as the command args = { "entityIds": [demisto.args()["accountObjectGuid"]] } resp = api_request("%s/unwatch" % ENTITIES_URI, args) demisto.results("User removed from watch list") sys.exit(0) if demisto.command() == "preempt-get-activities": query = """ query ($cursor: Cursor, $startTime: DateTimeInput, $endTime: DateTimeInput, $types: [TimelineEventType!], $authTypes: [AuthenticationType!], $sourceUserId: UUID) { timeline(limit: %d, types: $types, sourceEntityQuery: {id: $sourceUserId}, activityQuery: {authenticationTypes: $authTypes}, startTime: $startTime, endTime: $endTime, after: $cursor) { cursor timestamp eventType ... on TimelineSuccessfulAuthenticationEvent { authenticationType endpointEntity { primaryDisplayName hostName } userEntity { _id primaryDisplayName primaryAccount { samAccountName domain upn } } } } } """ % TIMELINE_LIMIT types = [] auth_types = [] for t in demisto.args().get("types", "").split(","): if t == "LOGIN": types.append("SUCCESSFUL_AUTHENTICATION") auth_types.append("DOMAIN_LOGIN") end_time = demisto.args().get("endTime") dt_end_time = parse_date(end_time) if end_time else datetime.utcnow() last_hours = int(demisto.args().get("numOfHours")) variables = dict({key: demisto.args().get(key) for key in ["sourceUserId"]}, start_time=datetime_to_iso(dt_end_time - timedelta(hours=last_hours)), end_time=datetime_to_iso(dt_end_time), types=(types or None), authTypes=(auth_types or None)) variables["cursor"] = demisto.args().get("cursor") data = { "query": query, "variables": variables } resp = api_request(GRAPHQL_URI, data) events = resp.json()["data"]["timeline"] cursor = events[-1]["cursor"] if len(events) == TIMELINE_LIMIT else None def prettyfy_result(res): return { "EventType": res["eventType"], "AuthenticationType": res["authenticationType"], "Timestamp": res["timestamp"], "EndpointHostName": res["endpointEntity"]["hostName"] } pretty_results = map(prettyfy_result, events) demisto.results({ "Type": 1, "ContentsFormat": "json", "Contents": json.dumps(events), "HumanReadable": tableToMarkdown("Activities in time frame", pretty_results, ["Timestamp", "EndpointHostName"]), "EntryContext": { 'Preempt.Activities': pretty_results, 'Preempt.Alerts.Cursor': cursor } }) sys.exit(0) if demisto.command() == "preempt-get-user-endpoints": query = """ query ($sourceUserId: UUID!) { entities(id: $sourceUserId) { associations(bindingTypes: [LOGIN, OWNERSHIP]) { bindingType ... on OriginAssociation { entityId entity { primaryDisplayName ... on EndpointEntity { hostName lastIpAddress staticIpAddresses } } } } } } """ variables = { "sourceUserId": demisto.args()["sourceUserId"] } data = { "query": query, "variables": variables } resp = api_request(GRAPHQL_URI, data) # Only associations are necessary. Add a flag to mark if it is ownership entities = resp.json()["data"]["entities"] if entities: entity = entities[0] ownedEndpointsId = [assoc["entityId"] for assoc in entity["associations"] if assoc["bindingType"] == "OWNERSHIP"] result = [dict(assoc, isOwned=(assoc["entityId"] in ownedEndpointsId)) for assoc in entity["associations"] if assoc["bindingType"] == "LOGIN"] else: result = [] def prettyfy_result(endpoint): return { "Id": endpoint["entityId"], "HostName": endpoint["entity"]["hostName"], "PrimaryDisplayName": endpoint["entity"]["primaryDisplayName"], "IsOwnedByUser": endpoint["isOwned"], "LastIpAddress": endpoint["entity"]["lastIpAddress"], "StaticIpAddresses": endpoint["entity"]["staticIpAddresses"] } pretty_results = map(prettyfy_result, result) demisto.results({ "Type": 1, "ContentsFormat": "json", "Contents": json.dumps(result), "HumanReadable": tableToMarkdown("User's regular endpoints", pretty_results, ["HostName", "IsOwnedByUser"]), "EntryContext": { 'Endpoint': pretty_results } }) sys.exit(0) if demisto.command() == "preempt-get-alerts": end_time = demisto.args().get("endTime") dt_end_time = parse_date(end_time) if end_time else datetime.utcnow() last_hours = int(demisto.args().get("numOfHours")) alerts = get_alerts(cursor=demisto.args().get("cursor"), start_time=dt_end_time - timedelta(hours=last_hours), end_time=dt_end_time, source_user_id=demisto.args().get("sourceUserId")) cursor = alerts[-1]["cursor"] if len(alerts) == TIMELINE_LIMIT else None demisto.results({ "Type": 1, "ContentsFormat": "json", "Contents": json.dumps(alerts), "HumanReadable": tableToMarkdown("User's last 48 hours alerts", alerts), "EntryContext": { 'Preempt.Alerts': alerts, 'Preempt.Alerts.Cursor': cursor } }) sys.exit(0) type: python subtype: python2 commands: - name: preempt-add-to-watch-list arguments: - name: accountObjectGuid description: Object GUID of the AD account description: Adds requested user to Preempt's watch list - name: preempt-remove-from-watch-list arguments: - name: accountObjectGuid description: Object GUID of the AD account description: Removes requested user from Preempt's watch list - name: preempt-get-activities arguments: - name: sourceUserId required: true description: ID of a user whose activities to retrieve - name: types description: List of specific incident types (comma delimited) defaultValue: LOGIN - name: endTime description: End of the timeframe to search in - name: numOfHours default: true description: Number of hours to look back from end time defaultValue: "48" outputs: - contextPath: Preempt.Activities.EndpointHostName description: Hostname of the activity's endpoint type: string - contextPath: Preempt.Activities.EventType description: Type of the activity type: string - contextPath: Preempt.Activities.AuthenticationType description: For authentication, specific type type: string - contextPath: Preempt.Activities.Timestamp description: Date/time of the activity type: date - contextPath: Preempt.Activities.Cursor description: Cursor of last retrieved activity for pagination type: string description: Get activities from a time frame - name: preempt-get-user-endpoints arguments: - name: sourceUserId required: true description: ID of the user outputs: - contextPath: Endpoint.Hostname description: Hostname of the endpoint type: string - contextPath: Endpoint.ID description: Object GUID of the computer account type: string - contextPath: Endpoint.PrimaryDisplayName description: The computer's display name in AD type: string - contextPath: Endpoint.IsOwnedByUser description: True if the user owns this endpoint type: boolean - contextPath: Endpoint.IPAddress description: The last IP address associated with this endpoint seen by the system type: string - contextPath: Endpoint.StaticIpAddresses description: Static IP addresses which have been associated with the endpoint type: string description: Gets the endpoints regularly used by the user account - name: preempt-get-alerts arguments: - name: sourceUserId description: ID of the user associated with the alerts - name: numOfHours description: Number of hours to look back from end time defaultValue: "48" - name: endTime description: End of time frame to look in outputs: - contextPath: Preempt.Alerts.AlertType description: Type of the Alert type: string - contextPath: Preempt.Alerts.timestamp description: Date/time of the activity type: date - contextPath: Preempt.Alerts.startTime description: Date/time of beginning of the alert type: date - contextPath: Preempt.Alerts.EndTime description: Date/time when the alert was ended type: date - contextPath: Preempt.Alerts.eventLabel description: The label of the alert type: string - contextPath: Preempt.Alerts.Cursor description: Cursor of last retrieved activity for pagination description: Get the alerts generated according to given arguments isfetch: true dockerimage: demisto/python:2.7.18.27799 fromversion: 5.0.0 deprecated: true tests: - No Test