ArcSight ESM v2

ArcSight ESM SIEM by Micro Focus (Formerly HPE Software).

Analytics & SIEM · ArcSight ESM

Details

IDArcSight ESM v2
ProviderOpenText
CategoryAnalytics & SIEM
From Version5.0.0
Docker Imagedemisto/python3:3.12.13.10116658
Supported ModulesAgentix XSIAM

README

ArcSight ESM

ArcSight ESM is a security information and event management (SIEM) product.
It collects security log data from an enterprise’s security technologies, operating systems, applications and other log sources, and analyzes that data for signs of compromise, attacks or other malicious activity.
The product generates cases to security administrators and analysts.

NOTE

ArcSight XML is no longer supported. Use the ArcSight ESM integration instead.

Use Cases

  1. Fetching events and cases based on a query viewer.
  2. Getting additional information by event or case ID.
  3. Searching for events.
  4. Updating a case or deleting it.
  5. Getting all entries from an active list, updating an entry and clearing the list.

Set up ArcSight ESM to work with Cortex XSOAR

The set up for using ArcSight ESM to work with Cortex XSOAR depends on whether you will be using the integration to fetch events or cases.

For fetching Events/Cases

  1. Create an Event/Case query.

  2. Add a row limit (1000).

  3. Add a start time limit (e.g. $Now-10m).

  4. Go to the following fields and add conditions if needed:

    • Select the Event ID and Start Time fields for Events (mandatory).
    • Select the ID and Create Time fields for Cases (mandatory).
    • Select additional fields of your choice.
    • Add conditions if needed (malicious/suspicious behavior such as malware found, failed login,
      access to a known malicious site and/or conditions like severity, criticality, assets etc).

Note

Cortex XSOAR is designed for an automatic response, so make sure to define conditions for actionable/sever/critical events only.

5.Create a query viewer based on the query.

- In your ArcSight ESM environment, navigate to the Query Viewer > Attributes tab.
- Set the Refresh Data After parameter to 1.
- Configure the rest of the query viewer as necessary.

6.Save the Query Viewer resource ID integration configuration in Cortex XSOAR.

Configure ArcSight ESM on Cortex XSOAR

  1. Navigate to Settings>Integrations>Servers & Services.
  2. Search for ArcSight ESM.
  3. Click Add instance to create and configure a new integration instance.
    • Name: a textual name for the integration instance.
    • Server URL (e.g. https://192.168.0.1:8443): The hostname or IP address of the appliance being used, for example, https://your_arcsight_esm:port.
    • Credentials and Password: Use the username and password used to access the ArcSight ESM account. By default, a user with the admin role will have all the necessary permissions to run all integration commands. For more granular authorization, refer to the ESM documentation on how to create custom roles.
    • Fetch Events as incidents via Query Viewer ID: Must have Start Time and Event ID fields.
    • Fetch Cases as incidents via Query Viewer ID: Must have Create Time and ID fields.
    • The maximum number of unique IDs expected to be fetched: If unique IDs exceeds the maximum, duplicates will be fetched.
    • Do not validate server certificate (unsecured): Select to avoid server certification validation. You may want to do this in case Cortex XSOAR cannot validate the integration server certificate (due to missing CA certificate).
    • Use system proxy settings: Select whether to communicate via the system proxy server or not.
    • Fetch incidents: Mark the Fetch incidents checkbox to automatically create Cortex XSOAR incidents from this integration instance.
    • Incident type: Select the incident type to trigger.
    • Product Version: Select the ArcSight ESM version. 7.4 above using the new Swagger detect-api. Note - not all the commands are using the new API at the moment.
    • Use REST Endpoints: Mark this checkbox to use REST endpoints for the commands related to ‘entries’ instead of the default legacy SOAP endpoints.
  4. Click Test to validate the URLs, token, and connection.
    If you are experiencing issues with the service configuration, please contact Cortex XSOAR support at support@example.com.
  5. After completing the test successfully, press the ‘Done’ button.

Use-Cases

  • Fetch events - New events that match the predefined condition will be fetched to Cortex XSOAR as an incident and will trigger playbooks for automation and response. Such events could be any kind of security events.
  • Fetch cases - New cases that match the predefined condition will be fetched to Cortex XSOAR as an incident and will trigger playbooks for automation and response. Such cases could include any kind of security events. The final step of the playbook could be updating, closing or deleting the case.
  • Search events - Query specific events based on an existing query viewer.
  • Getting active list entries - Returning active list entries (such as “Block list IPS”, “Malicious MD5s”, etc) by using as-get-entries and providing the resource ID of the active list. The entries can be added as a list in Cortex XSOAR for cross-platform usage, additional automation, and data enrichment.

Fetched Incidents Data

The integration can fetch events and cases.

  • When first turned on, the integration fetches all events/cases from the query viewer.
  • The fetched incidents are later filtered by timestamp (start time/create time).
  • In case of slowness, timeouts or crashes try reducing the max fetch parameter.

Commands

You can execute these commands from the Cortex XSOAR CLI, as part of automation, or in a playbook.
After you successfully execute a command, a DBot message appears in the War Room with the command details.

  1. (Deprecated) Get all case resource IDs: as-get-all-cases
  2. Get information for a single case: as-get-case
  3. Get query viewer results: as-get-matrix-data
  4. Add entries to the Active List: as-add-entries
  5. Delete all entries from the Active List: as-clear-entries
  6. Get all entries on the Active List: as-get-entries
  7. Get details for security event: as-get-security-events
  8. Get all case event IDs: as-get-case-event-ids
  9. Update a single case: as-update-case
  10. Get all query viewer IDs: as-get-all-query-viewers
  11. Delete a single case: as-case-delete
  12. Get all query viewer results: as-get-query-viewer-results
  13. Fetches incidents: as-fetch-incidents
  14. Delete entries from the Active List: as-delete-entries

as-get-all-cases


(Deprecated) Retrieves all case resource IDs.

Base Command

as-get-all-cases

Input

There are no input arguments for this command.

Context Output

Path Type Description
ArcSightESM.AllCaseIDs Unknown All case resource IDs

Command Example


#### Context Example

{
“ArcSightESM”: {
“AllCaseIDs”: [
“1234DfGkBABCenF0601F2Ww==”,
“456mUEWcBABD6cSFwTn5Fog==”,
“789pEo2gBABCBcJbK9kU04Q==”,
]
}
}


#### Human Readable Output

>### All cases
>
>|caseID|
>|---|
>| 1234DfGkBABCenF0601F2Ww== |
>| 456mUEWcBABD6cSFwTn5Fog== |
>| 789pEo2gBABCBcJbK9kU04Q== |

### as-get-case

***
Gets information about a single case.

#### Base Command

`as-get-case`

#### Input

| **Argument Name** | **Description** | **Required** |
| --- | --- | --- |
| resourceId | Resource ID of the case to get information for | Required |
| withBaseEvents | If "true", then will return case and base events of that case | Optional |

#### Context Output

| **Path** | **Type** | **Description** |
| --- | --- | --- |
| ArcSightESM.Cases.resourceid | string | Case ID |
| ArcSightESM.Cases.name | string | Case name |
| ArcSightESM.Cases.eventIDs | Unknown | Related base event IDs |
| ArcSightESM.Cases.createdTimestamp | number | Time the case was created \(in milliseconds\) |
| ArcSightESM.Cases.createdTime | string | Created time \(dd\-mm\-yyyyTHH:MM:SS.SSS timezone\) |
| ArcSightESM.Cases.modifiedTimestamp | number | Modified timestamp \(in milliseconds\) |
| ArcSightESM.Cases.modifiedTime | date | Modified time \(dd\-mm\-yyyyTHH:MM:SS.SSS timezone\) |
| ArcSightESM.Cases.action | string | Action \(e.g., BLOCK\_OR\_SHUTDOWN\) |
| ArcSightESM.Cases.associatedImpact | string | Associated impact \(e.g., AVAILABILITY\) |
| ArcSightESM.Cases.attackAgent | string | Attack agent \(e.g., INSIDER\) |
| ArcSightESM.Cases.attackMechanism | string | Attack mechanism \(e.g., PHYSICAL\) |
| ArcSightESM.Cases.consequenceSeverity | string | Consequence severity \(e.g., NONE\) |
| ArcSightESM.Cases.detectionTime | date | Detection time \(dd\-mm\-yyyyTHH:MM:SS.SSS timezone\) |
| ArcSightESM.Cases.displayID | number | Display ID |
| ArcSightESM.Cases.estimatedStartTime | date | Estimated start time \(dd\-mm\-yyyyTHH:MM:SS.SSS timezone\) |
| ArcSightESM.Cases.eventIDs | unknown | Base event IDs |
| ArcSightESM.Cases.frequency | string | Frequency \(e.g., NEVER\_OR\_ONCE\) |
| ArcSightESM.Cases.history | Unknown | History \(e.g., KNOWN\_OCCURENCE\) |
| ArcSightESM.Cases.numberOfOccurences | number | Number Of Occurences |
| ArcSightESM.Cases.resistance | string | Resistance \(e.g., HIGH\) |
| ArcSightESM.Cases.securityClassification | string | Security Classification \(e.g., UNCLASSIFIED\) |
| ArcSightESM.Cases.sensitivity | string | Sensitivity \(e.g., UNCLASSIFIED\) |
| ArcSightESM.Cases.stage | string | Stage \(e.g., QUEUED,INITIAL,FOLLOW\_UP,FINAL,CLOSED\) |
| ArcSightESM.Cases.ticketType | string | Ticket type \(e.g., INTERNAL,CLIENT,INCIDENT\) |
| ArcSightESM.Cases.vulnerability | string | Vulnerability \(e.g., DESIGN\) |

#### Command Example

```!as-get-case resourceId="12ax-uGgBABCWb2puJdY8ZA=="```

#### Context Example

{
“ArcSightESM”: {
“Cases”: {
“URI”: “/All Cases/All Cases/Downloads/test”,
“action”: “BLOCK_OR_SHUTDOWN”,
“associatedImpact”: “AVAILABILITY”,
“attackAgent”: “INSIDER”,
“attackMechanism”: “PHYSICAL”,
“attributeInitializationInProgress”: false,
“consequenceSeverity”: “INSIGNIFICANT”,
“createdDate”: “2019-02-04T12:33:21.000Z”,
“createdTime”: {
“day”: 4,
“hour”: 7,
“milliSecond”: 646,
“minute”: 33,
“month”: 1,
“second”: 21,
“timezoneID”: “America/New_York”,
“year”: 2019
},
“createdTimestamp”: 1549283601646,
“creatorName”: “admin”,
“deprecated”: false,
“detectionTime”: {
“day”: 5,
“hour”: 4,
“milliSecond”: 986,
“minute”: 20,
“month”: 1,
“second”: 41,
“timezoneID”: “America/New_York”,
“year”: 2019
},
“disabled”: false,
“displayID”: 10017,
“estimatedStartTime”: {
“day”: 5,
“hour”: 4,
“milliSecond”: 525,
“minute”: 19,
“month”: 1,
“second”: 55,
“timezoneID”: “America/New_York”,
“year”: 2019
},
“eventIDs”: [
12395741,
45696713,
78996719
],
“frequency”: “NEVER_OR_ONCE”,
“history”: “KNOWN_OCCURENCE”,
“inCache”: false,
“inactive”: false,
“initialized”: true,
“isAdditionalLoaded”: false,
“localID”: 30064771012,
“modificationCount”: 1462,
“modifiedDate”: “2020-05-10T10:42:34.000Z”,
“modifiedTime”: {
“day”: 10,
“hour”: 6,
“milliSecond”: 194,
“minute”: 42,
“month”: 4,
“second”: 34,
“timezoneID”: “America/New_York”,
“year”: 2020
},
“modifiedTimestamp”: 1589107354194,
“modifierName”: “admin”,
“name”: “test”,
“numberOfOccurences”: 0,
“operationalImpact”: “NO_IMPACT”,
“reference”: {
“id”: “12ax-uGgBABCWb2puJdY8ZA==”,
“isModifiable”: true,
“managerID”: “A1xxqmYBABCAXZPTkLg+BA==”,
“referenceName”: “Case”,
“referenceString”: “<Resource URI="/All Cases/All Cases/Downloads/test" ID="12ax-uGgBABCWb2puJdY8ZA=="/>”,
“referenceType”: 7,
“uri”: “/All Cases/All Cases/Downloads/test”
},
“reportingLevel”: 1,
“resistance”: “HIGH”,
“resourceid”: “12ax-uGgBABCWb2puJdY8ZA==”,
“securityClassification”: “UNCLASSIFIED”,
“securityClassificationCode”: “P I D U A B “,
“sensitivity”: “UNCLASSIFIED”,
“stage”: “QUEUED”,
“state”: 2,
“ticketType”: “INTERNAL”,
“type”: 7,
“typeName”: “Case”,
“vulnerability”: “DESIGN”,
“vulnerabilityType1”: “ACCIDENTAL”,
“vulnerabilityType2”: “EMI_RFI”
}
}
}


#### Human Readable Output

>### Case 12ax-uGgBABCWb2puJdY8ZA==
>
>|Action|CaseID|CreatedTime|EventIDs|Name|Severity|Stage|
>|---|---|---|---|---|---|---|
>| BLOCK_OR_SHUTDOWN | 12ax-uGgBABCWb2puJdY8ZA== | 2019-02-04 12:33:21 | 12395741, 45696713, 7896719 | test | INSIGNIFICANT | QUEUED |

### as-get-matrix-data

***
Retrieves query viewer results (query viewer must be configured to be refreshed every minute, see documentation)

#### Base Command

`as-get-matrix-data`

#### Input

| **Argument Name** | **Description** | **Required** |
| --- | --- | --- |
| id | Resource ID of a query viewer | Required |
| onlyColumns | If "true", will return only the columns of the query. If "false", will return the column headers and all query results. | Optional |

#### Context Output

There is no context output for this command.

#### Command Example

```!as-get-matrix-data id=aBBnu5XEBABCJHuGRQA-nwg==```

#### Context Example

{
“ArcSightESM.QueryViewerResults”: [
{
“Alias”: null,
“Create Time”: “1582763229550”,
“Display ID”: “30001”,
“Event-Name”: null,
“ID”: “123nu5XEBABCJHuGRQA-nwg==”,
“Name”: “test1”,
“Originator”: null
},
{
“Alias”: null,
“Create Time”: “1589103446811”,
“Display ID”: “30003”,
“Event-Name”: null,
“ID”: “123gfy-XEBABCAD7Y9AVwrTA==”,
“Name”: “test2”,
“Originator”: null
},
{
“Alias”: null,
“Create Time”: “1588004035004”,
“Display ID”: “30002”,
“Event-Name”: “Login succeeded for user name ‘admin’”,
“ID”: “123lqvHEBABDmMHb-MM+jnA==”,
“Name”: “test3”,
“Originator”: null
},
{
“Alias”: null,
“Create Time”: “1588004035004”,
“Display ID”: “30002”,
“Event-Name”: “ArcSight User Login”,
“ID”: “123lqvHEBABDmMHb-MM+jnA==”,
“Name”: “test4”,
“Originator”: null
}
]
}


#### Human Readable Output

|Column Headers|
|---|
| Name |
| ID |
| Create Time |
| Event-Name |
| Originator |
| Alias |
| Display ID |

### Query Viewer Results: aBBnu5XEBABCJHuGRQA-nwg==

|**Create Time** | **Display ID** | **Event-Name** | **ID** | **Name** |
|---|---|---|---|---|
| 1582763229550 | 30001 |  | 123nu5XEBABCJHuGRQA-nwg== | test1 |
| 1589103446811 | 30003 |  | 123gfy-XEBABCAD7Y9AVwrTA== | test2 |
| 1588004035004 | 30002 | Login succeeded for user name 'admin' | 123lqvHEBABDmMHb-MM+jnA== | test3 |
| 1588004035004 | 30002 | ArcSight User Login | 123lqvHEBABDmMHb-MM+jnA== | test4 |

### as-add-entries

***
Adds new entries to the Active List.

#### Base Command

`as-add-entries`

#### Input

| **Argument Name** | **Description** | **Required** |
| --- | --- | --- |
| resourceId | Resource ID of the Active List | Required |
| entries | Entries are in JSON format. JSON must be an array of entries. Each entry must contain the same columns as they appear in the Active List, e.g., [{ "UserName": "john", "IP":"19.12.13.11"},{ "UserName": "bob", "IP":"22.22.22.22"}] | Required |

#### Context Output

There is no context output for this command.

#### Command Example

```!as-add-entries resourceId="A1LvlmWgBABCA5+HbRyHZoQ==" entries="[{\"name\": \"t3\", \"EventID\": \"9\"},{\"name\": \"t4\", \"EventID\": \"9\"}]"```

#### Context Example

{}


#### Human Readable Output

>Success

### as-clear-entries

***
Deletes all entries in the Active List.

#### Base Command

`as-clear-entries`

#### Input

| **Argument Name** | **Description** | **Required** |
| --- | --- | --- |
| resourceId | Resource ID of a specific Active List | Required |

#### Context Output

There is no context output for this command.

#### Command Example

```!as-clear-entries resourceId="A1LvlmWgBABCA5+HbRyHZoQ=="```

#### Context Example

{}


#### Human Readable Output

>Success

### as-get-entries

***
Returns all entries in the Active List

### Limitations

Returns up to 2000 entries.

#### Base Command

`as-get-entries`

#### Input

| **Argument Name** | **Description** | **Required** |
| --- | --- | --- |
| resourceId | Resource ID of a specific Active List | Required |
| entryFilter | Filters the entries, e.g., entryFilter="moo:moo1" | Optional |

#### Context Output

| **Path** | **Type** | **Description** |
| --- | --- | --- |
| ArcSightESM.ActiveList | Unknown | Active List is a map of active list resource id =&gt; active list entries |
| ArcSightESM.ActiveList.ListID | list | The ActiveList ID |
| ArcSightESM.ActiveList.Entries | Unknown | Active List is a map of active list resource id =&gt; active list |

#### Command Example

```!as-get-entries resourceId=A1LvlmWgBABCA5+HbRyHZoQ==```

#### Context Example

{
“ArcSightESM”: {
“ActiveList”: {
“A1LvlmWgBABCA5+HbRyHZoQ==”: [
{
“eventId”: “9”,
“startDate”: “None”,
“name”: “T4”,
“startTime”: “31 Dec 1969 19:00:00 EST”
},
{
“eventId”: “9”,
“startDate”: “None”,
“name”: “T3”,
“startTime”: “31 Dec 1969 19:00:00 EST”
}
]
}
}
}


#### Human Readable Output

>|Columns|
>|---|
>| eventId |
>| name |
>| startTime |
>Active List has no entries

### as-get-security-events

***
Returns the security event details

#### Base Command

`as-get-security-events`

#### Input

| **Argument Name** | **Description** | **Required** |
| --- | --- | --- |
| ids | ID or multiple ids separated by comma of security events. Event ID is ArcSight is always a number. Example: 13906590 | Required |
| lastDateRange | Query last events. Format follows 'number date_range_unit', e.g., 2 hours, 4 minutes, 6 month, 1 day | Optional |

#### Context Output

| **Path** | **Type** | **Description** |
| --- | --- | --- |
| ArcSightESM.SecurityEvents | Unknown | List of security events |
| ArcSightESM.SecurityEvents.name | string | Event name |
| ArcSightESM.SecurityEvents.eventId | number | Event ID |
| ArcSightESM.SecurityEvents.type | string | Event type \(e.g., CORRELATION\) |
| ArcSightESM.SecurityEvents.baseEventIds | Unknown | Base event IDs |
| ArcSightESM.SecurityEvents.source.address | Unknown | Event source address |
| ArcSightESM.SecurityEvents.destination.address | Unknown | Event destination address |
| ArcSightESM.SecurityEvents.startTime | date | Start time in milliseconds |

#### Command Example

```!as-get-security-events ids=12352349,45652798```

#### Context Example

{
“ArcSightESM”: {
“SecurityEvents”: [
{
“agent”: {
“address”: “1.1.1.1”,
“addressAsBytes”: “abgBRQ==”,
“assetId”: “123xxqmYBABCAWiGUuYaX-w==”,
“assetLocalId”: 17179869185,
“assetName”: “xsoar-example”,
“decodedAddress”: “1.1.1.1”,
“hostName”: “xsoar-example”,
“id”: “123xxqmYBABCAY8SQ92zN9g==”,
“mutable”: true,
“name”: “Manager Internal Agent”,
“type”: “arcsight_security_manager”,
“version”: “7.0.0.2436.1”,
“zone”: {
“id”: “12332AABABCDVFpYAT3UdQ==”,
“isModifiable”: false,
“managerID”: “123xqmYBABCAXZPTkLg+BA==”,
“referenceID”: 1102,
“referenceName”: “Zone”,
“referenceString”: “<Resource URI="/All Zones/ArcSight System/Private Address Space Zones/RFC1918: 192.168.0.0-192.168.255.255" ID="123U32AABABCDVFpYAT3UdQ=="/>”,
“referenceType”: 29,
“uri”: “/All Zones/ArcSight System/Private Address Space Zones/RFC1918: 192.168.0.0-192.168.255.255”
}
},
“agentSeverity”: 1,
“aggregatedEventCount”: 1,
“assetCriticality”: 0,
“baseEventCount”: 0,
“category”: {
“behavior”: “/Execute/Response”,
“deviceGroup”: “/Application”,
“mutable”: true,
“object”: “/Host/Application”,
“outcome”: “/Success”,
“significance”: “/Informational”
},
“concentratorAgents”: {
“address”: “1.1.1.1”,
“addressAsBytes”: “abgBRQ==”,
“assetId”: “123xxqmYBABCAWiGUuYaX-w==”,
“assetLocalId”: 17179869185,
“assetName”: “xsoar-example”,
“decodedAddress”: “1.1.1.1”,
“hostName”: “xsoar-example”,
“id”: “123xxqmYBABCAY8SQ92zN9g==”,
“mutable”: true,
“name”: “Manager Internal Agent”,
“type”: “arcsight_security_manager”,
“version”: “7.0.0.2436.1”,
“zone”: {
“id”: “12332AABABCDVFpYAT3UdQ==”,
“isModifiable”: false,
“managerID”: “123xqmYBABCAXZPTkLg+BA==”,
“referenceID”: 1102,
“referenceName”: “Zone”,
“referenceString”: “<Resource URI="/All Zones/ArcSight System/Private Address Space Zones/RFC1918: 192.168.0.0-192.168.255.255" ID="12U32AABABCDVFpYAT3UdQ=="/>”,
“referenceType”: 29,
“uri”: “/All Zones/ArcSight System/Private Address Space Zones/RFC1918: 192.168.0.0-192.168.255.255”
}
},
“concentratorDevices”: {
“address”: “1.1.1.1”,
“addressAsBytes”: “abgBRQ==”,
“assetId”: “126xxqmYBABCAWiGUuYaX-w==”,
“assetLocalId”: 17179869185,
“assetName”: “xsoar-example”,
“decodedAddress”: “1.1.1.1”,
“hostName”: “xsoar-example”,
“mutable”: true,
“product”: “ArcSight”,
“vendor”: “ArcSight”,
“version”: “7.0.0.2436.1”,
“zone”: {
“id”: “12U32AABABCDVFpYAT3UdQ==”,
“isModifiable”: false,
“managerID”: “12xxqmYBABCAXZPTkLg+BA==”,
“referenceID”: 1102,
“referenceName”: “Zone”,
“referenceString”: “<Resource URI="/All Zones/ArcSight System/Private Address Space Zones/RFC1918: 192.168.0.0-192.168.255.255" ID="12fU32AABABCDVFpYAT3UdQ=="/>”,
“referenceType”: 29,
“uri”: “/All Zones/ArcSight System/Private Address Space Zones/RFC1918: 192.168.0.0-192.168.255.255”
}
},
“correlatedEventCount”: 0,
“destination”: {
“address”: “1.1.1.1”,
“addressAsBytes”: “abgBRQ==”,
“assetId”: “126xxqmYBABCAWiGUuYaX-w==”,
“assetLocalId”: 17179869185,
“assetName”: “xsoar-example”,
“decodedAddress”: “1.1.1.1”,
“geo”: {
“latitude”: 0,
“latitudeLong”: 0,
“longitude”: 0,
“longitudeLong”: 0,
“mutable”: true
},
“hostName”: “xsoar-example”,
“mutable”: true,
“zone”: {
“id”: “12U32AABABCDVFpYAT3UdQ==”,
“isModifiable”: false,
“managerID”: “12xxqmYBABCAXZPTkLg+BA==”,
“referenceID”: 1102,
“referenceName”: “Zone”,
“referenceString”: “<Resource URI="/All Zones/ArcSight System/Private Address Space Zones/RFC1918: 192.168.0.0-192.168.255.255" ID="12U32AABABCDVFpYAT3UdQ=="/>”,
“referenceType”: 29,
“uri”: “/All Zones/ArcSight System/Private Address Space Zones/RFC1918: 192.168.0.0-192.168.255.255”
}
},
“device”: {
“address”: “1.1.1.1”,
“addressAsBytes”: “abgBRQ==”,
“assetId”: “126xxqmYBABCAWiGUuYaX-w==”,
“assetLocalId”: 17179869185,
“assetName”: “xsoar-example”,
“decodedAddress”: “1.1.1.1”,
“hostName”: “xsoar-example”,
“mutable”: true,
“product”: “ArcSight”,
“vendor”: “ArcSight”,
“version”: “7.0.0.2436.1”,
“zone”: {
“id”: “12fU32AABABCDVFpYAT3UdQ==”,
“isModifiable”: false,
“managerID”: “12xxqmYBABCAXZPTkLg+BA==”,
“referenceID”: 1102,
“referenceName”: “Zone”,
“referenceString”: “<Resource URI="/All Zones/ArcSight System/Private Address Space Zones/RFC1918: 192.168.0.0-192.168.255.255" ID="12fU32AABABCDVFpYAT3UdQ=="/>”,
“referenceType”: 29,
“uri”: “/All Zones/ArcSight System/Private Address Space Zones/RFC1918: 192.168.0.0-192.168.255.255”
}
},
“deviceCustom”: {
“mutable”: true,
“number1Label”: “Temporary Active list usage (Percent)”,
“string1Label”: “Unit”,
“string2Label”: “Time Frame”
},
“deviceCustomNumber1”: 0,
“deviceCustomString1”: “Percent”,
“deviceCustomString2”: “current value”,
“deviceEventCategory”: “/Monitor/ActiveLists/TemporaryPercentageUsed”,
“deviceEventClassId”: “monitor:121”,
“deviceReceiptDate”: “2020-05-07T14:43:00.000Z”,
“deviceReceiptTime”: 1588862580001,
“deviceSeverity”: “Warning”,
“endDate”: “2020-05-07T14:43:00.000Z”,
“endTime”: 1588862580001,
“eventAnnotation”: {
“auditTrail”: “1,1589114529805,root,Queued,,,,”,
“endDate”: “2020-05-07T14:43:00.000Z”,
“endTime”: 1588862580001,
“eventId”: 12352349,
“flags”: 0,
“managerReceiptDate”: “2020-05-07T14:43:00.000Z”,
“managerReceiptTime”: 1588862580001,
“modificationDate”: “2020-05-07T14:43:00.000Z”,
“modificationTime”: 1588862580001,
“stage”: {
“id”: “123HiNfoAABCASsxbPIxG0g==”,
“isModifiable”: false,
“managerID”: “123qmYBABCAXZPTkLg+BA==”,
“referenceID”: 2209,
“referenceName”: “Stage”,
“referenceString”: “<Resource URI="/All Stages/Queued" ID="12MHiNfoAABCASsxbPIxG0g=="/>”,
“referenceType”: 34,
“uri”: “/All Stages/Queued”
},
“stageUpdateDate”: “2020-05-07T14:43:00.000Z”,
“stageUpdateTime”: 1588862580001,
“version”: 1
},
“eventId”: 12352349,
“finalDevice”: {
“address”: “1.1.1.1”,
“addressAsBytes”: “abgBRQ==”,
“assetId”: “123xxqmYBABCAWiGUuYaX-w==”,
“assetLocalId”: 17179869185,
“assetName”: “xsoar-example”,
“decodedAddress”: “1.1.1.1”,
“hostName”: “xsoar-example”,
“mutable”: true,
“product”: “ArcSight”,
“vendor”: “ArcSight”,
“version”: “7.0.0.2436.1”,
“zone”: {
“id”: “123U32AABABCDVFpYAT3UdQ==”,
“isModifiable”: false,
“managerID”: “123xqmYBABCAXZPTkLg+BA==”,
“referenceID”: 1102,
“referenceName”: “Zone”,
“referenceString”: “<Resource URI="/All Zones/ArcSight System/Private Address Space Zones/RFC1918: 192.168.0.0-192.168.255.255" ID="123U32AABABCDVFpYAT3UdQ=="/>”,
“referenceType”: 29,
“uri”: “/All Zones/ArcSight System/Private Address Space Zones/RFC1918: 192.168.0.0-192.168.255.255”
}
},
“locality”: 0,
“managerId”: -128,
“managerReceiptDate”: “2020-05-07T14:43:00.000Z”,
“managerReceiptTime”: 1588862580001,
“modelConfidence”: 4,
“name”: “Monitor Event”,
“originalAgent”: {
“address”: “1.1.1.1”,
“addressAsBytes”: “abgBRQ==”,
“assetId”: “123xxqmYBABCAWiGUuYaX-w==”,
“assetLocalId”: 17179869185,
“assetName”: “xsoar-example”,
“decodedAddress”: “1.1.1.1”,
“hostName”: “xsoar-example”,
“id”: “123xxqmYBABCAY8SQ92zN9g==”,
“mutable”: true,
“name”: “Manager Internal Agent”,
“type”: “arcsight_security_manager”,
“version”: “7.0.0.2436.1”,
“zone”: {
“id”: “123U32AABABCDVFpYAT3UdQ==”,
“isModifiable”: false,
“managerID”: “123xqmYBABCAXZPTkLg+BA==”,
“referenceID”: 1102,
“referenceName”: “Zone”,
“referenceString”: “<Resource URI="/All Zones/ArcSight System/Private Address Space Zones/RFC1918: 192.168.0.0-192.168.255.255" ID="123U32AABABCDVFpYAT3UdQ=="/>”,
“referenceType”: 29,
“uri”: “/All Zones/ArcSight System/Private Address Space Zones/RFC1918: 192.168.0.0-192.168.255.255”
}
},
“originator”: “SOURCE”,
“priority”: 3,
“relevance”: 10,
“severity”: 0,
“startDate”: “2020-05-07T14:43:00.000Z”,
“startTime”: 1588862580001,
“ttl”: 10,
“type”: “BASE”
},
{
“agent”: {
“address”: “1.1.1.1”,
“addressAsBytes”: “abgBRQ==”,
“assetId”: “123xxqmYBABCAWiGUuYaX-w==”,
“assetLocalId”: 17179869185,
“assetName”: “xsoar-example”,
“decodedAddress”: “1.1.1.1”,
“hostName”: “xsoar-example”,
“id”: “123xxqmYBABCAY8SQ92zN9g==”,
“mutable”: true,
“name”: “Manager Internal Agent”,
“type”: “arcsight_security_manager”,
“version”: “7.0.0.2436.1”,
“zone”: {
“id”: “12332AABABCDVFpYAT3UdQ==”,
“isModifiable”: false,
“managerID”: “123xqmYBABCAXZPTkLg+BA==”,
“referenceID”: 1102,
“referenceName”: “Zone”,
“referenceString”: “<Resource URI="/All Zones/ArcSight System/Private Address Space Zones/RFC1918: 192.168.0.0-192.168.255.255" ID="123U32AABABCDVFpYAT3UdQ=="/>”,
“referenceType”: 29,
“uri”: “/All Zones/ArcSight System/Private Address Space Zones/RFC1918: 192.168.0.0-192.168.255.255”
}
},
“agentSeverity”: 1,
“aggregatedEventCount”: 1,
“assetCriticality”: 0,
“baseEventCount”: 0,
“category”: {
“behavior”: “/Authentication/Verify”,
“deviceGroup”: “/Application”,
“mutable”: true,
“object”: “/Host/Application”,
“outcome”: “/Success”,
“significance”: “/Normal”
},
“concentratorAgents”: {
“address”: “1.1.1.1”,
“addressAsBytes”: “abgBRQ==”,
“assetId”: “123xxqmYBABCAWiGUuYaX-w==”,
“assetLocalId”: 17179869185,
“assetName”: “xsoar-example”,
“decodedAddress”: “1.1.1.1”,
“hostName”: “xsoar-example”,
“id”: “123xxqmYBABCAY8SQ92zN9g==”,
“mutable”: true,
“name”: “Manager Internal Agent”,
“type”: “arcsight_security_manager”,
“version”: “7.0.0.2436.1”,
“zone”: {
“id”: “123U32AABABCDVFpYAT3UdQ==”,
“isModifiable”: false,
“managerID”: “123xqmYBABCAXZPTkLg+BA==”,
“referenceID”: 1102,
“referenceName”: “Zone”,
“referenceString”: “<Resource URI="/All Zones/ArcSight System/Private Address Space Zones/RFC1918: 192.168.0.0-192.168.255.255" ID="123U32AABABCDVFpYAT3UdQ=="/>”,
“referenceType”: 29,
“uri”: “/All Zones/ArcSight System/Private Address Space Zones/RFC1918: 192.168.0.0-192.168.255.255”
}
},
“concentratorDevices”: {
“address”: “1.1.1.1”,
“addressAsBytes”: “abgBRQ==”,
“assetId”: “123xxqmYBABCAWiGUuYaX-w==”,
“assetLocalId”: 17179869185,
“assetName”: “xsoar-example”,
“decodedAddress”: “1.1.1.1”,
“hostName”: “xsoar-example”,
“mutable”: true,
“product”: “ArcSight”,
“vendor”: “ArcSight”,
“version”: “7.0.0.2436.1”,
“zone”: {
“id”: “123U32AABABCDVFpYAT3UdQ==”,
“isModifiable”: false,
“managerID”: “123xqmYBABCAXZPTkLg+BA==”,
“referenceID”: 1102,
“referenceName”: “Zone”,
“referenceString”: “<Resource URI="/All Zones/ArcSight System/Private Address Space Zones/RFC1918: 192.168.0.0-192.168.255.255" ID="123U32AABABCDVFpYAT3UdQ=="/>”,
“referenceType”: 29,
“uri”: “/All Zones/ArcSight System/Private Address Space Zones/RFC1918: 192.168.0.0-192.168.255.255”
}
},
“correlatedEventCount”: 0,
“destination”: {
“address”: “1.1.1.1”,
“addressAsBytes”: “abgBRQ==”,
“assetId”: “123xxqmYBABCAWiGUuYaX-w==”,
“assetLocalId”: 17179869185,
“assetName”: “xsoar-example”,
“decodedAddress”: “1.1.1.1”,
“geo”: {
“latitude”: 0,
“latitudeLong”: 0,
“longitude”: 0,
“longitudeLong”: 0,
“mutable”: true
},
“hostName”: “xsoar-example”,
“mutable”: true,
“port”: 8443,
“userId”: “123FwqmYBABCA23X2wprUSg==”,
“userName”: “admin”,
“zone”: {
“id”: “12332AABABCDVFpYAT3UdQ==”,
“isModifiable”: false,
“managerID”: “123xqmYBABCAXZPTkLg+BA==”,
“referenceID”: 1102,
“referenceName”: “Zone”,
“referenceString”: “<Resource URI="/All Zones/ArcSight System/Private Address Space Zones/RFC1918: 192.168.0.0-192.168.255.255" ID="12332AABABCDVFpYAT3UdQ=="/>”,
“referenceType”: 29,
“uri”: “/All Zones/ArcSight System/Private Address Space Zones/RFC1918: 192.168.0.0-192.168.255.255”
}
},
“device”: {
“address”: “1.1.1.1”,
“addressAsBytes”: “abgBRQ==”,
“assetId”: “123xxqmYBABCAWiGUuYaX-w==”,
“assetLocalId”: 17179869185,
“assetName”: “xsoar-example”,
“decodedAddress”: “1.1.1.1”,
“hostName”: “xsoar-example”,
“mutable”: true,
“product”: “ArcSight”,
“vendor”: “ArcSight”,
“version”: “7.0.0.2436.1”,
“zone”: {
“id”: “123U32AABABCDVFpYAT3UdQ==”,
“isModifiable”: false,
“managerID”: “123xqmYBABCAXZPTkLg+BA==”,
“referenceID”: 1102,
“referenceName”: “Zone”,
“referenceString”: “<Resource URI="/All Zones/ArcSight System/Private Address Space Zones/RFC1918: 192.168.0.0-192.168.255.255" ID="123U32AABABCDVFpYAT3UdQ=="/>”,
“referenceType”: 29,
“uri”: “/All Zones/ArcSight System/Private Address Space Zones/RFC1918: 192.168.0.0-192.168.255.255”
}
},
“deviceCustom”: {
“mutable”: true,
“string2Label”: “Configuration Resource”,
“string3Label”: “Login Type”,
“string4Label”: “Session ID”,
“string5Label”: “Client Version”,
“string6Label”: “Client ID”
},
“deviceCustomString2”: “<Resource URI="/All Users/Administrators/admin" ID="12GFwqmYBABCA23X2wprUSg=="/>”,
“deviceCustomString3”: “password based login”,
“deviceCustomString4”: “acsfxxxx”,
“deviceCustomString5”: “7.0.0.2436.1”,
“deviceCustomString6”: “Service”,
“deviceEventCategory”: “/Authentication/Login/User?Success”,
“deviceEventClassId”: “authentication:100”,
“deviceReceiptDate”: “2020-05-07T14:48:54.000Z”,
“deviceReceiptTime”: 1588862934523,
“deviceSeverity”: “Warning”,
“endDate”: “2020-05-07T14:48:54.000Z”,
“endTime”: 1588862934523,
“eventAnnotation”: {
“auditTrail”: “1,1589114529805,root,Queued,,,,”,
“endDate”: “2020-05-07T14:48:54.000Z”,
“endTime”: 1588862934523,
“eventId”: 45652798,
“flags”: 0,
“managerReceiptDate”: “2020-05-07T14:48:54.000Z”,
“managerReceiptTime”: 1588862934523,
“modificationDate”: “2020-05-07T14:48:54.000Z”,
“modificationTime”: 1588862934523,
“stage”: {
“id”: “123HiNfoAABCASsxbPIxG0g==”,
“isModifiable”: false,
“managerID”: “123xqmYBABCAXZPTkLg+BA==”,
“referenceID”: 2209,
“referenceName”: “Stage”,
“referenceString”: “<Resource URI="/All Stages/Queued" ID="123HiNfoAABCASsxbPIxG0g=="/>”,
“referenceType”: 34,
“uri”: “/All Stages/Queued”
},
“stageUpdateDate”: “2020-05-07T14:48:54.000Z”,
“stageUpdateTime”: 1588862934523,
“version”: 1
},
“eventId”: 45652798,
“file”: {
“name”: “admin”,
“path”: “/All Users/Administrators/admin”,
“type”: “User”
},
“finalDevice”: {
“address”: “1.1.1.1”,
“addressAsBytes”: “abgBRQ==”,
“assetId”: “123xxqmYBABCAWiGUuYaX-w==”,
“assetLocalId”: 17179869185,
“assetName”: “xsoar-example”,
“decodedAddress”: “1.1.1.1”,
“hostName”: “xsoar-example”,
“mutable”: true,
“product”: “ArcSight”,
“vendor”: “ArcSight”,
“version”: “7.0.0.2436.1”,
“zone”: {
“id”: “123U32AABABCDVFpYAT3UdQ==”,
“isModifiable”: false,
“managerID”: “123xqmYBABCAXZPTkLg+BA==”,
“referenceID”: 1102,
“referenceName”: “Zone”,
“referenceString”: “<Resource URI="/All Zones/ArcSight System/Private Address Space Zones/RFC1918: 192.168.0.0-192.168.255.255" ID="123U32AABABCDVFpYAT3UdQ=="/>”,
“referenceType”: 29,
“uri”: “/All Zones/ArcSight System/Private Address Space Zones/RFC1918: 192.168.0.0-192.168.255.255”
}
},
“locality”: 0,
“managerId”: -128,
“managerReceiptDate”: “2020-05-07T14:48:54.000Z”,
“managerReceiptTime”: 1588862934523,
“modelConfidence”: 4,
“name”: “Login succeeded for user name ‘admin’”,
“originalAgent”: {
“address”: “1.1.1.1”,
“addressAsBytes”: “abgBRQ==”,
“assetId”: “123xxqmYBABCAWiGUuYaX-w==”,
“assetLocalId”: 17179869185,
“assetName”: “xsoar-example”,
“decodedAddress”: “1.1.1.1”,
“hostName”: “xsoar-example”,
“id”: “123xxqmYBABCAY8SQ92zN9g==”,
“mutable”: true,
“name”: “Manager Internal Agent”,
“type”: “arcsight_security_manager”,
“version”: “7.0.0.2436.1”,
“zone”: {
“id”: “123U32AABABCDVFpYAT3UdQ==”,
“isModifiable”: false,
“managerID”: “123xqmYBABCAXZPTkLg+BA==”,
“referenceID”: 1102,
“referenceName”: “Zone”,
“referenceString”: “<Resource URI="/All Zones/ArcSight System/Private Address Space Zones/RFC1918: 192.168.0.0-192.168.255.255" ID="123U32AABABCDVFpYAT3UdQ=="/>”,
“referenceType”: 29,
“uri”: “/All Zones/ArcSight System/Private Address Space Zones/RFC1918: 192.168.0.0-192.168.255.255”
}
},
“originator”: “SOURCE”,
“priority”: 3,
“relevance”: 10,
“severity”: 0,
“source”: {
“address”: “2.2.2.2”,
“addressAsBytes”: “ABCIDg==”,
“decodedAddress”: “2.2.2.2”,
“geo”: {
“countryCode”: “IE”,
“latitude”: 53.3331,
“latitudeLong”: 533331000000,
“locationInfo”: “Dublin”,
“longitude”: -6.2489,
“longitudeLong”: -62489000000,
“mutable”: true,
“postalCode”: “D02”,
“regionCode”: “L”
},
“hostName”: “ec2.eu.compute-1.amazonaws.com”,
“mutable”: true,
“zone”: {
“externalID”: “E.I. duPont de Nemours and Co. Inc.”,
“id”: “123TU5fsAABCCerv-GNArfg==”,
“isModifiable”: false,
“managerID”: “123xqmYBABCAXZPTkLg+BA==”,
“referenceID”: 2178,
“referenceName”: “Zone”,
“referenceString”: “<Resource URI="/All Zones/ArcSight System/Public Address Space Zones/E.I. duPont de Nemours and Co. Inc." ID="123TU5fsAABCCerv-GNArfg==" ExternalID="E.I. duPont de Nemours and Co. Inc."/>”,
“referenceType”: 29,
“uri”: “/All Zones/ArcSight System/Public Address Space Zones/E.I. duPont de Nemours and Co. Inc.”
}
},
“startDate”: “2020-05-07T14:48:54.000Z”,
“startTime”: 1588862934523,
“ttl”: 10,
“type”: “BASE”
}
]
}
}


#### Human Readable Output

>|Destination Address|Event ID|Name|Source Address|Time|
>|---|---|---|---|---|
>| 1.1.1.1 | 12352349 | Monitor Event |  | 2020-05-07, 14:43:00 |
>| 1.1.1.1 | 45652798 | Login succeeded for user name 'admin' | 2.2.2.2 | 2020-05-07, 14:48:54 |

### as-get-case-event-ids

***
Returns all case event IDs.

#### Base Command

`as-get-case-event-ids`

#### Input

| **Argument Name** | **Description** | **Required** |
| --- | --- | --- |
| caseId | Case ID, e.g., 7e6LEbF8BABCfA-dlp1rl1A== | Required |
| withCorrelatedEvents | If "true", then will return case and correlated events | Optional |

#### Context Output

| **Path** | **Type** | **Description** |
| --- | --- | --- |
| ArcSightESM.CaseEvents | Unknown | Map of caseId =&gt; related event ids |
| ArcSightESM.CaseEvents.LatestResult | Unknown | Event IDs of the last execution of this command |

#### Command Example

```!as-get-case-event-ids caseId="12ax-uGgBABCWb2puJdY8ZA==" withCorrelatedEvents="true"```

#### Context Example

{
“ArcSightESM”: {
“CaseEvents”: [
12396713,
45695741,
78996719
]
}
}


#### Human Readable Output

>|Case 12ax-uGgBABCWb2puJdY8ZA== Event IDs|
>|---|
>| 12396713 |
>| 45695741 |
>| 78996719 |

### as-update-case

***
Updates a specific case.

#### Base Command

`as-update-case`

#### Input

| **Argument Name** | **Description** | **Required** |
| --- | --- | --- |
| caseId | Case resource ID to update. The case must be unlocked, and the user should have edit permissions. | Required |
| stage | Stage the case is in | Optional |
| severity | Ticket consequence Severity | Optional |

#### Context Output

| **Path** | **Type** | **Description** |
| --- | --- | --- |
| ArcSightESM.Cases | unknown | List of cases |
| ArcSightESM.Cases.resourceid | string | Case resource ID |
| ArcSightESM.Cases.stage | string | Case stage  |
| ArcSightESM.Cases.consequenceSeverity | string | Case severity |

#### Command Example

```!as-update-case caseId="12ax-uGgBABCWb2puJdY8ZA==" stage="QUEUED" severity="INSIGNIFICANT"```

#### Context Example

{
“ArcSightESM”: {
“Cases”: {
“URI”: “/All Cases/All Cases/Downloads/test”,
“action”: “BLOCK_OR_SHUTDOWN”,
“associatedImpact”: “AVAILABILITY”,
“attackAgent”: “INSIDER”,
“attackMechanism”: “PHYSICAL”,
“attributeInitializationInProgress”: false,
“consequenceSeverity”: “INSIGNIFICANT”,
“createdDate”: “2019-02-04T12:33:21.000Z”,
“createdTime”: {
“day”: 4,
“hour”: 7,
“milliSecond”: 646,
“minute”: 33,
“month”: 1,
“second”: 21,
“timezoneID”: “America/New_York”,
“year”: 2019
},
“createdTimestamp”: 1549283601646,
“creatorName”: “admin”,
“deprecated”: false,
“detectionTime”: {
“day”: 5,
“hour”: 4,
“milliSecond”: 986,
“minute”: 20,
“month”: 1,
“second”: 41,
“timezoneID”: “America/New_York”,
“year”: 2019
},
“disabled”: false,
“displayID”: 12017,
“estimatedStartTime”: {
“day”: 5,
“hour”: 4,
“milliSecond”: 525,
“minute”: 19,
“month”: 1,
“second”: 55,
“timezoneID”: “America/New_York”,
“year”: 2019
},
“eventIDs”: [
12395741,
45696713,
78996719
],
“frequency”: “NEVER_OR_ONCE”,
“history”: “KNOWN_OCCURENCE”,
“inCache”: false,
“inactive”: false,
“initialized”: true,
“isAdditionalLoaded”: false,
“localID”: 12064771092,
“modificationCount”: 1462,
“modifiedDate”: “2020-05-10T10:42:34.000Z”,
“modifiedTime”: {
“day”: 10,
“hour”: 6,
“milliSecond”: 194,
“minute”: 42,
“month”: 4,
“second”: 34,
“timezoneID”: “America/New_York”,
“year”: 2020
},
“modifiedTimestamp”: 1589107354194,
“modifierName”: “admin”,
“name”: “test”,
“numberOfOccurences”: 0,
“operationalImpact”: “NO_IMPACT”,
“reference”: {
“id”: “12ax-uGgBABCWb2puJdY8ZA==”,
“isModifiable”: true,
“managerID”: “12xxqmYBABCAXZPTkLg+BA==”,
“referenceName”: “Case”,
“referenceString”: “<Resource URI="/All Cases/All Cases/Downloads/test" ID="12ax-uGgBABCWb2puJdY8ZA=="/>”,
“referenceType”: 7,
“uri”: “/All Cases/All Cases/Downloads/test”
},
“reportingLevel”: 1,
“resistance”: “HIGH”,
“resourceid”: “12ax-uGgBABCWb2puJdY8ZA==”,
“securityClassification”: “UNCLASSIFIED”,
“securityClassificationCode”: “P I D U A B “,
“sensitivity”: “UNCLASSIFIED”,
“stage”: “QUEUED”,
“state”: 2,
“ticketType”: “INTERNAL”,
“type”: 7,
“typeName”: “Case”,
“vulnerability”: “DESIGN”,
“vulnerabilityType1”: “ACCIDENTAL”,
“vulnerabilityType2”: “EMI_RFI”
}
}
}


#### Human Readable Output

>### Case 12ax-uGgBABCWb2puJdY8ZA==
>
>|Action|CaseID|CreatedTime|EventIDs|Name|Severity|Stage|
>|---|---|---|---|---|---|---|
>| BLOCK_OR_SHUTDOWN | 12ax-uGgBABCWb2puJdY8ZA== | 2019-02-04 12:33:21 | 12395741, 45696713, 78996719 | test | INSIGNIFICANT | QUEUED |

### as-get-all-query-viewers

***
Returns all the query viewer IDs.

#### Base Command

`as-get-all-query-viewers`

#### Input

There are no input arguments for this command.

#### Context Output

| **Path** | **Type** | **Description** |
| --- | --- | --- |
| ArcSightESM.AllQueryViewers | Unknown | List of all query viewer IDs |

#### Command Example

```!as-get-all-query-viewers```

#### Context Example

{
“ArcSightESM”: {
“AllQueryViewers”: [
“123457WYBABCw9lZRkCjVIQ==”,
“54321rlkBABCJREkQ7PrIRg==”,
“56789py4BABCN9NYml6MSoA==”,
]
}
}


#### Human Readable Output

>|Query Viewers|
>|---|
>| 123457WYBABCw9lZRkCjVIQ== |
>| 54321rlkBABCJREkQ7PrIRg== |
>| 56789py4BABCN9NYml6MSoA== |

### as-case-delete

***
Deletes a case

#### Base Command

`as-case-delete`

#### Input

| **Argument Name** | **Description** | **Required** |
| --- | --- | --- |
| caseId | Resource ID of the case | Required |

#### Context Output

| **Path** | **Type** | **Description** |
| --- | --- | --- |
| ArcSightESM.Cases.resourceid | string | Resource ID of case |
| ArcSightESM.Cases.Deleted | boolean | Boolean flag. "True" if deleted. |

#### Command Example

```!as-case-delete caseId=123WHEWcBABD6VdKLNcKE2Q==```

#### Context Example

{
“ArcSightESM”: {
“Cases”: {
“deleted”: “True”,
“resourceid”: “123WHEWcBABD6VdKLNcKE2Q==”
}
}
}


#### Human Readable Output

>Case 123WHEWcBABD6VdKLNcKE2Q== successfully deleted

### as-get-query-viewer-results

***
Retrieves query viewer results (query viewer must be configured to be refreshed every minute, see documentation)

#### Base Command

`as-get-query-viewer-results`

#### Input

| **Argument Name** | **Description** | **Required** |
| --- | --- | --- |
| id | Resource ID of the query viewer | Required |
| onlyColumns | If "true", will return only the columns of the query. If "false", will return the column headers and all query results. | Optional |

#### Context Output

| **Path** | **Type** | **Description** |
| --- | --- | --- |
| ArcSight.QueryViewerResults | Unknown | Query viewer results |

#### Command Example

```!as-get-query-viewer-results id="123457WYBABCw9lZRkCjVIQ=="```

#### Context Example

{
“ArcSightESM”: {
“QueryViewerResults”: [
{
“Attacker Address”: “1.1.1.1”,
“Attacker Zone URI”: “/All Zones/ArcSight System/Public Address Space Zones/E.I. duPont de Nemours and Co. Inc.”,
“End Time”: “1589028174502”,
“Event ID”: “12345678”,
“Name”: “Login succeeded for user name ‘admin’”,
“Start Time”: “1589028174502”
},
{
“Attacker Address”: “2.2.2.2”,
“Attacker Zone URI”: “/All Zones/ArcSight System/Public Address Space Zones/E.I. duPont de Nemours and Co. Inc.”,
“End Time”: “1589028234536”,
“Event ID”: “87654321”,
“Name”: “Login succeeded for user name ‘admin’”,
“Start Time”: “1589028234536”
},
{
“Attacker Address”: “3.3.3.3”,
“Attacker Zone URI”: “/All Zones/ArcSight System/Public Address Space Zones/E.I. duPont de Nemours and Co. Inc.”,
“End Time”: “1589028294471”,
“Event ID”: “14725836”,
“Name”: “Login succeeded for user name ‘admin’”,
“Start Time”: “1589028294471”
}
]
}
}


#### Human Readable Output

>|Column Headers|
>|---|
>| Name |
>| End Time |
>| Attacker Zone URI |
>| Attacker Address |
>| Event ID |
>| Start Time |
>
>### Query Viewer Results: 123457WYBABCw9lZRkCjVIQ==
>
>|Attacker Address|Attacker Zone URI|End Time|Event ID|Name|Start Time|
>|---|---|---|---|---|---|
>| 1.1.1.1 | /All Zones/ArcSight System/Public Address Space Zones/E.I. duPont de Nemours and Co. Inc. | 1589028174502 | 12345678 | Login succeeded for user name 'admin' | 1589028174502 |
>| 2.2.2.2 | /All Zones/ArcSight System/Public Address Space Zones/E.I. duPont de Nemours and Co. Inc. | 1589028234536 | 87654321 | Login succeeded for user name 'admin' | 1589028234536 |
>| 3.3.3.3 | /All Zones/ArcSight System/Public Address Space Zones/E.I. duPont de Nemours and Co. Inc. | 1589028294471 | 14725836 | Login succeeded for user name 'admin' | 1589028294471 |

### as-fetch-incidents

***
Fetches incidents

#### Base Command

`as-fetch-incidents`

#### Input

| **Argument Name** | **Description** | **Required** |
| --- | --- | --- |
| last_run | Last run to start fetching incidents from | Optional |

#### Context Output

There is no context output for this command.

#### Command Example

```!as-fetch-incidents```

#### Context Example

{}


### as-delete-entries

***
Delete entries from the Active List.

#### Base Command

`as-delete-entries`

#### Input

| **Argument Name** | **Description** | **Required** |
| --- | --- | --- |
| resourceId | Resource ID of the Active List | Required |
| entries | Entries are in JSON format. JSON must be an array of entries. Each entry must contain the same columns as they appear in the Active List, e.g., [{ "UserName": "john", "IP":"19.12.13.11"},{ "UserName": "bob", "IP":"22.22.22.22"}] | Required |

#### Context Output

There is no context output for this command.

#### Command Example

```!as-delete-entries resourceId="A1LvlmWgBABCA5+HbRyHZoQ==" entries="[{\"name\": \"t3\", \"EventID\": \"9\"},{\"name\": \"t4\", \"EventID\": \"9\"}]"```

#### Context Example

{}
```

Human Readable Output

Success

Configuration parameters

  • server — Server full URL (e.g., https://192.168.0.1:8443) (required)
  • credentials — Credentials (required)
  • viewerId — Fetch events as incidents via Query Viewer ID. Mandatory fields for query are "Start Time" and "Event ID".
  • casesQueryViewerId — Fetch cases as incidents via Query Viewer ID. Mandatory fields for query are "Create Time" and "ID".
  • max_unique — The maximum number of unique IDs expected to be fetched.
  • fetch_chunk_size — The maximum number of incidents to fetch each time. Default is 50, maximum is 300.
  • isFetch — Fetch incidents
  • incidentFetchInterval — Incidents Fetch Interval
  • use_rest — Use REST Endpoints
  • productVersion — Product Version
  • incidentType — Incident type
  • insecure — Trust any certificate (not secure)
  • proxy — Use system proxy settings

Commands (14)

  • as-add-entries

    Adds new entries to the Active List.

  • as-case-delete

    Deletes a case.

  • as-clear-entries

    Deletes all entries in the Active List.

  • as-delete-entries

    Delete entries from the Active List.

  • as-fetch-incidents

    Fetches incidents.

  • as-get-all-cases

    (Deprecated) Retrieves all case resource IDs.

  • as-get-all-query-viewers

    Returns all the query viewer IDs.

  • as-get-case

    Gets information about a single case.

  • as-get-case-event-ids

    Returns all case event IDs.

  • as-get-entries

    Returns all entries in the Active List.

  • as-get-matrix-data

    Retrieves query viewer results (query viewer must be configured to be refreshed every minute, see documentation).

  • as-get-query-viewer-results

    Retrieves query viewer results (query viewer must be configured to be refreshed every minute, see documentation).

  • as-get-security-events

    Returns the security event details.

  • as-update-case

    Updates a specific case.

import demistomock as demisto
from CommonServerPython import *
from CommonServerUserPython import *


""" GLOBALS """
HEADERS = {"Content-Type": "application/json", "Accept": "application/json"}

REQ_SOAP_BODY = """<?xml version="1.0" encoding="UTF-8"?>
    <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:act="http://ws.v1.service.resource.manager.product.arcsight.com/activeListService/">
    <soapenv:Header />
        <soapenv:Body>
            <act:{function}>
                <act:authToken>{auth_token}</act:authToken>
                <act:resourceId>{resource_id}</act:resourceId>
                {entryList}
            </act:{function}>
        </soapenv:Body>
    </soapenv:Envelope>
""".format

ENTRY_LIST = "<entryList>{}</entryList>".format
ENTRY = "<entry>{}</entry>".format
COLUMN = "<columns>{}</columns>".format
BODY = "<act:entryList>{}</act:entryList>".format


@logger
def int_to_ip(num):
    return f"{(num >> 24) & 255}.{(num >> 16) & 255}.{(num >> 8) & 255}.{num & 255}"


@logger
def decode_ip(address_by_bytes):
    """Decodes the enigmatic ways IPs are stored in ArcSight DB into IPv4/6 format"""
    str_address_by_bytes = str(address_by_bytes)
    if is_ip_valid(str_address_by_bytes) or is_ipv6_valid(str_address_by_bytes):
        return address_by_bytes

    if isinstance(address_by_bytes, int):
        return int_to_ip(address_by_bytes)

    try:
        # if it's not an int, it should be Base64 encoded string
        decoded_string = base64.b64decode(address_by_bytes).hex()
        if len(address_by_bytes) >= 20:
            # split the IPv6 address into 8 chunks of 4
            decoded_string = [decoded_string[i : i + 4] for i in range(0, len(decoded_string), 4)]  # type: ignore
            return "{}:{}:{}:{}:{}:{}:{}:{}".format(*decoded_string)
        elif len(address_by_bytes) >= 6:
            decoded_string = int(decoded_string, 16)  # type: ignore
            return int_to_ip(decoded_string)
        else:
            return address_by_bytes

    except Exception as e:
        # sometimes ArcSight would not encode IPs, this will cause the decoder to
        # throw an exception, and in turn, we will return the input in its original form.
        demisto.debug(str(e))
        return address_by_bytes


@logger
def parse_timestamp_to_datestring(timestamp):
    if timestamp and timestamp > 0:
        try:
            return datetime.fromtimestamp(timestamp / 1000.0).strftime("%Y-%m-%dT%H:%M:%S.000Z")
        except (ValueError, TypeError) as e:
            demisto.debug(str(e))
            if timestamp == "31 Dec 1969 19:00:00 EST":
                # Unix epoch 00:00:00 UTC
                return "None"
            return timestamp
    return None


@logger
def decode_arcsight_output(d, depth=0, remove_nones=True):
    """Converts some of the values from ArcSight DB into a more useful & readable format"""
    # ArcSight stores some None values as follows
    NONE_VALUES = [-9223372036854776000, -9223372036854775808, -2147483648, 5e-324]
    # ArcSight stores IP addresses as int, in the following keys
    IP_FIELDS = ["address", "addressAsBytes", "Destination Address", "Source Address"]
    # ArcSight stores Dates as timeStamps in the following keys, -> reformat into Date
    TIMESTAMP_FIELDS = [
        "createdTimestamp",
        "modifiedTimestamp",
        "deviceReceiptTime",
        "startTime",
        "endTime",
        "stageUpdateTime",
        "modificationTime",
        "managerReceiptTime",
        "createTime",
        "agentReceiptTime",
    ]
    if depth < 10:
        if isinstance(d, list):
            return [decode_arcsight_output(d_, depth + 1) for d_ in d]
        if isinstance(d, dict):
            for key, value in d.copy().items():
                if isinstance(value, list):
                    for value_ in value:
                        decode_arcsight_output(value_, depth + 1)
                if isinstance(value, dict):
                    decode_arcsight_output(value, depth + 1)
                elif value in NONE_VALUES:
                    if remove_nones:
                        d.pop(key, None)
                    else:
                        d[key] = "None"

                elif key in IP_FIELDS:
                    key = "decodedAddress" if key == "addressAsBytes" else key
                    d[key] = decode_ip(value)
                elif key in TIMESTAMP_FIELDS:
                    key = key.replace("Time", "Date").replace("stamp", "")
                    d[key] = parse_timestamp_to_datestring(value)
                elif key in ["eventId", "baseEventIds"]:
                    d[key] = str(value)
                elif isinstance(value, int) and value > 10000000000000000:
                    # the platform rounds number larger than 10000000000000000
                    # so we cast them to string to keep as is
                    d[key] = str(value)
                elif isinstance(value, bytes):
                    d[key] = value.decode()
    return d


@logger
def filter_entries(entries, entry_filter):
    """Filters the entries according to the entry_filter given"""
    if not entry_filter:
        return entries

    filtered_entries = []
    filters = entry_filter.split(",")
    for entry in entries:
        append_flag = True

        for f in filters:
            k, v = f.split(":")
            if k:
                if entry.get(k) != v:
                    # if there is a key and its value is not equal to the entry_filter value
                    append_flag = False
            elif v not in entry.values():
                # if there is no key check that the value exists in one of the entry's keys
                append_flag = False

        if append_flag:
            filtered_entries.append(entry)

    return filtered_entries


def repair_malformed_json(malformed_json: str) -> str:
    """
    Repairs a malformed JSON string by properly escaping quotes within dollar-sign ($) values.

    This function addresses a specific issue where quotes within dollar-sign values are not
    properly escaped, causing JSON parsing errors. It splits the input string into segments,
    identifies dollar-sign values, and escapes inner quotes while preserving the outermost quotes.

    Args:
        malformed_json (str): The input string containing malformed JSON data.

    Returns:
        str: A repaired JSON string with properly escaped quotes within dollar-sign values.

    Example:
        >>> malformed_json = '{"$": "value "with" quotes"}, {"$": "another "quoted" value"}'
        >>> repaired_json = repair_malformed_json(malformed_json)
        >>> print(repaired_json)
        '{"$": "value \\"with\\" quotes"}, {"$": "another \\"quoted\\" value"}'
    """

    def find_unescaped_quotes(json_value: str) -> List[int]:
        quote_positions = []
        search_start = 0
        while True:
            quote_pos = json_value.find('"', search_start)
            if quote_pos == -1:  # No more occurrences found
                break
            # Check if the quote is already escaped
            if quote_pos == 0 or json_value[quote_pos - 1] != "\\":
                quote_positions.append(quote_pos)
            search_start = quote_pos + 1  # Move start position to just after the found index
        return quote_positions

    def escape_inner_quotes(json_value, quote_indices):
        # We need to escape all quotes except the first and last found quotes
        json_chars = list(json_value)
        for i in range(1, len(quote_indices) - 1):  # Skip first and last quotes
            json_chars[quote_indices[i]] = '\\"'
        return "".join(json_chars)

    # Split the text by "},{"
    parts = malformed_json.split("},{")

    modified_parts = []
    for part in parts:
        # Split by "$": and get the last part
        dollar_key_parts = part.split('"$":')

        if len(dollar_key_parts) > 1:
            prefix = '"$":'.join(dollar_key_parts[:-1]) + '"$":'  # Keep all parts before the last `"$":`
            json_value = dollar_key_parts[-1].strip()  # Get the last value

            quote_positions = find_unescaped_quotes(json_value)

            if len(quote_positions) > 2:
                json_value = escape_inner_quotes(json_value, quote_positions)
            modified_parts.append(prefix + json_value)
        else:
            modified_parts.append(part)

    # Join the parts back together
    return "},{".join(modified_parts)


def login():
    query_path = "www/core-service/rest/LoginService/login"
    headers = {"Content-Type": "application/x-www-form-urlencoded", "Accept": "application/json"}
    params = {
        "login": demisto.get(demisto.params(), "credentials.identifier"),
        "password": demisto.get(demisto.params(), "credentials.password"),
        "alt": "json",
    }
    res = send_request(query_path, headers=headers, body=params, is_login=True)
    if not res.ok:
        demisto.debug(res.text)
        return_error("Failed to login, check integration parameters.")

    try:
        res_json = parse_json_response(res)
        if "log.loginResponse" in res_json and "log.return" in res_json.get("log.loginResponse"):
            auth_token = res_json.get("log.loginResponse").get("log.return")
            if demisto.command() not in ["test-module", "fetch-incidents"]:
                # this is done to bypass setting integration context outside of the cli
                demisto.setIntegrationContext({"auth_token": auth_token})
            return auth_token

        return_error("Failed to login. Have not received token after login")
    except ValueError:
        return_error("Failed to login. Please check integration parameters")


def send_request(query_path, body=None, params=None, json=None, headers=None, method="post", is_login=False):
    if headers is None:
        headers = HEADERS
    full_url = BASE_URL + query_path
    try:
        res = requests.request(method, full_url, headers=headers, verify=VERIFY_CERTIFICATE, data=body, params=params, json=json)

        if not res.ok and not is_login:
            if params and not body:
                params["authToken"] = login()
            elif "Authorization" in headers:
                headers["Authorization"] = f"Bearer {login()}"
            else:
                body = body.replace(demisto.getIntegrationContext().get("auth_token"), login())
            return requests.request(
                method, full_url, headers=headers, verify=VERIFY_CERTIFICATE, data=body, params=params, json=json
            )
        return res

    except Exception as ex:
        demisto.debug(str(ex))
        return_error("Connection Error. Please check integration parameters")


def test():
    """
    Login (already done in global).
    Test if fetch query viewers are valid.
    Run query viewer if fetch defined.
    """
    events_query_viewer_id = demisto.params().get("viewerId")
    cases_query_viewer_id = demisto.params().get("casesQueryViewerId")
    is_fetch = demisto.params().get("isFetch")

    if is_fetch and not events_query_viewer_id and not cases_query_viewer_id:
        return_error("If fetch is enabled, you must provide query viewer Resource ID for Cases or Events")

    if events_query_viewer_id:
        fields, results = get_query_viewer_results(events_query_viewer_id)
        if "Event ID" not in fields or "Start Time" not in fields:
            return_error(f'Query "{events_query_viewer_id}" must contain "Start Time" and "Event ID" fields')

    if cases_query_viewer_id:
        fields, results = get_query_viewer_results(cases_query_viewer_id)
        if "ID" not in fields or "Create Time" not in fields:
            return_error(f'Query "{cases_query_viewer_id}" must contain "Create Time" and "ID" fields')


@logger
def get_query_viewer_results(query_viewer_id):
    query_path = "www/manager-service/rest/QueryViewerService/getMatrixData"
    params = {"authToken": AUTH_TOKEN, "id": query_viewer_id, "alt": "json"}
    res = send_request(query_path, params=params, method="get")

    if not res.ok:
        demisto.debug(res.text)
        if "ResourceNotFoundException" in res.text:
            return_error(f"Invalid resource ID {query_viewer_id} for Query Viewer(ResourceNotFoundException)")
        else:
            return_error("Failed to get query viewer results.")

    return_object = None
    res_json = parse_json_response(res)

    if "qvs.getMatrixDataResponse" in res_json and "qvs.return" in res_json["qvs.getMatrixDataResponse"]:
        # ArcSight ESM version 6.7 & 6.9 rest API supports qvs.getMatrixDataResponse
        return_object = res_json.get("qvs.getMatrixDataResponse").get("qvs.return")

    elif "que.getMatrixDataResponse" in res_json and "que.return" in res_json["que.getMatrixDataResponse"]:
        # ArcSight ESM version 6.1 rest API supports que.getMatrixDataResponse
        return_object = res_json.get("que.getMatrixDataResponse").get("que.return")

    else:
        return_error("Invalid response structure. Open ticket to Demisto support and attach the logs")
        return None

    fields = return_object.get("columnHeaders", [])
    if not isinstance(fields, list):
        fields = [fields]

    results = return_object.get("rows", [])
    if not isinstance(results, list):
        results = [results]

    if len(fields) == 0 or len(results) == 0:
        return fields, results

    """
    we parse the rows by column headers and create formatted result

    "columnHeaders": [
        "ID",
        "Event-Event ID",
    ],
    "rows": [
        {
            "@xsi.type": "listWrapper",
            "value": [
                {
                    "@xsi.type": "xs:string",
                    "$": "<ID1>"
                },
                {
                    "@xsi.type": "xs:string",
                    "$": "<Event-Event ID1>"
                }
            ]
        },
        {
            "@xsi.type": "listWrapper",
            "value": [
                {
                    "@xsi.type": "xs:string",
                    "$": "<ID2>"
                },
                {
                    "@xsi.type": "xs:string",
                    "$": "<Event-Event ID2>"
                }
            ]
        }
    ]

    convert to ===>

    query_results = [
        {
            Event-Event ID:<Event-Event ID1>
            ID:<ID1>
        },
        {
            Event-Event ID:<Event-Event ID2>
            ID:<ID2>
        }
    ]
    """
    results = [{field: result.get("value")[idx].get("$") for idx, field in enumerate(fields)} for result in results]
    return fields, results


@logger
def get_query_viewer_results_command():
    resource_id = demisto.args().get("id")
    only_columns = demisto.args().get("onlyColumns")
    columns, query_results = get_query_viewer_results(query_viewer_id=resource_id)

    demisto.debug("printing Query Viewer column headers")
    demisto.results(
        {
            "Type": entryTypes["note"],
            "ContentsFormat": formats["json"],
            "Contents": columns,
            "HumanReadable": tableToMarkdown(name="", headers="Column Headers", t=columns, removeNull=True),
        }
    )
    if only_columns == "false":
        demisto.debug("printing Query Viewer results")

        contents = query_results
        human_readable = tableToMarkdown(name=f"Query Viewer Results: {resource_id}", t=contents, removeNull=True)
        outputs = {"ArcSightESM.QueryViewerResults": contents}
        return_outputs(readable_output=human_readable, outputs=outputs, raw_response=contents)


@logger
def fetch():
    """
    Query viewer should be defined in ArcSight ESM. fetch incidents fetches the results of query viewer
    and converts them to Demisto incidents. We can query Cases or Events. If Cases are fetched then the
    query viewer query must return fields ID and Create Time. If Events are fetched then Event ID and Start Time.
    """
    events_query_viewer_id = demisto.params().get("viewerId")
    cases_query_viewer_id = demisto.params().get("casesQueryViewerId")
    type_of_incident = "case" if events_query_viewer_id else "event"
    last_run = json.loads(demisto.getLastRun().get("value", "{}"))
    already_fetched = last_run.get("already_fetched", [])

    fields, query_results = get_query_viewer_results(events_query_viewer_id or cases_query_viewer_id)
    # sort query_results by creation time
    query_results.sort(key=lambda k: int(k.get("Start Time") or k.get("Create Time")))

    incidents = []
    for result in query_results:
        # convert case or event to demisto incident
        r_id = result.get("ID") or result.get("Event ID")
        if r_id not in already_fetched:
            create_time_epoch = int(result.get("Start Time") or result.get("Create Time"))
            result["Create Time"] = parse_timestamp_to_datestring(create_time_epoch)
            incident_name = result.get("Name") or f"New {type_of_incident} from arcsight at {datetime.now()}"
            labels = [
                {"type": key.encode("utf-8"), "value": value.encode("utf-8") if value else value} for key, value in result.items()
            ]
            incident = {"name": incident_name, "occurred": result["Create Time"], "labels": labels, "rawJSON": json.dumps(result)}

            incidents.append(incident)

            if len(already_fetched) > MAX_UNIQUE:
                already_fetched.pop(0)
            already_fetched.append(r_id)

            if len(incidents) >= FETCH_CHUNK_SIZE:
                break

    last_run = {
        "already_fetched": already_fetched,
    }
    demisto.setLastRun({"value": json.dumps(last_run)})
    decode_arcsight_output(incidents)

    if demisto.command() == "as-fetch-incidents":
        contents = {
            "last_run": last_run,
            "last_run_updated": demisto.getLastRun(),
            "incidents": incidents,
            "already_fetched": already_fetched,
        }
        return_outputs(readable_output="", outputs={}, raw_response=contents)
    else:
        demisto.incidents(incidents)


@logger
def get_case(resource_id, fetch_base_events=False):
    query_path = "www/manager-service/rest/CaseService/getResourceById"
    params = {
        "authToken": AUTH_TOKEN,
        "resourceId": resource_id,
    }
    res = send_request(query_path, params=params, method="get")

    if not res.ok:
        demisto.debug(res.text)
        if "InvalidResourceIDException: Invalid resource ID" in res.text and "for Case" in res.text:
            return_error(f"Invalid resource ID {resource_id} for Case")
        else:
            return_error(f"Failed to get case. StatusCode: {res.status_code}")

    res_json = parse_json_response(res)
    if "cas.getResourceByIdResponse" in res_json and "cas.return" in res_json.get("cas.getResourceByIdResponse"):
        case = res_json.get("cas.getResourceByIdResponse").get("cas.return")

        if case.get("eventIDs") and not isinstance(case["eventIDs"], list):
            # if eventIDs is single id then convert to list
            case["eventIDs"] = [case["eventIDs"]]

        if case.get("eventIDs") and fetch_base_events:
            case["events"] = decode_arcsight_output(get_security_events(case["eventIDs"], ignore_empty=True), remove_nones=False)

        return case

    return_error(f"Case {resource_id} not found")
    return None


@logger
def get_case_command():
    resource_id = demisto.args().get("resourceId")
    with_base_events = demisto.args().get("withBaseEvents") == "true"

    raw_case = get_case(resource_id, fetch_base_events=with_base_events)
    case = {
        "Name": raw_case.get("name"),
        "EventIDs": raw_case.get("eventIDs"),
        "Action": raw_case.get("action"),
        "Stage": raw_case.get("stage"),
        "CaseID": raw_case.get("resourceid"),
        "Severity": raw_case.get("consequenceSeverity"),
        "CreatedTime": epochToTimestamp(raw_case.get("createdTimestamp")),
    }
    if with_base_events:
        case["events"] = raw_case.get("events")

    contents = decode_arcsight_output(raw_case)
    if contents.get("events"):
        contents["events"] = decode_arcsight_output(contents["events"])
    human_readable = tableToMarkdown(name=f"Case {resource_id}", t=case, removeNull=True)
    outputs = {"ArcSightESM.Cases(val.resourceid===obj.resourceid)": contents}
    return_outputs(readable_output=human_readable, outputs=outputs, raw_response=contents)


@logger
def get_all_cases_command():
    query_path = "www/manager-service/rest/CaseService/findAllIds"
    params = {"authToken": AUTH_TOKEN, "alt": "json"}
    res = send_request(query_path, params=params, method="get")

    if not res.ok:
        demisto.debug(res.text)
        return_error(f"Failed to get case list. StatusCode: {res.status_code}")

    res_json = parse_json_response(res)
    contents = res_json.get("cas.findAllIdsResponse").get("cas.return")
    human_readable = tableToMarkdown(name="All cases", headers="caseID", t=contents, removeNull=True)
    outputs = {"ArcSightESM.AllCaseIDs": contents}
    return_outputs(readable_output=human_readable, outputs=outputs, raw_response=contents)


@logger
def get_security_events_command():
    ids = demisto.args().get("ids")
    last_date_range = demisto.args().get("lastDateRange")
    ids = argToList(str(ids) if isinstance(ids, int) else ids)
    raw_events = get_security_events(ids, last_date_range)
    if raw_events:
        events = []
        contents = decode_arcsight_output(raw_events)
        for raw_event in contents:
            event = {
                "Event ID": raw_event.get("eventId"),
                "Time": timestamp_to_datestring(raw_event.get("endTime"), "%Y-%m-%d, %H:%M:%S"),
                "Source Address": decode_ip(demisto.get(raw_event, "source.address")),
                "Destination Address": decode_ip(demisto.get(raw_event, "destination.address")),
                "Name": raw_event.get("name"),
                "Source Port": demisto.get(raw_event, "source.port"),
                "Base Event IDs": raw_event.get("baseEventIds"),
            }
            events.append(event)

        human_readable = tableToMarkdown("Security Event: {}".format(",".join(map(str, ids))), events, removeNull=True)
        outputs = {"ArcSightESM.SecurityEvents(val.eventId===obj.eventId)": contents}
        return_outputs(human_readable, outputs, contents)
    else:
        demisto.results("No events were found")


@logger
def get_security_events(event_ids, last_date_range=None, ignore_empty=False):
    start_time, end_time = -1, -1
    if last_date_range:
        # Must of format 'number date_range_unit'
        # Examples: (2 hours, 4 minutes, 6 month, 1 day, etc.)
        start_time, end_time = parse_date_range(last_date_range, to_timestamp=True)

    query_path = "www/manager-service/rest/SecurityEventService/getSecurityEvents"
    params = {"alt": "json"}
    json_ = {
        "sev.getSecurityEvents": {
            "sev.authToken": AUTH_TOKEN,
            "sev.ids": event_ids,
            "sev.startMillis": start_time,
            "sev.endMillis": end_time,
        }
    }
    res = send_request(query_path, json=json_, params=params)

    if not res.ok:
        demisto.debug(res.text)
        return_error(
            f"Failed to get security events with ids {event_ids}.\n"
            f"Full URL: {BASE_URL + query_path}\nStatus Code: {res.status_code}\nResponse Body: {res.text}"
        )

    res_json = parse_json_response(res)
    if res_json.get("sev.getSecurityEventsResponse") and res_json.get("sev.getSecurityEventsResponse").get("sev.return"):
        events = res_json.get("sev.getSecurityEventsResponse").get("sev.return")
        return events if isinstance(events, list) else [events]

    demisto.debug(res.text)
    if not ignore_empty:
        demisto.results("No events were found")
        return None
    return None


@logger
def update_case_command():
    case_id = demisto.args().get("caseId")
    stage = demisto.args().get("stage")
    severity = demisto.args().get("severity")

    raw_updated_case = update_case(case_id, stage, severity)
    updated_case = {
        "Name": raw_updated_case.get("name"),
        "EventIDs": raw_updated_case.get("eventIDs"),
        "Action": raw_updated_case.get("action"),
        "Stage": raw_updated_case.get("stage"),
        "CaseID": raw_updated_case.get("resourceid"),
        "Severity": raw_updated_case.get("consequenceSeverity"),
        "CreatedTime": epochToTimestamp(raw_updated_case.get("createdTimestamp")),
    }
    contents = decode_arcsight_output(raw_updated_case)
    human_readable = tableToMarkdown(name=f"Case {case_id}", t=updated_case, removeNull=True)
    outputs = {"ArcSightESM.Cases(val.resourceid===obj.resourceid)": contents}
    return_outputs(readable_output=human_readable, outputs=outputs, raw_response=contents)


@logger
def update_case(case_id, stage, severity):
    # get the case from arcsight
    case = get_case(case_id)
    case["stage"] = stage
    case["consequenceSeverity"] = severity if severity else case["consequenceSeverity"]

    # update its stage and send it back to arcsight
    query_path = "www/manager-service/rest/CaseService/update"
    params = {"alt": "json"}
    json_ = {
        "cas.update": {
            "cas.authToken": AUTH_TOKEN,
            "cas.resource": case,
        }
    }
    res = send_request(query_path, json=json_, params=params)

    if not res.ok:
        demisto.debug(res.text)
        return_error(
            f"Failed to get security update case {case_id}. \nPlease make sure user have edit permissions,"
            f" or case is unlocked. \nStatus Code: {res.status_code}\nResponse Body: {res.text}"
        )

    res_json = parse_json_response(res)
    if "cas.updateResponse" in res_json and "cas.return" in res_json.get("cas.updateResponse"):
        return case

    return_error(f"Failed to update case, fail to parse response. Response Body: {res.text}")
    return None


@logger
def get_correlated_events_ids(event_ids):
    related_ids = set(event_ids)
    correlated_events = decode_arcsight_output(get_security_events(event_ids, ignore_empty=True))

    if correlated_events:
        for raw_event in correlated_events:
            base_event_ids = raw_event.get("baseEventIds")
            if base_event_ids:
                if isinstance(base_event_ids, list):
                    related_ids.update(base_event_ids)
                else:
                    related_ids.add(base_event_ids)

    return list(related_ids)


@logger
def get_case_event_ids_command():
    case_id = demisto.args().get("caseId")
    with_correlated_events = demisto.args().get("withCorrelatedEvents") == "true"
    query_path = "www/manager-service/rest/CaseService/getCaseEventIDs"
    params = {"authToken": AUTH_TOKEN, "caseId": case_id}

    res = send_request(query_path, params=params, method="get")
    if not res.ok:
        demisto.debug(res.text)
        return_error(f"Failed to get Event IDs with:\nStatus Code: {res.status_code}\nResponse: {res.text}")

    res_json = parse_json_response(res)
    if "cas.getCaseEventIDsResponse" in res_json and "cas.return" in res_json.get("cas.getCaseEventIDsResponse"):
        event_ids = res_json.get("cas.getCaseEventIDsResponse").get("cas.return")
        if not isinstance(event_ids, list):
            event_ids = [event_ids]

        if with_correlated_events:
            event_ids = get_correlated_events_ids(event_ids)

        contents = decode_arcsight_output(res_json)
        human_readable = tableToMarkdown(name="", headers=f"Case {case_id} Event IDs", t=event_ids, removeNull=True)
        outputs = {"ArcSightESM.CaseEvents": event_ids}
        return_outputs(readable_output=human_readable, outputs=outputs, raw_response=contents)
    else:
        demisto.results("No result returned")


@logger
def delete_case_command():
    case_id = demisto.args().get("caseId")

    query_path = "www/manager-service/rest/CaseService/deleteByUUID"
    req_body = json.dumps({"cas.deleteByUUID": {"cas.authToken": AUTH_TOKEN, "cas.id": case_id}})
    params = {"alt": "json"}
    res = send_request(query_path, params=params, body=req_body)
    if not res.ok:
        demisto.debug(res.text)
        return_error(f"Failed to delete case.\nStatus Code: {res.status_code}\nResponse: {res.text}")

    entry_context = {"resourceid": case_id, "deleted": "True"}
    contents = f"Case {case_id}  was deleted successfully"
    human_readable = f"Case {case_id} successfully deleted"
    outputs = {"ArcSightESM.Cases(val.resourceid===obj.resourceid)": entry_context}
    return_outputs(readable_output=human_readable, outputs=outputs, raw_response=contents)


@logger
def get_entries_command(use_rest, args):
    resource_id = args.get("resourceId")
    entry_filter = args.get("entryFilter")

    if use_rest:
        query_path = "www/manager-service/rest/ActiveListService/getEntries"
        params = {"alt": "json"}
        body = {
            "act.getEntries": {
                "act.authToken": AUTH_TOKEN,
                "act.resourceId": resource_id,
            }
        }  # type: Union[str, Dict[str, Dict[str, Any]]]
        res = send_request(query_path, json=body, params=params)
    else:
        query_path = "www/manager-service/services/ActiveListService/"
        body = REQ_SOAP_BODY(function="getEntries", auth_token=AUTH_TOKEN, resource_id=resource_id, entryList=None)
        res = send_request(query_path, body=body)

    if not res.ok:
        demisto.debug(res.text)
        return_error(
            f"Failed to get entries:\nResource ID: {resource_id}\n"
            f"Status Code: {res.status_code}\nRequest Body: {body}\nResponse: {res.text}"
        )

    if use_rest:
        res_json = parse_json_response(res)
        raw_entries = res_json.get("act.getEntriesResponse", {}).get("act.return", {})
    else:
        res_json = json.loads(xml2json((res.text).encode("utf-8")))
        raw_entries = demisto.get(res_json, "Envelope.Body.getEntriesResponse.return")

    # retrieve columns
    cols = demisto.get(raw_entries, "columns")
    if cols:
        hr_columns = (
            tableToMarkdown(name="", headers=["Columns"], t=cols, removeNull=True) if cols else "Active list has no columns"
        )
        contents = cols
        return_outputs(readable_output=hr_columns, outputs={}, raw_response=contents)

    if "entryList" in raw_entries:
        entry_list = raw_entries["entryList"] if isinstance(raw_entries["entryList"], list) else [raw_entries["entryList"]]
        entry_list = [
            (d["entry"] if not isinstance(d["entry"], STRING_TYPES) else (d["entry"],)) for d in entry_list if "entry" in d
        ]
        keys = raw_entries.get("columns")
        entries = [dict(zip(keys, values)) for values in entry_list]

        # if the user wants only entries that contain certain 'field:value' sets (filters)
        # e.g., "name:myName,eventId:0,:ValueInUnknownField"
        # if the key is empty, search in every key
        filtered_entries = filter_entries(entries, entry_filter)

        contents = decode_arcsight_output(filtered_entries)
        ActiveListContext = {
            "ResourceID": resource_id,
            "Entries": contents,
        }
        outputs = {
            f"ArcSightESM.ActiveList.{resource_id}": contents,
            "ArcSightESM.ActiveList(val.ResourceID===obj.ResourceID)": ActiveListContext,
        }
        human_readable = tableToMarkdown(name=f"Active List entries: {resource_id}", t=filtered_entries, removeNull=True)
        return_outputs(readable_output=human_readable, outputs=outputs, raw_response=entries)

    else:
        demisto.results("Active List has no entries")


@logger
def clear_entries_command(use_rest, args):
    resource_id = args.get("resourceId")

    if use_rest:
        query_path = "www/manager-service/rest/ActiveListService/clearEntries"
        params = {"alt": "json"}
        body = {
            "act.clearEntries": {
                "act.authToken": AUTH_TOKEN,
                "act.resourceId": resource_id,
            }
        }  # type: Union[str, Dict[str, Dict[str, Any]]]
        res = send_request(query_path, json=body, params=params)
    else:
        query_path = "www/manager-service/services/ActiveListService/"
        body = REQ_SOAP_BODY(function="clearEntries", auth_token=AUTH_TOKEN, resource_id=resource_id, entryList=None)
        res = send_request(query_path, body=body)

    if not res.ok:
        demisto.debug(res.text)
        return_error(
            f"Failed to clear entries.\nResource ID: {resource_id}\n"
            f"Status Code: {res.status_code}\nRequest Body: {body}\nResponse: {res.text}"
        )

    demisto.results("Success")


@logger
def entries_command(func):
    resource_id = demisto.args().get("resourceId")
    entries = demisto.args().get("entries")
    query_path = "www/manager-service/services/ActiveListService/"
    if not isinstance(entries, dict):
        try:
            entries = json.loads(entries)
        except ValueError as ex:
            demisto.debug(str(ex))
            return_error("Entries must be in JSON format. Must be array of objects.")
        if not all(entry.keys() == entries[0].keys() for entry in entries[1:]):
            return_error("All entries must have the same fields")

    columns = "".join(COLUMN(column) for column in entries[0])  # the fields in the entryList matrix are the columns
    entry_list = BODY(columns + "".join(ENTRY_LIST("".join(ENTRY(v) for v in en.values())) for en in entries))
    body = REQ_SOAP_BODY(function=func, auth_token=AUTH_TOKEN, resource_id=resource_id, entryList=entry_list)
    res = send_request(query_path, body=body)

    if not res.ok:
        demisto.debug(res.text)
        return_error(
            f"Failed to {func}. Please make sure to enter Active List resource ID"
            f"\nResource ID: {resource_id}\nStatus Code: {res.status_code}\nRequest Body: {body}\nResponse: {res.text}"
        )

    demisto.results("Success")


def add_entries_command(args):
    resource_id = args.get("resourceId")
    entries_arg = args.get("entries")
    query_path = f"detect-api/rest/activelists/{resource_id}/entries"
    fields = []
    entries = []

    if not isinstance(entries_arg, list):
        try:
            entries_arg = json.loads(entries_arg)

        except ValueError as ex:
            demisto.error(str(ex))
            raise ValueError("entries must be in JSON format. Must be array of objects.")

    if len(entries_arg) > 0:
        if len(entries_arg) > 0:
            fields = list(entries_arg[0].keys())

        if not all(entry.keys() == entries_arg[0].keys() for entry in entries_arg[1:]):
            return_error("All entries must have the same fields")

        for entry_input in entries_arg:
            entry = []
            for k in fields:
                val = entry_input[k]
                entry.append(val)

            entries.append({"fields": entry})

    body = {"fields": fields, "entries": entries}
    headers = HEADERS
    headers["Authorization"] = f"Bearer {AUTH_TOKEN}"

    body = json.dumps(body)
    res = send_request(query_path, body=body)

    if not res.ok:
        raise ValueError(
            "Failed to add entries. Please make sure to enter Active List resource ID"
            f"\nResource ID: {resource_id}\nStatus Code: {res.status_code}\n"
            f"Request Body: {body}\nResponse: {res.text}"
        )

    demisto.results("Success")


@logger
def get_all_query_viewers_command():
    query_path = "www/manager-service/rest/QueryViewerService/findAllIds"
    params = {"authToken": AUTH_TOKEN, "alt": "json"}
    headers = {"Content-Type": "application/x-www-form-urlencoded", "Accept": "application/json"}
    res = send_request(query_path, headers=headers, params=params)
    if not res.ok:
        demisto.debug(res.text)
        return_error(f"Failed to get query viewers:\nStatus Code: {res.status_code}\nResponse: {res.text}")

    res_json = parse_json_response(res)
    if "qvs.findAllIdsResponse" in res_json and "qvs.return" in res_json.get("qvs.findAllIdsResponse"):
        query_viewers = res_json.get("qvs.findAllIdsResponse").get("qvs.return")

        contents = decode_arcsight_output(query_viewers)
        outputs = {"ArcSightESM.AllQueryViewers": contents}
        human_readable = tableToMarkdown(name="", t=query_viewers, headers="Query Viewers", removeNull=True)
        return_outputs(readable_output=human_readable, outputs=outputs, raw_response=contents)

    else:
        demisto.results("No Query Viewers were found")


def parse_json_response(response: requests.Response):
    """
    Parse the response to JSON.
    If the parsing fails due to an invalid escape sequence, the function will attempt to fix the response data.

    Args:
        response: The response to parse.

    Raises:
        JSONDecodeError: If the response data could not be parsed to JSON.
    """
    try:
        return response.json()

    except requests.exceptions.JSONDecodeError as e:
        demisto.debug(
            f"Failed to parse response to JSON.\n"
            f"HTTP status code: {response.status_code}\n"
            f"Headers: {response.headers}\n"
            f"Response:\n{response.text}\n\n"
            "Attempting to fix invalid escape sequences and parse the response again."
        )

        # Replace triple backslashes (where the last one doesn't escape anything) with two backslashes.
        fixed_response_text = re.sub(r'(?<!\\)((\\\\)*)\\(?![\\"])', r"\1\\\\", response.text)

        try:
            fixed_response_json = json.loads(fixed_response_text)

        except json.JSONDecodeError as json_error:
            demisto.debug(f"Failed to parse fixed response as JSON. Error: {json_error}")
            demisto.debug("Attempt two to fix the modified response as JSON.")
            try:
                fixed_response_json = json.loads(repair_malformed_json(fixed_response_text))
            except json.JSONDecodeError:
                demisto.debug("Failed to parse modified response as JSON. Raising original exception.")
                raise e  # Raise the original exception

        demisto.debug("Response successfully parsed after fixing invalid escape sequences.")
        return fixed_response_json


AUTH_TOKEN: str
MAX_UNIQUE: int
FETCH_CHUNK_SIZE: int
BASE_URL: str
VERIFY_CERTIFICATE: bool


def main():
    global BASE_URL
    BASE_URL = demisto.params().get("server").rstrip("/") + "/"

    handle_proxy()

    global MAX_UNIQUE
    MAX_UNIQUE = int(demisto.params().get("max_unique", 2000))

    global FETCH_CHUNK_SIZE
    FETCH_CHUNK_SIZE = int(demisto.params().get("fetch_chunk_size", 50))
    FETCH_CHUNK_SIZE = min(300, FETCH_CHUNK_SIZE)  # fetch size should no exceed 300

    global VERIFY_CERTIFICATE
    VERIFY_CERTIFICATE = not demisto.params().get("insecure", True)

    use_rest = demisto.params().get("use_rest", False)

    global AUTH_TOKEN
    AUTH_TOKEN = demisto.getIntegrationContext().get("auth_token") or login()

    use_detect_api = demisto.params().get("productVersion") == "7.4 and above"

    try:
        if demisto.command() == "test-module":
            test()
            demisto.results("ok")

        elif demisto.command() == "as-fetch-incidents" or demisto.command() == "fetch-incidents":
            fetch()

        elif demisto.command() == "as-get-matrix-data" or demisto.command() == "as-get-query-viewer-results":
            get_query_viewer_results_command()

        elif demisto.command() == "as-get-all-cases":
            get_all_cases_command()

        elif demisto.command() == "as-get-case":
            get_case_command()

        elif demisto.command() == "as-update-case":
            update_case_command()

        elif demisto.command() == "as-case-delete":
            delete_case_command()

        elif demisto.command() == "as-get-security-events":
            get_security_events_command()

        elif demisto.command() == "as-get-entries":
            get_entries_command(use_rest, demisto.args())

        elif demisto.command() == "as-add-entries":
            if use_detect_api:
                add_entries_command(demisto.args())
            else:
                entries_command(func="addEntries")

        elif demisto.command() == "as-delete-entries":
            entries_command(func="deleteEntries")

        elif demisto.command() == "as-clear-entries":
            clear_entries_command(use_rest, demisto.args())

        elif demisto.command() == "as-get-case-event-ids":
            get_case_event_ids_command()

        elif demisto.command() == "as-get-all-query-viewers":
            get_all_query_viewers_command()

    except Exception as e:
        return_error("Error:" + str(e), error=traceback.format_exc())


# python2 uses __builtin__ python3 uses builtins
if __name__ in ("__builtin__", "builtins", "__main__"):
    main()