You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
646 lines
33 KiB
646 lines
33 KiB
[Generate MITRE Enterprise List]
|
|
alert.track = 0
|
|
display.general.type = statistics
|
|
display.page.search.tab = statistics
|
|
description = This search formats the MITRE ATT&CK framework table into a list format.
|
|
dispatch.earliest_time = -24h@h
|
|
dispatch.latest_time = now
|
|
search = | mitremap output="list"
|
|
|
|
[Saved Searches and the Data that Enables Them]
|
|
dispatch.earliest_time = -24h@h
|
|
dispatch.latest_time = now
|
|
display.general.timeRangePicker.show = 0
|
|
display.general.type = statistics
|
|
display.page.search.tab = statistics
|
|
display.visualizations.show = 0
|
|
description = This expects that you have completed the Data Inventory configuration, and mapped your active content on the Manage Bookmarks page. You will then be get a list oriented to the saved searches, showing each saved search and the data set and products that enable it
|
|
request.ui_dispatch_app = Splunk_Security_Essentials
|
|
request.ui_dispatch_view = search
|
|
search = | inputlookup data_inventory_products_lookup \
|
|
| search stage!=step-sourcetype stage!=step-cim \
|
|
| rex field=basesearch "^\s*(?<basesearch>.*?)\s*$" \
|
|
| eval basesearch=if(like(basesearch, "(%") AND like(basesearch, "%)"), basesearch, "(" . basesearch . ")") \
|
|
| makemv delim="|" eventtypeId \
|
|
| mvexpand eventtypeId \
|
|
| rename eventtypeId as data_source_categories \
|
|
| join data_source_categories \
|
|
[| sseanalytics \
|
|
| search search_title!="" \
|
|
| stats count count(eval(bookmark_status="successfullyImplemented")) as count_successfullyImplemented values(search_title) as search_title by bookmark_status data_source_categories \
|
|
| eval search_title=mvjoin(search_title, "|")] \
|
|
| eval Product = vendorName . " " . productName \
|
|
| makemv search_title delim="|" \
|
|
| mvexpand search_title\
|
|
| stats values(basesearch) as basesearch values(Product) as Product by search_title\
|
|
| eval basesearch = "(" . mvjoin(basesearch, " OR ") . ")", "Products That Provide Visibility"=mvjoin(mvfilter(Product!=" "), ", ")\
|
|
| rename basesearch as "Dataset That Provides Visibility" search_title as "Saved Search Name"\
|
|
| table "Saved Search Name" "Dataset That Provides Visibility" "Products That Provide Visibility"
|
|
|
|
|
|
[Products and the Content Mapped to Them]
|
|
dispatch.earliest_time = -24h@h
|
|
dispatch.latest_time = now
|
|
display.general.timeRangePicker.show = 0
|
|
display.general.type = statistics
|
|
display.page.search.tab = statistics
|
|
display.visualizations.show = 0
|
|
description = This expects that you have completed the Data Inventory configuration, and mapped your active content on the Manage Bookmarks page. You will then get a complete view from product to the content that it enables.
|
|
request.ui_dispatch_app = Splunk_Security_Essentials
|
|
request.ui_dispatch_view = search
|
|
search = | inputlookup data_inventory_products_lookup \
|
|
| search stage!=step-sourcetype stage!=step-cim \
|
|
| rex field=basesearch "^\s*(?<basesearch>.*?)\s*$"\
|
|
| eval basesearch=if(like(basesearch, "(%") AND like(basesearch, "%)"), basesearch, "(" . basesearch . ")") \
|
|
| makemv delim="|" eventtypeId \
|
|
| mvexpand eventtypeId \
|
|
| rename eventtypeId as data_source_categories \
|
|
| join data_source_categories \
|
|
[| sseanalytics \
|
|
| search search_title!="" \
|
|
| stats count count(eval(bookmark_status="successfullyImplemented")) as count_successfullyImplemented values(search_title) as search_title by data_source_categories \
|
|
| eval search_title=mvjoin(search_title, "|")] \
|
|
| eval Product = vendorName . " " . productName\
|
|
| makemv delim="|" data_source_categories | mvexpand data_source_categories\
|
|
| rex field=data_source_categories "^(?<ds>[^-]*)" | sseidenrichment type=datasourceid field=ds | sseidenrichment type=dscid field=data_source_categories | eval data_source_categories = data_source . " > " . data_source_category| stats values(*) as * by Product | search Product!=" " \
|
|
| table Product basesearch data_source_categories metadata_json search_title count \
|
|
| spath input=metadata_json | fields - metadata_json\
|
|
| table Product basesearch data_source_categories search_title * count \
|
|
| rename count as "Total Mapped Content for This Product" basesearch as "Dataset That Provides Visibility" search_title as "Saved Search Name" data_source_categories as "Data Source Category" description as Description
|
|
|
|
|
|
[Generate Data Availability ML Model for Latency]
|
|
disabled = 1
|
|
action.email.useNSSubject = 1
|
|
alert.track = 0
|
|
dispatch.earliest_time = -24h@h
|
|
dispatch.latest_time = now
|
|
display.general.type = statistics
|
|
display.page.search.tab = statistics
|
|
display.visualizations.show = 0
|
|
request.ui_dispatch_app = Splunk_Security_Essentials
|
|
request.ui_dispatch_view = search
|
|
search = | tstats count values(source) as source avg(_indextime) as indextime where \
|
|
[| inputlookup data_inventory_products_lookup \
|
|
| eval category=case(isnotnull(daily_event_volume) AND daily_event_volume > 50000, "highvolumelowlatency", stage!="step-sourcetype", "normal", 1=1,"unused") \
|
|
| lookup SSE-data-availability-products-categorization productId OUTPUT category as category_override \
|
|
| eval category=coalesce(category_override, category) \
|
|
| search category="highvolumelowlatency" OR category="normal" \
|
|
| eval termsearch = if(len(termsearch)>0,"(" . termsearch . ")",null()) \
|
|
| stats values(termsearch) as search \
|
|
| eval search="(" . mvjoin(search, " OR ") . ")" ] earliest=-30d by index sourcetype _time span=5m \
|
|
| eval reduce_factor_to_limit_memory_explosion = 10\
|
|
| where random()%reduce_factor_to_limit_memory_explosion = 1 \
|
|
| eval lag = indextime - _time - 180 \
|
|
| stats values(lag) as lag values(source) as source by index sourcetype _time \
|
|
| where lag > 0 \
|
|
| eval productId=null, \
|
|
[| inputlookup data_inventory_products_lookup \
|
|
| eval category=case(isnotnull(daily_event_volume) AND daily_event_volume > 50000, "highvolumelowlatency", stage!="step-sourcetype", "normal", 1=1,"unused") \
|
|
| lookup SSE-data-availability-products-categorization productId OUTPUT category as category_override \
|
|
| eval category=coalesce(category_override, category) \
|
|
| search category="highvolumelowlatency" OR category="normal" \
|
|
| eval termsearch = if(len(termsearch)>0,"(" . termsearch . ")",null()) \
|
|
| rex field=termsearch mode=sed "s/\"/\\\"/g" \
|
|
| eval search = "productId=if(searchmatch(\"" . termsearch . "\"), mvappend(productId, \"" . productId . "\"), productId)" \
|
|
| stats values(search) as search \
|
|
| eval search=mvjoin(search, ", ")]\
|
|
| mvexpand productId\
|
|
| fit DensityFunction lag by productId upper_threshold=0.01 dist=norm into app:sse_event_lag_model\
|
|
| stats count as baseline_num_data_samples avg(lag) as baseline_avg_lag min(_time) as baseline_earliest max(_time) as baseline_latest by productId | eval baseline_update_last_run = now(), baseline_lag_at_last_update = now() - baseline_latest | outputlookup SSE-data_availability_latency_status.csv
|
|
|
|
[Generate Datamodels Lookup]
|
|
action.email.useNSSubject = 1
|
|
action.keyindicator.invert = 0
|
|
action.makestreams.param.verbose = 0
|
|
action.nbtstat.param.verbose = 0
|
|
action.notable.param.verbose = 0
|
|
action.nslookup.param.verbose = 0
|
|
action.ping.param.verbose = 0
|
|
action.risk.forceCsvResults = 1
|
|
action.risk.param.verbose = 0
|
|
action.send2uba.param.verbose = 0
|
|
action.threat_add.param.verbose = 0
|
|
alert.track = 0
|
|
search = | datamodel \
|
|
| spath input=_raw output=modelName path=modelName \
|
|
| spath input=_raw output=objectName path=objects{}.objectName \
|
|
| spath input=_raw output=parentName path=objects{}.parentName \
|
|
| spath input=_raw output=tags path=objects{}.comment \
|
|
| fields modelName objectName parentName tags \
|
|
| eval objectName=mvappend(objectName,"ROOT - "+modelName) \
|
|
| eval tags=mvappend(tags,mvindex(tags,0)) \
|
|
| eval nodeNameMerge=mvzip(objectName,tags) \
|
|
| mvexpand nodeNameMerge \
|
|
| eval nodeName=mvindex(split(nodeNameMerge,","),0) \
|
|
| eval tags=mvindex(split(nodeNameMerge,",{\"tags\":"),1) \
|
|
| eval tags=replace(tags,"[\[\]\"\}]","") \
|
|
| eval datamodel=if(like(nodeName,"ROOT%"),modelName,modelName.".".nodeName) \
|
|
| eval nodeName=if(like(nodeName,"ROOT%"),null(),nodeName) \
|
|
| table datamodel modelName nodeName tags \
|
|
| join modelName \
|
|
[| rest splunk_server=local count=0 /servicesNS/-/-/admin/datamodel-files \
|
|
| rename title AS modelName,eai:acl.app AS app \
|
|
| table modelName, app \
|
|
| search NOT app IN(SplunkAppForWebAnalytics, search) \
|
|
| join app \
|
|
[| rest /services/apps/local \
|
|
| table title version \
|
|
| rename title as app\
|
|
]\
|
|
] \
|
|
| join datamodel type=outer \
|
|
[| ssedata config="data_inventory" \
|
|
| fields data_source data_source_category data_source_category_tags data_source_category_datamodel \
|
|
| eval data_source_category_datamodel=split(data_source_category_datamodel,"|") \
|
|
| stats values(data_source_category) AS data_source_category BY data_source_category_datamodel \
|
|
| rename data_source_category_datamodel AS datamodel \
|
|
| eval data_source_category=mvjoin(data_source_category,"|")\
|
|
]\
|
|
| outputlookup datamodels
|
|
|
|
[Generate STRT Macros to Data Source Categories Lookup]
|
|
search = | generatestrt | outputlookup createinapp=t SSE-STRT-macros-to-data_source_categories
|
|
|
|
[Generate STRT Macros to Data Source Categories Lookup - Backup]
|
|
search = | inputlookup sse_json_doc_storage_lookup \
|
|
| eval len=len(json), key=_key \
|
|
| search key="*macros*" \
|
|
| table key description version len json \
|
|
| spath input=json path="macros{}" output="macros" \
|
|
| fields macros \
|
|
| mvexpand macros \
|
|
| spath input=macros \
|
|
| table name definition \
|
|
| rename name AS macro\
|
|
\
|
|
| search definition=*source* OR definition=*eventtype*\
|
|
| rex field=definition max_match=0 "sourcetype=(\"|)(?<sourcetype>[^\"\s]*)(|\")" \
|
|
| rex field=definition max_match=0 "source=(\"|)(?<source>[^\"\s]*)(|\")" \
|
|
| eval sourcetype=case(\
|
|
like(definition,"%eventtype%") AND like(definition,"%cisco_ios%"),"eventtype=cisco_ios",\
|
|
like(definition,"%eventtype%") AND like(definition,"%osquery-process%"),"osquery:results",\
|
|
like(definition,"%eventtype%") AND like(definition,"%okta_log%"),"Okta",\
|
|
1=1,sourcetype\
|
|
)\
|
|
| eval source=case(\
|
|
like(definition,"%eventtype%") AND like(definition,"%wineventlog_security%"),"WinEventLog:Security",\
|
|
like(definition,"%eventtype%") AND like(definition,"%wineventlog_system%"),"WinEventLog:System",\
|
|
1=1,source\
|
|
)\
|
|
| rex field="sourcetype" max_match=0 \
|
|
[| inputlookup SSE-default-data-inventory-products.csv \
|
|
| eval eventtypeId=split(eventtypeId,"|") \
|
|
| mvexpand eventtypeId \
|
|
| search regex_pattern=* \
|
|
| search NOT productId IN (MSSQL*, SQL*,MySQL*, Oracle*, ESXi* , VMWare*, Linux*, FireEye*, Fortinet*, Cylance*, Check*, Juniper*)\
|
|
| sort 0 eventtypeId \
|
|
| streamstats count \
|
|
| eval row_id="row_"+count \
|
|
| fields row_id regex_pattern \
|
|
| eval rexValue="(?<P_"+row_id+">"+regex_pattern+")" \
|
|
| head 300 \
|
|
| stats values(rexValue) AS regexMerge \
|
|
| eval regexMerge=mvjoin(regexMerge,"|") \
|
|
| eval search="\"(".regexMerge.")\"" \
|
|
| fields search \
|
|
]\
|
|
| rex field="sourcetype" max_match=0 \
|
|
[| inputlookup SSE-default-data-inventory-products.csv \
|
|
| eval eventtypeId=split(eventtypeId,"|") \
|
|
| mvexpand eventtypeId \
|
|
| search regex_pattern=* \
|
|
| search NOT productId IN (MSSQL*, SQL*,MySQL*, Oracle*, ESXi* , VMWare*, Linux*, FireEye*, Fortinet*, Cylance*, Check*, Juniper*)\
|
|
| sort 0 eventtypeId \
|
|
| streamstats count \
|
|
| eval row_id="row_"+count \
|
|
| fields row_id regex_pattern \
|
|
| eval rexValue="(?<P_"+row_id+">"+regex_pattern+")" \
|
|
| tail 300 \
|
|
| stats values(rexValue) AS regexMerge \
|
|
| eval regexMerge=mvjoin(regexMerge,"|") \
|
|
| eval search="\"(".regexMerge.")\"" \
|
|
| fields search \
|
|
]\
|
|
| rex field="source" max_match=0 \
|
|
[| inputlookup SSE-default-data-inventory-products.csv \
|
|
| eval eventtypeId=split(eventtypeId,"|") \
|
|
| mvexpand eventtypeId \
|
|
| search regex_pattern=* \
|
|
| search NOT productId IN (MSSQL*, SQL*,MySQL*, Oracle*, ESXi* , VMWare*, Linux*, FireEye*, Fortinet*, Cylance*, Check*, Juniper*)\
|
|
| sort 0 eventtypeId \
|
|
| streamstats count \
|
|
| eval row_id="row_"+count \
|
|
| fields row_id regex_pattern \
|
|
| eval rexValue="(?<P_"+row_id+">"+regex_pattern+")" \
|
|
| head 300 \
|
|
| stats values(rexValue) AS regexMerge \
|
|
| eval regexMerge=mvjoin(regexMerge,"|") \
|
|
| eval search="\"(".regexMerge.")\"" \
|
|
| fields search \
|
|
]\
|
|
| rex field="source" max_match=0 \
|
|
[| inputlookup SSE-default-data-inventory-products.csv \
|
|
| eval eventtypeId=split(eventtypeId,"|") \
|
|
| mvexpand eventtypeId \
|
|
| search regex_pattern=* \
|
|
| search NOT productId IN (MSSQL*, SQL*,MySQL*, Oracle*, ESXi* , VMWare*, Linux*, FireEye*, Fortinet*, Cylance*, Check*, Juniper*)\
|
|
| sort 0 eventtypeId \
|
|
| streamstats count \
|
|
| eval row_id="row_"+count \
|
|
| fields row_id regex_pattern \
|
|
| eval rexValue="(?<P_"+row_id+">"+regex_pattern+")" \
|
|
| tail 300 \
|
|
| stats values(rexValue) AS regexMerge \
|
|
| eval regexMerge=mvjoin(regexMerge,"|") \
|
|
| eval search="\"(".regexMerge.")\"" \
|
|
| fields search \
|
|
]\
|
|
| foreach P_* \
|
|
[| eval PatternStringMatch=if('<<FIELD>>'!="", mvappend(PatternStringMatch,'<<FIELD>>'),PatternStringMatch) \
|
|
| eval PatternStringDescription=if('<<FIELD>>'!="", mvappend(PatternStringDescription,"<<MATCHSTR>>"),PatternStringDescription)\
|
|
] \
|
|
| fields - P_*\
|
|
| join PatternStringDescription type=outer[\
|
|
| inputlookup SSE-default-data-inventory-products.csv \
|
|
| eval eventtypeId=split(eventtypeId,"|") \
|
|
| mvexpand eventtypeId \
|
|
| search regex_pattern=* \
|
|
| search NOT productId IN (MSSQL*, SQL*,MySQL*, Oracle*, ESXi* , VMWare*, Linux*, FireEye*, Fortinet*, Cylance*, Check*, Juniper*)\
|
|
| sort 0 eventtypeId \
|
|
| streamstats count \
|
|
| eval PatternStringDescription="row_"+count \
|
|
\
|
|
| fields PatternStringDescription eventtypeId productId\
|
|
| eventstats values(eventtypeId) AS eventtypeId BY productId\
|
|
| eval eventtypeId=mvjoin(eventtypeId,"|")\
|
|
]\
|
|
| fields - Pattern*\
|
|
```Filter our matches against non-Vendor specific data source categories. If a detection uses this specific vendor technology it will only rely on that and not of datamodels```\
|
|
| eval eventtypeId=split(eventtypeId,"|")\
|
|
| eval eventtypeId_VendorOnly=mvfilter(match(eventtypeId, "Vendor"))\
|
|
| eval eventtypeId=coalesce(eventtypeId_VendorOnly,eventtypeId)\
|
|
| fields - eventtypeId_VendorOnly\
|
|
```END ```\
|
|
|
|
|
|
[Generate Local Saved Search Lookup]
|
|
action.keyindicator.invert = 0
|
|
action.makestreams.param.verbose = 0
|
|
action.nbtstat.param.verbose = 0
|
|
action.notable.param.verbose = 0
|
|
action.nslookup.param.verbose = 0
|
|
action.ping.param.verbose = 0
|
|
action.risk.forceCsvResults = 1
|
|
action.risk.param.verbose = 0
|
|
action.send2uba.param.verbose = 0
|
|
action.threat_add.param.verbose = 0
|
|
alert.track = 0
|
|
search = | rest splunk_server=local count=0 /servicesNS/-/-/saved/searches \
|
|
| rex field=qualifiedSearch ".*datamodel(=\"|:\"|\(\"|\s|:|=)(\"|)(?<datamodel>[a-z,A-Z,_]*)"\
|
|
| rex field=qualifiedSearch ".*datamodel(=\"|:\"|\(\"|\s|:|=)(\"|)[a-z,A-Z,_]*(\"|)\.(\"|)(?<nodeName>[a-z,A-Z,_]*)"\
|
|
| eval datamodel=if(isnotnull(nodeName), datamodel.".".nodeName, datamodel)\
|
|
| rex field=qualifiedSearch max_match=0 "sourcetype=(\"|)(?<sourcetype>[^\"\s]*)(|\")" \
|
|
| rex field=qualifiedSearch max_match=0 "source=(\"|)(?<source>[^\"]*)(|\")" \
|
|
| rex field=qualifiedSearch max_match=0 "`(?<macro>[^`]*)`" \
|
|
| rex field=qualifiedSearch max_match=0 ".*(?:input| )lookup (?:[a-z,A-Z,_]*=[a-z,A-Z,_]{1,4} |)(?<lookup>[a-z,A-Z,_,0-9]*)" \
|
|
\
|
|
| eval isCorrelationSearch=if('action.notable'=1 OR 'action.risk'=1 OR 'action.correlationsearch.enabled'=1,"true","false")\
|
|
| eval isEnabled=if('disabled'="0","true","false")\
|
|
| eval isScheduled=if(len('cron_schedule') >= 9,"true","false")\
|
|
| rename title AS name\
|
|
| rename \
|
|
qualifiedSearch AS search,\
|
|
action.correlationsearch.label as displayTitle, \
|
|
cron_schedule AS schedule,\
|
|
eai:acl.owner AS owner,\
|
|
eai:acl.app as app,\
|
|
action.correlationsearch.annotations AS annotations\
|
|
| eval displayTitle=coalesce(name,displayTitle)\
|
|
| eval link=id\
|
|
| lookup datamodels datamodel\
|
|
| lookup SSE-STRT-macros-to-data_source_categories.csv macro OUTPUTNEW eventtypeId AS data_source_category\
|
|
| eval data_source_category=mvdedup(data_source_category)\
|
|
| eval sourcetype=mvjoin(mvdedup(sourcetype),"|")\
|
|
| eval source=mvjoin(mvdedup(source),"|")\
|
|
| eval macro=mvjoin(mvdedup(macro),"|")\
|
|
| eval lookup=mvjoin(mvdedup(lookup),"|")\
|
|
| eval datamodel=mvjoin(mvdedup(datamodel),"|")\
|
|
\
|
|
| eval sourcetype_regex_match=if(isnull(data_source_category) AND isnotnull(sourcetype),sourcetype,null())\
|
|
| eval source_regex_match=if(isnull(data_source_category) AND isnotnull(source),source,null())\
|
|
\
|
|
| rex field="sourcetype_regex_match" max_match=0 \
|
|
[| inputlookup SSE-default-data-inventory-products.csv \
|
|
| eval eventtypeId=split(eventtypeId,"|") \
|
|
| mvexpand eventtypeId \
|
|
| search regex_pattern=* \
|
|
| search NOT productId IN (MSSQL*, SQL*,MySQL*, Oracle*, ESXi* , VMWare*, Linux*, FireEye*, Fortinet*, Cylance*, Check*, Juniper*)\
|
|
| sort 0 eventtypeId \
|
|
| streamstats count \
|
|
| eval row_id="row_"+count \
|
|
| fields row_id regex_pattern \
|
|
| eval rexValue="(?<P_"+row_id+">"+regex_pattern+")" \
|
|
| head 300 \
|
|
| stats values(rexValue) AS regexMerge \
|
|
| eval regexMerge=mvjoin(regexMerge,"|") \
|
|
| eval search="\"(".regexMerge.")\"" \
|
|
| fields search \
|
|
]\
|
|
| rex field="sourcetype_regex_match" max_match=0 \
|
|
[| inputlookup SSE-default-data-inventory-products.csv \
|
|
| eval eventtypeId=split(eventtypeId,"|") \
|
|
| mvexpand eventtypeId \
|
|
| search regex_pattern=* \
|
|
| search NOT productId IN (MSSQL*, SQL*,MySQL*, Oracle*, ESXi* , VMWare*, Linux*, FireEye*, Fortinet*, Cylance*, Check*, Juniper*)\
|
|
| sort 0 eventtypeId \
|
|
| streamstats count \
|
|
| eval row_id="row_"+count \
|
|
| fields row_id regex_pattern \
|
|
| eval rexValue="(?<P_"+row_id+">"+regex_pattern+")" \
|
|
| tail 300 \
|
|
| stats values(rexValue) AS regexMerge \
|
|
| eval regexMerge=mvjoin(regexMerge,"|") \
|
|
| eval search="\"(".regexMerge.")\"" \
|
|
| fields search \
|
|
]\
|
|
| rex field="source_regex_match" max_match=0 \
|
|
[| inputlookup SSE-default-data-inventory-products.csv \
|
|
| eval eventtypeId=split(eventtypeId,"|") \
|
|
| mvexpand eventtypeId \
|
|
| search regex_pattern=* \
|
|
| search NOT productId IN (MSSQL*, SQL*,MySQL*, Oracle*, ESXi* , VMWare*, Linux*, FireEye*, Fortinet*, Cylance*, Check*, Juniper*)\
|
|
| sort 0 eventtypeId \
|
|
| streamstats count \
|
|
| eval row_id="row_"+count \
|
|
| fields row_id regex_pattern \
|
|
| eval rexValue="(?<P_"+row_id+">"+regex_pattern+")" \
|
|
| head 300 \
|
|
| stats values(rexValue) AS regexMerge \
|
|
| eval regexMerge=mvjoin(regexMerge,"|") \
|
|
| eval search="\"(".regexMerge.")\"" \
|
|
| fields search \
|
|
]\
|
|
| rex field="source_regex_match" max_match=0 \
|
|
[| inputlookup SSE-default-data-inventory-products.csv \
|
|
| eval eventtypeId=split(eventtypeId,"|") \
|
|
| mvexpand eventtypeId \
|
|
| search regex_pattern=* \
|
|
| search NOT productId IN (MSSQL*, SQL*,MySQL*, Oracle*, ESXi* , VMWare*, Linux*, FireEye*, Fortinet*, Cylance*, Check*, Juniper*)\
|
|
| sort 0 eventtypeId \
|
|
| streamstats count \
|
|
| eval row_id="row_"+count \
|
|
| fields row_id regex_pattern \
|
|
| eval rexValue="(?<P_"+row_id+">"+regex_pattern+")" \
|
|
| tail 300 \
|
|
| stats values(rexValue) AS regexMerge \
|
|
| eval regexMerge=mvjoin(regexMerge,"|") \
|
|
| eval search="\"(".regexMerge.")\"" \
|
|
| fields search \
|
|
]\
|
|
| foreach P_* \
|
|
[| eval PatternStringMatch=if('<<FIELD>>'!="", mvappend(PatternStringMatch,'<<FIELD>>'),PatternStringMatch) \
|
|
| eval PatternStringDescription=if('<<FIELD>>'!="", mvappend(PatternStringDescription,"<<MATCHSTR>>"),PatternStringDescription)\
|
|
] \
|
|
| fields - P_*\
|
|
| join PatternStringDescription type=outer[\
|
|
| inputlookup SSE-default-data-inventory-products.csv \
|
|
| eval eventtypeId=split(eventtypeId,"|") \
|
|
| mvexpand eventtypeId \
|
|
| search regex_pattern=* \
|
|
| search NOT productId IN (MSSQL*, SQL*,MySQL*, Oracle*, ESXi* , VMWare*, Linux*, FireEye*, Fortinet*, Cylance*, Check*, Juniper*)\
|
|
| sort 0 eventtypeId \
|
|
| streamstats count \
|
|
| eval PatternStringDescription="row_"+count \
|
|
\
|
|
| fields PatternStringDescription eventtypeId productId\
|
|
| eventstats values(eventtypeId) AS eventtypeId BY productId\
|
|
| eval eventtypeId=mvjoin(eventtypeId,"|")\
|
|
]\
|
|
| fields - Pattern*\
|
|
| eval data_source_category=coalesce(data_source_category,eventtypeId)\
|
|
| table app description displayTitle id isCorrelationSearch isEnabled isScheduled link name next_scheduled_time owner schedule search updated annotations data_source_category datamodel sourcetype source macro lookup\
|
|
| table app description displayTitle id isCorrelationSearch isEnabled isScheduled link name next_scheduled_time owner schedule search updated annotations data_source_category datamodel sourcetype source macro lookup\
|
|
| outputlookup createinapp=t SSE-local_savedsearches.csv
|
|
|
|
[Generate MITRE Environment Count]
|
|
action.email.useNSSubject = 1
|
|
action.keyindicator.invert = 0
|
|
action.makestreams.param.verbose = 0
|
|
action.nbtstat.param.verbose = 0
|
|
action.notable.param.verbose = 0
|
|
action.nslookup.param.verbose = 0
|
|
action.ping.param.verbose = 0
|
|
action.risk.forceCsvResults = 1
|
|
action.risk.param.verbose = 0
|
|
action.send2uba.param.verbose = 0
|
|
action.threat_add.param.verbose = 0
|
|
alert.track = 0
|
|
dispatch.earliest_time = 0
|
|
display.general.type = statistics
|
|
display.page.search.mode = verbose
|
|
display.page.search.tab = statistics
|
|
display.statistics.rowNumbers = 1
|
|
display.visualizations.charting.chart = pie
|
|
display.visualizations.charting.chart.style = minimal
|
|
display.visualizations.custom.type = custom-radar-chart-viz.radar_chart
|
|
display.visualizations.show = 0
|
|
request.ui_dispatch_app = Splunk_Security_Essentials
|
|
request.ui_dispatch_view = search
|
|
search = | sseanalytics \
|
|
| lookup use_cases.csv title AS "usecase" OUTPUT order_title AS use_case_order_title \
|
|
| eval "Use Case Orig"=if(isnull('usecase'),"Other",'usecase') \
|
|
| eval "Use Case"=if(isnull(use_case_order_title), "9_Other",use_case_order_title) \
|
|
| eval "Has Data"=if(data_available="Available" OR data_available="Mixed", "Yes", "No") \
|
|
| eval displayapp=mvappend(displayapp,"Any")\
|
|
| eval Status=case(\
|
|
'enabled'="Yes" AND 'Has Data'="Yes","Active",\
|
|
'enabled'!="Yes" AND 'Has Data'="Yes","Available",\
|
|
1=1,"Needs data"\
|
|
) \
|
|
| eval App=displayapp, Enabled=enabled, Title=name, Journey=journey, "Data Source"=datasource, "Data Source Category"=data_source_categories_display \
|
|
| where (mitre_tactic_display!="" AND mitre_tactic_display!="None") OR (mitre_technique_display!="" AND mitre_technique_display!="None" AND mvcount(mitre_technique_display)>0) \
|
|
| eval mitre_sub_technique_display=if(mitre_sub_technique_display="None","",mitre_sub_technique_display) \
|
|
| eval "MITRE Tactic"=if('mitre_tactic_display'="","-",'mitre_tactic_display'), "MITRE Technique"=mitre_technique_display, "MITRE Sub-Technique"=mitre_sub_technique_display, "MITRE Threat Group"=mitre_threat_groups, "MITRE Platforms"=mitre_platforms, Industry=split(industryMapping,"|") \
|
|
| table mitre_matrix "MITRE Tactic" "MITRE Technique" "MITRE Sub-Technique" Status "Data Source" App bookmark_status mitre_id Title\
|
|
| rename mitre_matrix AS "MITRE Matrix" \
|
|
| mvexpand "mitre_id" \
|
|
| lookup mitre_enterprise_list TechniqueIdCombined AS "mitre_id" OUTPUT Sub_Technique AS "MITRE Sub-Technique" Technique AS "MITRE Technique" Tactic AS "MITRE Tactic" \
|
|
| mvexpand "MITRE Tactic" \
|
|
| eval "MITRE Sub-Technique"=mvdedup('MITRE Sub-Technique'),"MITRE Technique"=mvdedup('MITRE Technique'),"MITRE Tactic"=mvdedup('MITRE Tactic') \
|
|
| eval mitre_technique_datasource_merge=mvzip('MITRE Technique','Data Source',"::") \
|
|
| eventstats sum(eval(if(len('MITRE Sub-Technique')=1,1,0))) AS MITRE_Technique_Datasource_Total BY "mitre_technique_datasource_merge" \
|
|
| eval mitre_technique_datasource_merge=mvzip('Data Source','MITRE_Technique_Datasource_Total',"::") \
|
|
\
|
|
| eventstats sum(eval(if(len('MITRE Sub-Technique')<=1,1,0))) AS MITRE_Tactic_Total BY "MITRE Tactic" \
|
|
| eventstats sum(eval(if(len('MITRE Sub-Technique')<=1,1,0))) AS MITRE_Technique_Total BY "MITRE Technique" "MITRE Tactic" \
|
|
| eventstats count AS MITRE_Technique_Total BY "MITRE Technique" "MITRE Tactic" \
|
|
| eventstats sum(eval(if(len('MITRE Sub-Technique')>1,1,0))) AS MITRE_Sub_Technique_Total BY "MITRE Tactic" "MITRE Sub-Technique" \
|
|
| eventstats sum(eval(if(len('MITRE Sub-Technique')<=1,1,0))) AS MITRE_Tactic_Technique_Total BY "MITRE Tactic" "MITRE Technique" \
|
|
\
|
|
| mvexpand App\
|
|
| eventstats delim=","\
|
|
values(eval(if(Status="Active",Title,null()))) AS "Active_TechniqueTotal",\
|
|
values(eval(if(Status="Available",Title,null()))) AS "Available_TechniqueTotal",\
|
|
values(eval(if(Status="Needs data",Title,null()))) AS "Needs data_TechniqueTotal",\
|
|
BY "MITRE Tactic","MITRE Technique","MITRE Matrix" App\
|
|
| foreach *_TechniqueTotal [\
|
|
| eval "<<FIELD>>" = mvcount('<<FIELD>>')\
|
|
]\
|
|
| fields - Title\
|
|
\
|
|
| stats delim=","\
|
|
sum(eval(if(len('MITRE Sub-Technique')<=1 AND Status="Active",1,0))) AS "Active",\
|
|
sum(eval(if(len('MITRE Sub-Technique')<=1 AND Status="Available",1,0))) AS "Available",\
|
|
sum(eval(if(len('MITRE Sub-Technique')<=1 AND Status="Needs data",1,0))) AS "Needs data",\
|
|
sum(eval(if(len('MITRE Sub-Technique')<=1 AND bookmark_status!="none",1,0))) AS "Bookmarked_Technique",\
|
|
sum(eval(if(len('MITRE Sub-Technique')>1 AND Status="Active",1,0))) AS "Active_SubTechnique",\
|
|
sum(eval(if(len('MITRE Sub-Technique')>1 AND Status="Available",1,0))) AS "Available_SubTechnique",\
|
|
sum(eval(if(len('MITRE Sub-Technique')>1 AND Status="Needs data",1,0))) AS "Needs data_SubTechnique",\
|
|
sum(eval(if(len('MITRE Sub-Technique')>1 AND bookmark_status!="none",1,0))) AS "Bookmarked_SubTechnique",\
|
|
max(MITRE_Tactic_Total) AS MITRE_Tactic_Total,\
|
|
max(MITRE_Technique_Total) AS MITRE_Technique_Total\
|
|
max(MITRE_Sub_Technique_Total) AS MITRE_Sub_Technique_Total,\
|
|
max(MITRE_Tactic_Technique_Total) AS MITRE_Tactic_Technique_Total,\
|
|
values(mitre_technique_datasource_merge) AS "Data Source",\
|
|
max(Active_TechniqueTotal) AS Active_TechniqueTotal,\
|
|
max(Available_TechniqueTotal) AS Available_TechniqueTotal,\
|
|
max("Needs data_TechniqueTotal") AS "Needs data_TechniqueTotal"\
|
|
BY "MITRE Tactic","MITRE Technique","MITRE Sub-Technique","MITRE Matrix" App\
|
|
| eval c="This fixes the counts for Techniques that have Sub-Techniques" \
|
|
| eval "Active"=if(isnull('Sub-Technique'), 'Active_TechniqueTotal', 'Active') \
|
|
| eval "Available"=if(isnull('Sub-Technique'), 'Available_TechniqueTotal', 'Available') \
|
|
| eval "Needs data"=if(isnull('Sub-Technique'), 'Needs data_TechniqueTotal', 'Needs data') \
|
|
| eval "Active"=if(len('MITRE Sub-Technique')>1, 'Active_SubTechnique', 'Active') \
|
|
| eval "Available"=if(len('MITRE Sub-Technique')>1, 'Available_SubTechnique', 'Available') \
|
|
| eval "Needs data"=if(len('MITRE Sub-Technique')>1, 'Needs data_SubTechnique', 'Needs data') \
|
|
| eval "Bookmarked"='Bookmarked_Technique'+'Bookmarked_SubTechnique' \
|
|
| fields - *_TechniqueTotal *_SubTechnique \
|
|
| rename "MITRE *" AS *,"MITRE_*" AS * \
|
|
| eval "Sub-Technique"=if('Sub-Technique'="", "-", 'Sub-Technique') \
|
|
| eval IsSubTechnique=if('Sub-Technique'="-", "No", "Yes") \
|
|
| table Matrix Tactic Tactic_Total Technique Technique_Total "Sub-Technique" "Sub_Technique_Total" IsSubTechnique Active "Available" "Needs data" Technique_Total "Data Source" App Bookmarked \
|
|
| eval c="This appends all techniques and sub-techniques for which we have no detections" \
|
|
| lookup mitre_enterprise_list Matrix Tactic Technique Sub_Technique AS "Sub-Technique" OUTPUT Technique_Order Sub_Technique_Order \
|
|
| append \
|
|
[| inputlookup mitre_enterprise_list \
|
|
| fields Matrix Tactic Sub_Technique Technique Technique_Order Sub_Technique_Order \
|
|
| rename Sub_Technique AS "Sub-Technique"] \
|
|
| eventstats values(App) AS AllApps\
|
|
| eval Technique_Order=coalesce(Technique_Order,"-"),Sub_Technique_Order=coalesce(Sub_Technique_Order,"-"),App=coalesce(App,AllApps) \
|
|
| stats delim=","\
|
|
sum(Active) AS Active,\
|
|
sum(Available) AS Available,\
|
|
sum("Needs data") AS "Needs data",\
|
|
sum(Sub_Technique_Total) AS Sub_Technique_Total,\
|
|
sum(Tactic_Total) AS Tactic_Total,\
|
|
sum(Technique_Total) AS Technique_Total,\
|
|
sum(Bookmarked) AS Bookmarked,\
|
|
values("Data Source") AS "Data Source",\
|
|
values("IsSubTechnique") AS "IsSubTechnique"\
|
|
BY\
|
|
Matrix, Tactic Technique Sub-Technique Technique_Order Sub_Technique_Order, App\
|
|
| fillnull Active Available "Needs data" Sub_Technique_Total Tactic_Total Technique_Total value="0" \
|
|
| eval IsSubTechnique=if('Sub-Technique'="-", "No", "Yes") \
|
|
| eval Bookmarked=coalesce(Bookmarked, 0) \
|
|
| sort 0 Technique_Order Sub_Technique_Order \
|
|
| fields - Technique_Order Sub_Technique_Order\
|
|
| outputlookup mitre_environment_count.csv
|
|
|
|
[Generate MITRE Data Source Lookup]
|
|
action.webhook.enable_allowlist = 0
|
|
alert.track = 0
|
|
description = This search formats the MITRE ATT&CK framework Data Sources into a lookup
|
|
dispatch.earliest_time = -24h@h
|
|
dispatch.latest_time = now
|
|
display.general.type = statistics
|
|
display.page.search.tab = statistics
|
|
search = | ssedata config="mitreattack"\
|
|
| where type="x-mitre-data-source" OR type="x-mitre-data-component"\
|
|
| spath input=json path="x_mitre_data_source_ref" output="x_mitre_data_source_ref"\
|
|
| table type id name description external_id x_mitre_data_source_ref\
|
|
| eval ds_id=coalesce(x_mitre_data_source_ref,id)\
|
|
| sort 0 ds_id\
|
|
\
|
|
\
|
|
| eventstats\
|
|
first(eval(if(type="x-mitre-data-source",name, null()))) AS Name \
|
|
first(eval(if(type="x-mitre-data-source",description, null()))) AS Description \
|
|
BY ds_id\
|
|
| rename external_id AS Id\
|
|
| filldown Id\
|
|
| where type="x-mitre-data-component"\
|
|
| rename name AS Data_Component\
|
|
| rename description AS Data_Component_Description\
|
|
| eval Data_Source=Name.": ".Data_Component\
|
|
| table Id Name Data_Source Description Data_Component Data_Component_Description\
|
|
| outputlookup mitre_data_sources
|
|
|
|
[Generate MITRE Detections Lookup]
|
|
action.webhook.enable_allowlist = 0
|
|
alert.track = 0
|
|
description = This search formats the MITRE ATT&CK framework Detections into a lookup
|
|
dispatch.earliest_time = -24h@h
|
|
dispatch.latest_time = now
|
|
display.general.type = statistics
|
|
display.page.search.tab = statistics
|
|
search = | ssedata config="mitreattack"\
|
|
| where type="relationship" \
|
|
| spath input=json path="relationship_type" output="relationship_type"\
|
|
| where relationship_type="detects"\
|
|
| spath input=json path="source_ref" output="source_ref"\
|
|
| spath input=json path="target_ref" output="target_ref"\
|
|
| join type=outer target_ref [\
|
|
| ssedata config="mitreattack"\
|
|
| where type="attack-pattern"\
|
|
| table id external_id name description\
|
|
| rename id AS target_ref\
|
|
| rename external_id AS TechniqueIdCombined\
|
|
| rename name AS Technique\
|
|
| rename description AS MitreDescription\
|
|
]\
|
|
| join type=outer source_ref [\
|
|
| ssedata config="mitreattack"\
|
|
| where type="x-mitre-data-component"\
|
|
| table id name description\
|
|
| rename id AS source_ref\
|
|
| rename name AS Data_Component\
|
|
| rename description AS Data_Component_Description\
|
|
]\
|
|
| eval Type="Detection"\
|
|
| rename description AS Description\
|
|
| table Type Description TechniqueIdCombined Technique Data_Component Data_Component_Description\
|
|
| outputlookup mitre_detections
|
|
|
|
[Generate MITRE Threat Group Lookup]
|
|
action.webhook.enable_allowlist = 0
|
|
alert.track = 0
|
|
description = This search formats the MITRE ATT&CK framework Threat Groups into a lookup. It also attaches the Industry field based on keyword matching.
|
|
dispatch.earliest_time = -24h@h
|
|
dispatch.latest_time = now
|
|
display.general.type = statistics
|
|
display.page.search.tab = statistics
|
|
search = | ssedata config="mitreattack"\
|
|
| where type="intrusion-set"\
|
|
| spath input="json" path="aliases{}" output="Alias"\
|
|
| rename name AS Threat_Group, description AS Description, external_id AS Id\
|
|
| fields Threat_Group Industry Description Alias Id\
|
|
\
|
|
``` Logic for splitting the description text to match the industry keywords to something that is close to the sentence break words below ```\
|
|
| eval description_words=lower(Description)\
|
|
| eval description_words=case(\
|
|
like(description_words, "%target%"), mvindex(split(description_words,"target"),1)+coalesce(mvindex(split(description_words,"target"),2),"")+coalesce(mvindex(split(description_words,"target"),3),""),\
|
|
like(description_words, "%against%"), mvindex(split(description_words,"against"),1),\
|
|
like(description_words, "%industries%"), mvindex(split(description_words,"industries"),1),\
|
|
like(description_words, "%interest in%"), mvindex(split(description_words,"interest in"),1),\
|
|
like(description_words, "%interested in%"), mvindex(split(description_words,"interested in"),1),\
|
|
like(description_words, "%victims%"), mvindex(split(description_words,"victims"),1),\
|
|
1=1, ""\
|
|
)\
|
|
``` Lookup contains wildcard matches to industry keyqords ```\
|
|
| lookup sse_industries IndustryAlias AS description_words OUTPUT Industry\
|
|
| eval Industry=mvsort(mvdedup(Industry))\
|
|
| fields - description_words\
|
|
| eval Industry=if(isnull(Industry),"-",Industry)\
|
|
| table Threat_Group Industry Description Alias Id\
|
|
| outputlookup mitre_threat_groups output_format=splunk_mv_csv |