Skip to content

Commit

Permalink
Issue 102 (#104)
Browse files Browse the repository at this point in the history
* Fix broken panels, format SPL

* Fix labels, add fields to REST calls, format SPL

* Add .DS_Store

* Fix broken panels, format SPL, include missing risk fields

* Remove restrictive RR - * filters, fix issues, format SPL

* Add support for any asset name from A&I, Format SPL

* Add threat object to count, format SPL

* Add threat object to count, format SPL
  • Loading branch information
ccl0utier authored Oct 16, 2023
1 parent 977291d commit 33e90fc
Show file tree
Hide file tree
Showing 7 changed files with 320 additions and 222 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
PipFile**
.DS_Store
58 changes: 38 additions & 20 deletions dashboards/attack_matrix_risk.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
<!-- Initial dashboard created by the wonderful Jim Apger -->
<form script="mitre_matrix.js" stylesheet="mitre_matrix.css" theme="light" version="1.1">
<!-- Initial dashboard created by the wonderful Jim Apger --><form script="mitre_matrix.js" stylesheet="mitre_matrix.css" theme="light" version="1.1">
<label>ATT&amp;CK Matrix Risk (Business View)</label>
<description>This dashboard portraoys risk in your environment through the lens of RBA and the MITRE ATT&amp;CK framework</description>
<search id="mitre_base_1">
Expand All @@ -24,10 +23,12 @@
<single>
<title>Reduction in notables by using the Attribution based approach</title>
<search>
<query>index=notable|eval notable=if(eventtype="risk_notables","Risk Notable","Notable")|stats count by notable
|transpose 0 header_field=notable
|eval p=round(100-('Risk Notable'/Notable)*100,1)
|table p</query>
<query>index=notable
| eval notable=if(eventtype="risk_notables","Risk Notable","Notable")
| stats count by notable
| transpose 0 header_field=notable
| eval p=round(100-('Risk Notable'/Notable)*100,1)
| table p</query>
<earliest>$field1.earliest$</earliest>
<latest>$field1.latest$</latest>
</search>
Expand All @@ -45,8 +46,9 @@
<chart>
<title>Traditional Notables versus Risk Notables</title>
<search>
<query>index=notable|eval notable=if(eventtype="risk_notables","Risk Notable","Notable")
|timechart span=1h count by notable</query>
<query>index=notable
| eval notable=if(eventtype="risk_notables","Risk Notable","Notable")
| timechart span=1h count by notable</query>
<earliest>$field1.earliest$</earliest>
<latest>$field1.latest$</latest>
</search>
Expand Down Expand Up @@ -83,7 +85,7 @@
<single>
<search>
<query>`notable`
| search search_name="Threat - ATT&amp;CK*"
| search eventtype="risk_notables"
| stats count</query>
<earliest>$field1.earliest$</earliest>
<latest>$field1.latest$</latest>
Expand All @@ -100,19 +102,35 @@
</row>
<row>
<panel>
<input type="dropdown" token="tokDetectionStatus" searchWhenChanged="true">
<label>Detection Status</label>
<choice value="disabled=*">ALL</choice>
<choice value="disabled=0">Enabled</choice>
<choice value="disabled=1">Disabled</choice>
<default>disabled=0</default>
<initialValue>disabled=0</initialValue>
</input>
<table>
<title>Techniques Covered in Our Environment</title>
<search>
<query>|inputlookup mitre_attack_lookup
| stats dc(mitre_technique_id) as total_techniques by mitre_tactic
|append [| rest splunk_server=local count=0 /services/saved/searches|search action.correlationsearch.label="RR - *"|table action.correlationsearch.annotations|spath input=action.correlationsearch.annotations|rename mitre_attack{} as mitre_technique_id|mvexpand mitre_technique_id|lookup mitre_attack_lookup mitre_technique_id OUTPUT mitre_tactic|stats dc(mitre_technique_id) as num_covered_techniques by mitre_tactic]|stats values(total_techniques) as total_techniques, values(num_covered_techniques) as num_covered_techniques by mitre_tactic
| fillnull value="0" num_covered_techniques
| eval combo = num_covered_techniques." of ".total_techniques
|eval perc=round((num_covered_techniques/total_techniques)*100,1)
|eval perc="(".perc."%)"
|table mitre_tactic, combo,perc
| transpose 0 header_field=mitre_tactic
|fields - column</query>
<query>| inputlookup mitre_attack_lookup
| stats dc(mitre_technique_id) as total_techniques by mitre_tactic
| append
[| rest splunk_server=local count=0 /services/saved/searches f=actions f=action.correlationsearch.enabled f=action.correlationsearch.annotations f=disabled
| where isnotnull('action.correlationsearch.enabled') AND match(actions, "risk") AND $tokDetectionStatus$
| spath input=action.correlationsearch.annotations
| rename mitre_attack{} as mitre_technique_id
| mvexpand mitre_technique_id
| lookup mitre_attack_lookup mitre_technique_id OUTPUT mitre_tactic
| stats dc(mitre_technique_id) as num_covered_techniques by mitre_tactic]
| stats values(total_techniques) as total_techniques, values(num_covered_techniques) as num_covered_techniques by mitre_tactic
| fillnull value="0" num_covered_techniques
| eval combo = num_covered_techniques." of ".total_techniques
| eval perc=round((num_covered_techniques/total_techniques)*100,1)
| eval perc="(".perc."%)"
| table mitre_tactic, combo,perc
| transpose 0 header_field=mitre_tactic
| fields - column</query>
<earliest>$field1.earliest$</earliest>
<latest>$field1.latest$</latest>
</search>
Expand Down Expand Up @@ -347,4 +365,4 @@
</table>
</panel>
</row>
</form>
</form>
14 changes: 9 additions & 5 deletions dashboards/audit_attribution_analytics.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
<!-- Initial dashboard created by the wonderful Jim Apger -->
<form version="1.1">
<!-- Initial dashboard created by the wonderful Jim Apger --><form version="1.1">
<label>Audit: Attribution Analytics (Tuning View)</label>
<description>Helpful for tuning new detections</description>
<fieldset submitButton="false" autoRun="true">
Expand Down Expand Up @@ -158,9 +157,11 @@
<earliest>$time_picker.earliest$</earliest>
<latest>$time_picker.latest$</latest>
</search>
<option name="charting.axisLabelsX.majorLabelStyle.rotation">-45</option>
<option name="charting.chart">column</option>
<option name="charting.chart.overlayFields">"Risk Threshold"</option>
<option name="charting.drilldown">none</option>
<option name="height">444</option>
</chart>
</panel>
<panel>
Expand All @@ -172,9 +173,11 @@
<earliest>$time_picker.earliest$</earliest>
<latest>$time_picker.latest$</latest>
</search>
<option name="charting.axisLabelsX.majorLabelStyle.rotation">-45</option>
<option name="charting.chart">column</option>
<option name="charting.chart.overlayFields">"Risk Threshold"</option>
<option name="charting.drilldown">none</option>
<option name="height">445</option>
<option name="refresh.display">progressbar</option>
</chart>
</panel>
Expand All @@ -186,9 +189,11 @@
<earliest>$time_picker.earliest$</earliest>
<latest>$time_picker.latest$</latest>
</search>
<option name="charting.axisLabelsX.majorLabelStyle.rotation">-45</option>
<option name="charting.chart">column</option>
<option name="charting.chart.overlayFields">"Risk Threshold"</option>
<option name="charting.drilldown">none</option>
<option name="height">444</option>
<option name="refresh.display">progressbar</option>
</chart>
</panel>
Expand All @@ -202,8 +207,7 @@
| extract pairdelim=",", kvdelim="=", auto=f
| stats avg(result_count) as avg_results max(result_count) as max_results sparkline avg(run_time) as avg_runtime max(run_time) as max_runtime count AS execution_count by savedsearch_name, app
| join savedsearch_name type=outer
[| rest splunk_server=local /servicesNS/-/-/saved/searches
| fields title description eai:acl.app eai:acl.sharing eai:acl.owner cron_schedule dispatch.earliest_time dispatch.latest_time, disabled actions
[| rest splunk_server=local /servicesNS/-/-/saved/searches f=title f=description f=eai* f=cron_schedule f=dispatch.earliest_time f=dispatch.latest_time f=disabled f=actions
| rename title AS savedsearch_name eai:acl.app AS App eai:acl.owner AS Owner cron_schedule AS "Cron Schedule" dispatch.earliest_time AS "Dispatch Earliest Time" dispatch.latest_time AS "Dispatch Latest Time" actions AS "Adaptive Response Actions", eai:acl.sharing AS Sharing]

|eval comment="This is just to make the demo work below since we do not have execution results in _internal"
Expand Down Expand Up @@ -231,4 +235,4 @@
</table>
</panel>
</row>
</form>
</form>
105 changes: 52 additions & 53 deletions dashboards/rba_data_source_overview.xml
Original file line number Diff line number Diff line change
@@ -1,35 +1,35 @@
<form theme="dark" version="1.1">
<label>RBA Data Source Review</label>
<search id="basesearch">
<query>| rest splunk_server=local count=0 /servicesNS/-/SplunkEnterpriseSecuritySuite/saved/searches
| where match('action.correlationsearch.enabled', "1|[Tt]|[Tt][Rr][Uu][Ee]")
| where disabled=0
| eval actions=split(actions, ",")
| rename action.risk.param._risk as risk_param action.risk.param._risk_object_type as risk_object_type0 action.risk.param._risk_object as risk_object0 action.risk.param._risk_score as risk_score0
<query>| rest splunk_server=local count=0 /servicesNS/-/SplunkEnterpriseSecuritySuite/saved/searches f=disabled f=title f=search f=actions f=action.correlationsearch.enabled f=action.correlationsearch.annotations f=action.risk.param._risk f=action.risk.param._risk_object
| where match('action.correlationsearch.enabled', "1|[Tt]|[Tt][Rr][Uu][Ee]") AND match('actions',"risk") AND disabled=0
| rex field=search "index=(?&lt;index&gt;.+?)\s"
| rex field=search "sourcetype=(?&lt;sourcetype&gt;.+?)\s"
| rex field=search "datamodel:?\W?(?&lt;datamodel&gt;\w+)"
| rex field=search "mitre_tactic=(?&lt;mitre_tactic&gt;.+)"
| rex field=search "mitre_technique=(?&lt;mitre_technique&gt;.+)"
| eval index=replace(index,"\"","")
| eval data_source=coalesce(index, datamodel)
| spath input=action.correlationsearch.annotations
| spath input=action.risk.param._risk
| rename mitre_attack{} as mitre_technique, {}.risk_object_field as risk_object_field
| eval risk_object = coalesce(risk_object_field, 'action.risk.param._risk_object')
| fields - risk_object_field, action.risk.param._risk_object
| lookup mitre_attack_lookup mitre_technique_id as mitre_technique OUTPUT mitre_tactic_id as mitre_tactic
</query>
<earliest>-1h</earliest>
<latest>now</latest>
<sampleRatio>1</sampleRatio>
</search>
<fieldset submitButton="false"></fieldset>
<fieldset submitButton="false" autoRun="true"></fieldset>
<row>
<panel>
<title>Risk Rules</title>
<single>
<title>Detections that populate the Risk index</title>
<search base="basesearch">
<query>| stats dc(title) as Risk_Detections</query>
<query>| stats dc(title) as Risk_Detections</query>
</search>
<option name="colorBy">value</option>
<option name="colorMode">none</option>
<option name="drilldown">none</option>
<option name="height">230</option>
<option name="numberPrecision">0</option>
<option name="rangeColors">["0x53a051", "0x0877a6", "0xf8be34", "0xf1813f", "0xdc4e41"]</option>
<option name="rangeValues">[0,30,70,100]</option>
Expand Down Expand Up @@ -94,7 +94,9 @@
<title>Technique Overview</title>
<chart>
<search base="basesearch">
<query>| stats count by mitre_technique</query>
<query>| lookup mitre_attack_lookup mitre_technique_id as mitre_technique OUTPUT mitre_technique as mitre_technique_label
| eval mitre_technique = mitre_technique + " - " + mitre_technique_label
| stats count by mitre_technique</query>
</search>
<option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
<option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
Expand Down Expand Up @@ -135,7 +137,9 @@
<title>Tactic Overview</title>
<chart>
<search base="basesearch">
<query>| stats count by mitre_tactic</query>
<query>| lookup mitre_attack_lookup mitre_tactic_id as mitre_tactic OUTPUT mitre_tactic_label
| eval mitre_tactic = mitre_tactic + " - " + mitre_tactic_label
| stats count by mitre_tactic</query>
</search>
<option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
<option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
Expand Down Expand Up @@ -175,10 +179,16 @@
</row>
<row>
<panel>
<title>Risk Rules by Data Source</title>
<title>Risk Rules by Data Model</title>
<table>
<search base="basesearch">
<query>| stats values(title) as Risk_Rule, values(mitre_tactic) as mitre_tactic values(mitre_technique) as mitre_technique by data_source</query>
<query>| rex field=search "index=(?&lt;index&gt;.+?)\s"
| rex field=search "datamodel:?\W?(?&lt;datamodel&gt;\w+)"
| eval data_source=coalesce(index, datamodel)
| spath input=action.correlationsearch.annotations
| rename mitre_attack{} as mitre_technique
| lookup mitre_attack_lookup mitre_technique_id as mitre_technique OUTPUT mitre_tactic_id as mitre_tactic
| stats values(title) as Risk_Rule, values(mitre_tactic) as mitre_tactic values(mitre_technique) as mitre_technique by data_source</query>
</search>
<option name="count">10</option>
<option name="dataOverlayMode">none</option>
Expand All @@ -191,26 +201,22 @@
</table>
</panel>
<panel>
<title>Risk Data Source Event Overview</title>
<title>Risk Data Source Event Overview - Last 60 minutes</title>
<table>
<search base="basesearch">
<query>
| eval source=title

| join type=left source
[search index=risk source=*
| stats count as total_events earliest(_time) as first_seen last(_time) as last_seen by source ]

| table title mitre_technique mitre_tactic first_seen last_seen total_events

| fieldformat first_seen=strftime(first_seen, "%c")
| fieldformat last_seen=strftime(last_seen, "%c")
<query>| eval source=title
| join type=left source
[| tstats count as total_events min(_time) as first_seen max(_time) as last_seen WHERE index=risk by source ]
| table title mitre_technique mitre_tactic first_seen last_seen total_events
| fieldformat first_seen=strftime(first_seen, "%c")
| fieldformat last_seen=strftime(last_seen, "%c")
| fillnull total_events value="No Events Found"</query>
</search>
<option name="count">10</option>
<option name="count">15</option>
<option name="dataOverlayMode">none</option>
<option name="drilldown">none</option>
<option name="percentagesRow">false</option>
<option name="refresh.display">progressbar</option>
<option name="rowNumbers">false</option>
<option name="totalsRow">false</option>
<option name="wrap">true</option>
Expand All @@ -235,9 +241,8 @@
<fieldForValue>data_source</fieldForValue>
<search base="basesearch">
<query>
| table data_source
| dedup data_source
| sort data_source</query>
| stats count by data_source
| fields - count</query>
</search>
</input>
<input type="dropdown" token="mitre_tactic_token" searchWhenChanged="true">
Expand All @@ -249,9 +254,8 @@
<fieldForValue>mitre_tactic</fieldForValue>
<search base="basesearch">
<query>
| table mitre_tactic
| dedup mitre_tactic
| sort mitre_tactic</query>
| stats count by mitre_tactic
| fields - count</query>
</search>
</input>
<input type="dropdown" token="mitre_technique_token" searchWhenChanged="true">
Expand All @@ -263,9 +267,8 @@
<fieldForValue>mitre_technique</fieldForValue>
<search base="basesearch">
<query>
| table mitre_technique
| dedup mitre_technique
| sort mitre_technique</query>
| stats count by mitre_technique
| fields - count</query>
</search>
</input>
<input type="dropdown" token="risk_object" searchWhenChanged="true">
Expand All @@ -277,32 +280,28 @@
<fieldForValue>risk_object</fieldForValue>
<search base="basesearch">
<query>
| rex field=risk_param max_match=0 "\"risk_object_field\":\"(?&lt;risk_object&gt;\w+)"
| rex field=risk_param max_match=0 "\"risk_object_type\":\"(?&lt;risk_object_type&gt;\w+)"
| rex field=risk_param max_match=0 "\"risk_score\":(?&lt;risk_score&gt;\d+)"

|table risk_object
|dedup risk_object
|sort risk_object</query>
| rex field=risk_param max_match=0 "\"risk_object_field\":\"(?&lt;risk_object&gt;\w+)"
| rex field=risk_param max_match=0 "\"risk_object_type\":\"(?&lt;risk_object_type&gt;\w+)"
| rex field=risk_param max_match=0 "\"risk_score\":(?&lt;risk_score&gt;\d+)"
| table risk_object
| dedup risk_object
| sort risk_object</query>
</search>
</input>
<table>
<search base="basesearch">
<query>
| rename action.risk.param._risk as risk_param action.risk.param._risk_object_type as risk_object_type0 action.risk.param._risk_object as risk_object0 action.risk.param._risk_score as risk_score0
| rex field=risk_param max_match=0 "\"risk_object_field\":\"(?&lt;risk_object&gt;\w+)"
| rex field=risk_param max_match=0 "\"risk_object_type\":\"(?&lt;risk_object_type&gt;\w+)"
| rex field=risk_param max_match=0 "\"risk_score\":(?&lt;risk_score&gt;\d+)"

| rename action.risk.param._risk as risk_param action.risk.param._risk_object_type as risk_object_type0 action.risk.param._risk_object as risk_object0 action.risk.param._risk_score as risk_score0
| rex field=risk_param max_match=0 "\"risk_object_field\":\"(?&lt;risk_object&gt;\w+)"
| rex field=risk_param max_match=0 "\"risk_object_type\":\"(?&lt;risk_object_type&gt;\w+)"
| rex field=risk_param max_match=0 "\"risk_score\":(?&lt;risk_score&gt;\d+)"
| search actions=risk
| eval risk_object=coalesce(risk_object, risk_object0)
| eval risk_object_type=coalesce(risk_object_type, risk_object_type0)
| eval risk_score=coalesce(risk_score, risk_score0)
| eval data_source=coalesce(index, datamodel)

| table title actions risk_param risk_object risk_object_type risk_score search index sourcetype datamodel mitre_technique mitre_tactic data_source
|fillnull value="nothing listed"

| fillnull value="nothing listed"
| search data_source=$data_token$ AND mitre_tactic=$mitre_tactic_token$ AND mitre_technique=$mitre_technique_token$ AND risk_object=$risk_object$</query>
</search>
<option name="count">5</option>
Expand Down Expand Up @@ -338,4 +337,4 @@
</table>
</panel>
</row>
</form>
</form>
Loading

0 comments on commit 33e90fc

Please sign in to comment.