merge with 120 dev and fix conflicts

This commit is contained in:
m0duspwnens
2025-01-23 10:56:48 -05:00
92 changed files with 3711 additions and 528531 deletions
+9
View File
@@ -176,6 +176,15 @@ socusersroles:
- require:
- sls: manager.sync_es_users
socclientsroles:
file.managed:
- name: /opt/so/conf/soc/soc_clients_roles
- user: 939
- group: 939
- mode: 600
- allow_empty: true
- create: true
socuploaddir:
file.directory:
- name: /nsm/soc/uploads
+121 -16
View File
@@ -119,6 +119,13 @@ soc:
- identity_id
- http_request.headers.user-agent
- msg
':hydra:':
- soc_timestamp
- event.dataset
- http_request.headers.x-real-ip
- identity_id
- http_request.headers.user-agent
- msg
'::conn':
- soc_timestamp
- event.dataset
@@ -277,6 +284,27 @@ soc:
- kerberos.service
- kerberos.request_type
- log.id.uid
'::ldap':
- soc_timestamp
- event.dataset
- source.ip
- source.port
- destination.ip
- destination.port
- ldap.result
- ldap.common_name
- ldap.object
- ldap.opcode
'::ldap_search':
- soc_timestamp
- event.dataset
- source.ip
- source.port
- destination.ip
- destination.port
- ldap.result
- ldap.object
- ldap_search.filter
'::modbus':
- soc_timestamp
- event.dataset
@@ -332,6 +360,16 @@ soc:
- file.os
- file.subsystem
- log.id.fuid
'::quic':
- soc_timestamp
- event.dataset
- source.ip
- source.port
- destination.ip
- destination.port
- quic.server_name
- log.id.uid
- network.community_id
'::radius':
- soc_timestamp
- event.dataset
@@ -1311,6 +1349,8 @@ soc:
jobDir: jobs
kratos:
hostUrl:
hydra:
hostUrl:
elastalertengine:
aiRepoUrl: https://github.com/Security-Onion-Solutions/securityonion-resources
aiRepoBranch: generated-summaries-published
@@ -1318,16 +1358,49 @@ soc:
showAiSummaries: true
autoUpdateEnabled: true
autoEnabledSigmaRules:
default:
- core+critical
- securityonion-resources+critical
- securityonion-resources+high
so-eval:
- securityonion-resources+critical
- securityonion-resources+high
so-import:
- securityonion-resources+critical
- securityonion-resources+high
default: []
so-eval: []
so-import: []
enabledSigmaRules:
default: |-
# SOS - resources ruleset
- ruleset: ["securityonion-resources"]
level: ["critical", "high"]
product: ["*"]
category: ["*"]
service: ["*"]
# SigmaHQ - Core ruleset - Logsource: System events supported by Elastic Agent
- ruleset: ["core"]
level: ["critical"]
product: ["*"]
category: ["process_creation", "file_event", "registry_event", "network_connection", "dns_query"]
service: ["*"]
# SigmaHQ - Core ruleset - Logsource: Windows eventlogs
- ruleset: ["core"]
level: ["critical"]
product: ["windows"]
category: ["*"]
service: ["security", "system", "dns-client", "application"]
# SigmaHQ - Core ruleset - Logsource: misc
- ruleset: ["core"]
level: ["critical"]
product: ["*"]
category: ["antivirus"]
service: ["*"]
so-eval: |-
# SOS - resources ruleset
- ruleset: ["securityonion-resources"]
level: ["critical", "high"]
product: ["*"]
category: ["*"]
service: ["*"]
so-import: |-
# SOS - resources ruleset
- ruleset: ["securityonion-resources"]
level: ["critical", "high"]
product: ["*"]
category: ["*"]
service: ["*"]
communityRulesImportFrequencySeconds: 86400
communityRulesImportErrorSeconds: 300
failAfterConsecutiveErrorCount: 10
@@ -1400,6 +1473,7 @@ soc:
- rbac/custom_roles
userFiles:
- rbac/users_roles
- rbac/clients_roles
strelkaengine:
aiRepoUrl: https://github.com/Security-Onion-Solutions/securityonion-resources
aiRepoBranch: generated-summaries-published
@@ -1449,6 +1523,10 @@ soc:
integrityCheckFrequencySeconds: 1200
ignoredSidRanges:
- '1100000-1101000'
navigator:
intervalMinutes: 30
outputPath: /opt/sensoroni/navigator
lookbackDays: 3
client:
enableReverseLookup: false
docsUrl: /docs/
@@ -1639,23 +1717,23 @@ soc:
showSubtitle: true
- name: HTTP
description: HTTP grouped by destination port
query: 'tags:http | groupby destination.port'
query: '(tags:http OR tags:http2) | groupby destination.port'
showSubtitle: true
- name: HTTP
description: HTTP grouped by status code and message
query: 'tags:http | groupby http.status_code http.status_message'
query: '(tags:http OR tags:http2) | groupby http.status_code http.status_message'
showSubtitle: true
- name: HTTP
description: HTTP grouped by method and user agent
query: 'tags:http | groupby http.method http.useragent'
query: '(tags:http OR tags:http2) | groupby http.method http.useragent'
showSubtitle: true
- name: HTTP
description: HTTP grouped by virtual host
query: 'tags:http | groupby http.virtual_host'
query: '(tags:http OR tags:http2) | groupby http.virtual_host'
showSubtitle: true
- name: HTTP
description: HTTP with exe downloads
query: 'tags:http AND file.resp_mime_types:*exec* | groupby http.virtual_host'
query: '(tags:http OR tags:http2) AND file.resp_mime_types:*exec* | groupby http.virtual_host'
showSubtitle: true
- name: Intel
description: Intel framework hits grouped by indicator
@@ -1669,6 +1747,14 @@ soc:
description: KERBEROS grouped by service
query: 'tags:kerberos | groupby kerberos.service'
showSubtitle: true
- name: LDAP
description: LDAP grouped by source ip and result
query: 'tags:ldap | groupby source.ip ldap.result'
showSubtitle: true
- name: LDAP_SEARCH
description: LDAP_SEARCH grouped by source.ip and filter
query: 'tags:ldap_search | groupby source.ip | groupby ldap_search.filter'
showSubtitle: true
- name: MODBUS
description: MODBUS grouped by function
query: 'tags:modbus | groupby modbus.function'
@@ -1689,6 +1775,10 @@ soc:
description: PE files list
query: 'tags:pe | groupby file.machine file.os file.subsystem'
showSubtitle: true
- name: QUIC
description: QUIC connections
query: 'tags:quic | groupby quic.server_name | groupby source.ip quic.server_name destination.ip'
showSubtitle: true
- name: RADIUS
description: RADIUS grouped by username
query: 'tags:radius | groupby user.name'
@@ -1882,25 +1972,40 @@ soc:
query: 'tags:ftp | groupby ftp.command | groupby -sankey ftp.command source.ip | groupby source.ip | groupby -sankey source.ip destination.ip | groupby destination.ip | groupby destination.port | groupby destination_geo.organization_name | groupby ftp.argument | groupby ftp.user'
- name: HTTP
description: HTTP (Hyper Text Transport Protocol) network metadata
query: 'tags:http | groupby http.method | groupby -sankey http.method http.virtual_host | groupby http.virtual_host | groupby http.uri | groupby http.useragent | groupby http.status_code | groupby http.status_message | groupby file.resp_mime_types | groupby source.ip | groupby destination.ip | groupby destination.port | groupby destination_geo.organization_name'
query: '(tags:http OR tags:http2) | groupby http.method | groupby -sankey http.method http.virtual_host | groupby http.virtual_host | groupby http.uri | groupby http.useragent | groupby http.status_code | groupby http.status_message | groupby file.resp_mime_types | groupby source.ip | groupby destination.ip | groupby destination.port | groupby destination_geo.organization_name'
- name: Intel
description: Zeek Intel framework hits
query: 'tags:intel | groupby intel.indicator | groupby -sankey intel.indicator source.ip | groupby source.ip | groupby -sankey source.ip destination.ip | groupby destination.ip | groupby destination.port | groupby intel.indicator_type | groupby intel.seen_where'
- name: IPSec
description: IPSec VPN connection metadata
query: 'tags:ipsec | groupby source.ip | groupby -sankey source.ip destination.ip | groupby destination.ip | groupby destination.port | groupby destination.geo.country_name | groupby ipsec.version'
- name: IRC
description: IRC (Internet Relay Chat) network metadata
query: 'tags:irc | groupby irc.command.type | groupby -sankey irc.command.type irc.username | groupby irc.username | groupby irc.nickname | groupby irc.command.value | groupby irc.command.info | groupby source.ip | groupby destination.ip | groupby destination.port | groupby destination_geo.organization_name'
- name: Kerberos
description: Kerberos network metadata
query: 'tags:kerberos | groupby kerberos.service | groupby -sankey kerberos.service source.ip | groupby source.ip | groupby -sankey source.ip destination.ip | groupby destination.ip | groupby destination.port | groupby kerberos.client | groupby kerberos.request_type'
- name: LDAP
description: LDAP (Lightweight Directory Access Protocol) network metadata
query: 'tags:ldap | groupby source.ip | groupby destination.ip | groupby destination.port | groupby ldap.user_email | groupby ldap.property | groupby ldap.result | groupby ldap.common_name | groupby ldap.organizational_unit | groupby ldap.domain | groupby ldap.version | groupby ldap.object'
- name: LDAP_SEARCH
description: LDAP_SEARCH (Lightweight Directory Access Protocol) Search network metadata
query: 'tags:ldap_search | groupby source.ip | groupby destination.ip | groupby destination.port | groupby ldap_search.scope | groupby ldap.object | groupby ldap.domain | groupby ldap_search.filter'
- name: MySQL
description: MySQL network metadata
query: 'tags:mysql | groupby mysql.command | groupby -sankey mysql.command source.ip | groupby source.ip | groupby -sankey source.ip destination.ip | groupby destination.ip | groupby destination.port | groupby mysql.argument | groupby mysql.success | groupby mysql.response | groupby mysql.rows'
- name: NTLM
description: NTLM (New Technology LAN Manager) network metadata
query: 'tags:ntlm | groupby source.ip | groupby -sankey source.ip destination.ip | groupby destination.ip | groupby destination.port | groupby ntlm.server.dns.name | groupby ntlm.server.nb.name | groupby ntlm.server.tree.name | groupby ntlm.success | groupby source.ip | groupby destination.ip'
- name: OpenVPN
description: OpenVPN connection metadata
query: 'tags:openvpn | groupby source.ip | groupby -sankey source.ip destination.ip | groupby destination.ip | groupby destination.port | groupby destination.geo.country_name'
- name: PE
description: PE (Portable Executable) files transferred via network traffic
query: 'tags:pe | groupby file.machine | groupby -sankey file.machine file.os | groupby file.os | groupby -sankey file.os file.subsystem | groupby file.subsystem | groupby file.section_names | groupby file.is_exe | groupby file.is_64bit'
- name: QUIC
description: QUIC network metadata
query: 'tags:quic | groupby quic.server_name | groupby -sankey quic.server_name source.ip | groupby source.ip | groupby -sankey source.ip destination.ip | groupby destination.ip | groupby destination.port | groupby destination_geo.organization_name | groupby quic.server_scid | groupby quic.version | groupby quic.client_protocol'
- name: RADIUS
description: RADIUS (Remote Authentication Dial-In User Service) network metadata
query: 'tags:radius | groupby user.name | groupby -sankey user.name source.ip | groupby source.ip | groupby -sankey source.ip destination.ip | groupby destination.ip | groupby destination.port | groupby destination_geo.organization_name'
+3
View File
@@ -34,6 +34,7 @@ so-soc:
- /opt/so/log/soc/:/opt/sensoroni/logs/:rw
- /opt/so/conf/soc/soc.json:/opt/sensoroni/sensoroni.json:ro
- /opt/so/conf/soc/ai_summary_repos:/opt/sensoroni/ai_summary_repos:rw
- /opt/so/conf/navigator/layers/:/opt/sensoroni/navigator/:rw
{% if SOCMERGED.telemetryEnabled and not GLOBALS.airgap %}
- /opt/so/conf/soc/analytics.js:/opt/sensoroni/html/js/analytics.js:ro
{% endif %}
@@ -44,6 +45,7 @@ so-soc:
- /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
- /opt/so/conf/soc/soc_clients_roles:/opt/sensoroni/rbac/clients_roles:rw
- /opt/so/conf/soc/queue:/opt/sensoroni/queue:rw
- /opt/so/saltstack:/opt/so/saltstack:rw
- /opt/so/conf/soc/migrations:/opt/so/conf/soc/migrations:rw
@@ -82,6 +84,7 @@ so-soc:
- file: soccustom
- file: soccustomroles
- file: socusersroles
- file: socclientsroles
delete_so-soc_so-status.disabled:
file.uncomment:
+76 -2
View File
@@ -89,7 +89,7 @@ function manage_user() {
add)
email=$(echo "$request" | jq -r .email)
password=$(echo "$request" | jq -r .password)
role=$(echo "$request" | jq -r .role)
perm=$(echo "$request" | jq -r .role)
firstName=$(echo "$request" | jq -r .firstName)
lastName=$(echo "$request" | jq -r .lastName)
note=$(echo "$request" | jq -r .note)
@@ -97,7 +97,7 @@ function manage_user() {
response=$(echo "$password" | so-user "$op" --email "$email" --firstName "$firstName" --lastName "$lastName" --note "$note" --role "$role" --skip-sync)
exit_code=$?
;;
add|enable|disable|delete)
enable|disable|delete)
email=$(echo "$request" | jq -r .email)
log "Performing user '$op' for user '$email'"
response=$(so-user "$op" --email "$email" --skip-sync)
@@ -155,6 +155,77 @@ function manage_user() {
fi
}
function manage_client() {
id=$1
request=$2
op=$(echo "$request" | jq -r .operation)
webResponse="true"
max_tries=10
tries=0
while [[ $tries -lt $max_tries ]]; do
case "$op" in
add)
name=$(echo "$request" | jq -r .name)
note=$(echo "$request" | jq -r .note)
log "Performing client '$op' for client with name '$name' and note '$note'"
response=$(so-client "$op" --name "$name" --note "$note" --json)
exit_code=$?
webResponse=$response
;;
delete)
client_id=$(echo "$request" | jq -r .id)
log "Performing client '$op' for client '$client_id'"
response=$(so-client "$op" --id "$client_id")
exit_code=$?
;;
addperm|delperm)
client_id=$(echo "$request" | jq -r .id)
perm=$(echo "$request" | jq -r .permission)
log "Performing '$op' for client '$client_id' with permission '$perm'"
response=$(so-client "$op" --id "$client_id" --permission "$perm")
exit_code=$?
;;
generate-secret)
client_id=$(echo "$request" | jq -r .id)
log "Performing '$op' operation for client '$client_id'"
response=$(so-client "$op" --id "$client_id" --json)
exit_code=$?
webResponse=$response
;;
update)
client_id=$(echo "$request" | jq -r .id)
name=$(echo "$request" | jq -r .name)
note=$(echo "$request" | jq -r .note)
searchusername=$(echo "$request" | jq -r .searchusername)
log "Performing '$op' update for client '$client_id' with name '$name', search username '$searchusername', and note '$note'"
response=$(so-client "$op" --id "$client_id" --name "$name" --searchusername "$searchusername" --note "$note")
exit_code=$?
;;
*)
response="Unsupported client operation: $op"
exit_code=1
;;
esac
tries=$((tries+1))
if [[ "$response" == "Another process is using so-user"* ]]; then
log "Retrying after brief delay to let so-user unlock ($tries/$max_tries)"
sleep 5
else
break
fi
done
if [[ exit_code -eq 0 ]]; then
log "Successful command execution"
respond "$id" "$webResponse"
else
log "Unsuccessful command execution: $response ($exit_code)"
respond "$id" "false"
fi
}
function manage_salt() {
id=$1
request=$2
@@ -319,6 +390,9 @@ while true; do
list-minions)
list_minions "$id"
;;
manage-client)
manage_client "$id" "${request}"
;;
manage-minion)
manage_minion "$id" "${request}"
;;
+21 -20
View File
@@ -45,24 +45,25 @@ transformations:
rule_conditions:
- type: logsource
category: antivirus
# Drops the Hashes field which is specific to Sysmon logs
# Ingested sysmon logs will have the Hashes field mapped to ECS specific fields
- id: hashes_drop_sysmon-specific-field
type: drop_detection_item
# 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
- id: hashes_break_out_field
type: hashes_fields
valid_hash_algos: ["MD5", "SHA1", "SHA256", "SHA512", "IMPHASH"]
field_prefix: "file"
drop_algo_prefix: False
field_name_conditions:
- type: include_fields
fields:
- winlog.event_data.Hashes
rule_conditions:
- type: logsource
product: windows
- winlog.event_data.Hashes
- id: hashes_process-creation
type: field_name_mapping
mapping:
winlog.event_data.sha256: process.hash.sha256
winlog.event_data.sha1: process.hash.sha1
winlog.event_data.md5: process.hash.md5
winlog.event_data.Imphash: process.pe.imphash
fileSHA256: process.hash.sha256
fileSHA1: process.hash.sha1
fileMD5: process.hash.md5
fileIMPHASH: process.pe.imphash
rule_conditions:
- type: logsource
product: windows
@@ -70,10 +71,10 @@ transformations:
- id: hashes_image-load
type: field_name_mapping
mapping:
winlog.event_data.sha256: dll.hash.sha256
winlog.event_data.sha1: dll.hash.sha1
winlog.event_data.md5: dll.hash.md5
winlog.event_data.Imphash: dll.pe.imphash
fileSHA256: dll.hash.sha256
fileSHA1: dll.hash.sha1
fileMD5: dll.hash.md5
fileIMPHASH: dll.pe.imphash
rule_conditions:
- type: logsource
product: windows
@@ -81,10 +82,10 @@ transformations:
- id: hashes_driver-load
type: field_name_mapping
mapping:
winlog.event_data.sha256: dll.hash.sha256
winlog.event_data.sha1: dll.hash.sha1
winlog.event_data.md5: dll.hash.md5
winlog.event_data.Imphash: dll.pe.imphash
fileSHA256: dll.hash.sha256
fileSHA1: dll.hash.sha1
fileMD5: dll.hash.md5
fileIMPHASH: dll.pe.imphash
rule_conditions:
- type: logsource
product: windows
+9 -1
View File
@@ -35,13 +35,21 @@
{# since cases is not a valid soc config item and only used for the map files, remove it from being placed in the config #}
{% do SOCMERGED.config.server.modules.pop('cases') %}
{# set Sigma rules based on role if defined and default if not #}
{# set enabled Sigma rules based on role if defined and default if not #}
{# this particular config is deprecated as of 2.4.120 - use enabledSigmaRules instead #}
{% if GLOBALS.role in SOCMERGED.config.server.modules.elastalertengine.autoEnabledSigmaRules %}
{% do SOCMERGED.config.server.modules.elastalertengine.update({'autoEnabledSigmaRules': SOCMERGED.config.server.modules.elastalertengine.autoEnabledSigmaRules[GLOBALS.role]}) %}
{% else %}
{% do SOCMERGED.config.server.modules.elastalertengine.update({'autoEnabledSigmaRules': SOCMERGED.config.server.modules.elastalertengine.autoEnabledSigmaRules.default}) %}
{% endif %}
{# set enabled Sigma rules based on role if defined and default if not #}
{% if GLOBALS.role in SOCMERGED.config.server.modules.elastalertengine.enabledSigmaRules %}
{% do SOCMERGED.config.server.modules.elastalertengine.update({'enabledSigmaRules': SOCMERGED.config.server.modules.elastalertengine.enabledSigmaRules[GLOBALS.role]}) %}
{% else %}
{% do SOCMERGED.config.server.modules.elastalertengine.update({'enabledSigmaRules': SOCMERGED.config.server.modules.elastalertengine.enabledSigmaRules.default}) %}
{% endif %}
{# set elastalertengine.rulesRepos and strelkaengine.rulesRepos based on airgap or not #}
{% if GLOBALS.airgap %}
{% do SOCMERGED.config.server.modules.elastalertengine.update({'rulesRepos': SOCMERGED.config.server.modules.elastalertengine.rulesRepos.airgap}) %}
+33 -1
View File
@@ -215,14 +215,29 @@ soc:
duplicates: True
forcedType: string
jinjaEscaped: True
enabledSigmaRules:
default: &enabledSigmaRules
description: 'Sigma rules to automatically enable on initial import. The format is a YAML list, with the ability to filter for ruleset, level, product, category and service. Refer to the documentation for further details. These will be applied based on role if defined and default if not.'
global: True
helpLink: sigma.html
multiline: True
syntax: yaml
forcedType: string
jinjaEscaped: True
so-eval: *enabledSigmaRules
so-import: *enabledSigmaRules
autoEnabledSigmaRules:
default: &autoEnabledSigmaRules
description: 'Sigma rules to automatically enable on initial import. Format is $Ruleset+$Level - for example, for the core community ruleset and critical level rules: core+critical. These will be applied based on role if defined and default if not.'
description: 'DEPRECATED: Will be removed in a future release - use enabledSigmaRules instead.'
global: True
advanced: True
helpLink: sigma.html
so-eval: *autoEnabledSigmaRules
so-import: *autoEnabledSigmaRules
autoUpdateEnabled:
description: 'Automatically update Sigma rules on a regular basis. This will update the rules based on the configured frequency.'
global: True
advanced: True
communityRulesImportFrequencySeconds:
description: 'How often to check for new Sigma rules (in seconds). This applies to both Community Rule Packages and any configured Git repos.'
global: True
@@ -329,6 +344,10 @@ soc:
showAiSummaries:
description: Show AI summaries for Strelka rules.
global: True
autoUpdateEnabled:
description: 'Automatically update YARA rules on a regular basis. This will update the rules based on the configured frequency.'
global: True
advanced: True
autoEnabledYaraRules:
description: 'YARA rules to automatically enable on initial import. Format is $Ruleset - for example, for the default shipped ruleset: securityonion-yara'
global: True
@@ -367,6 +386,10 @@ soc:
showAiSummaries:
description: Show AI summaries for Suricata rules.
global: True
autoUpdateEnabled:
description: 'Automatically update Suricata rules on a regular basis. This will update the rules based on the configured frequency.'
global: True
advanced: True
communityRulesImportFrequencySeconds:
description: 'How often to check for new Suricata rules (in seconds).'
global: True
@@ -396,6 +419,15 @@ soc:
advanced: True
forcedType: "[]string"
helpLink: detections.html#rule-engine-status
navigator:
intervalMinutes:
description: How often to generate the Navigator Layers. (minutes)
global: True
helpLink: attack-navigator.html
lookbackDays:
description: How far back to search for ATT&CK-tagged alerts. (days)
global: True
helpLink: attack-navigator.html
client:
enableReverseLookup:
description: Set to true to enable reverse DNS lookups for IP addresses in the SOC UI.