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.
Splunk_Deploiement/apps/audit_trail/default/savedsearches.conf

95 lines
7.1 KiB

# Version 10.0.2
# main query used in audit trail for users activities app
[audit_trail_users_query]
disabled=0
dispatch.earliest_time = -24h@h
dispatch.latest_time = now
search = ```filter out capability checks, internal users and quota checks``` \
index=_audit NOT info IN (denied, granted, "denied *", "granted *") NOT cap=1 NOT action=quota user IN ($ss_user_names$) host IN ($ss_host_names$) $ss_text$ \
```Filter out audit v2 logs```\
| search sourcetype="audittrail"\
| rex field=_raw "user=(?<auditrep_user>[a-zA-Z0-9/\s_\.-]*)," \
| rex field=_raw "action=(?<auditrep_action>[a-zA-Z0-9_\s]*)," \
```calculate user_action to get rid of spaces``` \
| eval user_action=lower(replace(auditrep_action, "\s", "_")) \
```filter out internal or unknown users, preserve specific actions``` \
| eval auditrep_user=IF(auditrep_user == "n/a" AND user_action IN ("splunkstarting", "splunkshuttingdown"), "unknown", auditrep_user) \
| search NOT auditrep_user IN ("n/a", internal_observability, splunk-system-user, internal_automation, soar_proxy_user, soar_automation_user) \
```filter out SCS events``` \
| spath input=info path=generated_by output=scs_generated_by | where isnull(scs_generated_by) \
```filter out internal automated non-human actions``` \
| search NOT user_action IN (validate_token, get_password, alert_fired, list_scs_token) \
```calculate useragent_prefix for login_attempt actions``` \
| eval normalized_useragent=IF(user_action=="login_attempt" AND (isnull(useragent) OR useragent=""), "unknown", useragent) \
| eval useragent_prefix=IF(user_action=="login_attempt", mvindex(split(mvindex(split(normalized_useragent,"/"),0), " "), 0), "n/a") \
```filter out cancelled searches, searches ran by scheduler and subsearches``` \
| eval skip="0" \
| eval skip=IF(user_action=="search" AND (info=="cancel" OR info=="canceled" OR provenance="scheduler" OR search_id like "'subsearch_%"), "1", skip) \
```| eval skip=IF(user_action=="login_attempt" AND useragent_prefix != "Mozilla", "1", skip) ``` \
| search skip="0" \
```calculate extended user_action - ex_user_action``` \
| rex field=user_action "(?<object_action>[a-zA-Z]+)_(?<object_type>[a-zA-Z_]*)" \
| eval ex_user_action=user_action \
| eval object_name=name \
| eval object_name=IF(object_type=="saved_search", savedsearch_name, object_name) \
| eval object_name=IF(object_type=="token", tokenId, object_name) \
| eval object_name=IF(object_type=="user", IF(isnull(username), user, username), object_name) \
| eval object_name=IF(object_type=="app", IF( NOT isnull(app_name), app_name, IF(NOT isnull(app), app, object_name)), object_name) \
| eval object_name=IF(object_type=="saml_group_map", group, object_name) \
| eval object_name=IF(object_type=="datamodel", IF(isnull(object_name), displayName, object_name), object_name) \
| eval object_name=IF(object_type=="password", password_id, object_name) \
| eval ex_user_action=IF(object_action IN ("edit", "create", "new", "remove", "delete", "update", "updated", "disable", "enable", "move", "install") AND NOT isnull(object_name) AND NOT lower(provenance)=="n/a", ex_user_action."@".object_name, ex_user_action) \
| eval ex_user_action=IF(user_action like "login_attempt%" OR user_action like "logout%" , ex_user_action."@".user, ex_user_action) \
```search is treated a little differently``` \
| eval object_name=IF(user_action=="search", IF(NOT isnull(provenance) AND NOT provenance=="N/A", provenance, \
IF(NOT isnull(savedsearch_name) AND savedsearch_name != "", savedsearch_name, "noname_search")), object_name) \
| eval ex_user_action=IF(user_action=="search", "search@".object_name, ex_user_action) \
```Preserve original event body``` \
| eval orig_body=_raw \
| eval object_name=IF(isnull(object_name), "n/a", object_name) \
| eval host=IF(isnull(host), "n/a", host) \
| eval app=IF(isnull(app), "n/a", app) \
| eval useragent=IF(isnull(useragent_prefix), "n/a", useragent_prefix) \
| eval user=auditrep_user \
| stats count by _time, user, user_action, ex_user_action, app, object_name, host, useragent, info, orig_body \
# main query used in audit trail knowledge objects app
[audit_trail_knowledge_objects_query]
action.email.useNSSubject = 1
action.webhook.enable_allowlist = 0
dispatch.earliest_time = -7d@h
dispatch.latest_time = now
display.general.type = statistics
display.page.search.tab = statistics
display.visualizations.show = 0
request.ui_dispatch_app = audit_trail
request.ui_dispatch_view = search
search = ```Firstly filter out capability checks and non CRUD, non knowledge objects audit logs```\
index=_audit | where isnull(cap) AND NOT info IN ("granted", "denied") | search action IN ("create_*", "update_*", "updated_*", "edit_*", "remove_*", "delete_*", "disable_*", "new_*", "move_*", "enable_*", "acl_*") | search action IN ("*_user", "*_saved_search", "*_data_model_file", "*_event_type", "*_tag", "*_fields_*", "*_lookup_table", "*_ui_view*", "*_ui_panel", "*_macro", "*_command")\
```Filter out audit v2 logs```\
| search sourcetype="audittrail"\
```Extract object type and action```\
| rex action="(?<object_action>[a-zA-Z]+)_(?<object_type>[a-zA-Z_]*),"\
```Extract application name```\
| rex field=info "app=\"(?<apptmp>.*)\"" \
| eval appnametmp=IF(!isnull(apptmp),apptmp,IF(isnull(app),"-missing-",app) )\
| rex field=appnametmp "'(?<apptmp2>.*)'" \
| eval appname=IF(!isnull(apptmp2),apptmp2,appnametmp) \
```Unify object name```\
| eval name=IF(object_type="user",username,name) \
| eval name=IF(object_type="saved_search",savedsearch_name,name)\
| eval name=IF(!isnull(name),name,"-missing-")\
```Tags may have mnulti values: {[0]='tag_1' [1]='tag_2'}- split it to separate events```\
| eval tagnames=split(replace(name, "\\[[0-9]*\\]=",""), "' '") | mvexpand tagnames | eval name=ltrim(rtrim(tagnames,"'}"),"{'")\
```Extract host name from fqdn```\
| eval host=mvindex(split(host,"."),0)\
```Finally rename object type and actions to user friendly ones```\
| lookup object_types_normalization ORIG_OBJECT_TYPE AS object_type OUTPUT DEST_OBJECT_TYPE AS object_type\
| lookup action_types_normalization ORIG_ACTION AS object_action OUTPUT DEST_ACTION AS object_action\
```Preserve original event body```\
| eval orig_body=_raw\
```Apply filtering in the base search to avoid 'unknown sid' issue```\
```| where "text_token$"="-" OR orig_body like "%text_token$%"``` \
| stats count by _time, user, action, name, appname, host, info, object_type, object_action, orig_body