Jask Deprecated

Deprecated. Use Sumo Logic Cloud SIEM instead. Freeing the analyst with autonomous decisions.

Analytics & SIEM · Jask (Deprecated)

Details

IDJask
ProviderFrancisco Partners
CategoryAnalytics & SIEM
From Version5.0.0
Docker Imagedemisto/python:2.7.18.20958
Supported ModulesAgentix

README

Deprecated. Use Sumo Logic Cloud SIEM integration instead. For further details about the migration, visit our Sumo Logic SIEM integration documentation.

Overview


Use the JASK integration to manage entities, signals, and insights.

 

Configure the JASK Integration on Cortex XSOAR


  1. Navigate to Settings > Integrations > Servers & Services.
  2. Search for JASK.
  3. Click Add instance to create and configure a new integration instance.
    • Name: a textual name for the integration instance.
    • Fetch incidents
    • Incident type
    • Use system proxy settings
    • Override default fetch query
  4. Click Test to validate the URLs and token

 

Fetched Incidents Data


The integration fetches insights. The first fetch returns insights from the previous 24 hour period. By default, the fetch will fetch all insights with the status new and in-progress. This is a sample default query: workflow_status:(new OR inprogress). You can modify the default query in the Override default fetch query parameter.

 

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.

  1. Get details for an insight: jask-get-insight-details
  2. Get comments for an insight: jask-get-insight-comments
  3. Get details for a signal: jask-get-signal-details
  4. Get details for an entity: jask-get-entity-details
  5. Get related entities: jask-get-related-entities
  6. Get a list of entities on allow list: jask-get-whitelisted-entities
  7. Search JASK insights: jask-search-insights
  8. Search JASK signals: jask-search-signals
  9. Search JASK entities: jask-search-entities

 

1. Get details for an insight


Note: This command is deprecated. Use `sumologic-sec-insight-get-details` command in Sumo Logic SIEM integration. For further details, visit our Sumo Logic SIEM integration documentation.

Returns detailed information for a specified insight.

 

Base Command

jask-get-insight-details

 

Input
Parameter Description
insight-id The insight to retrieve details for

 

Context Output
Path Description
Jask.Insight.Id Insight ID
Jask.Insight.Name Insight name
Jask.Insight.Action Insight action
Jask.Insight.Entity The main entity related to the insight
Jask.Insight.AssignedTo Who the insight was assigned to
Jask.Insight.Description Insight description
Jask.Insight.IpAddress Insight IP address
Jask.Insight.LastUpdated The time the insight was last updated
Jask.Insight.LastUpdatedBy The last person to update the insight
Jask.Insight.Severity Insight severity
Jask.Insight.InsightTime The time of the insight
Jask.Insight.WorkflowStatus Insight status
Jask.Insight.RelatedEntityList.Id The ID of the related entity
Jask.Insight.RelatedEntityList.EntityType Related entity type
Jask.Insight.RelatedEntityList.Hostname The hostname of the related entity
Jask.Insight.SignalList.Id Signal ID
Jask.Insight.SignalList.Name Signal name
Jask.Insight.SignalList.Category Signal category
Jask.Insight.SignalList.SourceType The source of the signal
Jask.Insight.SignalListMetadata.Patterns.Count Number of signals of the category pattern
Jask.Insight.SignalListMetadata.Anomalies.Count Number of signals of the category anomaly
Jask.Insight.SignalListMetadata.ThreatIntel.Count Number of signals of the category threat intelligence
Jask.Insight.RelatedEntityList.IpAddress IP address of the related entity
Jask.Insight.RelatedEntityList.IsWhitelisted Whether or not the entity is on allow list
Jask.Insight.RelatedEntityList.RiskScore The risk score of the related entity
Jask.Insight.RelatedEntityList.Source The source of the related entity

 

Command Example

!jask-get-insight-details insight-id="7ead8dc9-d541-3484-9320-ea593729e7cc"

 

Context Example
{
    "Jask": {
        "Insight": {
            "SignalListMetadata": {
                "Patterns": {
                    "Count": 4
                },
                "ThreatIntel": {
                    "Count": 0
                },
                "Anomalies": {
                    "Count": 0
                }
            },
            "WorkflowStatus": "new",
            "Description": "Exfiltration, C2 Risk Score: 14",
            "IpAddress": "104.236.54.196",
            "Severity": 2,
            "RelatedEntityList": [],
            "LastUpdated": "2018-07-13T05:17:55.620330",
            "EntityDetails": {
                "EntityType": "ip",
                "Name": "^^^104.236.54.196^^^",
                "RiskScore": 9,
                "Hostname": "Unknown",
                "Source": "discovery",
                "LastSeen": "Sun, 05 Aug 2018 10:00:56 GMT",
                "PrimaryEntityType": null,
                "IpAddress": "^^^104.236.54.196^^^",
                "Id": "7ead8dc9-d541-3484-9320-ea593729e7cc",
                "FirstSeen": "Wed, 14 Feb 2018 19:54:31 GMT"
            },
            "InsightTime": "2018-07-11T18:59:12",
            "Id": "7ead8dc9-d541-3484-9320-ea593729e7cc",
            "SignalList": [
                {
                    "Category": "Exfiltration",
                    "Name": "Hexadecimal in DNS Query Domain",
                    "Timestamp": "2018-07-11T19:06:14",
                    "ThreatIndicators": [
                        {
                            "Value": "analytics-9dd8570e3fd957ce828c34761a8e98b8.xyz",
                            "IndicatorType": "hostname"
                        }
                    ],
                    "Score": "2",
                    "Description": "Encoding in hexadecimal is a way that attackers can bypass network security devices that are inspecting traffic.  While hexadecimal often appears in subdomains, it much less frequent in domains.",
                    "Id": "b7f76616-f27b-5c18-b503-2d3dbab1bb96",
                    "SourceType": "rule"
                },
                {
                    "Category": "C2",
                    "Name": "TeslaCrypt Ransomware Domain",
                    "Timestamp": "2018-07-11T19:51:16",
                    "ThreatIndicators": [
                        {
                            "Value": "o4dm3.leaama.at",
                            "IndicatorType": "hostname"
                        }
                    ],
                    "Score": "6",
                    "Description": "TeslaCrypt is a ransomware that encrypts documents, databases, code, bitcoin wallets and more. This rule looks for DNS queries that include domains known to be associated with TeslaCrypt.",
                    "Id": "67b2ba91-9c32-5ffb-9587-873ef68f7899",
                    "SourceType": "rule"
                },
                {
                    "Category": "C2",
                    "Name": "TeslaCrypt Ransomware Domain",
                    "Timestamp": "2018-07-11T19:51:17",
                    "ThreatIndicators": [
                        {
                            "Value": "kbv5s.kylepasse.at",
                            "IndicatorType": "hostname"
                        }
                    ],
                    "Score": "6",
                    "Description": "TeslaCrypt is a ransomware that encrypts documents, databases, code, bitcoin wallets and more. This rule looks for DNS queries that include domains known to be associated with TeslaCrypt.",
                    "Id": "26fc053b-ad5f-5f39-8e48-12feb39b77d2",
                    "SourceType": "rule"
                },
                {
                    "Category": "C2",
                    "Name": "TorrentLocker Ransomware Domain",
                    "Timestamp": "2018-07-11T19:51:19",
                    "ThreatIndicators": [
                        {
                            "Value": "mz7oyb3v32vshcvk.tormidle.at",
                            "IndicatorType": "hostname"
                        }
                    ],
                    "Score": "6",
                    "Description": "TorrentLocker is a ransomware that encrypts documents, databases, code, bitcoin wallets and more. This rule looks for DNS queries that include domains known to be associated with TorrentLocker.",
                    "Id": "7ed97e33-73fd-599c-9c55-6c89aa0e7bf3",
                    "SourceType": "rule"
                }
            ],
            "Name": "Possible Malware - Ransomware (TeslaCrypt) and Data Exfiltration"
        }
    }
}

 

Human Readable Output

 

2. Get comments for an insight


Note: This command is deprecated. Use `sumologic-sec-insight-get-comments` command in Sumo Logic SIEM integration. For further details, visit our Sumo Logic SIEM integration documentation.

Returns comments for a specified insight.

 

Base Command

jask-get-insight-comments

 

Input
Parameter Description
insight-id The insight to retrieve comments for

 

Context Output
Path Description
Jask.InsightCommentList.id Comment ID
Jask.InsightCommentList.InsightId Insight ID
Jask.InsightCommentList.Author Author of comment
Jask.InsightCommentList.Body Comment body
Jask.InsightCommentList.LastUpdated The date the comment was last updated
Jask.InsightCommentList.Timestamp The time of the comment

 

Command Example

asdf

 

Context Example
asdf

 

Human Readable Output

asdf

 

3. Get details for a signal


Note: This command is deprecated. Use `sumologic-sec-signal-get-details` command in Sumo Logic SIEM integration. For further details, visit our Sumo Logic SIEM integration documentation.

Returns detailed information for a specified signal.

 

Base Command

jask-get-signal-details

 

Input
Parameter Description
signal-id The signal to retrieve details for

 

Context Output
Path Description
Jask.Signal.Id Signal ID
Jask.Signal.Name Signal name
Jask.Signal.Category Signal category
Jask.Signal.Description Signal description
Jask.Signal.Score Signal score
Jask.Signal.SourceType The source type of the signal
Jask.Signal.Timestamp The time of the signal
Jask.Signal.Metadata.RecordType Record type
Jask.Signal.Metadata.RecordCount The associated count of each record type
Jask.SignalThreatIndicators.IndicatorType Threat indicator type
Jask.Signal.ThreatIndicators.Value Value of the threat indicator

 

Command Example

!jask-get-signal-details signal-id=b7f76616-f27b-5c18-b503-2d3dbab1bb96

 

Context Example
{
    "Jask": {
        "Signal": {
            "Category": "Exfiltration",
            "SourceType": "rule",
            "Name": "Hexadecimal in DNS Query Domain",
            "Timestamp": "2018-07-11T19:06:14",
            "ThreatIndicators": [
                {
                    "Value": "analytics-9dd8570e3fd957ce828c34761a8e98b8.xyz",
                    "IndicatorType": "hostname"
                }
            ],
            "Score": "2",
            "Description": "Encoding in hexadecimal is a way that attackers can bypass network security devices that are inspecting traffic.  While hexadecimal often appears in subdomains, it much less frequent in domains.",
            "Id": "b7f76616-f27b-5c18-b503-2d3dbab1bb96",
            "Metadata": [
                {
                    "RecordType": "flow",
                    "RecordCount": 0
                },
                {
                    "RecordType": "notice",
                    "RecordCount": 0
                },
                {
                    "RecordType": "http",
                    "RecordCount": 0
                }
            ]
        }
    }
}

 

Human Readable Output

image

 

4. Get details for an entity


Note: This command is deprecated. Use `sumologic-sec-entity-get-details` command in Sumo Logic SIEM integration. For further details, visit our Sumo Logic SIEM integration documentation.

Returns detailed information about a speficied entity.

 

Base Command

jask-get-entity-details

 

Input
Parameter Description
entity-id The entity to retrieve details for

 

Context Output
Path Description
Jask.Entity.Id Entity ID
Jask.Entity.Name Entity name
Jask.Entity.IpAddress Entity IP address
Jask.Entity.FirstSeen Time the entity was first seen
Jask.Entity.LastSeen Time the entity was last seen
Jask.Entity.Source The source of the entity
Jask.Entity.AssetType Asset type
Jask.Entity.PrimaryAssetType Primary asset type
Jask.Entity.HostName Hostname
Jask.Entity.RiskScore Risk score
Jask.Entity.IsWhiteListed Whether or not the entity is on allow list

 

Command Example

!jask-get-entity-details entity-id=d07ef37f-06c1-58c3-a7a0-c1cd0fa4cd8e

 

Context Example
{
    "Jask": {
        "Entity": {
            "Name": "craig.campbell",
            "EntityType": "username",
            "PrimaryEntityType": "hostname",
            "Source": "ad",
            "LastSeen": "Sun, 05 Aug 2018 10:30:18 GMT",
            "Groups": [
                "CN=Remote Desktop Users,CN=Builtin,DC=corp,DC=skaj,DC=ai"
            ],
            "Id": "d07ef37f-06c1-58c3-a7a0-c1cd0fa4cd8e",
            "FirstSeen": "Thu, 01 Mar 2018 16:52:50 GMT"
        }
    }
}

 

Human Readable Output

image

 

5. Get related entities


Note: This command is deprecated and will not be supported in Sumo Logic SIEM. For further details, visit our Sumo Logic SIEM integration documentation.

Get all related entities for the specified entity.

 

Base Command

jask-get-related-entities

 

Input
Parameter Description
entity-id The entity ID that the related entities are retrieved for

 

Context Output
Path Description
Jask.RelatedEntityList.Id Entity ID
Jask.RelatedEntityList.Name Entity name
Jask.RelatedEntityList.Email Entity email
Jask.RelatedEntityList.Source Entity source
Jask.RelatedEntityList.UserName Username of the related entity
Jask.RelatedEntityList.HostName Entity hostname
Jask.RelatedEntityList.Active Whether or not the entity is active
Jask.RelatedEntityList.Admin Entity admin
Jask.RelatedEntityList.AssetType Asset type
Jask.RelatedEntityList.CreatedTimestamp Time the entity was created
Jask.RelatedEntityList.FirstSeen Time the entity was first seen
Jask.RelatedEntityList.GivenName Name given to the entity
Jask.RelatedEntityList.IsWhiteListed Whether or not the entity is on allow list
Jask.RelatedEntityList.LastSeen Time the entity was last seen
Jask.RelatedEntityList.LastName The last name
Jask.RelatedEntityList.RiskScore Entity risk score

 

Command Example

!jask-get-related-entities entity-id=d5d04bc6-c00a-4a9a-a8f5-6f6231f55d80

 

Context Example
{
    "Jask": {
        "RelatedEntityList": [
            {
                "Username": "craig.campbell",
                "Name": "craig.campbell",
                "LastName": "Campbell",
                "EntityType": "username",
                "Id": "d07ef37f-06c1-58c3-a7a0-c1cd0fa4cd8e",
                "CreatedTimestamp": "2018-01-23T05:01:38",
                "Source": "ad",
                "LastSeen": "2018-08-05T10:30:18",
                "Groups": [
                    "CN=Remote Desktop Users,CN=Builtin,DC=corp,DC=skaj,DC=ai"
                ],
                "Active": true,
                "GivenName": "Craig",
                "Email": "example.gmail.com",
                "FirstSeen": "2018-03-01T16:52:50"
            },
            {
                "EntityType": "hostname",
                "Name": "sea-dt5820-357.corp.skaj.ai",
                "Hostname": "sea-dt5820-357.corp.skaj.ai",
                "Source": "ad",
                "LastSeen": "2018-08-05T10:30:38",
                "Groups": [
                    "CN=Pre-Windows 2000 Compatible Access,CN=Builtin,DC=corp,DC=skaj,DC=ai",
                    "CN=Cert Publishers,CN=Users,DC=corp,DC=skaj,DC=ai"
                ],
                "Id": "7d63f14f-81c0-5442-9de1-6061404bcbd7",
                "FirstSeen": "2018-02-15T16:04:35"
            }
        ]
    }
}

 

Human Readable Output

image

 

6. Get a list of entities on allow list


Note: This command is deprecated and will not be supported in Sumo Logic SIEM. For further details, visit our Sumo Logic SIEM integration documentation.

Returns a list of all entities on allow list.

 

Base Command

jask-get-whitelisted-entities

 

Input

There are no inputs for this command.

 

Context Output
Path Description
Jask.Whitelisted.EntityList.Id ID of the entity on allow list
Jask.Whitelisted.EntityList.Name Name of the entity on allow list
Jask.Whitelisted.EntityList.UserName Username of the entity on allow list
Jask.Whitelisted.EntityList.ModelId The modelID of the entity on allow list
Jask.Whitelisted.EntityList.Timestamp Time of the entity on allow list
Jask.Whitelisted.EntityList.Metadata.TotalCount Number of entities on allow list

 

Command Example

!jask-get-whitelisted-entities

 

Context Example
{
    "Jask": {
        "WhiteListed": {
            "EntityList": [
                {
                    "UserName": "demisto",
                    "Timestamp": "2018-05-31T21:20:45.302635",
                    "Name": "wittes-imac-pro.local",
                    "Id": "e0a7172f-aa5d-4ba9-ae66-b49d99d9b4e7",
                    "ModelId": "e0a7172f-aa5d-4ba9-ae66-b49d99d9b4e7"
                },
                {
                    "UserName": "demisto",
                    "Timestamp": "2018-05-31T21:12:54.003527",
                    "Name": "172.18.20.20",
                    "Id": "d5d04bc6-c00a-4a9a-a8f5-6f6231f55d80",
                    "ModelId": "d5d04bc6-c00a-4a9a-a8f5-6f6231f55d80"
                },
                {
                    "UserName": "demisto",
                    "Timestamp": "2018-05-31T21:20:37.218586",
                    "Name": "192.168.2.195",
                    "Id": "306360bb-57d2-4a8d-a882-a7b3f2b92429",
                    "ModelId": "306360bb-57d2-4a8d-a882-a7b3f2b92429"
                }
            ],
            "Metadata": {
                "TotalCount": 3
            }
        }
    }
}

 

Human Readable Output

image

 

7. Search JASK insights


Note: This command is deprecated. Use `sumologic-sec-insight-search` command in Sumo Logic SIEM integration. For further details, visit our Sumo Logic SIEM integration documentation.

Search for JASK insights according to specific criteria.

 

Base Command

jask-search-insights

 

Input
Parameter Description
last-seen When the insight was last seen. Defaults to 'All time' if no time arguments are specified.
rating Comma-separated list of values between 1-5 (inclusive)
status Comma-separated list of values (new, inprogress, closed)
assigned-team Comma-separated list of values
assigned-user Comma-separated list of values
offset The page offset for the results
limit How many results to retrieve
sort What to sort the results by
time-from Start time for the search (MM/DD/YYYY)
time-to End time for the search (MM/DD/YYYY)

 

Context Output
Path Description
Jask.Insight.Id Insight ID
Jask.Insight.Name Insight name
Jask.Insight.Action The action to take on the insight
Jask.Insight.AssignedTo Who the insight was assigned to
Jask.Insight.Description Insight description
Jask.Insight.IpAddress Insight IP address
Jask.Insight.LastUpdated When the insight was last updated
Jask.Insight.LastUpdatedBy Who the insight was last updated by
Jask.Insight.Severity Insight severity
Jask.Insight.InsightTime Time of the insight
Jask.WorkflowStatus Insight status

 

Command Example

!jask-search-insights last-seen="Last 48 hours" limit=2 assigned-user=unassigned

 

Context Example
{
    "Jask": {
        "Insight": [
            {
                "WorkflowStatus": "new",
                "Description": "Multiple signals related to lateral movement with other anomalies and threats.",
                "InsightTime": "2018-08-04T11:06:14",
                "LastUpdated": "2018-08-04T11:06:15.373616",
                "AssignedTo": "unassigned",
                "Severity": 1,
                "IpAddress": "172.18.20.20",
                "Id": "a01f689c-f7da-4838-bf5c-2046f1736aff",
                "Name": "Insider Threat - Lateral Movement with Increased Traffic"
            },
            {
                "WorkflowStatus": "new",
                "Description": "Multiple signals related to user, network and other threats.",
                "InsightTime": "2018-08-04T11:05:12",
                "LastUpdated": "2018-08-04T11:05:13.654486",
                "AssignedTo": "unassigned",
                "Severity": 1,
                "IpAddress": "^^^172.18.20.20^^^",
                "Id": "88cd2086-126f-4e95-a6c5-dde91f86afb6",
                "Name": "User Anomalies with Beaconing Behavior"
            }
        ]
    }
}

 

Human Readable Output

image

 

8. Search JASK signals


Note: This command is deprecated. Use `sumologic-sec-signal-search` command in Sumo Logic SIEM integration. For further details, visit our Sumo Logic SIEM integration documentation.

Search for JASK signals according to specific criteria.

 

Base Command

jask-search-signals

 

Input
Parameter Description
last-seen When the insight was last seen. Defaults to 'All time' if no time arguments are specified.
source Comma-separated list of values (threatintel, rule, anomaly)
category Comma-separated list of values form options (Attack Stage, C2, Defense Evasion, Discovery, Exfiltration, Exploitation, External Recon, Internal Recon, Lateral Movement, Threat Intelligence, Traffic Anomaly)
offset The page offset for the results
limit The maximum number of signals to retrieve
sort What to sort the results by
time-from Start time for the search (MM/DD/YYYY)
time-to End time for the search (MM/DD/YYYY)

 

Context Output

asdfas

 

Command Example

!jask-search-signals last-seen="Last 24 hours" category="Attack Stage, C2" offset="0" limit="10" sort="score:desc"

 

Context Example
{
    "Jask": {
        "Signal": [
            {
                "Category": "C2",
                "Name": "TeslaCrypt Ransomware Domain",
                "Timestamp": "2018-08-04T11:59:26.447586",
                "ThreatIndicators": [
                    {
                        "Value": "lovemydress.pl",
                        "IndicatorType": "hostname"
                    }
                ],
                "Score": "6",
                "Description": "TeslaCrypt is a ransomware that encrypts documents, databases, code, bitcoin wallets and more. This rule looks for DNS queries that include domains known to be associated with TeslaCrypt.",
                "Id": "79d796dc-97e6-11e8-bdd7-02346534339c",
                "SourceType": "rule"
            },
            {
                "Category": "Attack Stage",
                "Name": "SSH Password Brute Force",
                "Timestamp": "2018-08-04T10:36:35.256445",
                "ThreatIndicators": [
                    {
                        "Value": "104.236.48.178",
                        "IndicatorType": "ip"
                    }
                ],
                "Score": "2",
                "Description": "SSH Password brute force attack detected",
                "Id": "79d790a6-97e6-11e8-bdc7-02346534339c",
                "SourceType": "rule"
            },
            {
                "Category": "Attack Stage",
                "Name": "SSH Password Brute Force",
                "Timestamp": "2018-08-04T11:24:49.534168",
                "ThreatIndicators": [
                    {
                        "Value": "^^^104.236.48.178^^^",
                        "IndicatorType": "ip"
                    }
                ],
                "Score": "2",
                "Description": "SSH Password brute force attack detected",
                "Id": "79d78eb2-97e6-11e8-bdc2-02346534339c",
                "SourceType": "rule"
            }
        ]
    }
}

 

Human Readable Output

image

 

9. Search JASK entities


Note: This command is deprecated. Use `sumologic-sec-entity-search` command in Sumo Logic SIEM integration. For further details, visit our Sumo Logic SIEM integration documentation.

Search for JASK entities according to specific criteria.

 

Base Command

jask-search-entities

 

Input
Parameter Description
last-seen When the insight was last seen. Defaults to 'All time' if no time arguments are specified.
entity-type Comma-separated list of values (username, hostname, ip)
offset The page offset for the results
limit How many results to retrieve
sort What to sort the results by
time-from Start time for the search(MM/DD/YYYY)
time-to End time for the search (MM/DD/YYYY)

 

Context Output
Path Description
Jask.Entity.Id Entity ID
Jask.Entity.Name Entity name
Jask.Entity.FirstSeen When the entity was first seen
Jask.Entity.LastSeen When the entity was last seen
Jask.Entity.Source The source of the entity
Jask.Entity.EntityType Entity type
Jask.Entity.PrimaryEntityType The primary entity type
Jask.Entity.HostName Entity hostname
Jask.Entity.RiskScore Entity risk score
Jask.Entity.IsWhiteListed Whether or not the entity is on allow list
Jask.Entity.Groups The groups of the entity
Jask.Entity.Ip.Address Entity IP address

 

Command Example

!jask-search-entities entity-type=ip limit=3 time-from=08/04/2018 time-to=08/05/2018

 

Context Example
{
    "Jask": {
        "Entity": [
            {
                "EntityType": "ip",
                "Name": "112.175.209.72",
                "Hostname": "Unknown",
                "Source": "discovery",
                "PrimaryEntityType": null,
                "IpAddress": "^^^112.175.209.72^^^",
                "Id": "68fe56f0-4cbc-4664-9227-868069607636"
            },
            {
                "EntityType": "ip",
                "Name": "186.185.91.72",
                "Hostname": "Unknown",
                "Source": "discovery",
                "PrimaryEntityType": null,
                "IpAddress": "^^^186.185.91.72^^^",
                "Id": "ada67af4-a7c1-45f4-9740-69b095ffdac6"
            },
            {
                "EntityType": "ip",
                "Name": "105.102.75.16",
                "Hostname": "Unknown",
                "Source": "discovery",
                "PrimaryEntityType": null,
                "IpAddress": "^^^105.102.75.16^^^",
                "Id": "b3e40046-0450-48a4-8752-6a20aec89143"
            }
        ]
    }
}

 

Human Readable Output

image

 

Configuration parameters

  • URL — Server URL (required)
  • Username — Username (required)
  • APIKey — API Key (required)
  • isFetch — Fetch incidents
  • incidentType — Incident type
  • insecure — Trust any certificate (not secure)
  • proxy — Use system proxy settings
  • fetchQuery — Override default fetch query
  • fetchLimit — Limit the maximum incidents amount per fetch

Commands (9)

  • jask-get-entity-details

    Get entity details for a specific entity ID

  • jask-get-insight-comments

    Get comments for a specific Insight ID. (Users can post and update comments on the JASK SIEM portal for any Insight ID.)

  • jask-get-insight-details

    Get Insight details for a specific Insight ID. Insight details command references SmartAlerts, which are the highest level abstractions in JASK SIEM consisting of multiple signals, and records and relating to one or more assets.

  • jask-get-related-entities

    Get entities related to a specific entity ID.

  • jask-get-signal-details

    Get Signal details for a specific Signal ID. Signal details command references signals in JASK which are created when records exhibit suspicious properties and mate with patterns or other detection logic.

  • jask-get-whitelisted-entities

    Get the entities on allow list.

  • jask-search-entities

    Search entities using the given filters.

  • jask-search-insights

    Search insights using the given filters.

  • jask-search-signals

    Search signals using the given filters.

import demistomock as demisto
from CommonServerPython import *
from CommonServerUserPython import *
import json
from datetime import datetime
import requests

# Disable insecure warnings
requests.packages.urllib3.disable_warnings()

URL = demisto.getParam('URL')
if URL[-1] != '/':
    URL += '/'
QUERY = {'username': demisto.getParam('Username'), 'api_key': demisto.getParam('APIKey')}
FETCH_LIMIT = int(demisto.params().get('fetchLimit', 100))
USE_SSL = not demisto.params().get('insecure', False)


def req(method, path, query):
    """
    Send the request to JASK and return the JSON response
    """
    r = requests.request(method, URL + path, params=query, verify=USE_SSL)
    if r.status_code != requests.codes.ok:
        return_error('Error in API call to Jask service - %s' % r.text)
    if not r.text:
        return {}
    return r.json()


def to_readable(o, fields, translated):
    """
    Convert object properties to nice title readable
    """
    res = {}
    if o:
        for f in fields:
            if o.get(f):
                if translated.get(f):
                    res[translated.get(f)] = o.get(f)
                else:
                    res[f.title().replace('_', '')] = o.get(f)
    return res


def entity_to_readable(entity_json):
    """
    Convert entity response JSON to nicely formatted object
    """
    entity = to_readable(entity_json,
                         ['id', 'name', 'source', 'hostname', 'risk_score', 'is_whitelisted', 'groups', 'asset_type',
                          'firstSeen', 'lastSeen'],
                         {'asset_type': 'EntityType', 'firstSeen': 'FirstSeen', 'lastSeen': 'LastSeen'})
    entity['PrimaryEntityType'] = demisto.get(entity_json, 'current_entity.primary_asset_type')
    return entity


def signal_to_readable(signal_json):
    """
    Convert signal response JSON to nicely formatted object
    """
    signal = to_readable(
        signal_json, ['id', 'name', 'category', 'description', 'score', 'source_type', 'timestamp'], {})
    threat_indicators = demisto.get(signal_json, 'threat_indicators')
    if threat_indicators and isinstance(threat_indicators, dict):
        signal['ThreatIndicators'] = [{
            'IndicatorType': ti.get('indicator_type'),
            'Value': ti.get('value')
        } for ti in threat_indicators]
    return signal


def insight_to_readable(insight_json):
    """
    Convert insight response JSON to nicely formatted object
    """
    insight = to_readable(insight_json,
                          ['id', 'name', 'action', 'assigned_to', 'description', 'last_updated_by', 'last_updated',
                           'severity', 'workflow_status'], {})
    if insight_json.get('record_start_time'):
        insight['InsightTime'] = datetime.utcfromtimestamp(insight_json.get('record_start_time')).isoformat()
    if demisto.get(insight_json, 'ip') and demisto.get(insight_json['ip'], 'address'):
        insight['IpAddress'] = demisto.get(insight_json['ip'], 'address')
    return insight


def convert_string_date_to_unix(dstr):
    """
    Convert a given string with MM/DD/YYYY format to millis since epoch
    """
    d = datetime.strptime(dstr, '%m/%d/%Y')
    return int((d - datetime.utcfromtimestamp(0)).total_seconds() * 1000)


def get_insight_details():
    """
    Get insight details
    """
    alert_id = demisto.getArg('insight-id')
    resp_json = req('GET', 'alert/' + alert_id, QUERY)
    ec = insight_to_readable(resp_json)

    details_md = tableToMarkdown('Insight Details:', [ec],
                                 ['Id', 'Name', 'Action', 'AssignedTo', 'Description', 'IpAddress', 'LastUpdated',
                                  'LastUpdatedBy', 'Severity', 'InsightTime', 'WorkflowStatus'])

    entity_display = entity_to_readable(resp_json.get('asset_details'))
    entity_display.update({'IpAddress': demisto.get(resp_json['asset_details']['ip'], 'address')})
    ec['EntityDetails'] = entity_display
    entity_display['Id'] = resp_json.get('id')

    entity_markdown = tableToMarkdown('Insight\'s Main Entity Details:', [entity_display],
                                      ['Id', 'EntityType', 'Hostname', 'Groups', 'FirstSeen', 'LastSeen', 'IpAddress',
                                       'IsWhitelisted', 'RiskScore', 'Source'])

    related_assets_json = resp_json.get('related_assets') or []
    results_assets_list = []
    for rel_asset in related_assets_json:
        results_asset = to_readable(rel_asset, ['id', 'is_whitelisted', 'risk_score', 'source', 'asset_type'],
                                    {'asset_type': 'EntityType'})
        if rel_asset.get('asset_type') == 'hostname':
            results_asset['Name'] = rel_asset.get('hostname')
        elif rel_asset.get('asset_type') == 'username':
            results_asset['Name'] = rel_asset.get('username')

        if demisto.get(rel_asset, 'ip.address'):
            results_asset['IpAddress'] = demisto.get(rel_asset, 'ip.address')

        results_assets_list.append(results_asset)
    ec['RelatedEntityList'] = results_assets_list
    rel_assets_md = tableToMarkdown('Related Entities:', results_assets_list,
                                    ['Id', 'EntityType', 'IpAddress', 'Name', 'IsWhitelisted', 'RiskScore', 'Source'])

    signal_list_json = resp_json.get('signals') or []
    signal_list = []
    threat_intel = 0
    anomalies = 0
    patterns = 0
    for signal_item in signal_list_json:
        result_signal = signal_to_readable(signal_item)
        source_type = result_signal.get('SourceType', '')
        if source_type == 'threatintel':
            threat_intel += 1
        elif source_type == 'rule':
            patterns += 1
        elif source_type == 'anomaly':
            anomalies += 1
        signal_list.append(result_signal)
    ec['SignalList'] = signal_list
    signals_md = tableToMarkdown('Related Signals:', signal_list,
                                 ['Id', 'Name', 'Description', 'Category', 'SourceType'])
    ec['SignalListMetadata'] = {
        'Patterns': {
            'Count': patterns
        },
        'Anomalies': {
            'Count': anomalies
        },
        'ThreatIntel': {
            'Count': threat_intel
        }
    }
    final_ec = {'Jask.Insight(val.Id === obj.Id)': ec}
    signal_metadata_md = tableToMarkdown('Signal Metadata:', [
        {'Pattern Count': patterns, 'Anomaly Count': anomalies, 'Threat Intel Count': threat_intel}],
        ['Pattern Count', 'Anomaly Count', 'Threat Intel Count'])
    combined_md = details_md + '\n\n' + entity_markdown + '\n\n' + rel_assets_md +\
        '\n\n' + signals_md + '\n\n' + signal_metadata_md
    link = URL.replace('/api/', '/insight/') + alert_id
    md_link = "[" + link + "](" + link + ")"
    combined_md += '\n\n' + md_link
    demisto.results({
        'Type': entryTypes['note'],
        'EntryContext': final_ec,
        'HumanReadable': combined_md,
        'Contents': resp_json,
        'ContentsFormat': formats['json']
    })


def get_insight_comments():
    """
    Get comments for insight
    """
    alert_id = demisto.getArg('insight-id')
    resp_json = req('GET', 'alert/%s/comments' % alert_id, QUERY)
    comments = [to_readable(comment, ['id', 'alert_id', 'author', 'body', 'last_updated', 'timestamp'],
                            {'alert_id': 'InsightId'}) for comment in resp_json['objects']]
    ec = {'Jask.Insight(val.Id == "%s").CommentList': comments}
    md = tableToMarkdown('Insight Comments:', comments,
                         ['Id', 'InsightId', 'Author', 'Body', 'LastUpdated', 'Timestamp'])
    demisto.results({
        'Type': entryTypes['note'],
        'EntryContext': ec,
        'HumanReadable': md,
        'Contents': resp_json,
        'ContentsFormat': formats['json']
    })


def get_signal_details():
    """
    Get signal details
    """
    alert_id = demisto.getArg('signal-id')
    resp_json = req('GET', 'signal/' + alert_id, QUERY)
    signal = signal_to_readable(resp_json)
    md = tableToMarkdown('Insight Signal Details:', [signal],
                         ['Id', 'Name', 'Category', 'Description', 'Score', 'SourceType', 'Timestamp'])

    flow = 0
    notice = 0
    http = 0
    if resp_json.get('extra_records'):
        for record in resp_json.get('extra_records'):
            if record.get('type') == 'http':
                http += 1
            elif record.get('type') == 'flow':
                flow += 1
            elif record.get('type') == 'notice':
                notice += 1
    record_types = [{'RecordType': 'flow', 'RecordCount': flow}, {'RecordType': 'notice', 'RecordCount': notice},
                    {'RecordType': 'http', 'RecordCount': http}]
    if signal.get('ThreatIndicators'):
        md = md + tableToMarkdown('Threat Indicators', signal.get('ThreatIndicators'), ['IndicatorType', 'Value'])
    md = md + tableToMarkdown('Record Metadata', {'Flow Count': flow, 'Notice Count': notice, 'Http Count': http},
                              ['Flow Count', 'Notice Count', 'Http Count'])
    signal['Metadata'] = record_types
    ec = {'Jask.Signal(val.Id === obj.Id)': signal}
    demisto.results({
        'Type': entryTypes['note'],
        'EntryContext': ec,
        'HumanReadable': md,
        'Contents': resp_json,
        'ContentsFormat': formats['json']
    })


def get_entity_details():
    """
    Get entity details
    """
    entity_id = demisto.getArg('entity-id')
    resp_json = req('GET', 'asset/' + entity_id, QUERY)
    entity = entity_to_readable(resp_json)
    md = tableToMarkdown('Entity Details:', [entity],
                         ['Id', 'Name', 'FirstSeen', 'LastSeen', 'Source', 'EntityType', 'PrimaryEntityType',
                          'Hostname', 'RiskScore', 'IsWhitelisted', 'Groups'])
    demisto.results({
        'Type': entryTypes['note'],
        'EntryContext': {'Jask.Entity': entity},
        'HumanReadable': md,
        'Contents': resp_json,
        'ContentsFormat': formats['json']
    })


def get_related_entities():
    """
    Get related entities
    """
    entity_id = demisto.getArg('entity-id')
    resp_json = req('GET', 'asset/%s/related_assets' % entity_id, QUERY)
    entities = [
        to_readable(e,
                    ['id', 'name', 'email', 'source', 'username', 'hostname', 'active', 'admin', 'asset_type',
                     'created_ts', 'firstSeen', 'given_name', 'is_whitelisted', 'lastSeen', 'last_name', 'risk_score',
                     'groups'],
                    {
                        'asset_type': 'EntityType', 'created_ts': 'CreatedTimestamp', 'firstSeen': 'FirstSeen',
                        'lastSeen': 'LastSeen'
                    }) for e in resp_json['objects']
    ]

    ec = {'Jask.RelatedEntityList(val.Id === obj.Id)': entities}
    md = tableToMarkdown('Related Entities:', entities, ['Id', 'Name', 'EntityType', 'FirstSeen', 'LastSeen', 'Source',
                                                         'Hostname', 'Username', 'GivenName', 'Email', 'RiskScore',
                                                         'IsWhitelisted', 'Groups', 'CreatedTimestamp', 'Admin'])
    demisto.results({
        'Type': entryTypes['note'],
        'EntryContext': ec,
        'HumanReadable': md,
        'Contents': resp_json,
        'ContentsFormat': formats['json']
    })


def get_whitelisted_entities():
    """
    Get whitelisted entities
    """
    resp_json = req('GET', 'asset/whitelisted', QUERY)
    items = []
    for whitelisted_item in resp_json.get('objects'):
        w = to_readable(whitelisted_item, ['id', 'name'], {})
        w['ModelId'] = demisto.get(whitelisted_item, 'history.model_id')
        w['Timestamp'] = demisto.get(whitelisted_item, 'history.timestamp')
        w['UserName'] = demisto.get(whitelisted_item, 'history.username')
        items.append(w)
    ec = {
        'Jask.WhiteListed.EntityList(val.Id === obj.Id)': items,
        'Jask.WhiteListed.Metadata.TotalCount': len(items)
    }
    md = tableToMarkdown('Whitelisted:', items,
                         ['Id', 'Name', 'ModelId', 'Timestamp', 'UserName']) + '\n' + '### Count: ' + str(len(items))
    demisto.results({
        'Type': entryTypes['note'],
        'EntryContext': ec,
        'HumanReadable': md,
        'Contents': resp_json,
        'ContentsFormat': formats['json']
    })


def convert_date_to_unix(d):
    """
    Convert a given date to seconds
    """
    return int((d - datetime.utcfromtimestamp(0)).total_seconds() * 1000)


def translate_last_seen(last):
    """
    Convert last-seen argument to querystring
    """
    if not last or last == 'All time':
        return ''
    if last == 'Last week':
        return 'timestamp:[%d TO *]' % (convert_date_to_unix(datetime.utcnow()) - 7 * 24 * 60 * 60 * 1000)
    if last == 'Last 48 hours':
        return 'timestamp:[%d TO *]' % (convert_date_to_unix(datetime.utcnow()) - 2 * 24 * 60 * 60 * 1000)
    if last == 'Last 24 hours':
        return 'timestamp:[%d TO *]' % (convert_date_to_unix(datetime.utcnow()) - 24 * 60 * 60 * 1000)


def _add_list_to_q(q, translate):
    """
    Add arguments in the translate dictionary to querystring
    """
    for v in translate:
        arg_list = argToList(demisto.getArg(translate[v]))
        if len(arg_list) == 1:
            q += ' AND ' + v + ':(%s)' % (arg_list[0])
        elif len(arg_list) > 1:
            q += ' AND ' + v + ':(%s)' % (' OR '.join(arg_list))
    return q


def _add_time_to_q(q):
    """
    Add the time filter to the query string
    Defaults to All time if no fields specified
    """
    last_seen = demisto.getArg('last-seen')
    time_from = demisto.getArg('time-from')
    time_to = demisto.getArg('time-to')
    if last_seen:
        if time_from or time_to:
            return_error('You cannot specify absolute times [time-to, time-from] with relative time [last-seen]')
        else:
            if translate_last_seen(last_seen) != '':
                q += ' AND ' + translate_last_seen(last_seen)
    elif time_from and time_to:
        q += ' AND timestamp:[%d TO %d]' % (
            convert_string_date_to_unix(time_from), convert_string_date_to_unix(time_to))
    elif time_from or time_to:
        return_error('You must specify both absolute times [time-to, time-from] or relative time [last-seen]')
    return q


def search_insights():
    """
    Search insights using available filters
    """
    q = _add_time_to_q('*')
    q = _add_list_to_q(q, {'workflow_status': 'status', 'rating': 'rating', 'group_assigned_to': 'assigned_team',
                           'assigned_to': 'assigned-user'})
    query = QUERY.copy()
    query['q'] = q
    query['offset'] = demisto.getArg('offset')
    query['limit'] = demisto.getArg('limit')
    query['sort_by'] = demisto.getArg('sort')
    resp_json = req('GET', 'search/alerts', query)
    insights = []
    for insight in resp_json['objects']:
        readable_insight = insight_to_readable(insight)
        readable_insight['IpAddress'] = demisto.get(insight, 'asset.ip')
        readable_insight['InsightTime'] = demisto.get(insight, 'timestamp')
        insights.append(readable_insight)
    ec = {'Jask.Insight(val.Id === obj.Id)': insights}
    demisto.results({
        'Type': entryTypes['note'],
        'ContentsFormat': formats['json'],
        'Contents': resp_json,
        'EntryContext': ec,
        'HumanReadable': tableToMarkdown('Insights', insights,
                                         ['Id', 'Name', 'Action', 'AssignedTo', 'Description', 'IpAddress',
                                          'LastUpdated', 'LastUpdatedBy', 'Severity', 'InsightTime', 'WorkflowStatus'])
    })


def search_signals():
    """
    Search signals using available filters
    """
    q = _add_time_to_q('*')
    q = _add_list_to_q(q, {'source_type': 'source', 'category': 'category'})
    query = QUERY.copy()
    query['q'] = q
    query['offset'] = demisto.getArg('offset')
    query['limit'] = demisto.getArg('limit')
    query['sort_by'] = demisto.getArg('sort')
    resp_json = req('GET', 'search/signals', query)
    signals = [signal_to_readable(signal) for signal in resp_json['objects']]
    ec = {'Jask.Signal(val.Id === object.Id)': signals}
    demisto.results({
        'Type': entryTypes['note'],
        'ContentsFormat': formats['json'],
        'Contents': resp_json,
        'EntryContext': ec,
        'HumanReadable': tableToMarkdown('Signals', signals,
                                         ['Id', 'Name', 'Category', 'Description', 'Score', 'SourceType', 'Timestamp',
                                          'ThreatIndicators'])
    })


def search_entities():
    """
    Search entities using the available filters
    """
    q = _add_time_to_q('*')
    q = _add_list_to_q(q, {'asset_type': 'entity-type'})
    query = QUERY.copy()
    query['q'] = q
    query['offset'] = demisto.getArg('offset')
    query['limit'] = demisto.getArg('limit')
    query['sort_by'] = demisto.getArg('sort')
    resp_json = req('GET', 'search/assets', query)
    entities = []
    for entity in resp_json['objects']:
        readable = entity_to_readable(entity)
        readable['IpAddress'] = entity.get('ip')
        entities.append(readable)
    ec = {'Jask.Entity(val.Id === obj.Id)': entities}
    demisto.results({
        'Type': entryTypes['note'],
        'ContentsFormat': formats['json'],
        'Contents': resp_json,
        'EntryContext': ec,
        'HumanReadable': tableToMarkdown('Entities', entities, [
            'Id', 'Name', 'FirstSeen', 'LastSeen', 'Source', 'EntityType', 'PrimaryEntityType', 'Hostname', 'RiskScore',
            'IsWhitelisted', 'Groups', 'IpAddress'
        ])
    })


def translate_severity(severity):
    """
    Translate from Jask insight severity to Demisto severity
    """
    if severity <= 4:
        return severity
    return 4


def fetch_incidents():
    """
    Retrieve new incidents periodically based on pre-defined instance parameters
    """
    now = convert_date_to_unix(datetime.utcnow())
    last_run_object = demisto.getLastRun()
    if last_run_object and last_run_object.get('time'):
        last_run = last_run_object.get('time')
    else:
        last_run = now - 24 * 60 * 60 * 1000
    next_fetch = last_run
    q = '* AND timestamp:[%d TO *]' % last_run
    if demisto.getParam('fetchQuery'):
        q += ' AND ' + demisto.getParam('fetchQuery')
    else:
        q += ' AND workflow_status:(new OR inprogress)'
    query = QUERY.copy()
    query['q'] = q
    query['offset'] = 0
    query['limit'] = FETCH_LIMIT
    query['sort_by'] = 'timestamp:asc'
    resp_json = req('GET', 'search/alerts', query)
    incidents = []
    for a in resp_json['objects']:
        current_fetch = a.get('timestamp')
        if current_fetch:
            try:
                current_fetch = datetime.strptime(current_fetch, "%Y-%m-%dT%H:%M:%S")
            except ValueError:
                current_fetch = datetime.strptime(current_fetch, "%Y-%m-%dT%H:%M:%S.%f")
            current_fetch = convert_date_to_unix(current_fetch)
            if current_fetch > last_run:
                incidents.append({
                    'name': a.get('name', 'No name') + ' - ' + a.get('id'),
                    'occurred': a.get('timestamp') + 'Z',
                    'details': a.get('description'),
                    'severity': translate_severity(a.get('severity')),
                    'rawJSON': json.dumps(a)
                })
            if current_fetch > next_fetch:
                next_fetch = current_fetch

    demisto.incidents(incidents)
    demisto.setLastRun({'time': next_fetch})


def main():
    try:
        handle_proxy()
        if demisto.command() == 'test-module':
            req('GET', 'asset/whitelisted', QUERY)
            demisto.results('ok')
        elif demisto.command() == 'jask-get-insight-details':
            get_insight_details()
        elif demisto.command() == 'jask-get-insight-comments':
            get_insight_comments()
        elif demisto.command() == 'jask-get-signal-details':
            get_signal_details()
        elif demisto.command() == 'jask-get-entity-details':
            get_entity_details()
        elif demisto.command() == 'jask-get-related-entities':
            get_related_entities()
        elif demisto.command() == 'jask-get-whitelisted-entities':
            get_whitelisted_entities()
        elif demisto.command() == 'jask-search-insights':
            search_insights()
        elif demisto.command() == 'jask-search-entities':
            search_entities()
        elif demisto.command() == 'jask-search-signals':
            search_signals()
        elif demisto.command() == 'fetch-incidents':
            fetch_incidents()
        else:
            return_error('Unrecognized command: ' + demisto.command())
    except Exception as e:
        LOG(e)
        LOG.print_log(False)
        return_error(e.message)


# python2 uses __builtin__ python3 uses builtins
if __name__ == "__builtin__" or __name__ == "builtins":
    main()