RSA NetWitness Security Analytics
RSA Security Analytics, compatible with prior to v11. A distributed and modular system that enables highly flexible deployment architectures that scale with the needs of the organization. Security Analytics allows administrators to collect two types of data from the network infrastructure, packet data and log data.
Analytics & SIEM · RSA NetWitness Security Analytics
Details
| ID | RSA NetWitness Security Analytics |
|---|---|
| Provider | PartnerOne |
| Category | Analytics & SIEM |
| From Version | 5.0.0 |
| Supported Modules | Agentix XSIAM |
README
RSA Security Analytics is a distributed and modular system that enables highly flexible deployment architectures that scale with the needs of the organization. Security Analytics allows administrators to collect two types of data from the network infrastructure, packet data and log data.
This integraitons should work with RSA Netwitness older than v11. For versions v11 and above use the integration RSA NetWitness v11.1.
Configure RSA NetWitness Security Analytics in Cortex
| Parameter | Description | Required |
|---|---|---|
| url | Server Url (192.168.56.101) | True |
| username | Username | True |
| password | Password | True |
| isFetch | Fetch incidents | False |
| incidentType | Incident type | False |
| proxy | Use system proxy settings | False |
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.
nw-login
Logins to the system and returns valid sessionId
Base Command
nw-login
Input
| Argument Name | Description | Required |
| — | — | — |
Context Output
There is no context output for this command.
fetch-incidents
Simulates fetching incidents. Returns array of incidents from NetWitness.
Base Command
fetch-incidents
Input
| Argument Name | Description | Required |
| — | — | — |
Context Output
There is no context output for this command.
netwitness-im-list-incidents
Fetches incidents by filter
Base Command
netwitness-im-list-incidents
Input
| Argument Name | Description | Required |
|---|---|---|
| query | If query provided all other parameters ignored. Query should contain page, limit, start, sort and filter, joined by &, For example: page=1&start=0&limit=100&sort=[{“property”:”created”,”direction”:”DESC”}]&filter=[{“property”:”created”,”value”:[851171984031,1482323984031]}] | Optional |
| page | The default is 1. Indicates the page number of incidents | Optional |
| start | The default is 0. Indicates the start index of incident in page | Optional |
| limit | The default is 100. Limits the number of incidents per page | Optional |
| sort | By default sorts by “created” field in “DESC” order. Example: “[{"property":"created","direction":"DESC"}]” | Optional |
| filter | By default filters by “created” from 1996 to this date. Example: “[{"property":"id", "value":"INC-21"}]” | Optional |
| incidentManagementId | [optional number] This is the id of NetWitness INCIDENT_MANAGEMENT device/component id. It can be received by running netwitness-im-get-component command. If this argument is not filled/passed, the script will automatically get the first device of type INCIDENT_MANAGEMENT from the SA server. | Optional |
| loadAlerts | [optinal boolean] By default alerts and events related to incident not loaded. If loadAlerts is true, then command will load all alerts and their events from SA. Please be noticed THIS IS HAS PERFORMANCE IMPACT! For each alert XHR request send to SA. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| Netwitness.Incident.Id | unknown | Netwitness Incident ID |
| Netwitness.Incident.Name | unknown | Netwitness Incident Name |
| Netwitness.Incident.Priority | unknown | Netwitness Incident Priority |
| Netwitness.Incident.CreatedBy | unknown | User who created Netwitness Incident |
| Netwitness.Incident.Summary | unknown | Netwitness Incident Summary |
| Netwitness.Incident.Assignee | unknown | User Assigned To Incident |
| Netwitness.Incident.Created | unknown | Time of Incident Creation |
| Netwitness.Incident.FirstAlertTime | unknown | Time of Incident Creation |
| Netwitness.Incident.LastUpdatedByUserName | unknown | User who was last to update Incident |
| Netwitness.Incident.RiskScore | unknown | Netwitness Incident Risk Score |
| Netwitness.Incident.AverageAlertRiskScore | unknown | Netwitness Incident Average Risk Score |
| Netwitness.Incident.Categories | unknown | Netwitness Incident Category |
| Netwitness.Incident.AlertCount | unknown | Netwitness Incident Alerts Counts |
netwitness-im-login
Logins to the system and returns valid sessionId
Base Command
netwitness-im-login
Input
| Argument Name | Description | Required |
| — | — | — |
Context Output
There is no context output for this command.
netwitness-im-get-components
Returns all the components in the system
Base Command
netwitness-im-get-components
Input
| Argument Name | Description | Required |
|---|---|---|
| query | [optional string] Query must contain page, start, limit | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| Netwitness.Component.Id | unknown | Netwitness Component ID |
| Netwitness.Component.DisplayName | unknown | Netwitness Component DisplayName |
| Netwitness.Component.DeviceVersion | unknown | Netwitness Component Device Version |
| Netwitness.Component.DisplayType | unknown | Netwitness Component Device Type |
| Netwitness.Component.Host | unknown | Netwitness Component Device Host |
| Netwitness.Component.Port | unknown | Netwitness Component Device Port |
| Netwitness.Component.Validated | unknown | Netwitness Component is passed validation |
| Netwitness.Component.Licensed | unknown | Netwitness Component license |
| Netwitness.Component.Username | unknown | Netwitness Component User Name |
| Netwitness.Component.EnableSSL | unknown | Netwitness Component Enable SSL |
netwitness-im-get-events
Returns all the events in defined time range
Base Command
netwitness-im-get-events
Input
| Argument Name | Description | Required |
|---|---|---|
| timeRangeType | Filter of time range in which events occured | Required |
| deviceId | [number] Id of the device where the events stored/occurred. In order to get list of available devices/components run command netwitness-im-get-components | Required |
| collectionName | [optional] | Optional |
| predicateIds | [optional] | Optional |
| startDate | [optional datetime] If timeRangeType defined as CUSTOM, set this argument | Optional |
| endDate | [optional datetime] If timeRangeType defined as CUSTOM, set this argument | Optional |
| lastCollectionTime | [optional datetime] Last collection time | Optional |
| mid1 | The unique meta id for this field. If nw-get-events was called this will be your starting id for this distinct value | Optional |
| mid2 | The unique meta id for this field. If nw-get-events was called this will be your ending id for this distinct value. | Optional |
| investigationToken | [optional guid] Investigation id token | Optional |
| page | [optional number] Default set to 1. The page number | Optional |
| start | [optional number] Default set to 0. The starting index of event in page. | Optional |
| limit | [optional number] Default set to 25. Limits the number of events per page | Optional |
| sort | By default sorts by “id” field in “ASC” order. Example: “[{"property":"id","direction":"ASC"}]” | Optional |
| filter | <string> Must provide key value pairs of fieldName and their value separated by comma. Example: “ip.src=1.1.1.1,meta.device.type="crowdstrike"” | Optional |
Context Output
There is no context output for this command.
netwitness-im-get-available-assignees
Returns the available users to be assigned to incidents
Base Command
netwitness-im-get-available-assignees
Input
| Argument Name | Description | Required |
| — | — | — |
Context Output
| Path | Type | Description |
|---|---|---|
| Netwitness.Account.Id | unknown | Netwitness Account ID |
| Netwitness.Account.Name | unknown | Netwitness Account Name |
| Netwitness.Account.Login | unknown | Netwitness Account Login Name |
| Netwitness.Account.EmailAddress | unknown | Netwitness Account Email Address |
netwitness-im-create-incident
Creating new incident
Base Command
netwitness-im-create-incident
Input
| Argument Name | Description | Required |
|---|---|---|
| alertSummary | [string] Short summary of the alert which will be attached to incident | Required |
| severity | [optional string] Default set to “50”. | Optional |
| name | [string] The name of the incident. | Required |
| assigned | [optional string] Set assignee login name if assignee has changed. You can execute netwitness-im-get-available-assignees to get the list of users. Example: demisto123 | Optional |
| eventList | List of event ids separated by comma [,] must not include spaces in it. In order to get list of events you can use netwitness-im-get-events | Required |
| deviceId | The id of the device/component (Concentrator, Log Decoder, Packet Decoder, etc.) from which the events are. You can view the list of devices by executing the command netwitness-im-get-components | Required |
| priority | Priority of the incident | Required |
| summary | Summary of the incident | Optional |
| incidentManagementId | [optional number] This is the id of NetWitness INCIDENT_MANAGEMENT device/component id. It can be received by running netwitness-im-get-component command. If this argument is not filled/passed, the script will automatically get the first device of type INCIDENT_MANAGEMENT from the SA server. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| Netwitness.Incident.Id | unknown | Netwitness Incident ID |
| Netwitness.Incident.Name | unknown | Netwitness Incident Name |
| Netwitness.Incident.Priority | unknown | Netwitness Incident Priority |
| Netwitness.Incident.CreatedBy | unknown | User who created Netwitness.Incident |
| Netwitness.Incident.AlertIDList | unknown | Alerts which rised by incident |
netwitness-im-add-events-to-incident
This command will add new events to existing incident
Base Command
netwitness-im-add-events-to-incident
Input
| Argument Name | Description | Required |
|---|---|---|
| incidentId | [string] Existing incident id. | Required |
| eventList | [array of strings] List of event ids separated by comma [,] must not include spaces in it. In order to get list of events you can use netwitness-im-get-events. Example: “23,12,3” | Required |
| alertSummary | [string] Short summary of the alert which will be attached to incident | Required |
| severity | [number] Severity of the incident. Example: 50 | Required |
| deviceId | [number] The id of the device/component (Concentrator, Log Decoder, Packet Decoder, etc.) from which the events are. You can view the list of devices by executing the command netwitness-im-get-components | Required |
| incidentManagementId | [optional number] This is the id of NetWitness INCIDENT_MANAGEMENT device/component id. It can be received by running netwitness-im-get-component command. If this argument is not filled/passed, the script will automatically get the first device of type INCIDENT_MANAGEMENT from the SA server. | Optional |
Context Output
There is no context output for this command.
netwitness-im-update-incident
Updates incident
Base Command
netwitness-im-update-incident
Input
| Argument Name | Description | Required |
|---|---|---|
| idList | List of incident ids which will be updated, separated by comma [,]. Must not contain spaces. Example: “INC-13,INC-15,INC-23” | Required |
| name | [optional string] Set name if incident name has been changed | Optional |
| summary | [optional string] Updated incident summary | Optional |
| assignee | [optional string] Set assignee login name if assignee has changed. You can execute netwitness-im-get-available-assignees to get the list of users. Example: demisto123 | Optional |
| comment | [optional string] Add a journal entry describing your changes | Optional |
| status | [optional status] Set status if changed | Optional |
| priority | [optional priority] Set priority if incident priority has been changed | Optional |
| categories | List of categories. | Optional |
| incidentManagementId | [optional number] This is the id of NetWitness INCIDENT_MANAGEMENT device/component id. It can be received by running netwitness-im-get-component command. If this argument is not filled/passed, the script will automatically get the first device of type INCIDENT_MANAGEMENT from the SA server. | Optional |
Context Output
There is no context output for this command.
netwitness-im-get-alerts
Return all the alerts filtered by filter.
Base Command
netwitness-im-get-alerts
Input
| Argument Name | Description | Required |
|---|---|---|
| page | The default is 1. Indicates the page number of incidents | Optional |
| start | The default is 0. Indicates the start index of incident in page | Optional |
| limit | The default is 100. Limits the number of incidents per page | Optional |
| sort | By default sorts by “alert.timestamp” field in “DESC” order. Example: “[{"property":"alert.timestamp","direction":"DESC"}]” | Optional |
| filter | By default filters by “alert.timestamp” from 1996 to this date. Example: “[{"property":"incidentId", "value":"INC-21"}]” | Optional |
Context Output
There is no context output for this command.
netwitness-im-get-alert-details
Return single alert by id
Base Command
netwitness-im-get-alert-details
Input
| Argument Name | Description | Required |
|---|---|---|
| alertId | Alert id | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| Netwitness.Alert.Id | unknown | Netwitness Alert ID |
| Netwitness.Alert.Name | unknown | Netwitness Alert Name |
| Netwitness.Alert.IncidentId | unknown | Id of Incident which caused to Alert |
| Netwitness.Alert.Timestamp | unknown | Time of Alert |
| Netwitness.Alert.HostSummary | unknown | Netwitness Alert Summary |
| Netwitness.Alert.SignatureId | unknown | Singnature Id of Alert |
| Netwitness.Alert.Source | unknown | Score of Alert |
| Netwitness.Alert.Type | unknown | Type of Alert |
| Netwitness.Alert.RiskScore | unknown | Risk score of Alert |
| Netwitness.Alert.SourceCountry | unknown | Netwitness Alert Source Country |
| Netwitness.Alert.DestinationCountry | unknown | Netwitness Alert Destination Country |
| Netwitness.Alert.NumEvents | unknown | Netwitness Alert Evevts Number |
| Netwitness.Alert.SourceIp | unknown | Netwitness Alert Source Ip |
| Netwitness.Alert.DestonationIp | unknown | Netwitness Alert Destonation Ip |
| Netwitness.Alert.DestonationPort | unknown | Netwitness Alert Destonation Port |
netwitness-im-get-event-details
Returns two entries. One is event details json and the second is
Base Command
netwitness-im-get-event-details
Input
| Argument Name | Description | Required |
|---|---|---|
| deviceId | [number] Id of the device where the events stored/occurred. In order to get list of available devices/components run command netwitness-im-get-components | Required |
| eventId | [number] Id of the event | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| Netwitness.Event.EventId | unknown | Netwitness Event ID |
| Netwitness.Event.DeviceId | unknown | Netwitness Event Device Id |
| Netwitness.Event.ReconstructedContentType | unknown | Netwitness Event Reconstructed Content |
| Netwitness.Event.PacketsTotal | unknown | Total Packets Netwitness Event |
| Netwitness.Event.PacketsProcessed | unknown | Packets Processed in Current Event |
netwitness-im-get-incident-details
Returns incident json by id
Base Command
netwitness-im-get-incident-details
Input
| Argument Name | Description | Required |
|---|---|---|
| incidentId | [number] ID of incident. Example: “INC-12” | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| Netwitness.Incident.Id | unknown | Netwitness Incident ID |
| Netwitness.Incident.Name | unknown | Netwitness Incident Name |
| Netwitness.Incident.Priority | unknown | Netwitness Incident Priority |
| Netwitness.Incident.CreatedBy | unknown | User who created Netwitness Incident |
| Netwitness.Incident.Summary | unknown | Netwitness Incident Summary |
| Netwitness.Incident.Assignee | unknown | User Assigned To Incident |
| Netwitness.Incident.Created | unknown | Time of Incident Creation |
| Netwitness.Incident.FirstAlertTime | unknown | Time of Incident Creation |
| Netwitness.Incident.LastUpdatedByUserName | unknown | User who was last to update Incident |
| Netwitness.Incident.RiskScore | unknown | Netwitness Incident Risk Score |
| Netwitness.Incident.AverageAlertRiskScore | unknown | Netwitness Incident Average Risk Score |
| Netwitness.Incident.Categories | unknown | Netwitness Incident Category |
| Netwitness.Incident.AlertCount | unknown | Netwitness Incident Alerts Counts |
netwitness-im-get-alert-original
Returns the original events which this alert contains
Base Command
netwitness-im-get-alert-original
Input
| Argument Name | Description | Required |
|---|---|---|
| alertId | Id of the alert | Required |
Configuration parameters
url— Server Url (192.168.56.101) (required)username— Usernamepassword— Passwordcredentials— UsernameisFetch— Fetch incidentsincidentType— Incident typeincidentFetchInterval— Incidents Fetch Intervalproxy— Use system proxy settings
Commands (27)
-
fetch-incidentsSimulates fetching incidents. Returns array of incidents from NetWitness.
-
netwitness-im-add-events-to-incidentThis command will add new events to existing incident.
-
netwitness-im-create-incidentCreating new incident.
-
netwitness-im-get-alert-detailsReturn single alert by id
-
netwitness-im-get-alert-originalReturns the original events which this alert contains.
-
netwitness-im-get-alertsReturn all the alerts filtered by filter.
-
netwitness-im-get-available-assigneesReturns the available users to be assigned to incidents.
-
netwitness-im-get-componentsReturns all the components in the system.
-
netwitness-im-get-event-detailsReturns two entries. One is event details json and the second is.
-
netwitness-im-get-eventsReturns all the events in defined time range.
-
netwitness-im-get-incident-detailsReturns incident json by id.
-
netwitness-im-list-incidentsFetches incidents by filter.
-
netwitness-im-loginLogins to the system and returns valid sessionId.
-
netwitness-im-update-incidentUpdates incident.
-
nw-add-events-to-incidentDeprecatedThis command will add new events to existing incident.
-
nw-create-incidentDeprecatedCreating new incident.
-
nw-get-alert-detailsDeprecatedReturn single alert by id
-
nw-get-alert-originalDeprecatedReturns the original events which this alert contains.
-
nw-get-alertsDeprecatedReturn all the alerts filtered by filter.
-
nw-get-available-assigneesDeprecatedReturns the available users to be assigned to incidents.
-
nw-get-componentsDeprecatedReturns all the components in the system.
-
nw-get-event-detailsDeprecatedReturns two entries. One is event details json and the second is event/session content.
-
nw-get-eventsDeprecatedReturns all the events in defined time range.
-
nw-get-incident-detailsDeprecatedReturns incident json by id.
-
nw-list-incidentsDeprecatedFetches incidents by filter.
-
nw-loginLogins to the system and returns valid sessionId.
-
nw-update-incidentDeprecatedUpdates incident.
var url = params.url; if (url.indexOf("https://") < 0) { url = 'https://' + url; } var username = params.credentials ? params.credentials.identifier : params.username; var password = params.credentials ? params.credentials.password : params.password; var proxy = params.proxy || false; var COOKIE_PREFIX = 'RSA_SA_LICENSE=true; JSESSIONID='; function FailedRequestError(message, url, query, reqBody, resBody) { return { message: message, url: url, query: query, reqBody: reqBody, resBody: resBody, toString: function() { var error = [ message, 'Request url: ' + url, ]; if (query) { error.push('Request query: ' + JSON.stringify(query)); } if (reqBody) { error.push('Request body:' + JSON.stringify(reqBody)); } error.push('Response: ' + resBody); return error.join('\n'); } }; } function escapeRegExp(str) { return str.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1"); } function replaceAll(str, find, replace) { return str.replace(new RegExp(escapeRegExp(find), 'g'), replace); } function login(url, username, password) { if (!(username && password)){ raise ('Username and Password must be provided.'); } var fullUrl = url + '/j_spring_security_check'; var res = http( fullUrl, { Method: 'POST', Headers: { 'Origin': [url], 'Content-Type': ['application/x-www-form-urlencoded'], 'Referer': [url + '/login'] }, Body: 'j_username=' + username + '&j_password=' + password }, true, proxy, true ); if (res.StatusCode !== 302) { throw 'Failed to login with status [' + res.StatusCode + ']. Expected status 302. Check username or password. \nOriginal error: ' + res.Body; } var sessionId = null; res.Cookies.forEach(function(cookie) { if (cookie.Name === 'JSESSIONID') { sessionId = cookie.Value; } }); try { getAvailableAssignees(sessionId); } catch(err) { throw 'Failed to login! Check username or password. Error: ' + err; } return sessionId; } function logout(url, sessionId) { var fullUrl = url + '/j_spring_security_logout'; var res = http( fullUrl, { Method: 'GET', Headers: { 'Origin': [url], 'Content-Type': ['application/x-www-form-urlencoded'], 'Cookie': [COOKIE_PREFIX + sessionId] } }, true, proxy, true ); if (res.StatusCode !== 302) { throw 'Failed to logout with status [' + res.StatusCode + ']. Expected status 302.\nOriginal error: ' + res.Body; } } function createQuery(args, defaultQuery) { args = args || {}; defaultQuery = defaultQuery || {}; var query = {}; if (args.page || defaultQuery.page) { query.page = args.page || defaultQuery.page; } if (args.start || defaultQuery.start) { query.start = args.start || defaultQuery.start; } if (args.limit || defaultQuery.limit) { query.limit = args.limit || defaultQuery.limit; } if (args.sort || defaultQuery.sort) { query.sort = args.sort || defaultQuery.sort; } if (args.filter || defaultQuery.filter) { query.filter = args.filter || defaultQuery.filter; } return query; } function createQueryFromString(q) { if (!q.match(/(.*=.*&)*(.*=.*)/)) { throw 'invalid query. query must be of structure: key1=value1&key2=value2&keyN=valueN'; } var query = replaceAll(q, '\"', '"') .split('&') .reduce(function(qArgs, nextArg) { var na = nextArg.split('='); var argKey = na[0]; var argValue = na[1]; qArgs[argKey] = argValue; return qArgs; }, {}); return query; } var defaultIncidentFilter = { page: 1, start: 0, limit: 50, sort: JSON.stringify([ { property:'created', direction: 'DESC' } ]), filter: JSON.stringify([ { property: 'created', value: [ 851171984031, // year 1996 new Date().getTime() ] } ]) }; function listIncidents(sessionId, args, incidentManagementId) { var fullUrl = url + '/ajax/incidents/' + incidentManagementId; var query = {}; if (args.query) { query = createQueryFromString(args.query); } else { query = createQuery(args, defaultIncidentFilter); } fullUrl += encodeToURLQuery(query); var res = http( fullUrl, { Method: 'GET', Headers: { 'Cookie': [COOKIE_PREFIX + sessionId] } }, true, proxy ); if (res.StatusCode < 200 || res.StatusCode >= 300) { throw 'Failed to fetch incidents with status [' + res.StatusCode + ']. \nOriginal error: ' + res.Body; } try { incidentsRes = JSON.parse(res.Body); if (incidentsRes.success) { var incidents = incidentsRes.data; if (!args.loadAlerts) { return incidents; } // loading all the alerts which related to incident // we load the alerts and original alerts which contains the original events which the alert created from // this has performance impact for (var i = 0; i < incidents.length; i++) { var alerts = filterAlerts(sessionId, { filter: JSON.stringify([ { property: 'incidentId', value: incidents[i].id } ]) }) incidents[i].alerts = []; alerts.forEach(function(alert) { var originalAlert = getOriginalAlertById(sessionId, { alertId: alert.id }); incidents[i].alerts.push({ alert: alert, orignalAlert: originalAlert }); }); } return incidents; } else { throw FailedRequestError('Fetch incidents failed.', fullUrl, query, null, incidentsRes).toString(); } } catch (err) { throw FailedRequestError('Unexpected error while fetching incidents. \nOriginal error: ' + err, fullUrl, query, null, res.Body).toString(); } } function fetchIncidents(sessionId, args, incidentManagementId) { var now = new Date().getTime(); var lastRun = getLastRun().lastRun || now - 1*60*1000; // last minute var lastRunNext = lastRun; var tillNow = now; var query = { loadAlerts: true, page: 1, start: 0, limit: 50, filter: JSON.stringify([{ property: 'created', value: [ lastRun, tillNow ] }]) }; // TODO handle paging. If number of incidents are more than 50, then we need to // fetch the next pages too. var lastIncidents = listIncidents(sessionId, query, incidentManagementId); var convertedIncidents = []; for (var i = 0; i < lastIncidents.length; i++) { var inc = lastIncidents[i]; if (inc.created > lastRunNext) { // we get the last incident which created lastRunNext = inc.created + 1; } convertedIncidents.push({ name: inc.id, occurred: new Date(inc.firstAlertTime), owner: inc.assignee ? inc.assignee.login : '', reason: inc.name, rawJSON: JSON.stringify(inc) }); } setLastRun({ lastRun: lastRunNext }); return JSON.stringify(convertedIncidents); } function getIncidentById(sessionId, args, incidentManagementId) { var fullUrl = [ url, 'ajax/incident', incidentManagementId, args.incidentId ].join('/'); var res = http( fullUrl, { Method: 'GET', Headers: { 'Cookie': [COOKIE_PREFIX + sessionId] } }, true, proxy ); if (res.StatusCode < 200 || res.StatusCode >= 300) { throw 'Failed to get incident by id with status [' + res.StatusCode + ']. \nOriginal error: ' + res.Body; } try { incident = JSON.parse(res.Body); if (incident.success) { return incident.data; } else { throw FailedRequestError('Fetch incident by id failed.', fullUrl, null, null, incident).toString(); } } catch (err) { throw FailedRequestError('Unexpected error while fetching incident by id. \nOriginal error: ' + err, fullUrl, null, null, res.Body).toString(); } } var defaultComponentFilter = { page: 1, start: 0, limit: 1000, sort: replaceAll(JSON.stringify([ { property: 'displayName', direction: 'ASC' } ]), '\"', '"') }; function getComponents(sessionId, argz, types) { var fullUrl = url + '/common/devices'; var query = {}; if (argz.query) { query = createQueryFromString(argz.query); } else { query = createQuery(argz, defaultComponentFilter); } fullUrl += types ? '/types/' + types.join('/') : ''; fullUrl += encodeToURLQuery(query); var res = http( fullUrl, { Method: 'GET', Headers: { 'Cookie': [COOKIE_PREFIX + sessionId] } }, true, proxy ); if (res.StatusCode < 200 || res.StatusCode >= 300) { throw 'Failed to fetch components with status [' + res.StatusCode + ']. \nOriginal error: ' + res.Body; } try { components = JSON.parse(res.Body); if (components.success) { return components.data; } else { throw FailedRequestError('Fetch components failed.', fullUrl, query, null, components).toString(); } } catch (err) { throw FailedRequestError('Unexpected error when fetching components. \nOriginal error: ' + err, fullUrl, query, null, res.Body).toString(); } } function getIncidentManagementId(sessionId) { var incidentManagement = getComponents(sessionId, {}, ['INCIDENT_MANAGEMENT']); if (!incidentManagement || incidentManagement.length === 0) { throw 'Failed to find RSA NetWitness INCIDENT_MANAGEMENT component/device: ' + JSON.stringify(incidentManagement); } return incidentManagement[0].id; } function createEventsQuery(args, predicateIds) { args = args || {}; var query = {}; query.deviceId = args.deviceId; query.collectionName = args.collectionName || ''; query.predicateIds = predicateIds ? predicateIds.join(',') : ''; query.timeRangeType = args.timeRangeType; query.startDate = args.startDate || ''; query.endDate = args.endDate || ''; query.lastCollectionTime = args.lastCollectionTime || ''; query.mid1 = args.mid1 || 0; query.mid2 = args.mid2 || 0; query.investigationToken = args.investigationToken || ''; query.page = args.page || 1; query.start = args.start || 0; query.limit = args.limit || 25; query.sort = args.sort ? replaceAll(args.sort, '\"', '"') : JSON.stringify([ { property: 'id', direction: 'ASC' } ]); return query; } function getEvents(sessionId, args) { var predicateIds = []; if (args.filter) { var eventsViewHTML = getEventsViewHtml(sessionId); var csrfToken = extractCsrfTokenFromHTML(eventsViewHTML); var filters = args.filter.split(','); for (var i = 0; i < filters.length; i++) { var predicate = postEventsTransient(sessionId, filters[i], csrfToken); predicateIds.push(predicate); } } var query = createEventsQuery(args, predicateIds); var fullUrl = url + '/ajax/investigation/events' + encodeToURLQuery(query); var res = http( fullUrl, { Method: 'GET', Headers: { 'Cookie': [COOKIE_PREFIX + sessionId] } }, true, proxy ); if (res.StatusCode < 200 || res.StatusCode >= 300) { throw 'Failed to fetch events with status [' + res.StatusCode + ']. \nOriginal error: ' + res.Body; } try { events = JSON.parse(res.Body); if (events.success) { return events.data; } else { throw FailedRequestError('Fetch events failed.', fullUrl, query, null, events).toString(); } } catch (err) { throw FailedRequestError('Unexpected while fetching events. \nOriginal error: ' + err, fullUrl, query, null, res.Body).toString(); } } function postEventsTransient(sessionId, query, ctoken) { var fullUrl = url + '/predicates/transient'; var body = { name: query, query: query, ctoken: ctoken }; var res = http( fullUrl, { Method: 'POST', Headers: { 'Cookie': [COOKIE_PREFIX + sessionId], 'Content-Type': ['application/x-www-form-urlencoded'] }, Body: encodeToURLQuery(body).replace(/^\?/, '') }, true, proxy ); if (res.StatusCode < 200 || res.StatusCode >= 300) { throw 'Failed to fetch events with status [' + res.StatusCode + ']. \nOriginal error: ' + res.Body; } try { transient = JSON.parse(res.Body); if (transient.success) { return transient.object; } else { throw FailedRequestError('Posting transient for events failed.', fullUrl, null, body, transient).toString(); } } catch (err) { throw FailedRequestError('Unexpected while posting transient for events. \nOriginal error: ' + err, fullUrl, null, body, res.Body).toString(); } } function getEventDetails(sessionId, args) { var fullUrl = url + '/investigation/reconstruct/event'; var eventsViewHTML = getEventsViewHtml(sessionId); var csrfToken = extractCsrfTokenFromHTML(eventsViewHTML); var body = { deviceId: args.deviceId, collectionName: args.collectionName || '', eventId: args.eventId, contentType: 'AUTO', contentSide: 'REQUEST_AND_RESPONSE', contentLayout: 'TOP_TO_BOTTOM', packetOverride: -1, ctoken: csrfToken }; var res = http( fullUrl, { Method: 'POST', Headers: { 'Cookie': [COOKIE_PREFIX + sessionId], 'Content-Type': ['application/x-www-form-urlencoded'] }, Body: encodeToURLQuery(body).replace(/^\?/, '') }, true, proxy ); if (res.StatusCode < 200 || res.StatusCode >= 300) { throw 'Failed to fetch event with status [' + res.StatusCode + ']. \nOriginal error: ' + res.Body; } try { event = JSON.parse(res.Body); if (event.success) { var content = getEventContent(sessionId, event.data.uri); return {data: event.data, content: content}; } else { throw FailedRequestError('Fetching event details', fullUrl, null, body, event).toString(); } } catch (err) { throw FailedRequestError('Unexpected while fetching event details. \nOriginal error: ' + err, fullUrl, null, body, res.Body).toString(); } } // Returns events/session data content. function getEventContent(sessionId, urlSuffix) { var fullUrl = url + urlSuffix; var res = http( fullUrl, { Method: 'GET', Headers: { 'Cookie': [COOKIE_PREFIX + sessionId] } }, true, proxy ); if (res.StatusCode < 200 || res.StatusCode >= 300) { throw 'Failed to fetch event data (recontruction) with status [' + res.StatusCode + ']. \nOriginal error: ' + res.Body; } try { return res.Body; } catch (err) { throw FailedRequestError('Unexpected while fetching event data (recontruction). \nOriginal error: ' + err, fullUrl, query, null, res.Body).toString(); } } var defaultAlertQuery = { page: 1, start: 0, limit: 100, sort: JSON.stringify([ { property:'alert.timestamp', direction: 'DESC' } ]), filter: JSON.stringify([ { property: 'alert.timestamp', value: [ 851171984031, // year 1996 new Date().getTime() ] } ]) }; function filterAlerts(sessionId, args) { var query = createQuery(args, defaultAlertQuery); var fullUrl = [ url, '/ajax/alerts/', incidentManagementId, encodeToURLQuery(query) ].join(''); var res = http( fullUrl, { Method: 'GET', Headers: { 'Cookie': [COOKIE_PREFIX + sessionId] } }, true, proxy ); if (res.StatusCode < 200 || res.StatusCode >= 300) { throw 'Failed to fetch alerts with status [' + res.StatusCode + ']. \nOriginal error: ' + res.Body; } try { alerts = JSON.parse(res.Body); if (alerts.success) { return alerts.data; } else { throw FailedRequestError('Fetch alerts failed.', fullUrl, query, null, alerts).toString(); } } catch (err) { throw FailedRequestError('Unexpected while fetching alerts. Original error:' + err, fullUrl, query, null, res.Body).toString(); } } function getAlertById(sessionId, args) { var fullUrl = [ url, 'ajax/alerts', incidentManagementId, args.alertId ].join('/'); var res = http( fullUrl, { Method: 'GET', Headers: { 'Cookie': [COOKIE_PREFIX + sessionId] } }, true, proxy ); if (res.StatusCode < 200 || res.StatusCode >= 300) { throw 'Failed to get events of alert with status [' + res.StatusCode + ']. \nOriginal error: ' + res.Body; } try { alert = JSON.parse(res.Body); if (alert.success) { return alert.data; } else { throw FailedRequestError('Fetch alert details failed.', fullUrl, query, null, alert).toString(); } } catch (err) { throw FailedRequestError('Unexpected while fetching alert details. \nOriginal error: ' + err, fullUrl, null, null, res.Body).toString(); } } function getOriginalAlertById(sessionId, args) { var fullUrl = [ url, 'ajax/alerts/originalalert', incidentManagementId, args.alertId ].join('/'); var res = http( fullUrl, { Method: 'GET', Headers: { 'Cookie': [COOKIE_PREFIX + sessionId] } }, true, proxy ); if (res.StatusCode < 200 || res.StatusCode >= 300) { throw 'Failed to get events of alert with status [' + res.StatusCode + ']. \nOriginal error: ' + res.Body; } try { alert = JSON.parse(res.Body); if (alert.success) { return alert.data; } else { throw FailedRequestError('Fetch alert details failed.', fullUrl, query, null, alert).toString(); } } catch (err) { throw FailedRequestError('Unexpected while fetching alert details. \nOriginal error: ' + err, fullUrl, null, null, res.Body).toString(); } } function getAvailableAssignees(sessionId) { var fullUrl = url + '/ajax/incident/user/availableAssignees'; var res = http( fullUrl, { Method: 'GET', Headers: { 'Cookie': ['RSA_SA_LICENSE=true; SaneID=10.64.49.14-1456516139492605; s_pers=%20s_fid%3D0D47AAAFD2A1592B-3436DC4A7A7EB300%7C1531522908438%3B%20gpv_pn%3DMYTOOLSSTATIC%252FTOOLS%252FTHE%2520SQUARE%7C1468452708438%3B%20s_lv%3D1468450908454%7C1563058908454%3B%20s_lv_s%3DLess%2520than%25201%2520day%7C1468452708454%3B; s_vi=[CS]v1|2B6795DE050118E9-40001608C00050FA[CE]; s_fid=3D8DF632622AC544-1283F8DF4BA4E8DC; JSESSIONID=' + sessionId] } }, true, proxy ); if (res.StatusCode < 200 || res.StatusCode >= 300) { throw 'Failed to fetch availabe assignees with status [' + res.StatusCode + ']. \nOriginal error: ' + res.Body; } try { availableAssignees = JSON.parse(res.Body); if (availableAssignees.success) { return availableAssignees.data; } else { throw FailedRequestError('Fetch available assignees failed.', fullUrl, null, null, availableAssignees).toString(); } } catch (err) { throw FailedRequestError('Unexpected error while fetching available assignees. \nOriginal error: ' + err, fullUrl, null, null, res.Body).toString(); } } function getEventsViewHtml(sessionId) { var fullUrl = url + '/investigation/events'; var res = http( fullUrl, { Method: 'GET', Headers: { 'Cookie': [COOKIE_PREFIX + sessionId] } }, true, proxy ); if (res.StatusCode < 200 || res.StatusCode >= 300) { throw 'Failed to fetch CSRF token with status [' + res.StatusCode + ']. \nOriginal error: ' + res.Body; } return res.Body; } function extractCsrfTokenFromHTML(html) { var matched = html.match(/<meta name="csrf-token" content=".*"/); if (!matched) { throw 'CSRF token not found! Internal error in NetWitness. Response body: \n' + html; } var csrfToken = replaceAll(matched[0].replace('<meta name="csrf-token" content=', ''), '"', ''); return csrfToken; } function extractLoggedUserFromHTML(html) { var matchedLoggedUser = html.match(/name: Ext\.htmlDecode\(.*\)/); if (!matchedLoggedUser) { throw 'Failed to determine logged in user. Html: ' + html; } var name = matchedLoggedUser[0].replace('name: Ext.htmlDecode(\'', '').replace('\')', ''); var user = { name: name }; return user; } var DEFAULT_SEVERITY = "50"; function createAlert(sessionId, args, incidentManagementId, createdUser, csrfToken) { var eventListString = replaceAll(args.eventList, ' ', ''); var fullUrl = [ url, 'ajax/alert/create', args.deviceId, eventListString, incidentManagementId + '', '?ctoken=' + csrfToken ].join('/'); var body = { alertSummary: args.alertSummary, event_id_list: eventListString.split(','), severity: args.severity ? args.severity + '' : DEFAULT_SEVERITY, create_by_user: createdUser.name }; var res = http( fullUrl, { Method: 'POST', Headers: { 'Cookie': [COOKIE_PREFIX + sessionId], 'Content-Type': ['application/json'] }, Body: JSON.stringify(body) }, true, proxy ); if (res.StatusCode < 200 || res.StatusCode >= 300) { throw 'Failed to create new alert with status [' + res.StatusCode + ']. \nOriginal error: ' + res.Body; } try { var alertRes = JSON.parse(res.Body); if (alertRes.success) { return alertRes.data; } else { throw FailedRequestError('Failed to create alert.', fullUrl, null, body, alertRes).toString(); } } catch (err) { throw FailedRequestError('Unexpected error while creating alert. \nOriginal error: ' + err, fullUrl, null, body, res.Body).toString(); } } function createIncident(sessionId, args, incidentManagementId, availableAssignees) { var eventsViewHTML = getEventsViewHtml(sessionId); var csrfToken = extractCsrfTokenFromHTML(eventsViewHTML); var loggedUser = extractLoggedUserFromHTML(eventsViewHTML); // currently we extract only the name of the logged in user. But the all the user object is exist in the html. // it just will take more development time. // that is why we look for the user in availableAssigness availableAssignees.forEach(function(user) { if (user.name === loggedUser.name) { loggedUser = user; } }); var newAlert = createAlert(sessionId, args, incidentManagementId, loggedUser, csrfToken); var fullUrl = [ url, 'ajax/incident/create', incidentManagementId + '', '?ctoken=' + csrfToken ].join('/'); var newIncident = { name: args.name, summary: args.summary || '', priority: args.priority, createdBy: loggedUser.name, alert_id_list: [ newAlert.id ] }; var res = http( fullUrl, { Method: 'POST', Headers: { 'Cookie': [COOKIE_PREFIX + sessionId], 'Content-Type': ['application/json'] }, Body: JSON.stringify(newIncident) }, true, proxy ); if (res.StatusCode < 200 || res.StatusCode >= 300) { throw 'Failed to create incident with status [' + res.StatusCode + ']\n.' + 'Request Body: ' + JSON.stringify(body) + '\n. Response Body: ' + res.Body; } try { var newIncidentRes = JSON.parse(res.Body); if (newIncidentRes.success) { newIncident.id = newIncidentRes.data.id; return newIncident; } else { throw FailedRequestError('Failed to create incident.', fullUrl, null, body, newIncidentRes).toString(); } } catch (err) { throw FailedRequestError('Unexpected error while creating incident. \nOriginal error: ' + err, fullUrl, null, body, res.Body).toString(); } } function addEventsToIncident(sessionId, args, incidentManagementId, availableAssignees) { var eventsViewHTML = getEventsViewHtml(sessionId); var csrfToken = extractCsrfTokenFromHTML(eventsViewHTML); var loggedUser = extractLoggedUserFromHTML(eventsViewHTML); // currently we extract only the name of the logged in user. But the all the user object is exist in the html. // it just will take more development time. // that is why we look for the user in availableAssigness availableAssignees.forEach(function(user) { if (user.name === loggedUser.name) { loggedUser = user; } }); var newAlert = createAlert(sessionId, args, incidentManagementId, loggedUser, csrfToken); var fullUrl = [ url, 'ajax/incident/addToIncident', incidentManagementId + '', '?ctoken=' + csrfToken ].join('/'); var reqBody = { alertIds: [ newAlert.id ], incidentId: args.incidentId }; var res = http( fullUrl, { Method: 'POST', Headers: { 'Cookie': [COOKIE_PREFIX + sessionId], 'Content-Type': ['application/json'] }, Body: JSON.stringify(reqBody) }, true, proxy ); if (res.StatusCode < 200 || res.StatusCode >= 300) { throw 'Failed to add events to incident with status [' + res.StatusCode + ']\n.' + 'Request Body: ' + JSON.stringify(body) + '\n. Response Body: ' + res.Body; } try { var resObject = JSON.parse(res.Body); if (resObject.success) { return true; } else { throw FailedRequestError('Failed to add events to incident.', fullUrl, null, body, newIncidentRes).toString(); } } catch (err) { throw FailedRequestError('Unexpected error while adding new events to incident. \nOriginal error: ' + err, fullUrl, null, body, res.Body).toString(); } } function updateIncident(sessionId, args, incidentManagementId, availableAssignees) { var eventsViewHTML = getEventsViewHtml(sessionId); var csrfToken = extractCsrfTokenFromHTML(eventsViewHTML); var loggedUser = extractLoggedUserFromHTML(eventsViewHTML); // currently we extract only the name of the logged in user. But the all the user object is exist in the html. // it just will take more development time. // that is why we look for the user in availableAssigness availableAssignees.forEach(function(user) { if (user.name === loggedUser.name) { loggedUser = user; } }); var fullUrl = [ url, 'ajax/incidents/update', incidentManagementId + '', '?ctoken=' + csrfToken ].join('/'); var updatedIncident = { id_list: replaceAll(args.idList, ' ', '').split(','), attribute_map: { lastUpdatedByUser: loggedUser }, benign_domain_list: [] }; if (args.name) { updatedIncident.attribute_map.name = args.name; } if (args.priority) { updatedIncident.attribute_map.priority = args.priority; } if (args.status) { updatedIncident.attribute_map.status = args.status; } if (args.summary) { updatedIncident.attribute_map.summary = args.summary; } if (args.comment) { updatedIncident.attribute_map.comment = args.comment; } if (args.assignee) { var assigneeUser = null; availableAssignees.forEach(function(user) { if (user.login === args.assignee) { assigneeUser = user; } }); if (!assigneeUser) { throw 'assignee argument is invalid. No such [' + args.assignee + '] available assignee user exist'; } updatedIncident.attribute_map.assignee = assigneeUser; } if (args.categories) { updatedIncident.attribute_map.categories = args.categories; } var res = http( fullUrl, { Method: 'POST', Headers: { 'Cookie': [COOKIE_PREFIX + sessionId], 'Content-Type': ['application/json'] }, Body: JSON.stringify(updatedIncident) }, true, proxy ); if (res.StatusCode < 200 || res.StatusCode >= 300) { throw 'Failed to create incident with status [' + res.StatusCode + ']\n.' + 'Request Body: ' + JSON.stringify(updatedIncident) + '\n. Response Body: ' + res.Body; } try { var updateRes = JSON.parse(res.Body); if (updateRes.success) { return updateRes; } else { throw FailedRequestError('Failed to update incident.', fullUrl, null, updatedIncident, updateRes).toString(); } } catch (err) { throw FailedRequestError('Failed to update incident.', fullUrl, null, updatedIncident, res.Body).toString(); } } function makeUpperCase (o) { for (var key in o ) { if(o.hasOwnProperty(key)) { var newKey = key.charAt(0).toUpperCase() + key.slice(1); o[newKey] = o[key]; delete o[key]; } } return o; } function getIncidentObject(e) { return { "Id": e.id, "Name": e.name, "Status": e.status, "Priority": e.priority, "Summary": e.summary, "Assignee": e.assignee ? e.assignee.name : "", "CreatedBy": e.createdBy, "Created": convertTimestampToString(e.created), "FirstAlertTime": convertTimestampToString(e.firstAlertTime), "LastUpdatedByUserName": e.lastUpdatedByUserName, "RiskScore": e.riskScore, "AverageAlertRiskScore": e.averageAlertRiskScore, "Categories": e.categories, "AlertCount": e.alertCount }; } function getAlert (alert) { return { "Id": alert.id, "Name": alert.name, "IncidentId": alert.incidentId, "Timestamp": convertTimestampToString(alert.timestamp), "HostSummary": alert.host_summary, "SignatureId": alert.signature_id, "Source": alert.source, "Type": alert.type, "RiskScore": alert.risk_score, "SourceCountry": alert.groupby_source_country, "DestinationCountry": alert.groupby_destination_country, "NumEvents": alert.numEvents, "SourceIp": alert.groupby_source_ip, "DestonationIp": alert.groupby_destination_ip, "DestonationPort": alert.groupby_destination_port }; } function buildRetValListIncidents (incidets) { var md = []; var ctx = {"Netwitness.Incident":[]} if (!Array.isArray(incidets)) { incidets = [incidets] } incidets.forEach(function (e) { var toPush = getIncidentObject(e); md.push(toPush); ctx["Netwitness.Incident"].push(toPush); }) return {Type: entryTypes.note, Contents: incidets, ContentsFormat: formats.json, HumanReadable: tableToMarkdown(command, md), ReadableContentsFormat: formats.markdown, EntryContext: ctx}; } function buildRetValGetIncidentDetails (incident) { var md = []; var ctx = {"Netwitness.Incident":[]} var toPush = getIncidentObject(incident); md.push(toPush); ctx["Netwitness.Incident"].push(toPush); return {Type: entryTypes.note, Contents: incident, ContentsFormat: formats.json, HumanReadable: tableToMarkdown(command, md), ReadableContentsFormat: formats.markdown, EntryContext: ctx}; } function buildRetValGetComponents (components) { var md = []; var ctx = {"Netwitness.Component":[]} if (!Array.isArray(components)) { components = [components] } components.forEach(function (e) { var toPush = { "Id": e.id, "DisplayName": e.displayName, "DeviceVersion": e.deviceVersion, "DisplayType": e.deviceType, "Host": e.host, "Port": e.port, "Validated": e.validated, "Licensed": e.licensed, "Username": e.username, "EnableSSL": e.enableSSL }; md.push(toPush) ctx["Netwitness.Component"].push(toPush); }) return {Type: entryTypes.note, Contents: components, ContentsFormat: formats.json, HumanReadable: tableToMarkdown(command, md), ReadableContentsFormat: formats.markdown, EntryContext: ctx}; } function buildRetValGetEvents (events) { var md = []; var ctx = {"Netwitness.Event":[]} if (!Array.isArray(events)) { events = [events] } events.forEach(function (event) { var toPush = { "Id": event.id, "Medium": event.medium, "Service": event.service, "Size": event.size } event["meta"].forEach(function (meta) { toPush["meta." + meta.name] = meta.value }); md.push(toPush); }); return {Type: entryTypes.note, Contents: events, ContentsFormat: formats.json, HumanReadable: tableToMarkdown(command, md), ReadableContentsFormat: formats.markdown}; } function buildRetValGetEventDetails (event) { var md = []; var ctx = {"Netwitness.Event":[]}; var data = event.data; var content = event.content; var toPush = { "EventId": data.eventId, "DeviceId": data.deviceId, "ReconstructedContentType": data.reconstructedContentType, "PacketsTotal": data.stats ? data.stats.packetsTotal : "", "PacketsProcessed": data.stats ? data.stats.packetsProcessed : "" }; data.summaryAttributes.forEach(function (e) { toPush[e.name] = e.value }); md.push(toPush); ctx["Netwitness.Event"].push(toPush); return {Type: entryTypes.note, Contents: event, ContentsFormat: formats.json, HumanReadable: tableToMarkdown(command, md), ReadableContentsFormat: formats.markdown, EntryContext: ctx}; } function buildRetValGetAlerts (alerts) { var md = []; var ctx = {"Netwitness.Alert":[]} if (!Array.isArray(alerts)) { alerts = [alerts] } alerts.forEach(function (e) { var toPush = getAlert(e); md.push(toPush); ctx["Netwitness.Alert"].push(toPush); }) return {Type: entryTypes.note, Contents: alerts, ContentsFormat: formats.json, HumanReadable: tableToMarkdown(command, md), ReadableContentsFormat: formats.markdown, EntryContext: ctx}; } function buildRetValGetAlert (alert) { var ctx = {"Netwitness.Alert":[]} var alertValue = getAlert(alert); var eventValue = []; alert.events.forEach(function (evnt) { eventValue.push(treeToFlattenObject(evnt)); }); var relatedLinksValue = alert.related_links; var hr = tableToMarkdown('Alerts',alertValue) + tableToMarkdown('Events', eventValue) + tableToMarkdown('Related Links', relatedLinksValue); ctx["Netwitness.Alert"].push(alertValue); return {Type: entryTypes.note, Contents: alert, ContentsFormat: formats.json, HumanReadable: hr, ReadableContentsFormat: formats.markdown, EntryContext: ctx}; } function buildRetValGetAlertOrig (alertOrig) { var md = []; var ctx = {"Netwitness.Event": []} if(!alertOrig.events) { return {"ContentsFormat": formats["markdown"], "Type": entryTypes["error"], "Contents": "Received an error from NetWitness Please ensure that the referred alert Id exist in NetWitness"}; } alertOrig.events.forEach(function (evnt) { for (var key in evnt) { if (key === 'time') { evnt[key] = convertTimestampToString(evnt[key]); } } }); md = alertOrig.events; ctx["Netwitness.Event"] = alertOrig.events; return {Type: entryTypes.note, Contents: alertOrig, ContentsFormat: formats.json, HumanReadable: tableToMarkdown(command, md), ReadableContentsFormat: formats.markdown, EntryContext: ctx}; } function buildRetValAvailableAssignees(availableAssignees) { var md = []; var ctx = {"Netwitness.Account":[]} if (!Array.isArray(availableAssignees)) { availableAssignees = [availableAssignees] } availableAssignees.forEach(function (e) { var toPush ={ "Id": e.id, "Name": e.name, "Login": e.login, "EmailAddress": e.emailAddress }; md.push(toPush); ctx["Netwitness.Account"].push(toPush); }) return {Type: entryTypes.note, Contents: availableAssignees, ContentsFormat: formats.json, HumanReadable: tableToMarkdown(command, md), ReadableContentsFormat: formats.markdown, EntryContext: ctx}; } function buildRetValCreateIncident (newIncident) { var md = []; var ctx = {"Netwitness.Incident":[]} var toPush = { "Id": newIncident.id, "Name": newIncident.name, "Priority": newIncident.priority, "CreatedBy": newIncident.createdBy, "AlertIDList": newIncident.alertIdList }; md.push(toPush); ctx["Netwitness.Incident"].push(toPush) results = {Type: entryTypes.note, Contents: newIncident, ContentsFormat: formats.json, HumanReadable: tableToMarkdown(command, md), ReadableContentsFormat: formats.markdown, EntryContext: ctx}; } // The command input arg holds the command sent from the user. var sessionId = login(url, username, password); var incidentManagementId = args.incidentManagementId || getIncidentManagementId(sessionId); var results = false; switch (command) { case 'fetch-incidents': results = fetchIncidents(sessionId, args, incidentManagementId); break; case 'test-module': results = 'ok'; break; case 'nw-login': results = sessionId; break; case 'netwitness-im-list-incidents': var incidents = listIncidents(sessionId, args, incidentManagementId); results = buildRetValListIncidents(incidents); break; case 'netwitness-im-get-incident-details': var incident = getIncidentById(sessionId, args, incidentManagementId); results = buildRetValGetIncidentDetails(incident); break; case 'netwitness-im-get-components': var components = getComponents(sessionId, args); results = buildRetValGetComponents(components); break; case 'netwitness-im-get-events': var events = getEvents(sessionId, args); results = buildRetValGetEvents(events); break; case 'netwitness-im-get-event-details': event = getEventDetails(sessionId, args); results = buildRetValGetEventDetails(event); break; case 'netwitness-im-get-alerts': var alerts = filterAlerts(sessionId, args); results = buildRetValGetAlerts(alerts); break; case 'netwitness-im-get-alert-details': var alert = getAlertById(sessionId, args); results = buildRetValGetAlert(alert); break; case 'netwitness-im-get-alert-original': var alert = getOriginalAlertById(sessionId, args); results = buildRetValGetAlertOrig(alert); break; case 'netwitness-im-get-available-assignees': var availableAssignees = getAvailableAssignees(sessionId); results = buildRetValAvailableAssignees(availableAssignees); break; case 'netwitness-im-create-incident': var availableAssignees = getAvailableAssignees(sessionId); var newIncident = createIncident(sessionId, args, incidentManagementId, availableAssignees); results = buildRetValCreateIncident(newIncident); break; case 'netwitness-im-add-events-to-incident': var md = []; var availableAssignees = getAvailableAssignees(sessionId, args); var isSuccess = addEventsToIncident(sessionId, args, incidentManagementId, availableAssignees); md.push({ success: isSuccess }) results = {Type: entryTypes.note, Contents: { success: isSuccess }, ContentsFormat: formats.json, HumanReadable: tableToMarkdown(command, md), ReadableContentsFormat: formats.markdown}; break; case 'netwitness-im-update-incident': var availableAssignees = getAvailableAssignees(sessionId, args); var update_incident = updateIncident(sessionId, args, incidentManagementId, availableAssignees); if( update_incident.success != true) { results = {"ContentsFormat": formats["markdown"], "Type": entryTypes["error"], "Contents": "Didn't succed to update incident.\n" + tableToMarkdown("Data returned:", update_incident)}; } else if (update_incident.success == true && update_incident.data < 1) { results = {"ContentsFormat": formats["markdown"], "Type": entryTypes["error"], "Contents": "Received an error from NetWitness Please ensure that the referred incidents exist in NetWitness. Incidents count = " + update_incident.data}; } else { results = { "ContentsFormat": formats["text"], "Type": entryTypes["note"], "Contents": "Incident updated successfully." }; } break; default: // You can use args[argName] or args.argName to get a specific arg. args are strings. // You can use params[paramName] or params.paramName to get a specific params. // Params are of the type given in the integration page creation. } logout(url, sessionId); return results;