Created
October 3, 2018 22:44
-
-
Save chrissmith-mcafee/7f87ffc17134a60883b16d67dd91a836 to your computer and use it in GitHub Desktop.
This Node-RED flow executes a `McAfee Active Response` search for the running processes on a particular endpoint as specified by its IP address. The names of the processes found are retrieved and captured one page (up to 5 items) at a time.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[ | |
{ | |
"id": "15c35c35.087ac4", | |
"type": "tab", | |
"label": "MAR Basic Paging Example", | |
"disabled": false, | |
"info": "This sample executes a `McAfee Active Response` search for the running processes\r\non a particular endpoint as specified by its IP address. The names of the\r\nprocesses found are retrieved and captured one page (up to 5 items) at a time.\r\nThe resulting process names captured across all pages are displayed on the\r\nNode-RED `debug` tab.\r\n\r\n### Prerequisites\r\n\r\n* The samples configuration step has been completed (see\r\n [Client Configuration](https://opendxl.github.io/node-red-contrib-dxl/jsdoc/tutorial-configuration.html)).\r\n* A McAfee Active Response (MAR) service is available on the DXL fabric.\r\n* The DXL client associated with the\r\n`Search MAR for host` node has been authorized to perform MAR searches\r\n (see [Authorize Client to Perform MAR Search](https://opendxl.github.io/opendxl-client-python/pydoc/marsendauth.html)).\r\n\r\n### Setup\r\n\r\n* Edit the `Specify host to find` node and modify the `Payload` property with\r\n the IP address of a host to retrieve the process list from. For example:\r\n\r\n ```\r\n 192.168.1.1\r\n ```\r\n\r\n* To deploy the flow, press the `Deploy` button in the upper-right corner of the\r\n screen. If Node-RED is able to properly connect to the DXL fabric, a green dot\r\n with the word `connected` should appear under the `Search MAR for host` node.\r\n\r\n### Running\r\n\r\nTo exercise the flow, double-click the button on the left side of the\r\n`Specify host to find` node.\r\n\r\n### Output\r\n\r\nOutput similar to the following should appear in the Node-RED `debug` tab:\r\n\r\n```\r\n? [ array[5], array[5], array[5] ]\r\n```\r\n\r\nAfter clicking on the right arrow buttons to expand the contents of the array,\r\noutput similar to the following should appear:\r\n\r\n```\r\n? array[3]\r\n ? 0: array[5]\r\n 0: \"MARService.exe\"\r\n 1: \"OneDrive.exe\"\r\n 2: \"RuntimeBroker.exe\"\r\n 3: \"SearchIndexer.exe\"\r\n 4: \"SearchUI.exe\"\r\n ? 1: array[5]\r\n 0: \"ShellExperienceHost.exe\"\r\n 1: \"SkypeHost.exe\"\r\n 2: \"System\"\r\n 3: \"UpdaterUI.exe\"\r\n 4: \"VGAuthService.exe\"\r\n ? 2: array[5]\r\n 0: \"WUDFHost.exe\"\r\n 1: \"WmiApSrv.exe\"\r\n 2: \"WmiPrvSE.exe\"\r\n 3: \"WmiPrvSE.exe\"\r\n 4: \"[System Process]\"\r\n...\r\n```\r\n\r\n### Details\r\n\r\nThe flow exercises the nodes below.\r\n\r\n#### Specify host to find\r\n\r\nThis is an `inject` input node which starts the flow. This node injects a new\r\nmessage with a `payload` property which specifies the IP address of host to\r\nfind.\r\n\r\n#### Set search conditions\r\n\r\nThis is a `template` node which formats the IP address supplied on the\r\n`msg.payload` property by the `Specify host to find` node into the\r\n`conditions` property on the output message. The `Search MAR for host` node\r\nuses the `conditions` property when constructing the parameters for MAR\r\nsearch. \r\n\r\nThe JSON-formatted mustache template has the following:\r\n\r\n```json\r\n{\r\n \"or\": [{\r\n \"and\": [{\r\n \"name\": \"HostInfo\",\r\n \"output\": \"ip_address\",\r\n \"op\": \"EQUALS\",\r\n \"value\": \"{{payload}}\"\r\n }]\r\n }]\r\n}\r\n```\r\n\r\nIf the `payload` property on the input message, for example, were set to\r\n`192.168.1.1`, the resulting JavaScript object stored to the `conditions`\r\nproperty on the output message would be:\r\n\r\n```javascript\r\n{\r\n or: [{\r\n and: [{\r\n name: 'HostInfo',\r\n output: 'ip_address',\r\n op: 'EQUALS',\r\n value\": '192.168.1.1'\r\n }]\r\n }]\r\n}\r\n```\r\n\r\n#### Search MAR for host\r\n\r\nThis is a `mar search` node. This node connects to the DXL fabric and sends a\r\nsearch request to the MAR service to collect process information from a\r\nparticular system (as specified by the IP address in the `msg.conditions`\r\nproperty set by the `Set search conditions` node).\r\n\r\nThe JSON-formatted document provided for `Projections` property specifies that\r\n`Processes` for the target host should be returned:\r\n\r\n```json\r\n[\r\n {\r\n \"name\": \"Processes\"\r\n }\r\n]\r\n```\r\n\r\nThe `Limit` property specifies that up to the next \"5\" result items should be\r\nprovided per `page` of search results. This node is revisited repeatedly by the\r\n`More results available?` node until all of the result items available\r\nfor the search have been retrieved.\r\n\r\nThe `Sort by` and `Sort` properties, respectively, specify that the search\r\nresults should be sorted by the \"Processes|name\" field in \"Ascending\" order.\r\n\r\nThe `Return` property is set to \"a parsed JSON object\" to indicate that the\r\n`payload` for the response should be added to the output message as a JavaScript\r\nobject decoded from JSON.\r\n\r\n#### Extract process names\r\n\r\nThis is a `function` node. This node includes a JavaScript code snippet which\r\niterates over the search result items that were set on the `msg.payload`\r\nproperty by the `Search MAR for hosts` node. The source code for the code\r\nsnippet is included below:\r\n\r\n```javascript\r\nif (!msg.processes) {\r\n msg.processes = []\r\n}\r\n\r\nmsg.processes.push(\r\n msg.payload.map(function (processEntry) {\r\n return processEntry.output[\"Processes|name\"]\r\n })\r\n)\r\n\r\nreturn msg\r\n```\r\n\r\nAn array is assigned to the `processes` property in the message. Each element\r\nin the array contains an sub-array with the names of processes returned for\r\nthe previous page. New elements are appended to the array each time this node\r\nis revisited to capture a page of search results.\r\n\r\nFor example, the contents of the `processes` property after the first time this\r\nnode is visited within a flow might contain:\r\n\r\n```javascript\r\n[[\"MARService.exe\",\r\n \"OneDrive.exe\",\r\n \"RuntimeBroker.exe\",\r\n \"SearchIndexer.exe\", \r\n \"SearchUI.exe\"]]\r\n```\r\n\r\nAfter the second time this node is visited for a flow, the `processes` property\r\nmight contain:\r\n\r\n```javascript\r\n[[\"MARService.exe\",\r\n \"OneDrive.exe\",\r\n \"RuntimeBroker.exe\",\r\n \"SearchIndexer.exe\", \r\n \"SearchUI.exe\"],\r\n [\"ShellExperienceHost.exe\",\r\n \"SkypeHost.exe\",\r\n \"System\",\r\n \"UpdaterUI.exe\",\r\n \"VGAuthService.exe\"]]\r\n```\r\n\r\n#### More results available?\r\n\r\nThis is a `switch` node. This node routes the input message to a different\r\nnode based on the value of the `hasMoreItems` property.\r\n\r\nIf the value of `hasMoreItems` is `true`, additional items are available to be\r\nretrieved from the MAR server for the current search. In this case, the input\r\nmessage is routed back to the `Search MAR for host` node. When the\r\n`Search MAR for host` node is revisited, the next page of search results is\r\nobtained from the MAR server and forwarded along to the `Extract process names`\r\nnode.\r\n\r\nIf the value of `hasMoreItems` is `false`, no additional items are available\r\nto be retrieved from the MAR server for the current search. In this case, the\r\ninput message is routed to the `Output process names` node.\r\n\r\n#### Output process names\r\n\r\nThis is a `debug` output node. This node outputs the array of process names\r\nwritten by the `Extract process names` node to the `msg.processes` property\r\nfor each page of search results returned from the MAR server." | |
}, | |
{ | |
"id": "3fbfd464.d3a6cc", | |
"type": "inject", | |
"z": "15c35c35.087ac4", | |
"name": "Specify host to find", | |
"topic": "", | |
"payload": "<specify-host-ip-address>", | |
"payloadType": "str", | |
"repeat": "", | |
"crontab": "", | |
"once": false, | |
"onceDelay": 0.1, | |
"x": 130, | |
"y": 100, | |
"wires": [ | |
[ | |
"32c7d68f.2ed0ca" | |
] | |
] | |
}, | |
{ | |
"id": "53c77ace.c1e504", | |
"type": "switch", | |
"z": "15c35c35.087ac4", | |
"name": "More results available?", | |
"property": "hasMoreItems", | |
"propertyType": "msg", | |
"rules": [ | |
{ | |
"t": "true" | |
}, | |
{ | |
"t": "false" | |
} | |
], | |
"checkall": "true", | |
"repair": false, | |
"outputs": 2, | |
"x": 190, | |
"y": 400, | |
"wires": [ | |
[ | |
"b6e234bf.312e78" | |
], | |
[ | |
"cd7c5168.252d9" | |
] | |
] | |
}, | |
{ | |
"id": "cd7c5168.252d9", | |
"type": "debug", | |
"z": "15c35c35.087ac4", | |
"name": "Debug: Output process names", | |
"active": true, | |
"tosidebar": true, | |
"console": false, | |
"tostatus": false, | |
"complete": "processes", | |
"x": 490, | |
"y": 400, | |
"wires": [] | |
}, | |
{ | |
"id": "2a2240df.31f3b", | |
"type": "function", | |
"z": "15c35c35.087ac4", | |
"name": "Extract process names", | |
"func": "if (!msg.processes) {\n msg.processes = []\n}\n\nmsg.processes.push(\n msg.payload.map(function (processEntry) {\n return processEntry.output[\"Processes|name\"]\n })\n)\n\nreturn msg", | |
"outputs": 1, | |
"noerr": 0, | |
"x": 480, | |
"y": 280, | |
"wires": [ | |
[ | |
"53c77ace.c1e504" | |
] | |
] | |
}, | |
{ | |
"id": "b6e234bf.312e78", | |
"type": "dxl-mar-search", | |
"z": "15c35c35.087ac4", | |
"name": "Search MAR for host", | |
"pollInterval": 5, | |
"client": "42926d46.783374", | |
"projections": "[\n {\n \"name\": \"Processes\"\n }\n]", | |
"limit": "5", | |
"textFilter": "", | |
"sortBy": "Processes|name", | |
"sortDirection": "asc", | |
"returnType": "obj", | |
"x": 440, | |
"y": 180, | |
"wires": [ | |
[ | |
"2a2240df.31f3b" | |
] | |
] | |
}, | |
{ | |
"id": "32c7d68f.2ed0ca", | |
"type": "template", | |
"z": "15c35c35.087ac4", | |
"name": "Set search conditions", | |
"field": "conditions", | |
"fieldType": "msg", | |
"format": "json", | |
"syntax": "mustache", | |
"template": "{\n \"or\": [{\n \"and\": [{\n \"name\": \"HostInfo\",\n \"output\": \"ip_address\",\n \"op\": \"EQUALS\",\n \"value\": \"{{payload}}\"\n }]\n }]\n}", | |
"output": "json", | |
"x": 200, | |
"y": 180, | |
"wires": [ | |
[ | |
"b6e234bf.312e78" | |
] | |
] | |
}, | |
{ | |
"id": "c271164f.62d8b8", | |
"type": "comment", | |
"z": "15c35c35.087ac4", | |
"name": "Supply the IP address of the host to find in the 'Specify host to find' node", | |
"info": "", | |
"x": 270, | |
"y": 40, | |
"wires": [] | |
} | |
] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment