Splunk Phantom

Filtering via custom function return

alexgkirk
Explorer

I'm attempting to use the address_in_network function to compare results of a Splunk query against a custom list, and use matches to remove items from action_results.data of a that query, so that the remainder of the query results are easily accessible in following blocks. I've got the logic of accessing action_results.data, the custom list, and address_in_network all figured out - but I'm having a hard time figuring out exactly how to either remove items directly from action_results.data, or return my list of IP addresses in a type that a filter block can make use of, so that later blocks could just access filtered-data directly.

My variable created for output, Build_IP_Whitelist__tofilter, is assigned a type of None in the code framework that I can't edit. I went ahead and cast it to a list and used append to build out that list, which returns without error from my custom function. The problem arises when I try to use that list for comparison in a following filter block:

 

Wed Sep 23 2020 11:59:11 GMT-0400 (Eastern Daylight Time): phantom.condition(): condition 1 to evaluate: LHS: Build_IP_Whitelist:custom_function:tofilter OPERATOR: != RHS: Execute_External_IP_Query:action_result.data.*.dest_ip
Wed Sep 23 2020 11:59:11 GMT-0400 (Eastern Daylight Time): phantom.condition(): ERROR: LHS of this condition statement is a list data type while RHS is not. For this expression and data types, '!=' is not a supported data operator. Use 'in' or 'not in' operators
 
There's got to be a better data structure to fit my list of whitelist IPs into, but I'm having a hard time finding it in the documentation. Any pointers on that specifically, or a better approach to the general question?
Labels (2)
0 Karma
1 Solution

phanTom
SplunkTrust
SplunkTrust

@alexgkirk  filters and decision blocks are CIDR aware (probably use the same API call).

So if I read right, you should be able to have the outputted field containing the IP from the splunk search in the top of 1st condition, then 'is in' as the operator, then the CIDR range of the network you're trying to see if the IP is in. You can also add as many network ranges as needed in the same condition by using the 'OR' option!

This way requires 0 custom code and the filtered data can be pulled into any downstream block. 

Hope that helped?

View solution in original post

phanTom
SplunkTrust
SplunkTrust

@alexgkirk  filters and decision blocks are CIDR aware (probably use the same API call).

So if I read right, you should be able to have the outputted field containing the IP from the splunk search in the top of 1st condition, then 'is in' as the operator, then the CIDR range of the network you're trying to see if the IP is in. You can also add as many network ranges as needed in the same condition by using the 'OR' option!

This way requires 0 custom code and the filtered data can be pulled into any downstream block. 

Hope that helped?

View solution in original post

alexgkirk
Explorer

I was not aware of this - it simplifies things tremendously, and works flawlessly over here as you've described. You even responded faster than I could finish lunch, bravo good sir.

phanTom
SplunkTrust
SplunkTrust

Below is something I just tested on 4.9 to confirm. I setup a container with 5 ip's, 3 within the range i put in the container (192.16.0.0/16):

Wed Sep 23 2020 17:18:42 GMT+0100 (British Summer Time): filter_1() called
Wed Sep 23 2020 17:18:42 GMT+0100 (British Summer Time): phantom.condition(): called with 1 condition(s) '[['artifact:*.cef.sourceAddress', 'in', '192.168.0.0/16']]', operator : 'or', scope: 'all'
Wed Sep 23 2020 17:18:42 GMT+0100 (British Summer Time): phantom.condition(): condition 1 to evaluate: LHS: artifact:*.cef.sourceAddress OPERATOR: in RHS: 192.168.0.0/16
Wed Sep 23 2020 17:18:42 GMT+0100 (British Summer Time): phantom.collect(): called with datapath: ['artifact:*.cef.sourceAddress', 'artifact:*.id'], limit = 2000, scope=all, filter_artifact_ids=[] and none_if_first=False with trace:False
Wed Sep 23 2020 17:18:42 GMT+0100 (British Summer Time): phantom.collect(): called with datapath as LIST of paths, scope='all' and limit=2000. Found 5 TOTAL artifacts
Wed Sep 23 2020 17:18:42 GMT+0100 (British Summer Time): phantom.condition(): condition loop: condition 1, '192.168.0.1' 'in' '192.168.0.0/16' => result:True
Wed Sep 23 2020 17:18:42 GMT+0100 (British Summer Time): phantom.condition(): condition loop: condition 1, '192.168.10.1' 'in' '192.168.0.0/16' => result:True
Wed Sep 23 2020 17:18:42 GMT+0100 (British Summer Time): phantom.condition(): condition loop: condition 1, '192.168.0.11' 'in' '192.168.0.0/16' => result:True
Wed Sep 23 2020 17:18:42 GMT+0100 (British Summer Time): phantom.condition(): condition loop: condition 1, '8.8.8.8' 'in' '192.168.0.0/16' => result:False
Wed Sep 23 2020 17:18:42 GMT+0100 (British Summer Time): phantom.condition(): condition loop: condition 1, '9.9.9.9' 'in' '192.168.0.0/16' => result:False
Wed Sep 23 2020 17:18:42 GMT+0100 (British Summer Time): phantom.condition(): returned 3 filtered artifacts AND 0 filtered action results
Wed Sep 23 2020 17:18:42 GMT+0100 (British Summer Time): save_run_data() saving 110 bytes with key filtered-data:filter_1:condition_1
Take the 2021 Splunk Career Survey

Help us learn about how Splunk has
impacted your career by taking the 2021 Splunk Career Survey.

Earn $50 in Amazon cash!