Netskope Deprecated
Cloud access security broker that enables to find, understand, and secure cloud apps. Deprecated. Use Netskope (API v1) instead.
Network Security · Netskope
Details
| ID | Netskope |
|---|---|
| Provider | Netskope |
| Category | Network Security |
| From Version | 5.0.0 |
| Supported Modules | Agentix XSIAM |
README
Use the Netskope integration to manage your Netskope events and alerts.
This integration was integrated and tested with Netskope v51.
Prerequisites
You need to obtain the following Netskope information.
- Netskope tenant URL
- Tenant API token
Configure the Netskope Integration on Cortex XSOAR
- Navigate to Settings > Integrations > Servers & Services.
- Search for Netskope.
- Click Add instance to create and configure a new integration instance.
- Name: a textual name for the integration instance.
- URL of Netskope Tenant: for example, https://tenant.goskope.com
- Tenant API Token: paste the token that you copied.
- Do not validate server certificate (unsecure)
- Use system proxy settings
- Click Test to validate the URLs and connection.
Commands
You can execute these commands from the Cortex XSOAR CLI, as part of an automation, or in a playbook. After you successfully execute a command, a DBot message appears in the War Room with the command details.
1. Get Netskope events: netskope-events
Retrieve events from your Netskope environment.
Command Example
!netskope-events type=application timeperiod=Last24Hours
Input
| Input Parameter | Description |
| query | Filter query, for example, foo@test.com |
| timeperiod | Query time period (for example, last 60 minutes, last 24 hours) |
| starttime | Query start time: timestamp or dd-mm-yyyyTHH:MM:SSZ (e.g., 31-12-1999T11:59:59Z)
|
| endtime |
Query end time: timestamp or dd-mm-yyyyTHH:MM:SSZ (e.g., 31-12-1999T11:59:59Z) |
| type |
Event type
|
| limit |
Maximum number of events returned (useful for pagination in combination with skip) Must be an integer less than 5,000. |
| skip | Skip over specific events (useful for pagination in combination with limit) |
Context Output
| Path | Description |
| Netskope.Events.App | Application name |
| Netskope.Events.Timestamp | Event timestamp |
| Netskope.Events.Activity | Event activity |
| Netskope.Events.Object | Document/object from the event |
| Netskope.Events.hostname | Device hostname |
| Netskope.Events.AppCategory | Netskope application category (for example, Cloud Storage, Webmail, and so on) |
| Netskope.Events.device_classification | Device classification (for example, managed vs. unmanaged) |
| Netskope.Events.User | User |
| Netskope.Events.from_user | Login IDs for cloud applications |
| Netskope.Events.to_user | Destination user IDs |
| Netskope.Events.SourceIP | Source IP |
| Netskope.Events.AccessMethod | Access method (for example, client, reverse proxy, Secure Forwarder, and so on) |
| Netskope.Events.url | URL |
| Netskope.Events.ID | Event ID |
Raw Output
{
"AccessMethod":"API Connector",
"Activity":"HeadBucket",
"App":"Amazon Web Services",
"AppCategory":"IaaS/PaaS",
"DeviceClassification":null,
"FromUser":null,
"Hostname":null,
"ID":"1382a493090c36ba14bfc2bc",
"Object":"nstrail",
"SourceIP":"8.36.116.16",
"Timestamp":"Mon May 21 2018 13:26:30 GMT+0300 (IDT)",
"ToUser":null,
"URL":null,
"User":"assumed-role/ctaudit/AssumeRoleSession1"
}
2. Get Netskope alerts: netskope-alerts
Retrieve alerts from your Netskope environment.
Command Example
!netskope-alerts type=Malware timeperiod=Last60Days
Input
| Input Parameter | Description |
| type | Alert type |
| timeperiod | Query time period (for example, last 60 minutes, last 24 hours) |
| starttime |
Query start time: timestamp or dd-mm-yyyyTHH:MM:SSZ (e.g., 31-12-1999T11:59:59Z) |
| endtime |
Query end time: timestamp or dd-mm-yyyyTHH:MM:SSZ (e.g., 31-12-1999T11:59:59Z) |
| query | Valid event query described in the query language document |
Context Output
| Path | Description |
| Netskope.Alerts.App | Application name |
| Netskope.Alerts.Timestamp | Alert timestamp |
| Netskope.Alerts.Policy | Name of policy triggered |
| Netskope.Alerts.DLPFile | Name of DLP file that triggered |
| Netskope.Alerts.Hostname | Hostname |
| Netskope.Alerts.ID | Alert ID |
Raw Output
{
"App":"Microsoft Office 365 OneDrive for Business",
"DLPFile":null,
"DLPProfile":null,
"Hostname":"Ashutosh’s MacBook Pro",
"ID":"f95e5638432f538365d5b256",
"Policy":null,
"Timestamp":"Mon May 21 2018 13:29:34 GMT+0300 (IDT)"
}
Configuration parameters
url— URL of Netskope Tenant (e.g. https://tenant.goskope.com) (required)token— Tenant API Token (required)insecure— Trust any certificate (not secure)proxy— Use system proxy settingsisFetch— Fetch incidentsincidentType— Incident typefirstFetch— Timeframe for initial fetchmaxFetch— Maximum number of events to fetch per fetch
Commands (2)
-
netskope-alertsGets a list of alerts
-
netskope-eventsGets a list of events
var SERVER_URL = params.url.replace(/[\/]+$/, ''); var BASE_URL = SERVER_URL + '/api/v1/'; var TOKEN = params.token; function sendRequest(method, api, stringifyData) { var requestUrl = BASE_URL + api; var result = http( requestUrl, { Method: method, Headers: { 'Content-Type': ['application/json'], 'Accept': ['application/json'] } }, params.insecure, params.proxy ); if (result.StatusCode < 200 && result.StatusCode > 299) { throw 'Failed to perform request ' + path + ', request status code: ' + result.StatusCode + ', body: ' + result.Body; } if (result.Body === '') { throw 'No content received.' + requestUrl + result; } var body; try { // if fetching incidents, stringify long numbers to not round down long ids, e.g: // "dlp_incident_id":3747385551915191779 --> "dlp_incident_id":"3747385551915191779" if (stringifyData) { stringifyBody = result.Body.replace(/([\[:]){1}(\d{11,})([,\}\]])/g, "$1\"$2\"$3"); return JSON.parse(stringifyBody) } body = JSON.parse(result.Body); } catch (ex) { throw 'Error parsing reply - ' + result.Body + ' - ' + ex; } return body; } function normalizeTimestamp(timestamp) { return Date(timestamp); } function translateTimeperiod(timeperiod){ var timeperiodTranslator = { 'Last60Minutes': '3600', 'Last24Hours': '86400', 'Last7Days': '604800', 'Last30Days': '2592000', 'Last60Days': '5184000', 'Last90Days': '7776000' }; return timeperiodTranslator[timeperiod]; } function translateMonthName(monthName) { var monthTranslator = { 'january': 1, 'february': 2, 'march': 3, 'april': 4, 'may': 5, 'june': 6, 'july': 7, 'august': 8, 'september': 9, 'october': 10, 'november': 11, 'december': 12 }; return monthTranslator[monthName]; } /** * convert string formatted time to timestamp. * Note: Accept 2 string formats: "dd-mm-yyyyTHH:MM:SSZ" or "Month Day, Year HH:MM:SS". * @param {string} strDate - string formatted array * @return {string} timestamp */ function toTimestamp(strDate){ // accept: 31-12-1999T14:35:20Z var dateTuple = strDate.match('^(\\d{2})-(\\d{2})-(\\d{4})T(\\d{2}):(\\d{2}):(\\d{2})Z$'); var timestamp; if (dateTuple !== null) { // first element is the entire match, then the individual matches. // months in Date JS are an integer between 0 and 11. timestamp = new Date(dateTuple[3], dateTuple[2] - 1, dateTuple[1], dateTuple[4], dateTuple[5], dateTuple[6]); return timestamp.getTime()/1000; } // accept: December 31, 1999 14:35:20 dateTuple = strDate.toLowerCase().match('^(january|february|march|april|may|june|july|august|september|october|november|december) (\\d{1,2}), (\\d{4}) (\\d{2}):(\\d{2}):(\\d{2})$'); if (dateTuple !== null) { timestamp = new Date(dateTuple[3], translateMonthName(dateTuple[1]) - 1, dateTuple[2], dateTuple[4], dateTuple[5], dateTuple[6]); return timestamp.getTime()/1000; } return strDate; } function getAlerts(stringifyData) { var queryArgs = { token: TOKEN, type: encodeURIComponent(args.type) }; if (args.starttime && args.endtime) { queryArgs.starttime = toTimestamp(args.starttime); queryArgs.endtime = toTimestamp(args.endtime); if (args.timeperiod) { queryArgs.timeperiod = translateTimeperiod(args.timeperiod); } if (args.query) { queryArgs.query = encodeURIComponent(args.query); } } else if (args.timeperiod) { queryArgs.timeperiod = translateTimeperiod(args.timeperiod); if (args.query) { queryArgs.query = encodeURIComponent(args.query); } } else { throw 'Not given enough arguments to filter events by.'; } var cmdUrl = 'alerts' + encodeToURLQuery(queryArgs); logInfo('Getting/Fetching Netskope Alerts (to be incidents) with ' + String(cmdUrl)); var result = sendRequest('GET', cmdUrl, stringifyData); return result; } function getAlertsCommand() { result = getAlerts(false) var retArray = []; result.data.forEach(function(arrayItem) { var id = arrayItem._id; var app = arrayItem.app; var timestamp = normalizeTimestamp(arrayItem.timestamp); var dlp_profile = arrayItem.dlp_profile; var dlp_file = arrayItem.dlp_file; var hostname = arrayItem.hostname; var policy = arrayItem.policy; retArray.push({'ID': id, 'App' : app, 'Timestamp' : timestamp, 'DLPProfile' : dlp_profile, 'DLPFile' : dlp_file, 'Hostname' : hostname, 'Policy' : policy}); }); var ec = { "Netskope.Alerts(val.ID && val.ID === obj.ID)" : retArray }; headers = ['ID', 'Timestamp', 'DLPProfile', 'DLPFile', 'Hostname', 'Policy']; return { Type: entryTypes.note, ContentsFormat: formats.json, Contents: result.data, ReadableContensFormat: formats.markdown, HumanReadable: tableToMarkdown('Netskope Alerts', retArray, headers), EntryContext: ec }; } function getEvents() { var queryArgs = { token: TOKEN, type: encodeURIComponent(args.type) }; if (args.starttime && args.endtime) { queryArgs.starttime = toTimestamp(args.starttime); queryArgs.endtime = toTimestamp(args.endtime); if (args.timeperiod) { queryArgs.timeperiod = translateTimeperiod(args.timeperiod); } if (args.query) { queryArgs.query = encodeURIComponent(args.query); } } else if (args.timeperiod) { queryArgs.timeperiod = translateTimeperiod(args.timeperiod); if (args.query) { queryArgs.query = encodeURIComponent(args.query); } } else { throw 'Not given enough arguments to filter events by.'; } var cmdUrl = 'events' + encodeToURLQuery(queryArgs); var result = sendRequest('GET', cmdUrl); var retArray = []; result.data.forEach(function(arrayItem) { var id = arrayItem._id; var app = arrayItem.app; var timestamp = normalizeTimestamp(arrayItem.timestamp); var activity = arrayItem.activity; var object = arrayItem.object; var hostname = arrayItem.hostname; var category = arrayItem.category; var device_classification = arrayItem.device_classification; var user = arrayItem.user; var from_user = arrayItem.from_user; var to_user = arrayItem.to_user; var srcip = arrayItem.srcip; var access_method = arrayItem.access_method; var url = arrayItem.url; retArray.push({'ID': id, 'App' : app, 'Timestamp' : timestamp, 'Activity' : activity, 'Object' : object, 'Hostname' : hostname, 'AppCategory' : category, 'DeviceClassification' : device_classification, 'User' : user, 'FromUser' : from_user, 'ToUser' : to_user, 'SourceIP' : srcip, 'AccessMethod' : access_method, 'URL' : url}); }); var ec = { "Netskope.Events(val.ID && val.ID === obj.ID)" : retArray }; headers = ['ID', 'App', 'Timestamp', 'Activity', 'Object', 'Hostname', 'AppCategory', 'DeviceClassification', 'User', 'FromUser', 'ToUser', 'SourceIP', 'AccessMethod', 'URL']; return { Type: entryTypes.note, ContentsFormat: formats.json, Contents: result.data, ReadableContensFormat: formats.markdown, HumanReadable: tableToMarkdown('Netskope Events', retArray, headers), EntryContext: ec }; } function now() { return parseInt(new Date().getTime()/1000); } function fetchAlerts() { lastRun = getLastRun(); last_run = parseInt(lastRun.lastTime); if (isNaN(last_run)) { last_run = now() - parseInt(translateTimeperiod(params.firstFetch)); } args = {}; args.type = ""; args.starttime = last_run.toString(); args.endtime = now().toString(); alerts = getAlerts(true).data; var incidents = []; var latestIncidedentTimeString = null; var latestIncidedentTimeInt = null; if (typeof alerts !== 'undefined') { alerts.reverse(); // alerts are fetched in descending order, reversing to process older first for (var i = 0; i < alerts.length; i++) { item = alerts[i]; incident = {}; d = new Date(item.timestamp); incident.occurred = d.toISOString(); incident.name = item.alert_type + " - " + item.alert_name; incident.rawJSON = JSON.stringify(item); incidents.push(incident); if (latestIncidedentTimeInt == null || parseInt(item.timestamp) > latestIncidedentTimeInt) { latestIncidedentTimeInt = parseInt(item.timestamp); latestIncidedentTimeString = item.timestamp } if (incidents.length >= Math.min(50, params.maxFetch)) { break; } } } var incidentsLimitReached = (incidents.length >= Math.min(50, params.maxFetch)); lastTime = incidentsLimitReached ? latestIncidedentTimeString : args.endtime; lastRun = {'lastTime': lastTime}; setLastRun(lastRun); logInfo('Netskope lastRun is: ' + String(args.endtime)); return JSON.stringify(incidents); } switch (command) { case 'test-module': var queryArgs = { token: TOKEN, type: 'application', timeperiod: '3600', limit: '1' }; var cmdUrl = 'events' + encodeToURLQuery(queryArgs); result = sendRequest('GET', cmdUrl); if (result.status != "error") { return 'ok'; } return result; case 'fetch-incidents': return fetchAlerts(); case 'netskope-events': return getEvents(); case 'netskope-alerts': return getAlertsCommand(); }