QRadar_v2 Deprecated

Deprecated. Use the IBM QRadar v3 integration instead. Fetch offenses from QRadar using Cortex XSOAR. Supports API versions until 10.0. You can fetch the offenses with their related events and assets by creating a comma-separated list of event fields.

Analytics & SIEM · IBM QRadar

Details

IDQRadar_v2
ProviderPalo Alto Networks
CategoryAnalytics & SIEM
From Version6.0.0
Docker Imagedemisto/python3:3.12.12.5490952
Supported ModulesAgentix Cloud Runtime Security Cloud Posture Security XSIAM EDR Cortex Cloud

README

Fetch offenses as incidents and search QRadar.
Supports API versions until 10.0.
This integration was integrated and tested with version 7.3.2 of QRadar.

Configure QRadar v2 in Cortex

Parameter Description Required
server Server URL (e.g. https://8.8.8.8) True
credentials Username / API Key (see ‘?’) False
query Query to fetch offenses False
offenses_per_fetch Number of offenses to pull per API call (max 50) False
insecure Trust any certificate (not secure) False
proxy Use system proxy settings False
Long running instance Fetches incidents False
incidentType Incident type False
full_enrich Full Incident Enrichment False
longRunning Long running instance False
events_columns Event columns to return from the events query False
fetch_mode Fetch mode True
events_limit Max number of events per incident False
adv_params Advanced Parameters False

Troubleshooting

This section provides information for troubleshooting performance and fetching issues.

Performance Issues

In some cases, you might encounter performance issues when running QRadar AQL queries from Cortex XSOAR. This issue is caused by QRadar API limitations. We recommend that you test the QRadar API performance by running several cURL scripts.

1. Creating a search

Run the following command to use the QRadar API to create a new search.Save the QUERY ID that is attached to the response for the next step.

curl -H "SEC: <API KEY>" -X POST <QRADAR INSTANCE>/api/ariel/searches?query_expression=<QUERY IN URL SAFE ENCODING>

2. Check if the search status is Complete or Executing

Use the following command to use the QRadar API to check the query status (EXECUTE, COMPLETED, or ERROR).

curl -H "SEC: <API KEY>" -X GET <QRADAR INSTANCE>/api/ariel/searches?<QUERY ID>

Fetching Issues

If the integration fails to fetch with on a Docker timeout error and the enrichment is enabled within the integration configuration, the cause might be releated to a permissions issue with the enrichment.

Adding the following advanced parameter might resolve this issue: DOMAIN_ENRCH_FLG=False

Using API Token authentication

In order to use the integration with an API token you’ll first need to change the Username / API Key (see '?') field to _api_token_key. Following this step, you can now enter the API Token into the Password field - this value will be used as an API key.

Fetch incidents

To start fetching incidents, enable the parameter Long running instance - this will start a long running process that’ll fetch incidents periodically.
Depending on the system load, the initial fetch might take a long time.

Field (Schema) Mapping

The scheme is divided to 4 sections. Offense (root), Events: Builtins, Events: Custom Fields, and Assets.
For more details, see the Classification & Mapping documentation (Cortex XSOAR 6.13) or Classification & Mapping documentation (Cortex XSOAR 8 Cloud) or Classification & Mapping documentation (Cortex XSOAR 8.7 On-prem).

Query to fetch offenses

You can apply additional (optional) filters for the fetch-incident query using the Query to fetch offenses integration parameter. For more information on how to use the filter syntax, see the QRadar filter documentation and QRadar offense documentation.

  • Incident IP Enrichment - When enabled, fetched incidents IP values (local source addresses and local destination addresses) will be fetched from QRadar instead of their ID values.
  • Incident Asset Enrichment - When enabled, fetched offenses will also contain correlated assets.

Reset the “last run” timestamp

To reset fetch incidents, run qradar-reset-last-run - this will reset the fetch to its initial state (will try to fetch first available offense).
Please Note: It is recommended to disable and then enable the QRadar instance for the reset to take effect immediately.

Required Permissions

  • Assets - Vulnerability Management or Assets
  • Domains - Admin
  • Offenses (Manage Closing Reason) - Manage Offense Closing Reasons
  • Offenses (Assign Offenses to Users) - Assign Offenses to Users
  • Offenses (Read) - Offenses
  • References (Create/Update) - admin
  • References (Read) - View Reference Data

Commands

You can execute these commands from the 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.

qradar-offenses


Gets offenses from QRadar

Base Command

qradar-offenses

Input

Argument Name Description Required
filter Query to filter offenses. For reference please consult: https://www.ibm.com/support/knowledgecenter/en/SS42VS_7.3.1/com.ibm.qradar.doc/c_rest_api_filtering.html Optional
fields If used, will filter all fields except for the specified ones. Use this parameter to specify which fields you would like to get back in the response. Fields that are not named are excluded. Specify subfields in brackets and multiple fields in the same object are separated by commas. The filter uses QRadar’s field names, for reference please consult: https://www.ibm.com/support/knowledgecenter/SSKMKU/com.ibm.qradar.doc_cloud/9.1–siem-offenses-GET.html Optional
range Range of results to return. e.g.: 0-20 Optional
headers Table headers to use the human readable output (if none provided, will show all table headers) Optional

Context Output

Path Type Description
QRadar.Offense.Followup boolean Offense followup.
QRadar.Offense.ID number The ID of the offense.
QRadar.Offense.Description string The description of the offense.
QRadar.Offense.SourceAddress Unknown The source addresses that are associated with the offense.
QRadar.Offense.DestinationAddress Unknown The local destination addresses that are associated with the offense. If your offense has a remote destination, you will need to use QRadarFullSearch playbook with the following query - SELECT destinationip FROM events WHERE inOffense(<offenseID>) GROUP BY destinationip
QRadar.Offense.RemoteDestinationCount Unknown The remote destination that are associated with the offesne. If this value is greater than 0 that means your offense has a remote destination, you will need to use QRadarFullSearch playbook with the following query - SELECT destinationip FROM events WHERE inOffense(<offenseID>) GROUP BY destinationip
QRadar.Offense.StartTime date The time (ISO) when the offense was started.
QRadar.Offense.EventCount number The number of events that are associated with the offense.
QRadar.Offense.Magnitude number The magnitude of the offense.
QRadar.Offense.LastUpdatedTime date The time (ISO) when the offense was last updated.
QRadar.Offense.OffenseType string The offense type (due to API limitations if username and password were not provided, this value will be the id of offense type)

Command Example

!qradar-offenses range=0-1 filter="follow_up=false"

Context Example

{
    "QRadar": {
        "Offense": [
            {
                "Description": "Outbound port scan\n",
                "DestinationAddress": [
                    "8.8.8.8,
                ],
                "EventCount": 22,
                "Followup": false,
                "ID": 477,
                "LastUpdatedTime": "2020-08-04T08:37:49.416000Z",
                "Magnitude": 2,
                "OffenseType": "Source IP",
                "RemoteDestinationCount": 4,
                "SourceAddress": [
                    "8.8.8.8
                ],
                "StartTime": "2020-08-04T08:34:21.690000Z"
            },
            {
                "Description": "Multiple Login Failures for the Same User\n preceded by DJM\n preceded by Port Scan detected\n containing Failure Audit: An account failed to log on\n",
                "DestinationAddress": [
                    "8.8.8.8
                ],
                "EventCount": 15,
                "Followup": false,
                "ID": 476,
                "LastUpdatedTime": "2020-08-04T08:37:57.209000Z",
                "Magnitude": 1,
                "OffenseType": "Username",
                "RemoteDestinationCount": 0,
                "SourceAddress": [
                    "8.8.8.8
                ],
                "StartTime": "2020-08-04T08:36:57.209000Z"
            }
        ]
    }
}

Human Readable Output

QRadar offenses

ID Description Followup SourceAddress DestinationAddress RemoteDestinationCount StartTime EventCount Magnitude LastUpdatedTime OffenseType
477 Outbound port scan
false 8.8.8.8 8.8.8.8
8.8.8.8
8.8.8.8
4 2020-08-04T08:34:21.690000Z 22 2 2020-08-04T08:37:49.416000Z Source IP
476 Multiple Login Failures for the Same User
preceded by DJM
preceded by Port Scan detected
containing Failure Audit: An account failed to log on
false ::1,
8.8.8.8
8.8.8.8 0 2020-08-04T08:36:57.209000Z 15 1 2020-08-04T08:37:57.209000Z Username

qradar-offense-by-id


Gets offense with matching offense ID from qradar

Base Command

qradar-offense-by-id

Input

Argument Name Description Required
offense_id Offense ID Required
filter Query to filter offense. For refernce please consult: https://www.ibm.com/support/knowledgecenter/en/SS42VS_7.3.1/com.ibm.qradar.doc/c_rest_api_filtering.html Optional
fields If used, will filter all fields except for the specified ones. Use this parameter to specify which fields you would like to get back in the response. Fields that are not named are excluded. Specify subfields in brackets and multiple fields in the same object are separated by commas. The filter uses QRadar’s field names, for reference please consult: https://www.ibm.com/support/knowledgecenter/SSKMKU/com.ibm.qradar.doc_cloud/9.1–siem-offenses-offense_id-GET.html Optional
headers Table headers to use the human readable output (if none provided, will show all table headers) Optional

Context Output

Path Type Description
QRadar.Offense.Credibility number The credibility of the offense
QRadar.Offense.Relevance number The relevance of the offense
QRadar.Offense.Severity number The severity of the offense
QRadar.Offense.SourceAddress Unknown The source addresses that are associated with the offense.
QRadar.Offense.DestinationAddress Unknown The local destination addresses that are associated with the offense. If your offense has a remote destination, you will need to use QRadarFullSearch playbook with the following query - SELECT destinationip FROM events WHERE inOffense(<offenseID>) GROUP BY destinationip
QRadar.Offense.RemoteDestinationCount Unknown The remote destination that are associated with the offesne. If this value is greater than 0 that means your offense has a remote destination, you will need to use QRadarFullSearch playbook with the following query - SELECT destinationip FROM events WHERE inOffense(<offenseID>) GROUP BY destinationip
QRadar.Offense.AssignedTo string The user the offense is assigned to.
QRadar.Offense.StartTime date The time (ISO) when the offense was started.
QRadar.Offense.ID int The ID of the offense.
QRadar.Offense.DestinationHostname Unknown Destintion hostname
QRadar.Offense.Description string The description of the offense.
QRadar.Offense.EventCount number The number of events that are associated with the offense.
QRadar.Offense.OffenseSource string The source of the offense.
QRadar.Offense.Status string The status of the offense. One of “OPEN”, “HIDDEN”, or “CLOSED”.
QRadar.Offense.Magnitude number The magnitude of the offense.
QRadar.Offense.ClosingUser string The user that closed the offense
QRadar.Offense.ClosingReason string The offense closing reason.
QRadar.Offense.CloseTime date The time when the offense was closed.
QRadar.Offense.LastUpdatedTime date The time (ISO) when the offense was last updated.
QRadar.Offense.Categories Unknown Event categories that are associated with the offense.
QRadar.Offense.FlowCount number The number of flows that are associated with the offense.
QRadar.Offense.FollowUp boolean Offense followup.
QRadar.Offense.OffenseType string A number that represents the offense type
QRadar.Offense.Protected boolean Is the offense protected

Command Example

!qradar-offense-by-id offense_id=450

Context Example

{
    "QRadar": {
        "Offense": {
            "Categories": [
                "Firewall Session Closed",
                "Host Port Scan"
            ],
            "Credibility": 3,
            "Description": "Outbound port scan\n",
            "DestinationAddress": [
                "8.8.8.8
            ],
            "DestinationHostname": [
                "Net-10-172-192.Net_10_0_0_0"
            ],
            "EventCount": 5,
            "FlowCount": 0,
            "Followup": false,
            "ID": 450,
            "LastUpdatedTime": "2020-07-22T14:45:39.082000Z",
            "Magnitude": 2,
            "OffenseSource": "8.8.8.8,
            "OffenseType": "Source IP",
            "Protected": false,
            "Relevance": 0,
            "RemoteDestinationCount": 0,
            "Severity": 5,
            "SourceAddress": [
                "8.8.8.8
            ],
            "StartTime": "2020-07-22T14:40:43.870000Z",
            "Status": "OPEN"
        }
    }
}

Human Readable Output

QRadar Offenses

Categories Credibility Description DestinationAddress DestinationHostname EventCount FlowCount Followup ID LastUpdatedTime Magnitude OffenseSource OffenseType Protected Relevance RemoteDestinationCount Severity SourceAddress StartTime Status
Firewall Session Closed,
Host Port Scan
3 Outbound port scan
8.8.8.8 Net-10-172-192.Net_10_0_0_0 5 0 false 450 2020-07-22T14:45:39.082000Z 2 8.8.8.8 Source IP false 0 0 5 8.8.8.8 2020-07-22T14:40:43.870000Z OPEN

qradar-searches


Searches in QRadar using AQL. It is highly recommended to use the playbook ‘QRadarFullSearch’ instead of this command - it will execute the search, and will return the result.

Base Command

qradar-searches

Input

Argument Name Description Required
query_expression The query expressions in AQL (for more information about Ariel Query Language please review: https://www.ibm.com/docs/en/qsip/7.3.2?topic=qradar-ariel-query-language-aql ) Required
headers Table headers to use the human readable output (if none provided, will show all table headers) Optional

Context Output

Path Type Description
QRadar.Search.ID number Search ID
QRadar.Search.Status string The status of the search.

Command Example

!qradar-searches query_expression="SELECT sourceip AS 'MY Source IPs' FROM events"

Context Example

{
    "QRadar": {
        "Search": {
            "ID": "ddd8ef78-4bff-4453-ab10-24f0fe1fa763",
            "Status": "WAIT"
        }
    }
}

Human Readable Output

QRadar Search

ID Status
ddd8ef78-4bff-4453-ab10-24f0fe1fa763 WAIT

qradar-get-search


Gets a specific search id and status

Base Command

qradar-get-search

Input

Argument Name Description Required
search_id The search id Required
headers Table headers to use the human readable output (if none provided, will show all table headers) Optional

Context Output

Path Type Description
QRadar.Search.ID number Search ID
QRadar.Search.Status string The status of the search.

Command Example

!qradar-get-search search_id=6212b614-074e-41c1-8fcf-1492834576b8

Context Example

{
    "QRadar": {
        "Search": {
            "ID": "6212b614-074e-41c1-8fcf-1492834576b8",
            "Status": "COMPLETED"
        }
    }
}

Human Readable Output

QRadar Search Info

ID Status
6212b614-074e-41c1-8fcf-1492834576b8 COMPLETED

qradar-get-search-results


Gets search results

Base Command

qradar-get-search-results

Input

Argument Name Description Required
search_id The search id Required
range Range of results to return. e.g.: 0-20 Optional
headers Table headers to use the human readable output (if none provided, will show all table headers) Optional
output_path Replaces the default context output path for the query result (QRadar.Search.Result). e.g. for output_path=QRadar.Correlations the result will be under the key “QRadar.Correlations” in the context data. Optional

Context Output

Path Type Description
QRadar.Search.Result Unknown The result of the search

Command Example

!qradar-get-search-results search_id=6212b614-074e-41c1-8fcf-1492834576b8

Context Example

{
    "QRadar": {
        "Search": {
            "Result": {
                "events": [
                    {
                        "MY Source IPs": "8.8.8.8
                    }
                ]
            }
        }
    }
}

Human Readable Output

QRadar Search Results from events

MY Source IPs
8.8.8.8

qradar-update-offense


Update an offense

Base Command

qradar-update-offense

Input

Argument Name Description Required
offense_id The ID of the offense to update Required
protected Set to true to protect the offense Optional
follow_up Set to true to set the follow up flag on the offense Optional
status The new status for the offense Optional
closing_reason_id The id of a closing reason. You must provide a valid closing_reason_name when you close an offense. The default closing_reasons are: (1) False-Positive, Tuned (2) Non-Issues (3) Policy Violation Optional
closing_reason_name The name of a closing reason. You must provide a valid closing_reason_name when you close an offense. The default closing_reasons are: (1) False-Positive, Tuned (2) Non-Issues (3) Policy Violation Optional
assigned_to A user to assign the offense to Optional
fields Use this parameter to specify which fields you would like to get back in the response. Fields that are not named are excluded. Specify subfields in brackets and multiple fields in the same object are separated by commas. Please consult - https://www.ibm.com/support/knowledgecenter/SSKMKU/com.ibm.qradar.doc_cloud/9.1–siem-offenses-offense_id-POST.html Optional

Context Output

Path Type Description
QRadar.Offense.Credibility number The credibility of the offense
QRadar.Offense.Relevance number The relevance of the offense
QRadar.Offense.Severity number The severity of the offense
QRadar.Offense.SourceAddress Unknown The source addresses that are associated with the offense.
QRadar.Offense.DestinationAddress Unknown The destination addresses that are associated with the offense.
QRadar.Offense.AssignedTo string The user the offense is assigned to.
QRadar.Offense.StartTime date The time (ISO) when the offense was started.
QRadar.Offense.ID int The ID of the offense.
QRadar.Offense.DestinationHostname Unknown Destintion hostname
QRadar.Offense.Description string The description of the offense.
QRadar.Offense.EventCount number The number of events that are associated with the offense.
QRadar.Offense.OffenseSource string The source of the offense.
QRadar.Offense.Status string The status of the offense. One of “OPEN”, “HIDDEN”, or “CLOSED”.
QRadar.Offense.Magnitude number The magnitude of the offense.
QRadar.Offense.ClosingUser string The user that closed the offense
QRadar.Offense.ClosingReason string The offense closing reason.
QRadar.Offense.CloseTime date The time when the offense was closed.
QRadar.Offense.LastUpdatedTime date The time (ISO) when the offense was last updated.
QRadar.Offense.Categories Unknown Event categories that are associated with the offense.
QRadar.Offense.FlowCount number The number of flows that are associated with the offense.
QRadar.Offense.FollowUp boolean Offense followup.
QRadar.Offense.OffenseType string A number that represents the offense type
QRadar.Offense.Protected boolean Is the offense protected

Command Example

!qradar-update-offense offense_id=450 protected=false

Context Example

{
    "QRadar": {
        "Offense": {
            "Categories": [
                "Firewall Session Closed",
                "Host Port Scan"
            ],
            "Credibility": 3,
            "Description": "Outbound port scan\n",
            "DestinationAddress": [
                "8.8.8.8
            ],
            "DestinationHostname": [
                "Net-10-172-192.Net_10_0_0_0"
            ],
            "EventCount": 5,
            "FlowCount": 0,
            "Followup": false,
            "ID": 450,
            "LastUpdatedTime": "2020-07-22T14:45:39.082000Z",
            "Magnitude": 2,
            "OffenseSource": "8.8.8.8,
            "OffenseType": "Source IP",
            "Protected": false,
            "Relevance": 0,
            "RemoteDestinationCount": 0,
            "Severity": 5,
            "SourceAddress": [
                "8.8.8.8
            ],
            "StartTime": "2020-07-22T14:40:43.870000Z",
            "Status": "OPEN"
        }
    }
}

Human Readable Output

QRadar Offense

Categories Credibility Description DestinationAddress DestinationHostname EventCount FlowCount Followup ID LastUpdatedTime Magnitude OffenseSource OffenseType Protected Relevance RemoteDestinationCount Severity SourceAddress StartTime Status
Firewall Session Closed,
Host Port Scan
3 Outbound port scan
8.8.8.8 Net-10-172-192.Net_10_0_0_0 5 0 false 450 2020-07-22T14:45:39.082000Z 2 8.8.8.8 Source IP false 0 0 5 8.8.8.8 2020-07-22T14:40:43.870000Z OPEN

qradar-get-assets


List all assets found in the model

Base Command

qradar-get-assets

Input

Argument Name Description Required
filter Query to filter assets. For refernce please consult: https://www.ibm.com/support/knowledgecenter/en/SS42VS_7.3.1/com.ibm.qradar.doc/c_rest_api_filtering.html Optional
fields If used, will filter all fields except for the specified ones. Use this parameter to specify which fields you would like to get back in the response. Fields that are not named are excluded. Specify subfields in brackets and multiple fields in the same object are separated by commas. The filter uses QRadar’s field names, for reference please consult: https://www.ibm.com/support/knowledgecenter/SSKMKU/com.ibm.qradar.doc_cloud/9.1–asset_model-assets-GET.html Optional
range Range of results to return. e.g.: 0-20 Optional
headers Table headers to use the human readable output (if none provided, will show all table headers) Optional

Context Output

Path Type Description
QRadar.Assets.ID number The ID of the asset
Endpoint.IPAddress Unknown IP address of the asset
QRadar.Assets.Name.Value string Name of the asset
Endpoint.OS number Asset OS
QRadar.Assets.AggregatedCVSSScore.Value number CVSSScore
QRadar.Assets.AggregatedCVSSScore.LastUser string Last user who updated the Aggregated CVSS Score
QRadar.Assets.Weight.Value number Asset weight
QRadar.Assets.Weight.LastUser string Last user who updated the weight
QRadar.Assets.Name.LastUser string Last user who updated the name

Command Example

!qradar-get-assets range=0-1

Context Example

{
    "Endpoint": {
        "IPAddress": [
            "8.8.8.8,
            "8.8.8.8
        ]
    },
    "QRadar": {
        "Asset": [
            {
                "ID": 1914,
                "Name": {
                    "LastUser": "IDENTITY:0",
                    "Property Name": "Name",
                    "Value": "ec2.us.compute-1.amazonaws.com"
                }
            },
            {
                "ID": 1928,
                "Name": {
                    "LastUser": "IDENTITY:0",
                    "Property Name": "Name",
                    "Value": "ec2.us.compute-1.amazonaws.com"
                }
            }
        ]
    }
}

Human Readable Output

QRadar Assets

Asset(ID:1914)

LastUser Property Name Value
IDENTITY:0 Name ec2.us.compute-1.amazonaws.com

Asset(ID:1928)

LastUser Property Name Value
IDENTITY:0 Name ec2.us.compute-1.amazonaws.com

Endpoint

IPAddress
8.8.8.8
8.8.8.8

qradar-get-asset-by-id


Retrieves the asset by id

Base Command

qradar-get-asset-by-id

Input

Argument Name Description Required
asset_id The ID of the requested asset. Required

Context Output

Path Type Description
QRadar.Assets.ID number The ID of the asset.
Endpoint.MACAddress Unknown Asset MAC address.
Endpoint.IPAddress Unknown It’s in ip_addresses - value
QRadar.Assets.ComplianceNotes.Value string Compliance notes
QRadar.Assets.CompliancePlan.Value string Compliance plan
QRadar.Assets.CollateralDamagePotential.Value Unknown Collateral damage potential
QRadar.Assets.AggregatedCVSSScore.Value number CVSSScore
QRadar.Assets.Name.Value string Name of the asset
QRadar.Assets.GroupName string Name of the asset’s group
Endpoint.Domain Unknown DNS name
Endpoint.OS Unknown Asset OS
QRadar.Assets.Weight.Value number Asset weight
QRadar.Assets.Vulnerabilities.Value Unknown Vulnerabilities
QRadar.Assets.Location string Location.
QRadar.Assets.Description string The asset description.
QRadar.Assets.SwitchID number Switch ID
QRadar.Assets.SwitchPort number Switch port.
QRadar.Assets.Name.LastUser string Last user who updated the name
QRadar.Assets.AggregatedCVSSScore.LastUser string Last user who updated the Aggregated CVSS Score
QRadar.Assets.Weight.LastUser string Last user who updated the weight
QRadar.Assets.ComplianceNotes.LastUser string Last user who updated the compliance notes
QRadar.Assets.CompliancePlan.LastUser string Last user who updated the compliance plan
QRadar.Assets.CollateralDamagePotential.LastUser string Last user who updated the collateral damage potential
QRadar.Assets.Vulnerabilities.LastUser string Last user who updated the vulnerabilities

Command Example

!qradar-get-asset-by-id asset_id=1928

Context Example

{
    "Endpoint": {
        "IPAddress": [
            "8.8.8.8
        ],
        "MACAddress": [
            "Unknown NIC"
        ]
    },
    "QRadar": {
        "Asset": {
            "ID": 1928,
            "Name": {
                "LastUser": "IDENTITY:0",
                "Property Name": "Name",
                "Value": "ec2.us.compute-1.amazonaws.com"
            }
        }
    }
}

Human Readable Output

QRadar Asset

Asset(ID:1928)

LastUser Property Name Value
IDENTITY:0 Name ec2.us.compute-1.amazonaws.com

Endpoint

IPAddress MACAddress
8.8.8.8 Unknown NIC

qradar-get-closing-reasons


Get closing reasons

Base Command

qradar-get-closing-reasons

Input

Argument Name Description Required
include_reserved If true, reserved closing reasons are included in the response Optional
include_deleted If true, deleted closing reasons are included in the response Optional
filter Query to filter results. For refernce please consult: https://www.ibm.com/support/knowledgecenter/en/SS42VS_7.3.1/com.ibm.qradar.doc/c_rest_api_filtering.html Optional
fields If used, will filter all fields except for the specified ones. Use this parameter to specify which fields you would like to get back in the response. Fields that are not named are excluded. Specify subfields in brackets and multiple fields in the same object are separated by commas. The filter uses QRadar’s field names, for reference please consult: https://www.ibm.com/support/knowledgecenter/SSKMKU/com.ibm.qradar.doc_cloud/9.1–siem-offense_closing_reasons-GET.html Optional
range Range of results to return. e.g.: 0-20 Optional

Context Output

Path Type Description
QRadar.Offense.ClosingReasons.ID number Closing reason ID
QRadar.Offense.ClosingReasons.Name string Closing reason name

Command Example

!qradar-get-closing-reasons include_reserved=false

Context Example

{
    "QRadar": {
        "Offense": {
            "ClosingReasons": [
                {
                    "ID": 2,
                    "IsDeleted": false,
                    "IsReserved": false,
                    "Name": "False-Positive, Tuned"
                },
                {
                    "ID": 1,
                    "IsDeleted": false,
                    "IsReserved": false,
                    "Name": "Non-Issue"
                },
                {
                    "ID": 3,
                    "IsDeleted": false,
                    "IsReserved": false,
                    "Name": "Policy Violation"
                }
            ]
        }
    }
}

Human Readable Output

Offense Closing Reasons

ID Name IsReserved IsDeleted
2 False-Positive, Tuned false false
1 Non-Issue false false
3 Policy Violation false false

qradar-create-note


Create a note on an offense

Base Command

qradar-create-note

Input

Argument Name Description Required
offense_id The offense ID to add the note to Required
note_text The note text Required
fields If used, will filter all fields except for the specified ones. Use this parameter to specify which fields you would like to get back in the response. Fields that are not named are excluded. Specify subfields in brackets and multiple fields in the same object are separated by commas. The filter uses QRadar’s field names, for reference please consult: https://www.ibm.com/support/knowledgecenter/SSKMKU/com.ibm.qradar.doc_cloud/9.1–siem-offenses-offense_id-notes-POST.html Optional
headers Table headers to use the human readable output (if none provided, will show all table headers) Optional

Context Output

Path Type Description
QRadar.Note.ID number Note ID
QRadar.Note.Text string Note text
QRadar.Note.CreateTime date The creation time of the note
QRadar.Note.CreatedBy string The user who created the note

Command Example

!qradar-create-note offense_id=450 note_text="XSOAR has the best documentation!"

Context Example

{
    "QRadar": {
        "Note": {
            "CreateTime": "2020-09-02T08:12:47.314000Z",
            "CreatedBy": "API_user: admin",
            "ID": 1238,
            "Text": "XSOAR has the best documentation!"
        }
    }
}

Human Readable Output

QRadar Note

CreateTime CreatedBy ID Text
2020-09-02T08:12:47.314000Z API_user: admin 1238 XSOAR has the best documentation!

qradar-get-note


Retrieve a note for an offense

Base Command

qradar-get-note

Input

Argument Name Description Required
offense_id The offense ID to retrieve the note from Required
note_id The note ID Optional
fields If used, will filter all fields except for the specified ones. Use this parameter to specify which fields you would like to get back in the response. Fields that are not named are excluded. Specify subfields in brackets and multiple fields in the same object are separated by commas. The filter uses QRadar’s field names, for reference please consult: https://www.ibm.com/support/knowledgecenter/SSKMKU/com.ibm.qradar.doc_cloud/9.1–siem-offenses-offense_id-notes-note_id-GET.html Optional
headers Table headers to use the human readable output (if none provided, will show all table headers) Optional

Context Output

Path Type Description
QRadar.Note.ID number Note ID
QRadar.Note.Text string Note text
QRadar.Note.CreateTime date The creation time of the note
QRadar.Note.CreatedBy string The user who created the note

Command Example

!qradar-get-note offense_id=450 note_id=1232

Context Example

{
    "QRadar": {
        "Note": {
            "CreateTime": "2020-09-02T06:39:24.601000Z",
            "CreatedBy": "API_user: admin",
            "ID": 1232,
            "Text": "XSOAR has the best documentation!"
        }
    }
}

Human Readable Output

QRadar note for offense: 450

CreateTime CreatedBy ID Text
2020-09-02T06:39:24.601000Z API_user: admin 1232 XSOAR has the best documentation!

qradar-get-reference-by-name


Information about the reference set that had data added or updated. This returns information set but not the contained data. This feature is supported from version 8.1 and upward.

Base Command

qradar-get-reference-by-name

Input

Argument Name Description Required
ref_name The name of the requestered reference. Required
headers Table headers to use the human readable output (if none provided, will show all table headers) Optional
date_value If set to true will try to convert the data values to ISO-8601 string. Optional

Context Output

Path Type Description
QRadar.Reference.Name string The name of the reference set.
QRadar.Reference.CreationTime date The creation time (ISO) of the reference.
QRadar.Reference.ElementType string Reference element type.
QRadar.Reference.NumberOfElements number Number of elements.
QRadar.Reference.TimeToLive string Reference time to live.
QRadar.Reference.TimeoutType string Reference timeout type. One of: UNKNOWN, FIRST_SEEN, LAST_SEEN
QRadar.Reference.Data Unknown Reference set items

Command Example

!qradar-get-reference-by-name ref_name=Date date_value=True

Context Example

{
    "QRadar": {
        "Reference": {
            "CreationTime": "2020-09-02T08:12:49.020000Z",
            "ElementType": "DATE",
            "Name": "Date",
            "NumberOfElements": 0,
            "TimeoutType": "UNKNOWN"
        }
    }
}

Human Readable Output

QRadar References

CreationTime ElementType Name NumberOfElements TimeoutType
2020-09-02T08:12:49.020000Z DATE Date 0 UNKNOWN

qradar-create-reference-set


Creates a new reference set. If the provided name is already in use, this command will fail

Base Command

qradar-create-reference-set

Input

Argument Name Description Required
ref_name Reference name to be created Required
element_type The element type for the values allowed in the reference set. The allowed values are: ALN (alphanumeric), ALNIC (alphanumeric ignore case), IP (IP address), NUM (numeric), PORT (port number) or DATE. Note that date values need to be represented in milliseconds since the Unix Epoch January 1st 1970. Required
timeout_type The allowed values are “FIRST_SEEN”, LAST_SEEN and UNKNOWN. The default value is UNKNOWN. Optional
time_to_live The time to live interval, for example: “1 month” or “5 minutes” Optional

Context Output

Path Type Description
QRadar.Reference.CreationTime date Creation time of the reference set.
QRadar.Reference.ElementType string The element type for the values allowed in the reference set. The allowed values are: ALN (alphanumeric), ALNIC (alphanumeric ignore case), IP (IP address), NUM (numeric), PORT (port number) or DATE.
QRadar.Reference.Name string Name of the reference set.
QRadar.Reference.NumberOfElements number Number of elements in the created reference set.
QRadar.Reference.TimeoutType string Timeout type of the reference. The allowed values are FIRST_SEEN, LAST_SEEN and UNKNOWN.

Command Example

!qradar-create-reference-set ref_name=Date element_type=DATE

Context Example

{
    "QRadar": {
        "Reference": {
            "CreationTime": "2020-09-02T08:12:49.020000Z",
            "ElementType": "DATE",
            "Name": "Date",
            "NumberOfElements": 0,
            "TimeoutType": "UNKNOWN"
        }
    }
}

Human Readable Output

QRadar References

CreationTime ElementType Name NumberOfElements TimeoutType
2020-09-02T08:12:49.020000Z DATE Date 0 UNKNOWN

qradar-delete-reference-set


Deletes a reference set corresponding to the name provided.

Base Command

qradar-delete-reference-set

Input

Argument Name Description Required
ref_name The name of reference set to delete. Required

Context Output

There is no context output for this command.

Command Example

!qradar-delete-reference-set ref_name=Date

Context Example

{}

Human Readable Output

Reference Data Deletion Task for ‘Date’ was initiated. Reference set ‘Date’ should be deleted shortly.

qradar-create-reference-set-value


Add or update a value in a reference set.

Base Command

qradar-create-reference-set-value

Input

Argument Name Description Required
ref_name The name of the reference set to add or update a value in. Required
value The value/s to add or update in the reference set. Note: Date values must be represented in epoch in reference sets (milliseconds since the Unix Epoch January 1st 1970). If ‘date_value’ is set to ‘True’, then the argument will be converted from date in format: ‘%Y-%m-%dT%H:%M:%S.%f000Z’ (e.g. ‘2018-11-06T08:56:41.000000Z’) to epoch. Required
source An indication of where the data originated. The default value is ‘reference data api’. Optional
date_value If set to True will convert ‘value’ argument from date in format: ‘%Y-%m-%dT%H:%M:%S.%f000Z’ (e.g. ‘2018-11-06T08:56:41.000000Z’) to epoch. Optional

Context Output

Path Type Description
QRadar.Reference.Name string The name of the reference set.
QRadar.Reference.CreationTime date The creation time (ISO) of the reference.
QRadar.Reference.ElementType string Reference element type.
QRadar.Reference.NumberOfElements number Number of elements.
QRadar.Reference.TimeoutType string Reference timeout type. One of: UNKNOWN, FIRST_SEEN, LAST_SEEN

Command Example

!qradar-create-reference-set-value ref_name=Date value=2018-11-27T11:34:23.110000Z date_value=True

Context Example

{
    "QRadar": {
        "Reference": {
            "CreationTime": "2020-09-02T08:12:49.020000Z",
            "ElementType": "DATE",
            "Name": "Date",
            "NumberOfElements": 1,
            "TimeoutType": "UNKNOWN"
        }
    }
}

Human Readable Output

Element value was updated successfully in reference set

CreationTime ElementType Name NumberOfElements TimeoutType
2020-09-02T08:12:49.020000Z DATE Date 1 UNKNOWN

qradar-update-reference-set-value


Adds or updates a value in a reference set.

Base Command

qradar-update-reference-set-value

Input

Argument Name Description Required
ref_name The name of the reference set to add or update a value in. Required
value A comma-separated list of values to add or update in the reference set. Date values must be represented in milliseconds since the Unix Epoch January 1st 1970. Required
source An indication of where the data originated. The default value is ‘reference data api’. Optional
date_value If set to True will convert ‘value’ argument from date in format: ‘%Y-%m-%dT%H:%M:%S.%f000Z’ (e.g. ‘2018-11-06T08:56:41.000000Z’) to epoch. Optional

Context Output

Path Type Description
QRadar.Reference.Name string The name of the reference set.
QRadar.Reference.CreationTime date The creation time (ISO) of the reference.
QRadar.Reference.ElementType string Reference element type.
QRadar.Reference.NumberOfElements number Number of elements.
QRadar.Reference.TimeoutType string Reference timeout type. One of: UNKNOWN, FIRST_SEEN, LAST_SEEN

Command Example

!qradar-update-reference-set-value ref_name="Documentation Reference" value="Important information" source="Documentation"

Context Example

{
    "QRadar": {
        "Reference": {
            "CreationTime": "2020-09-02T06:45:52.294000Z",
            "ElementType": "ALNIC",
            "Name": "Documentation Reference",
            "NumberOfElements": 1,
            "TimeoutType": "UNKNOWN"
        }
    }
}

Human Readable Output

Element value was updated successfully in reference set

CreationTime ElementType Name NumberOfElements TimeoutType
2020-09-02T06:45:52.294000Z ALNIC Documentation Reference 1 UNKNOWN

qradar-delete-reference-set-value


Deletes a value in a reference set.

Base Command

qradar-delete-reference-set-value

Input

Argument Name Description Required
ref_name The name of the reference set to remove a value from. Required
value The value to remove from the reference set. Required
date_value If set to True will convert ‘value’ argument from date in format: ‘%Y-%m-%dT%H:%M:%S.%f000Z’ (e.g. ‘2018-11-06T08:56:41.000000Z’) to epoch. Optional

Context Output

Path Type Description
QRadar.Reference.Name string The name of the reference set.
QRadar.Reference.CreationTime date The creation time (ISO) of the reference.
QRadar.Reference.ElementType string Reference element type.
QRadar.Reference.NumberOfElements number Number of elements.
QRadar.Reference.TimeoutType string Reference timeout type. One of: UNKNOWN, FIRST_SEEN, LAST_SEEN

Command Example

!qradar-delete-reference-set-value ref_name=Date value=1543318463000

Context Example

{
    "QRadar": {
        "Reference": {
            "CreationTime": "2020-09-02T08:12:49.020000Z",
            "ElementType": "DATE",
            "Name": "Date",
            "NumberOfElements": 0,
            "TimeoutType": "UNKNOWN"
        }
    }
}

Human Readable Output

Element value was deleted successfully in reference set

CreationTime ElementType Name NumberOfElements TimeoutType
2020-09-02T08:12:49.020000Z DATE Date 0 UNKNOWN

qradar-get-domains


Retrieve all Domains

Base Command

qradar-get-domains

Input

Argument Name Description Required
fields If used, will filter all fields except for the specified ones. Use this parameter to specify which fields you would like to get back in the response. Fields that are not named are excluded. Specify subfields in brackets and multiple fields in the same object are separated by commas. The filter uses QRadar’s field names, for reference please consult: https://www.ibm.com/support/knowledgecenter/SSKMKU/com.ibm.qradar.doc_cloud/9.1–siem-offenses-offense_id-notes-note_id-GET.html Optional
range Number of results in return Optional
filter Query to filter offenses Optional

Context Output

Path Type Description
QRadar.Domains.AssetScannerIDs Number Array of Asset Scanner IDs.
QRadar.Domains.CustomProperties String Custom properties of the domain.
QRadar.Domains.Deleted Boolean Indicates if the domain is deleted.
QRadar.Domains.Description String Description of the domain.
QRadar.Domains.EventCollectorIDs Number Array of Event Collector IDs.
QRadar.Domains.FlowCollectorIDs Number Array of Flow Collector IDs.
QRadar.Domains.FlowSourceIDs Number Array of Flow Source IDs.
QRadar.Domains.ID Number ID of the domain.
QRadar.Domains.LogSourceGroupIDs Number Array of Log Source Group IDs.
QRadar.Domains.LogSourceIDs Number Array of Log Source IDs.
QRadar.Domains.Name String Name of the Domain.
QRadar.Domains.QVMScannerIDs Number Array of QVM Scanner IDs.
QRadar.Domains.TenantID Number ID of the Domain tenant.

Command Example


#### Context Example

{
“QRadar”: {
“Domains”: [
{
“Deleted”: false,
“ID”: 0,
“TenantID”: 0
},
{
“Deleted”: true,
“ID”: 1,
“Name”: “QRadarWhiteListIP”,
“TenantID”: 0
}
]
}
}


#### Human Readable Output

>### Domains Found
>
>|AssetScannerIDs|CustomProperties|Deleted|Description|EventCollectorIDs|FlowCollectorIDs|FlowSourceIDs|ID|LogSourceGroupIDs|LogSourceIDs|Name|QVMScannerIDs|TenantID|
>|---|---|---|---|---|---|---|---|---|---|---|---|---|
>|  |  | false |  |  |  |  | 0 |  |  |  |  | 0 |
>|  |  | true |  |  |  |  | 1 |  |  | QRadarWhiteListIP |  | 0 |

### qradar-get-domain-by-id

***
Retrieves Domain information By ID

#### Base Command

`qradar-get-domain-by-id`

#### Input

| **Argument Name** | **Description** | **Required** |
| --- | --- | --- |
| id | ID of the domain | Required |
| fields | If used, will filter all fields except for the specified ones. Use this parameter to specify which fields you would like to get back in the response. Fields that are not named are excluded. Specify subfields in brackets and multiple fields in the same object are separated by commas. The filter uses QRadar's field names, for reference please consult: https://www.ibm.com/support/knowledgecenter/SSKMKU/com.ibm.qradar.doc_cloud/9.1--siem-offenses-offense_id-notes-note_id-GET.html | Optional |

#### Context Output

| **Path** | **Type** | **Description** |
| --- | --- | --- |
| QRadar.Domains.AssetScannerIDs | Number | Array of Asset Scanner IDs. |
| QRadar.Domains.CustomProperties | String | Custom properties of the domain. |
| QRadar.Domains.Deleted | Boolean | Indicates if the domain is deleted. |
| QRadar.Domains.Description | String | Description of the domain. |
| QRadar.Domains.EventCollectorIDs | Number | Array of Event Collector IDs. |
| QRadar.Domains.FlowCollectorIDs | Number | Array of Flow Collector IDs. |
| QRadar.Domains.FlowSourceIDs | Number | Array of Flow Source IDs. |
| QRadar.Domains.ID | Number | ID of the domain. |
| QRadar.Domains.LogSourceGroupIDs | Number | Array of Log Source Group IDs. |
| QRadar.Domains.LogSourceIDs | Number | Array of Log Source IDs. |
| QRadar.Domains.Name | String | Name of the Domain. |
| QRadar.Domains.QVMScannerIDs | Number | Array of QVM Scanner IDs. |
| QRadar.Domains.TenantID | Number | ID of the Domain tenant. |

#### Command Example

```!qradar-get-domain-by-id id=0```

#### Context Example

{
“QRadar”: {
“Domains”: {
“Deleted”: false,
“ID”: 0,
“TenantID”: 0
}
}
}


#### Human Readable Output

>### Domains Found
>
>|Deleted|ID|TenantID|
>|---|---|---|
>| false | 0 | 0 |

### qradar-upload-indicators

***
Uploads indicators from Cortex XSOAR to Qradar.

#### Base Command

`qradar-upload-indicators`

#### Input

| **Argument Name** | **Description** | **Required** |
| --- | --- | --- |
| ref_name | The name of the reference set to add or update a value in. To create a new reference set, you need to set the element type. | Required |
| element_type | The element type for the values premitted in the reference set. Only required when creating a new reference set. The valid values are: ALN (alphanumeric), ALNIC (alphanumeric ignore case), IP (IP address), NUM (numeric), PORT (port number) or DATE. Note that date values need to be represented in milliseconds since the Unix Epoch January 1st 1970. | Optional |
| timeout_type | The timeout_type can be "FIRST_SEEN", "LAST_SEEN", or "UNKNOWN". The default value is UNKNOWN. Only required for creating a new refernce set. | Optional |
| time_to_live | The time to live interval, for example: "1 month" or "5 minutes". Only required when creating a new reference set. | Optional |
| query | The query for getting indicators. | Required |
| limit | The maximum number of indicators to return. The default value is 1000. | Optional |
| page | The page from which to get the indicators | Optional |

#### Context Output

There is no context output for this command.

#### Command Example

```!qradar-upload-indicators query=type:IP ref_name="XSOAR IP Indicators"```

#### Context Example

{}


#### Human Readable Output

>### reference set XSOAR IP Indicators was updated
>
>|Name|ElementType|TimeoutType|CreationTime|NumberOfElements|
>|---|---|---|---|---|
>| XSOAR IP Indicators | ALNIC | UNKNOWN | 2020-09-02T06:59:41.266000Z | 276 |
>
>### Indicators list
>
>|Value|Type|
>|---|---|
>| 8.8.8.8| IP |

### qradar-reset-last-run

***
Reset fetch incidents last run value, which resets the fetch to its initial fetch state (will try to fetch first available offense).

#### Base Command

`qradar-reset-last-run`

#### Input

There are no input arguments for this command.

#### Context Output

There is no context output for this command.

#### Command Example

```!qradar-reset-last-run```

#### Context Example

{}


#### Human Readable Output

>fetch-incidents was reset successfully.

### get-mapping-fields

***
Returns the list of fields for an incident type. This command is for debugging purposes.

#### Base Command

`get-mapping-fields`

#### Input

There are no input arguments for this command.

#### Context Output

There is no context output for this command.

### qradar-get-custom-properties

***
Retrieves a list of event regex properties.

#### Base Command

`qradar-get-custom-properties`

#### Input

| **Argument Name** | **Description** | **Required** |
| --- | --- | --- |
| limit | The maximum number of regex event properties to fetch. Default is 25. | Optional |
| field_name | A comma-separated list of names of exact properties to search for. | Optional |
| fields | A comma-separated list of fields that specifies the fields returned by the command output. When not given, will return all. Options are identifier, name, id, locale, datetime_format, description, username, property_type, auto_discovered, use_for_rule_engine. | Optional |
| like_name | A comma-separated names of a  properties to search for. Case insensitive. | Optional |
| filter | This parameter is used to restrict the elements in a list base on the contents of various fields. | Optional |

#### Context Output

| **Path** | **Type** | **Description** |
| --- | --- | --- |
| QRadar.Properties.auto_discovered | Number | The flag to indicate if the event regex property is generated by custom properties discovery engine. |
| QRadar.Properties.creation_date | Date | The date when the event regex property was created. |
| QRadar.Properties.datetime_format | String | The date/time pattern that the event regex property matches. |
| QRadar.Properties.description | String | The description of the event regex property. |
| QRadar.Properties.id | Number | The sequence ID of the event regex property. |
| QRadar.Properties.identifier | String | The ID of the event regex property. |
| QRadar.Properties.locale | String | The language tag of the locale that the Property matches. |
| QRadar.Properties.modification_date | Date | The date when the event regex property was last modified. |
| QRadar.Properties.name | String | The name of the event regex property. |
| QRadar.Properties.property_type | String | The property type \(STRING, NUMERIC, IP, PORT, TIME\) of event regex property. |
| QRadar.Properties.use_for_rule_engine | Number | The flag to indicate if the event regex property is parsed when the event is received. |
| QRadar.Properties.username | String | The owner of the event regex property. |

#### Command Example

```!qradar-get-custom-properties field_name="AVT-App-Name" like_name="rule" limit=2```

#### Context Example

{
“QRadar”: {
“Properties”: [
{
“auto_discovered”: false,
“creation_date”: “2012-07-04 17:05:02”,
“datetime_format”: null,
“description”: “”,
“id”: 213,
“identifier”: “DEFAULT_ACF2_RULE_KEY”,
“locale”: null,
“modification_date”: “2012-07-04 17:05:02”,
“name”: “ACF2 rule key”,
“property_type”: “string”,
“use_for_rule_engine”: true,
“username”: “admin”
},
{
“auto_discovered”: false,
“creation_date”: “2012-07-04 17:05:02”,
“datetime_format”: null,
“description”: “Rule name why Parity Agent blocked an access to a file.”,
“id”: 222,
“identifier”: “DEFAULT_RULE_NAME”,
“locale”: null,
“modification_date”: “2012-07-04 17:05:02”,
“name”: “Rule Name”,
“property_type”: “string”,
“use_for_rule_engine”: true,
“username”: “admin”
}
]
}
}
```

Human Readable Output

QRadar: Custom Properties

auto_discovered creation_date description id identifier modification_date name property_type use_for_rule_engine username
false 2012-07-04 17:05:02   213 DEFAULT_ACF2_RULE_KEY 2012-07-04 17:05:02 ACF2 rule key string true admin
false 2012-07-04 17:05:02 Rule name why Parity Agent blocked an access to a file. 222 DEFAULT_RULE_NAME 2012-07-04 17:05:02 Rule Name string true admin

Configuration parameters

  • incidentType — Incident type
  • server — Server URL (e.g. https://192.168.0.1) (required)
  • credentials — Username / API Key (see '?')
  • insecure — Trust any certificate (not secure)
  • proxy — Use system proxy settings
  • longRunning — Long running instance
  • query — Query to fetch offenses
  • offenses_per_fetch — Number of offenses to pull per API call (max 50)
  • ip_enrich — Incident IP Enrichment
  • asset_enrich — Incident Asset Enrichment
  • events_columns — Event fields to return from the events query (CAUTION this parameter is correlated to the incoming mapper, and changing the values may adversely affect mapping)
  • fetch_mode — Fetch mode (required)
  • events_limit — Max number of events per incident
  • adv_params — Advanced Parameters

Commands (23)

  • get-mapping-fields

    Returns the list of fields for an incident type. This command should be used for debugging purposes.

  • qradar-create-note

    Create a note on an offense.

  • qradar-create-reference-set

    Creates a new reference set. If the provided name is already in use, this command will fail.

  • qradar-create-reference-set-value

    Add or update a value in a reference set.

  • qradar-delete-reference-set

    Deletes a reference set corresponding to the name provided.

  • qradar-delete-reference-set-value

    Deletes a value in a reference set.

  • qradar-get-asset-by-id

    Retrieves the asset by id.

  • qradar-get-assets

    List all assets found in the model.

  • qradar-get-closing-reasons

    Get closing reasons.

  • qradar-get-custom-properties

    Retrieves a list of event regex properties.

  • qradar-get-domain-by-id

    Retrieves Domain information By ID.

  • qradar-get-domains

    Retrieve all Domains.

  • qradar-get-note

    Retrieve a note for an offense.

  • qradar-get-reference-by-name

    Information about the reference set that had data added or updated. This returns the information set, but not the contained data. This feature is supported from version 8.1 and upward.

  • qradar-get-search

    Gets a specific search id and status.

  • qradar-get-search-results

    Gets search results.

  • qradar-offense-by-id

    Gets offense with matching offense ID from qradar.

  • qradar-offenses

    Gets offenses from QRadar.

  • qradar-reset-last-run

    Reset fetch incidents last run value, which resets the fetch to its initial fetch state (will try to fetch first available offense).

  • qradar-searches

    Searches in QRadar using AQL. It is highly recommended to use the playbook 'QRadarFullSearch' instead of this command - it will execute the search, and will return the result.

  • qradar-update-offense

    Update an offense.

  • qradar-update-reference-set-value

    Adds or updates a value in a reference set.

  • qradar-upload-indicators

    Uploads indicators from Demisto to Qradar.

from copy import deepcopy

from CommonServerPython import DemistoException
import demistomock as demisto
import pytest
import json
import time
import QRadar_v2  # import module separately for mocker
from QRadar_v2 import (
    QRadarClient,
    FetchMode,
    search_command,
    get_search_command,
    get_search_results_command,
    get_assets_command,
    get_asset_by_id_command,
    get_closing_reasons_command,
    create_note_command,
    get_note_command,
    fetch_incidents_long_running_no_events,
    fetch_incidents_long_running_events,
    enrich_offense_with_events,
    try_create_search_with_retry,
    try_poll_offense_events_with_retry,
    enrich_offense_result,
    get_asset_ips_and_enrich_offense_addresses
)

with open("TestData/commands_outputs.json", "r") as f:
    COMMAND_OUTPUTS = json.load(f)
with open("TestData/raw_responses.json", "r") as f:
    RAW_RESPONSES = json.load(f)

QRadar_v2.FAILURE_SLEEP = 0

command_tests = [
    ("qradar-searches", search_command, {"query_expression": "SELECT sourceip AS 'MY Source IPs' FROM events"},),
    ("qradar-get-search", get_search_command, {"search_id": "6212b614-074e-41c1-8fcf-1492834576b8"},),
    ("qradar-get-search-results", get_search_results_command, {"search_id": "6212b614-074e-41c1-8fcf-1492834576b8"},),
    ("qradar-get-assets", get_assets_command, {"range": "0-1"}),
    ("qradar-get-asset-by-id", get_asset_by_id_command, {"asset_id": "1928"}),
    ("qradar-get-closing-reasons", get_closing_reasons_command, {}),
    (
        "qradar-create-note",
        create_note_command,
        {"offense_id": "450", "note_text": "XSOAR has the best documentation!"},
    ),
    ("qradar-get-note", get_note_command, {"offense_id": "450", "note_id": "1232"}),
]


class TestQRadarv2:
    @pytest.mark.parametrize("command,command_func,args", command_tests)
    def test_commands(self, command, command_func, args, mocker):
        """
        Test a set of commands given input->output
        tested commands:
          * qradar-searches
          * qradar-get-search
          * qradar-get-search-results
          * qradar-get-assets
          * qradar-get-asset-by
          * qradar-get-closing-reasons
          * qradar-create-note
          * qradar-get-note

        Given:
            - command - command name
            - command_func - function of command
            - args - arguments for command
        When:
            - Command `command` is being called
        Then:
            - Assert the entryContext matches the COMMAND_OUTPUTS map entry value (expected output)
        """
        client = QRadarClient("", {}, {"identifier": "*", "password": "*"})
        mocker.patch.object(client, "send_request", return_value=RAW_RESPONSES[command])
        mocker.patch.object(demisto, "debug")
        res = command_func(client, **args)
        assert COMMAND_OUTPUTS[command] == res.get("EntryContext")

    def test_fetch_incidents_long_running_no_events(self, mocker):
        """
        Assert fetch_incidents_long_running_no_events updates integration context with the expected id and samples

        Given:
            - Fetch incidents is set to: FetchMode.no_events
            - There is an offense to fetch: 450
        When:
            - Fetch loop is triggered
        Then:
            - Assert integration context id is set correctly
            - Assert integration context samples is set with correct length
        """
        client = QRadarClient("", {}, {"identifier": "*", "password": "*"})
        mocker.patch.object(QRadar_v2, "get_integration_context", return_value={})
        mocker.patch.object(QRadar_v2, "fetch_raw_offenses", return_value=[RAW_RESPONSES["fetch-incidents"]])
        mocker.patch.object(demisto, "createIncidents")
        mocker.patch.object(demisto, "debug")
        sic_mock = mocker.patch.object(QRadar_v2, "set_integration_context")

        fetch_incidents_long_running_no_events(client, '', user_query="", ip_enrich=False, asset_enrich=False)

        assert sic_mock.call_args[0][0]['id'] == 450
        assert len(sic_mock.call_args[0][0]['samples']) == 1

    def test_fetch_incidents_long_running_events__success(self, mocker):
        """
        Assert fetch_incidents_long_running_events updates integration context with the expected id, samples and events

        Given:
            - Fetch incidents is set to: FetchMode.all_events
            - There is an offense to fetch: 450
        When:
            - Fetch loop is triggered
        Then:
            - Assert integration context id is set correctly
            - Assert integration context samples is set with correct length
            - Assert integration context events is set with correct value
        """
        expected_events = "assert ok"

        def mock_enrich_offense_with_events(client, offense, fetch_mode, events_columns, events_limit):
            offense['events'] = expected_events
            return offense

        client = QRadarClient("", {}, {"identifier": "*", "password": "*"})
        fetch_mode = FetchMode.all_events
        mocker.patch.object(QRadar_v2, "get_integration_context", return_value={})
        mocker.patch.object(QRadar_v2, "fetch_raw_offenses", return_value=[RAW_RESPONSES["fetch-incidents"]])
        QRadar_v2.enrich_offense_with_events = mock_enrich_offense_with_events
        mocker.patch.object(demisto, "createIncidents")
        mocker.patch.object(demisto, "debug")
        sic_mock = mocker.patch.object(QRadar_v2, "set_integration_context")

        fetch_incidents_long_running_events(client, "", "", False, False, fetch_mode, "", "")

        assert sic_mock.call_args[0][0]['id'] == 450
        assert len(sic_mock.call_args[0][0]['samples']) == 1
        incident_raw_json = json.loads(sic_mock.call_args[0][0]['samples'][0]['rawJSON'])
        assert incident_raw_json['events'] == expected_events

    def test_fetch_incidents_long_running_events__timeout(self, mocker):
        """
        Assert raw offenses are populated as expected when timeout is reached

        Given:
            - Fetch incidents is set to: FetchMode.all_events
            - There is an offense to fetch: 450
        When:
            - Fetch loop is triggered
        Then:
            - Assert print_debug_msg was called with timeout message
            - Assert integration context id is set correctly
            - Assert integration context samples is set with correct length
            - Assert integration context events is not set
        """
        def mock_enrich_offense_with_events(client, offense, fetch_mode, events_columns, events_limit):
            time.sleep(0.001)
            return offense

        QRadar_v2.DEFAULT_EVENTS_TIMEOUT = 0
        offense_with_no_events = RAW_RESPONSES["fetch-incidents"]
        if 'events' in offense_with_no_events:
            del offense_with_no_events['events']
        client = QRadarClient("", {}, {"identifier": "*", "password": "*"})
        fetch_mode = FetchMode.all_events
        mocker.patch.object(QRadar_v2, "get_integration_context", return_value={})
        mocker.patch.object(QRadar_v2, "fetch_raw_offenses", return_value=[offense_with_no_events])
        print_debug_msg_mock = mocker.patch.object(QRadar_v2, "print_debug_msg")
        QRadar_v2.enrich_offense_with_events = mock_enrich_offense_with_events
        mocker.patch.object(demisto, "createIncidents")
        mocker.patch.object(demisto, "debug")
        sic_mock = mocker.patch.object(QRadar_v2, "set_integration_context")

        fetch_incidents_long_running_events(client, "", "", False, False, fetch_mode, "", "")

        assert print_debug_msg_mock.call_args_list[0].args[0] == "Timed out while waiting for events"
        assert sic_mock.call_args[0][0]['id'] == 450
        assert len(sic_mock.call_args[0][0]['samples']) == 1
        incident_raw_json = json.loads(sic_mock.call_args[0][0]['samples'][0]['rawJSON'])
        assert 'events' not in incident_raw_json
        QRadar_v2.DEFAULT_EVENTS_TIMEOUT = 30

    def test_enrich_offense_with_events__correlations(self, mocker):
        """
        Assert enrich_offense_with_events adds an additional WHERE query when FetchMode.correlations_only

        Given:
            - Fetch incidents is set to: FetchMode.correlations_only
        When:
            - Event fetch query is built via in enrich_offense_with_event
        Then:
            - Assert search is created with additional WHERE query
        """
        client = QRadarClient("", {}, {"identifier": "*", "password": "*"})
        offense = RAW_RESPONSES["fetch-incidents"]
        fetch_mode = FetchMode.correlations_only
        events_cols = ""
        events_limit = ""

        poee_mock = mocker.patch.object(QRadar_v2, "perform_offense_events_enrichment", return_value=offense)
        enrich_offense_with_events(client, offense, fetch_mode, events_cols, events_limit)
        assert poee_mock.call_args[0][1] == "AND LOGSOURCETYPENAME(devicetype) = 'Custom Rule Engine'"

    def test_enrich_offense_with_events__all_events(self, mocker):
        """
        Assert enrich_offense_with_events doesn't add an additional WHERE query when FetchMode.all_events

        Given:
            - Fetch incidents is set to: FetchMode.all_events
        When:
            - Event fetch query is built via in enrich_offense_with_event
        Then:
            - Assert search is created without additional WHERE query
        """
        client = QRadarClient("", {}, {"identifier": "*", "password": "*"})
        offense = RAW_RESPONSES["fetch-incidents"]
        fetch_mode = FetchMode.all_events
        events_cols = ""
        events_limit = ""

        poee_mock = mocker.patch.object(QRadar_v2, "perform_offense_events_enrichment", return_value=offense)
        enrich_offense_with_events(client, offense, fetch_mode, events_cols, events_limit)
        assert poee_mock.call_args[0][1] == ""

    def test_try_create_search_with_retry__semi_happy(self, mocker):
        """
        Create an event search with a connection error first, and succesful try after

        Given:
            - Event fetch is to be created via the qradar client
        When:
            - Search first returns ConnectionError
            - Search then returns search object
        Then:
            - Assert search is created with id and status
        """
        client = QRadarClient("", {}, {"identifier": "*", "password": "*"})
        events_query = ""
        offense = RAW_RESPONSES["fetch-incidents"]
        max_retries = 3

        mocker.patch.object(client, "search", side_effect=[ConnectionError, RAW_RESPONSES["qradar-searches"]])

        actual_status, actual_id = try_create_search_with_retry(client, events_query, offense, max_retries)
        assert actual_status == "EXECUTE"
        assert actual_id == "a135f4cb-c22a-4b3a-aa7d-83058c219d33"

    def test_try_create_search_with_retry__sad(self, mocker):
        """
        Create an event search with a connection error first, and succesful try after

        Given:
            - Event fetch is to be created via the qradar client
        When:
            - Search first returns ConnectionError
            - Search then returns search object
        Then:
            - Assert search is created with id and status
        """
        client = QRadarClient("", {}, {"identifier": "*", "password": "*"})
        events_query = ""
        offense = RAW_RESPONSES["fetch-incidents"]
        max_retries = 0
        exception_raised = False
        mocker.patch.object(client, "search", side_effect=[ConnectionError, RAW_RESPONSES["qradar-searches"]])

        try:
            try_create_search_with_retry(client, events_query, offense, max_retries)
        except DemistoException:
            exception_raised = True
        assert exception_raised

    def test_try_poll_offense_events_with_retry__semi_happy(self, mocker):
        """
        Poll event with a failure, recovery and success flow

        Given:
            - Event fetch is to be polled via the qradar client
        When:
            - Search first returns ConnectionError
            - Search then returns search is COMPLETED
        Then:
            - Assert events are fetched correctly
        """
        client = QRadarClient("", {}, {"identifier": "*", "password": "*"})
        offense_id = 450
        query_status = "EXECUTE"
        search_id = "1"
        max_retries = 3
        expected = [{'MY Source IPs': '8.8.8.8'}]

        mocker.patch.object(QRadar_v2, "is_reset_triggered", return_value=False)
        mocker.patch.object(client, "get_search", side_effect=[ConnectionError, RAW_RESPONSES["qradar-get-search"]])
        mocker.patch.object(client, "get_search_results", return_value=RAW_RESPONSES["qradar-get-search-results"])
        mocker.patch.object(demisto, "debug")
        mocker.patch.object(demisto, "error")

        actual = try_poll_offense_events_with_retry(client, offense_id, query_status, search_id, max_retries)
        assert actual == expected

    def test_try_poll_offense_events_with_retry__sad(self, mocker):
        """
        Poll event with a failure

        Given:
            - Event fetch is to be polled via the qradar client
        When:
            - Search first returns ConnectionError
            - Recovery is set to 0
        Then:
            - Stop fetch and return empty list
        """
        client = QRadarClient("", {}, {"identifier": "*", "password": "*"})
        offense_id = 450
        query_status = "EXECUTE"
        search_id = "1"
        max_retries = 0

        mocker.patch.object(QRadar_v2, "is_reset_triggered", return_value=False)
        mocker.patch.object(client, "get_search", side_effect=[ConnectionError, RAW_RESPONSES["qradar-get-search"]])
        mocker.patch.object(demisto, "debug")
        mocker.patch.object(demisto, "error")

        actual = try_poll_offense_events_with_retry(client, offense_id, query_status, search_id, max_retries)
        assert actual == []

    def test_enrich_offense_result(self, mocker):
        """
        Enrich offense results with assets, domains and rules

        Given:
            - Offense response was fetched from QRadar with rule ids and domain ids
        When:
            - Enriching fetched offense
        Then:
            - domain_name has been added to offense
            - domain_name has been added to offense asset
            - rule name has been added to offense
        """
        closing_reason_dict = [{'is_deleted': False, 'is_reserved': False, 'text': 'False-Positive, Tuned', 'id': 2}]
        offense_types = [{'property_name': 'sourceIP', 'custom': False, 'name': 'Source IP', 'id': 0}]
        domains = [{'name': '', 'tenant_id': 0, 'id': 0, 'log_source_group_ids': []}]
        rules = [{'name': 'Outbound port scan', 'id': 100452}]
        client = QRadarClient("", {}, {"identifier": "*", "password": "*"})
        offense = deepcopy(RAW_RESPONSES["qradar-update-offense"])
        offense['assets'] = deepcopy(RAW_RESPONSES['qradar-get-asset-by-id'])
        response = [offense]

        mocker.patch.object(client, "get_closing_reasons", return_value=closing_reason_dict)
        mocker.patch.object(client, "get_offense_types", return_value=offense_types)
        mocker.patch.object(client, "get_devices", return_value=domains)
        mocker.patch.object(client, "get_rules", return_value=rules)

        enrich_offense_result(client, response)
        assert 'domain_name' in response[0]
        assert 'domain_name' in response[0]['assets'][0]
        assert 'name' in response[0]['rules'][0]

    def test_get_asset_ips_and_enrich_offense_addresses__no_enrich(self):
        """
        Run offense ips enrichment with skip_enrichment=True

        Given:
            - Offense response was fetched from QRadar with source_ip and destination_ip
        When:
            - Enriching fetched offense with skip_enrichment=True
        Then:
            - IPs are not enriched
            - Asset map is returned as a result
        """
        offense = deepcopy(RAW_RESPONSES["qradar-update-offense"])
        src_adrs = {254: '8.8.8.8'}
        dst_adrs = {4: '1.2.3.4'}
        expected = {'8.8.8.8', '1.2.3.4'}
        actual = get_asset_ips_and_enrich_offense_addresses(
            offense, src_adrs, dst_adrs, skip_enrichment=True)
        assert offense == RAW_RESPONSES["qradar-update-offense"]
        assert expected == actual

    def test_get_asset_ips_and_enrich_offense_addresses__with_enrich(self):
        """
        Run offense ips enrichment with skip_enrichment=False

        Given:
            - Offense response was fetched from QRadar with source_ip and destination_ip
        When:
            - Enriching fetched offense with skip_enrichment=False
        Then:
            - IPs are enriched
            - Asset map is returned as a result
        """
        offense = deepcopy(RAW_RESPONSES["qradar-update-offense"])
        src_adrs = {254: '8.8.8.8', 5: '1.2.3.5'}
        dst_adrs = {4: '1.2.3.4'}
        expected_assets = {'8.8.8.8', '1.2.3.4'}
        actual = get_asset_ips_and_enrich_offense_addresses(
            offense, src_adrs, dst_adrs, skip_enrichment=False)
        assert offense != RAW_RESPONSES["qradar-update-offense"]
        assert offense['source_address_ids'] == [src_adrs[254]]
        assert offense['local_destination_address_ids'] == [dst_adrs[4]]
        assert expected_assets == actual

    def test_get_assets_for_offense__empty(self):
        """Check get assets for offense returns an empty list when no value is given

        Given:
        - No assets_ips
        When:
        - Calling get_assets_for_offense
        Then:
        - Return an empty list
        """
        from QRadar_v2 import get_assets_for_offense
        client = QRadarClient("", {}, {"identifier": "*", "password": "*"})
        assert [] == get_assets_for_offense(client, [])

    def test_get_assets_for_offense__happy(self, requests_mock, mocker):
        """Check get assets for offense returns the expected assets

        Given:
        - 1 item in assets_ips
        When:
        - Calling get_assets_for_offense
        Then:
        - Return the asset correlating to assets_ips
        - The asset properties are flatten
        - The interfaces are simplified
        - The assets match the mapping fields
        """
        from QRadar_v2 import get_assets_for_offense, get_mapping_fields
        client = QRadarClient("https://example.com", {}, {"identifier": "*", "password": "*"})
        requests_mock.get(
            'https://example.com/api/asset_model/assets',
            json=RAW_RESPONSES['qradar-get-asset-by-id']
        )
        mocker.patch.object(QRadarClient, 'get_custom_fields', return_value=[])
        mapping_fields = get_mapping_fields(client)

        res = get_assets_for_offense(client, ['8.8.8.8'])
        res_interfaces = res[0]['interfaces'][0]

        assert res[0]['id'] == 1928

        # flatten properties check
        assert res[0]['Unified Name'] == 'ec2.eu.compute-1.amazonaws.com'

        # simplify interfaces check
        assert len(res_interfaces) == 3
        assert res_interfaces['mac_address'] == 'Unknown NIC'
        assert res_interfaces['id'] == 1915
        assert res_interfaces['ip_addresses'] == [{'type': 'IPV4', 'value': '8.8.8.8'}]

        # assets match the mapping fields
        mapping_fields_interfaces = mapping_fields['Assets']['assets']['interfaces']
        assert set(res_interfaces.keys()).issubset(mapping_fields_interfaces.keys())
        assert res_interfaces['ip_addresses'][0].keys() == mapping_fields_interfaces['ip_addresses'].keys()

    def test_get_mapping_fields(self, mocker):
        """Check keys available in the mapping

        Given:
        - One custom field

        When:
        - Calling get-mapping-fields from the UI

        Then:
        - Validate main keys are in
        - Validate custom field came back as intended
        """
        from QRadar_v2 import get_mapping_fields
        custom_fields = [{'name': 'bloop', 'property_type': 'string'}]
        mocker.patch.object(QRadarClient, 'get_custom_fields', return_value=custom_fields)
        client = QRadarClient("", {}, {"identifier": "*", "password": "*"})
        response = get_mapping_fields(client)
        assert response['Offense']
        assert response['Events: Builtin Fields']
        assert response['Assets']
        assert response['Events: Custom Fields']['events']['bloop'] == 'string'

    def test_fetch_event_no_event_field(self, mocker):
        """
        Given:
            - fetch mode: fetching all event
            - events_columns: None

        Then:
            - Run test_module

        Then:
            - Validate DemistoException is raised
        """
        client = QRadarClient('', {}, {"identifier": '*', 'password': '*'})
        mocker.patch.object(client, 'test_connection', return_value=True)
        mocker.patch.object(client, 'get_offenses', return_value=True)
        mocker.patch.object(demisto, 'params', return_value={
            'longRunning': True,
            'fetch_mode': FetchMode.all_events,
            'events_columns': None
        })
        with pytest.raises(DemistoException):
            QRadar_v2.test_module(client)


class TestGetCustomProperties:
    error = 'Can\'t send the `filter` argument with `field_name` or `like_name`'
    client = QRadarClient("https://example.com", {}, {"identifier": "*", "password": "*"})

    def test_filter_with_field_name(self):
        from QRadar_v2 import get_custom_properties_command
        with pytest.raises(DemistoException, match=self.error):
            get_custom_properties_command(self.client, filter='name="hatul"', field_name='b,c')

    def test_filter_with_like_name(self):
        from QRadar_v2 import get_custom_properties_command
        with pytest.raises(DemistoException, match=self.error):
            get_custom_properties_command(self.client, filter='name="hatul"', like_name='b,c')

    def test_filter_with_like_name_and_name_field(self):
        from QRadar_v2 import get_custom_properties_command
        with pytest.raises(DemistoException, match=self.error):
            get_custom_properties_command(self.client, filter='name="hatul"', field_name='a,g', like_name='b,c')

    def test_filter_only(self, requests_mock):
        from QRadar_v2 import get_custom_properties_command
        requests_mock.get(
            'https://example.com/api/config/event_sources/custom_properties/regex_properties?filter=name%3D%22trol%22',
            json=[{'name': 'bloop'}]
        )
        resp = get_custom_properties_command(self.client, filter='name="trol"')
        assert resp['EntryContext']['QRadar.Properties'][0]['name'] == 'bloop'

    def test_name_field_only(self, requests_mock):
        from QRadar_v2 import get_custom_properties_command
        requests_mock.get(
            'https://example.com/api/config/event_sources/custom_properties/regex_properties?filter=name%3D+%22trol%22',
            json=[{'name': 'bloop'}]
        )
        resp = get_custom_properties_command(self.client, field_name='trol')
        assert resp['EntryContext']['QRadar.Properties'][0]['name'] == 'bloop'

    def test_like_name_only(self, requests_mock):
        from QRadar_v2 import get_custom_properties_command
        requests_mock.get(
            'https://example.com/api/config/event_sources/custom_properties/regex_properties?filter=name+ILIKE+%22%25trol%25%22',
            json=[{'name': 'bloop'}]
        )
        resp = get_custom_properties_command(self.client, like_name='trol')
        assert resp['EntryContext']['QRadar.Properties'][0]['name'] == 'bloop'