var SERVER_URL = params.url; if (SERVER_URL[SERVER_URL.length - 1] !== '/') { SERVER_URL += '/'; } //HELPER FUNCTIONS function doReq(method, path, query, body) { var result = http( SERVER_URL + path + encodeToURLQuery(query), { Headers: { 'Content-Type': ['application/json'], 'Accept': ['application/json'] }, Username: params.id, Password: params.key, Method: method, Body: body ? JSON.stringify(body) : '' }, params.insecure, params.useproxy ); if (result.StatusCode < 200 || result.StatusCode > 299) { if (result.StatusCode === 404 && result.Body.indexOf('Resource Not Found') > -1) { // Skip this error - it just means query returned no results. Handle as no results. } else { throw 'Failed to perform request ' + path + ', request status code: ' + result.StatusCode + ', body: ' + result.Body; } } if (result.Body === '') { throw 'No content received.'; } else { var obj; try { obj = JSON.parse(result.Body); } catch (ex) { throw 'Error parsing reply - ' + result.Body + ' - ' + ex; } if (obj.errors && obj.errors.length > 0) { if (dq(obj, 'errors.[0].code') === 404 && dq(obj, 'errors.[0].message').indexOf('Resource Not Found') > -1) { // Skip this error - it just means query returned no results. Handle as no results. } else { throw JSON.stringify(obj.errors); } } return { body: result.Body, obj: obj, statusCode: result.StatusCode }; } } function dateToEpoch(d) { return d ? new Date(d).getTime() : null; } function uploadIOC() { args.expiration_days = parseInt(args.expiration_days) var res = doReq('POST', 'indicators/entities/iocs/v1', {}, [args]); return { Type: entryTypes.note, Contents: res.body, ContentsFormat: formats.json, HumanReadable: 'IOC [' + args.value + '] uploaded' }; } // add args to a if exists function add(a, k, f) { if (args[k]) { // check if the argument is a number if(!isNaN(args[k])){ args[k] = args[k].toString(); } var parts = argToList(args[k]); for (var i=0; i 1 ? parts : parts[0]; } } //COMMANDS// function getIOC() { var res = doReq('GET', 'indicators/entities/iocs/v1', {ids: args.type + ':' + args.value}); var md = '### Falcon Host custom IOC retrieval\n'; if (res.obj.resources) { for (var i=0; i 0) { ec.FalconHostDevices = res.obj.resources; md += '### Devices\n'; for (var i=0; i 0) { md += arrToMd(res.obj.resources); } else { md += 'No result found'; } return { Type: entryTypes.note, Contents: res.obj, ContentsFormat: formats.json, HumanReadable: md }; } function deviceRanOn() { var res = doReq('GET', 'indicators/queries/devices/v1', args); var md = '## Falcon Host IOC Device Ran On\n'; var ec = {}; if (res.obj.resources && res.obj.resources.length > 0) { ec.FalconHostDevices = res.obj.resources; md += '### Devices\n'; for (var i=0; i 0) { ec.FalconHostProcesses = res.obj.resources; md += '### Processes\n'; for (var i=0; i 0) { md += arrToMd(res.obj.resources); } else { md += 'No result found'; } return { Type: entryTypes.note, Contents: res.obj, ContentsFormat: formats.json, HumanReadable: md }; } function resolveDetection() { var ids = argToList(args.ids); doReq('PATCH', 'detects/entities/detects/v2', {}, {ids: ids, status: args.status}); var res = doReq('POST', 'detects/entities/summaries/GET/v1', {}, {ids: ids}); var md = '## Falcon Host Detection Details\n'; var ec = {}; if (res.obj.resources && res.obj.resources.length > 0) { ec = res.obj.resources; md += tableToMarkdown('', prettifyDetectionsDetails(res.obj.resources), ['First Behavior', 'Device Hostname', 'Max Severity Display Name', 'Technique', 'Filename', 'Commandline', 'Detection ID', 'Device ID', 'Status']); } else { md += 'No result found'; } return { Type: entryTypes.note, Contents: res.obj, ContentsFormat: formats.json, HumanReadable: md, EntryContext: { "CrowdStrikeHost.Detections(val.detection_id == obj.detection_id)": ec } }; } function detectionSearch() { var headers = {}; if ((!args.query && !args.first_behavior)) { return { Type: entryTypes.error, Contents: 'You must specify at least one of the following: query, first_behavior', ContentsFormat: formats.text, }; } if (args.query) { headers.q = args.query; } if (args.first_behavior) { headers.first_behavior = args.first_behavior; } var res = doReq('GET', 'detects/queries/detects/v1', headers); var ec = []; var md = '## Falcon Host List of Detections\n'; if (res.obj.resources && res.obj.resources.length > 0) { //ec.detectionID = res.obj.resources; md += '### Detections\n'; for (var i=0; i 0) { ec = res.obj.resources; md += tableToMarkdown('', prettifyDetectionsDetails(res.obj.resources), ['First Behavior', 'Device Hostname', 'Max Severity Display Name', 'Technique', 'Filename', 'Commandline', 'Detection ID', 'Device ID', 'Status']); } else { md += 'No result found'; } return { Type: entryTypes.note, Contents: res.obj, ContentsFormat: formats.json, HumanReadable: md, EntryContext: { "CrowdStrikeHost.Detections(val.detection_id == obj.detection_id)": ec } }; } function threatGraphSummary() { var ids = argToList(args.ctg_id); var res = doReq('GET', 'threatgraph/combined/control-graphs/summary/v1', {ids: ids}); var md = '## Falcon Host Threat Graph Summary\n'; var ec = {}; if (res.obj.resources && res.obj.resources.length > 0) { ec = {"CrowdStrikeHost.ThreatGraphSummary(val.id == obj.id)": res.obj.resources}; md += tableToMarkdown('', res.obj.resources) } else { md += 'No result found'; } return { Type: entryTypes.note, Contents: res.obj, ContentsFormat: formats.json, HumanReadable: md, EntryContext: ec }; } function threatGraphProcesses() { var ids = argToList(args.process_id); var res = doReq('GET', 'threatgraph/combined/processes/summary/v1', {ids: ids}); var md = '## Falcon Host Threat Graph Processess Summary\n'; var ec = {}; if (res.obj.resources && res.obj.resources.length > 0) { ec = {"CrowdStrikeHost.ThreatGraphProcessess(val.id == obj.id)": res.obj.resources}; md += tableToMarkdown('', res.obj.resources) } else { md += 'No result found'; } return { Type: entryTypes.note, Contents: res.obj, ContentsFormat: formats.json, HumanReadable: md, EntryContext: ec }; } function threatGraphDetections() { var ids = argToList(args.detection_id); var res = doReq('GET', 'threatgraph/combined/detections/summary/v1', {ids: ids}); var md = '## Falcon Host Threat Graph Detections Summary\n'; var ec = {}; if (res.obj.resources && res.obj.resources.length > 0) { ec = {"CrowdStrikeHost.ThreatGraphDetections":res.obj.resources}; md += tableToMarkdown('', res.obj.resources) } else { md += 'No result found'; } return { Type: entryTypes.note, Contents: res.obj, ContentsFormat: formats.json, HumanReadable: md, EntryContext: ec }; } switch (command) { case 'test-module': args = {filter: "platform_name:'Windows'"}; deviceSearch(); return true; case 'cs-upload-ioc': return uploadIOC(); case 'cs-get-ioc': return getIOC(); case 'cs-update-ioc': return updateIOC(); case 'cs-delete-ioc': return deleteIOC(); case 'cs-search-iocs': return searchIOCs(); case 'cs-device-search': return deviceSearch(); case 'cs-device-details': return deviceDetails(); case 'cs-device-count-ioc': return deviceCountIOC(); case 'cs-device-ran-on': return deviceRanOn(); case 'cs-processes-ran-on': return processesRanOn(); case 'cs-process-details': return processDetails(); case 'cs-resolve-detection': return resolveDetection(); case 'cs-detection-search': return detectionSearch(); case 'cs-detection-details': return detectionDetails(); case 'cs-threatgraph-summary': return threatGraphSummary(); case 'cs-threatgraph-processes': return threatGraphProcesses(); case 'cs-threatgraph-detections': return threatGraphDetections(); default: throw 'Unknown command - ' + command; }