diff --git a/salt/soc/config.sls b/salt/soc/config.sls index 7e2beefa0..3609b7024 100644 --- a/salt/soc/config.sls +++ b/salt/soc/config.sls @@ -134,6 +134,30 @@ socsigmasopipeline: - group: 939 - mode: 600 +socsigmaplaybookpipeline: + file.managed: + - name: /opt/so/conf/soc/sigma_playbook_pipeline.yaml + - source: salt://soc/files/soc/sigma_playbook_pipeline.yaml + - user: 939 + - group: 939 + - mode: 600 + +socplaybookplaceholdermap: + file.managed: + - name: /opt/so/conf/soc/playbook_placeholder_map.yaml + - source: salt://soc/files/soc/playbook_placeholder_map.yaml + - user: 939 + - group: 939 + - mode: 600 + +socplaybookplaceholdermapcustom: + file.managed: + - name: /opt/so/conf/soc/playbook_placeholder_map_custom.yaml + - source: salt://soc/files/soc/playbook_placeholder_map_custom.yaml + - user: 939 + - group: 939 + - mode: 600 + socbanner: file.managed: - name: /opt/so/conf/soc/banner.md diff --git a/salt/soc/defaults.yaml b/salt/soc/defaults.yaml index ff8a504ac..d041e3318 100644 --- a/salt/soc/defaults.yaml +++ b/salt/soc/defaults.yaml @@ -1502,6 +1502,9 @@ soc: - repo: https://github.com/Security-Onion-Solutions/securityonion-resources-playbooks branch: main folder: securityonion-normalized + - repo: https://github.com/Security-Onion-Solutions/securityonion-resources-playbooks + branch: published + folder: sigma airgap: - repo: file:///nsm/airgap-resources/playbooks/securityonion-resources-playbooks branch: main diff --git a/salt/soc/enabled.sls b/salt/soc/enabled.sls index 1805bacaf..b907864a2 100644 --- a/salt/soc/enabled.sls +++ b/salt/soc/enabled.sls @@ -45,7 +45,10 @@ so-soc: - /opt/so/conf/soc/motd.md:/opt/sensoroni/html/motd.md:ro - /opt/so/conf/soc/banner.md:/opt/sensoroni/html/login/banner.md:ro - /opt/so/conf/soc/sigma_so_pipeline.yaml:/opt/sensoroni/sigma_so_pipeline.yaml:ro - - /opt/so/conf/soc/sigma_final_pipeline.yaml:/opt/sensoroni/sigma_final_pipeline.yaml:rw + - /opt/so/conf/soc/sigma_playbook_pipeline.yaml:/opt/sensoroni/sigma_playbook_pipeline.yaml:ro + - /opt/so/conf/soc/sigma_final_pipeline.yaml:/opt/sensoroni/sigma_final_pipeline.yaml:ro + - /opt/so/conf/soc/playbook_placeholder_map.yaml:/opt/sensoroni/playbook_placeholder_map.yaml:ro + - /opt/so/conf/soc/playbook_placeholder_map_custom.yaml:/opt/sensoroni/playbook_placeholder_map_custom.yaml:ro - /opt/so/conf/soc/custom.js:/opt/sensoroni/html/js/custom.js:ro - /opt/so/conf/soc/custom_roles:/opt/sensoroni/rbac/custom_roles:ro - /opt/so/conf/soc/soc_users_roles:/opt/sensoroni/rbac/users_roles:rw @@ -99,6 +102,8 @@ so-soc: - file: soccustomroles - file: socusersroles - file: socclientsroles + - file: socplaybookplaceholdermap + - file: socplaybookplaceholdermapcustom delete_so-soc_so-status.disabled: file.uncomment: diff --git a/salt/soc/files/soc/playbook_placeholder_map.yaml b/salt/soc/files/soc/playbook_placeholder_map.yaml new file mode 100644 index 000000000..eeddb4474 --- /dev/null +++ b/salt/soc/files/soc/playbook_placeholder_map.yaml @@ -0,0 +1,49 @@ +# Global Playbook placeholder map: %token% -> event field path. +# +# Loaded by the SOC Playbook module and used to resolve `field|expand:%placeholder%` values +# from an alert when converting playbook questions to OQL. +# Left: the %token% used in a question +# Right: the event field its value is read from (event_data.-nested or bare; the module +# tries both). +# +# Example: with `src_ip: source.ip` (below), a question that writes +# `source.ip|expand: '%src_ip%'` resolves %src_ip% to the alert's source.ip at convert time. +# +# This is the global base layer. To add or override tokens edit playbook_placeholder_map_custom.yaml. +# those entries overlay this map and win on conflict. + +CommandLine: process.command_line +CurrentDirectory: process.working_directory +Image: process.executable +ImageLoaded: dll.name +ParentImage: process.parent.executable +ParentName: process.parent.name +ParentProcessGuid: process.parent.entity_id +ProcessGuid: process.entity_id +TargetFilename: file.name +TargetObject: registry.path +TargetUserName: user.target.name +User: user.name +community_id: network.community_id +dns_resolved_ip: dns.resolved_ip +document_id: soc_id +dst_ip: destination.ip +dst_port: destination.port +event_data_source_ip: source.ip +file_path: file.path +file_dirs: process.file_dirs +file_name: process.name +file_paths: process.file_paths +hostname: host.name +private_ip: network.private_ip +public_ip: network.public_ip +related_hosts: related.hosts +related_ip: related.ip +src_ip: source.ip +dns_query_name: dns.query_name +flow_id: log.id.uid +payload: network.data.decoded +rule_category: rule.category +rule_name: rule.name +rule_uuid: rule.uuid +src_port: source.port diff --git a/salt/soc/files/soc/playbook_placeholder_map_custom.yaml b/salt/soc/files/soc/playbook_placeholder_map_custom.yaml new file mode 100644 index 000000000..0d586db18 --- /dev/null +++ b/salt/soc/files/soc/playbook_placeholder_map_custom.yaml @@ -0,0 +1,14 @@ +# Custom Playbook placeholder map: %token% -> event field path. +# +# +# Left: the %token% used in a playbook question. +# Right: the event field its value is read from (event_data.-nested or bare; the module tries +# both). Note: a token that is simply named after a flat event field resolves automatically +# without an entry here - only add a mapping when the token name differs from the field name. +# +# Example: +# +# account_id: cloudflare.account_id +# +# A question that writes +# `account_id|expand: '%account_id%'` resolves %account_id% from the alert at convert time. diff --git a/salt/soc/files/soc/sigma_playbook_pipeline.yaml b/salt/soc/files/soc/sigma_playbook_pipeline.yaml new file mode 100644 index 000000000..6fcdedbb4 --- /dev/null +++ b/salt/soc/files/soc/sigma_playbook_pipeline.yaml @@ -0,0 +1,12 @@ +name: Security Onion - Playbook Pipeline +priority: 97 +transformations: + # Route string fields to their lowercase-normalized .caseless subfield so wildcard + # matches are case-insensitive. + - id: case_insensitive_string_fields + type: field_name_mapping + mapping: + process.executable: process.executable.caseless + process.parent.executable: process.parent.executable.caseless + process.command_line: process.command_line.caseless + process.parent.command_line: process.parent.command_line.caseless diff --git a/salt/soc/files/soc/sigma_so_pipeline.yaml b/salt/soc/files/soc/sigma_so_pipeline.yaml index b5bc96dc4..dee93c84e 100644 --- a/salt/soc/files/soc/sigma_so_pipeline.yaml +++ b/salt/soc/files/soc/sigma_so_pipeline.yaml @@ -63,6 +63,14 @@ transformations: rule_conditions: - type: logsource category: antivirus + # OS-agnostic process_creation scoping for product-less (NIDS/host-pivot) rules. + - id: process_creation_os_agnostic + type: add_condition + conditions: + event.category: process + rule_conditions: + - type: logsource + category: process_creation # Transforms the `Hashes` field to ECS fields # ECS fields are used by the hash fields emitted by Elastic Defend # If shipped with Elastic Agent, sysmon logs will also have hashes mapped to ECS fields @@ -108,6 +116,40 @@ transformations: - type: logsource product: windows category: driver_load + - id: ecs_fix_process_creation + type: field_name_mapping + mapping: + # bare `Hashes` (the combined-string case is broken out above) + winlog.event_data.Hashes: process.hash.sha256 + winlog.event_data.IntegrityLevel: process.Ext.token.integrity_level_name + winlog.event_data.ParentName: process.parent.name + rule_conditions: + - type: logsource + product: windows + category: process_creation + - id: ecs_fix_registry_set + type: field_name_mapping + mapping: + winlog.event_data.Details: registry.data.strings + # field rename only; EventType values (SetValue/CreateKey) still differ from + # event.action values (modification/creation) + winlog.event_data.EventType: event.action + rule_conditions: + - type: logsource + product: windows + category: registry_set + - id: ecs_fix_image_load + type: field_name_mapping + mapping: + file.path: dll.path + file.code_signature.signed: dll.code_signature.exists + winlog.event_data.Signature: dll.code_signature.subject_name + file.code_signature.status: dll.code_signature.status + winlog.event_data.Hashes: dll.hash.sha256 + rule_conditions: + - type: logsource + product: windows + category: image_load - id: linux_security_add-fields type: add_condition conditions: @@ -281,6 +323,15 @@ transformations: rule_conditions: - type: logsource category: file_event + # Scope image_load rules to Elastic Endpoint library events (event.category:library, dll.* + # populated). + - id: endpoint_image_load_add-fields + type: add_condition + conditions: + event.category: 'library' + rule_conditions: + - type: logsource + category: image_load # Maps network rules to all network logs # This targets all network logs, all services, generated from endpoints and network - id: network_add-fields diff --git a/salt/soc/soc_soc.yaml b/salt/soc/soc_soc.yaml index 19853196a..594dbf88c 100644 --- a/salt/soc/soc_soc.yaml +++ b/salt/soc/soc_soc.yaml @@ -46,7 +46,15 @@ soc: syntax: yaml file: True global: True - advanced: True + advanced: False + helpLink: security-onion-console-customization + playbook_placeholder_map_custom__yaml: + title: Playbook Placeholder Map + description: Custom mappings of Playbook %placeholder% tokens to event fields. + syntax: yaml + file: True + global: True + advanced: False helpLink: security-onion-console-customization config: licenseKey: