From df538595508acbe9eea97f873866322623186200 Mon Sep 17 00:00:00 2001 From: JocLRojas Date: Fri, 14 Aug 2026 15:17:13 +0300 Subject: [PATCH 1/4] feat(filters): update bitdefender_gz filter --- .../filters/antivirus/bitdefender_gz.yaml | 391 ++++++++++++++++-- 1 file changed, 362 insertions(+), 29 deletions(-) diff --git a/definitions/filters/antivirus/bitdefender_gz.yaml b/definitions/filters/antivirus/bitdefender_gz.yaml index 393c92280..2856fec96 100644 --- a/definitions/filters/antivirus/bitdefender_gz.yaml +++ b/definitions/filters/antivirus/bitdefender_gz.yaml @@ -1,4 +1,4 @@ -# Bitdefender GravityZone filter, version 3.0.2 +# Bitdefender GravityZone filter, version 3.1.0 # Based on https://www.bitdefender.com/business/support/en/77212-237089-event-types.html # and the previous version of the same filter @@ -128,7 +128,8 @@ pipeline: pattern: '{{.greedy}}' source: log.restData - # Using grok to parse kv issued fields with space + # ---- CEF-aware extraction of space-bearing extension values ---- + - grok: patterns: - fieldName: log.2trash @@ -139,6 +140,23 @@ pipeline: pattern: '{{.greedy}}' source: log.restData + - grok: + patterns: + - fieldName: log.dvcFull + pattern: '{{.greedy}}{{.space}}' + - fieldName: log.irrelevant + pattern: '{{.greedy}}' + source: log.dvcToParse + + - grok: + patterns: + - fieldName: log.2trash + pattern: '{{.data}}dvc=' + - fieldName: log.dvcFull + pattern: '{{.greedy}}' + source: log.restData + where: '!exists("log.dvcFull")' + - grok: patterns: - fieldName: log.2trash @@ -149,24 +167,239 @@ pipeline: pattern: '{{.greedy}}' source: log.restData - # Applying grok to remove unnecessary data - grok: patterns: - - fieldName: log.deviceIps + - fieldName: log.requestFull pattern: '{{.greedy}}{{.space}}' - fieldName: log.irrelevant pattern: '{{.greedy}}' - source: log.dvcToParse + source: log.requestToParse + + - grok: + patterns: + - fieldName: log.2trash + pattern: '{{.data}}request=' + - fieldName: log.requestFull + pattern: '{{.greedy}}' + source: log.restData + where: '!exists("log.requestFull")' + + - grok: + patterns: + - fieldName: log.2trash + pattern: '{{.data}}act=' + - fieldName: log.actToParse + pattern: '{{.data}}{{.word}}\=' + - fieldName: log.irrelevant + pattern: '{{.greedy}}' + source: log.restData - grok: patterns: - - fieldName: log.requested + - fieldName: log.actFull pattern: '{{.greedy}}{{.space}}' - fieldName: log.irrelevant pattern: '{{.greedy}}' - source: log.requestToParse + source: log.actToParse + + - grok: + patterns: + - fieldName: log.2trash + pattern: '{{.data}}act=' + - fieldName: log.actFull + pattern: '{{.greedy}}' + source: log.restData + where: '!exists("log.actFull")' + + - grok: + patterns: + - fieldName: log.2trash + pattern: '{{.data}}sproc=' + - fieldName: log.sprocToParse + pattern: '{{.data}}{{.word}}\=' + - fieldName: log.irrelevant + pattern: '{{.greedy}}' + source: log.restData + + - grok: + patterns: + - fieldName: log.sprocFull + pattern: '{{.greedy}}{{.space}}' + - fieldName: log.irrelevant + pattern: '{{.greedy}}' + source: log.sprocToParse + + - grok: + patterns: + - fieldName: log.2trash + pattern: '{{.data}}sproc=' + - fieldName: log.sprocFull + pattern: '{{.greedy}}' + source: log.restData + where: '!exists("log.sprocFull")' + + - grok: + patterns: + - fieldName: log.2trash + pattern: '{{.data}}filePath=' + - fieldName: log.filePathToParse + pattern: '{{.data}}{{.word}}\=' + - fieldName: log.irrelevant + pattern: '{{.greedy}}' + source: log.restData + + - grok: + patterns: + - fieldName: log.filePathFull + pattern: '{{.greedy}}{{.space}}' + - fieldName: log.irrelevant + pattern: '{{.greedy}}' + source: log.filePathToParse + + - grok: + patterns: + - fieldName: log.2trash + pattern: '{{.data}}filePath=' + - fieldName: log.filePathFull + pattern: '{{.greedy}}' + source: log.restData + where: '!exists("log.filePathFull")' + + - grok: + patterns: + - fieldName: log.2trash + pattern: '{{.data}}BitdefenderGZDetectionName=' + - fieldName: log.BitdefenderGZDetectionNameToParse + pattern: '{{.data}}{{.word}}\=' + - fieldName: log.irrelevant + pattern: '{{.greedy}}' + source: log.restData + + - grok: + patterns: + - fieldName: log.BitdefenderGZDetectionNameFull + pattern: '{{.greedy}}{{.space}}' + - fieldName: log.irrelevant + pattern: '{{.greedy}}' + source: log.BitdefenderGZDetectionNameToParse + + - grok: + patterns: + - fieldName: log.2trash + pattern: '{{.data}}BitdefenderGZDetectionName=' + - fieldName: log.BitdefenderGZDetectionNameFull + pattern: '{{.greedy}}' + source: log.restData + where: '!exists("log.BitdefenderGZDetectionNameFull")' + + - grok: + patterns: + - fieldName: log.2trash + pattern: '{{.data}}BitdefenderGZAttackTypes=' + - fieldName: log.BitdefenderGZAttackTypesToParse + pattern: '{{.data}}{{.word}}\=' + - fieldName: log.irrelevant + pattern: '{{.greedy}}' + source: log.restData + + - grok: + patterns: + - fieldName: log.BitdefenderGZAttackTypesFull + pattern: '{{.greedy}}{{.space}}' + - fieldName: log.irrelevant + pattern: '{{.greedy}}' + source: log.BitdefenderGZAttackTypesToParse + + - grok: + patterns: + - fieldName: log.2trash + pattern: '{{.data}}BitdefenderGZAttackTypes=' + - fieldName: log.BitdefenderGZAttackTypesFull + pattern: '{{.greedy}}' + source: log.restData + where: '!exists("log.BitdefenderGZAttackTypesFull")' + + - grok: + patterns: + - fieldName: log.2trash + pattern: '{{.data}}suser=' + - fieldName: log.suserToParse + pattern: '{{.data}}{{.word}}\=' + - fieldName: log.irrelevant + pattern: '{{.greedy}}' + source: log.restData + + - grok: + patterns: + - fieldName: log.suserFull + pattern: '{{.greedy}}{{.space}}' + - fieldName: log.irrelevant + pattern: '{{.greedy}}' + source: log.suserToParse + + - grok: + patterns: + - fieldName: log.2trash + pattern: '{{.data}}suser=' + - fieldName: log.suserFull + pattern: '{{.greedy}}' + source: log.restData + where: '!exists("log.suserFull")' + + - grok: + patterns: + - fieldName: log.2trash + pattern: '{{.data}}fname=' + - fieldName: log.fnameToParse + pattern: '{{.data}}{{.word}}\=' + - fieldName: log.irrelevant + pattern: '{{.greedy}}' + source: log.restData + + - grok: + patterns: + - fieldName: log.fnameFull + pattern: '{{.greedy}}{{.space}}' + - fieldName: log.irrelevant + pattern: '{{.greedy}}' + source: log.fnameToParse + + - grok: + patterns: + - fieldName: log.2trash + pattern: '{{.data}}fname=' + - fieldName: log.fnameFull + pattern: '{{.greedy}}' + source: log.restData + where: '!exists("log.fnameFull")' + + - grok: + patterns: + - fieldName: log.2trash + pattern: '{{.data}}BitdefenderGZMalwareName=' + - fieldName: log.BitdefenderGZMalwareNameToParse + pattern: '{{.data}}{{.word}}\=' + - fieldName: log.irrelevant + pattern: '{{.greedy}}' + source: log.restData + + - grok: + patterns: + - fieldName: log.BitdefenderGZMalwareNameFull + pattern: '{{.greedy}}{{.space}}' + - fieldName: log.irrelevant + pattern: '{{.greedy}}' + source: log.BitdefenderGZMalwareNameToParse + + - grok: + patterns: + - fieldName: log.2trash + pattern: '{{.data}}BitdefenderGZMalwareName=' + - fieldName: log.BitdefenderGZMalwareNameFull + pattern: '{{.greedy}}' + source: log.restData + where: '!exists("log.BitdefenderGZMalwareNameFull")' - # Using the kv filter with default config, usefull in key-value logs - kv: fieldSplit: " " valueSplit: "=" @@ -181,12 +414,13 @@ pipeline: - rename: from: - log.src - to: origin.ip + to: target.ip - rename: from: - - log.deviceIps - to: origin.ip + - log.dvcFull + to: target.ip + where: '!exists("target.ip")' - rename: from: @@ -195,19 +429,30 @@ pipeline: - rename: from: - - log.sproc - to: target.path + - log.sprocFull + to: target.process - rename: from: - - log.filePath - to: origin.path + - log.filePathFull + to: target.path - rename: from: - - log.act + - log.actFull + - log.BitdefenderGZMainAction to: action + - rename: + from: + - log.BitdefenderGZDetectionNameFull + to: log.BitdefenderGZDetectionName + + - rename: + from: + - log.BitdefenderGZAttackTypesFull + to: log.BitdefenderGZAttackTypes + # Removing unnecessary characters - trim: function: prefix @@ -250,6 +495,89 @@ pipeline: fields: - log.processPid + - rename: + from: + - log.start + - log.end + - log.BitdefenderGZDetectionTime + to: deviceTime + + - rename: + from: + - log.severity + to: severity + + - rename: + from: + - log.BitdefenderGZComputerFQDN + to: target.domain + + - rename: + from: + - log.suserFull + to: target.user + + - rename: + from: + - log.BitdefenderGZMalwareNameFull + to: target.malware + + - rename: + from: + - log.BitdefenderGZMalwareType + to: target.malwareType + + - rename: + from: + - log.BitdefenderGZMalwareHash + - log.BitdefenderGZFileHashSha256 + to: target.sha256 + + - rename: + from: + - log.fileHash + to: target.md5 + + - rename: + from: + - log.fnameFull + to: target.filename + + - rename: + from: + - log.requestFull + to: origin.url + + - rename: + from: + - log.BitdefenderGZDetectionLocalPort + to: target.port + + - rename: + from: + - log.BitdefenderGZDetectionAttackerIp + to: origin.ip + + - rename: + from: + - log.BitdefenderGZEventSourceIP + to: origin.ip + + # Adding actionResult field to indicate whether the action was successful or failed + - add: + function: string + params: + key: actionResult + value: success + where: 'oneOf("action", ["blocked", "block", "aph_blocked", "portscan_blocked", "deleted", "disinfected", "quarantined", "restored"])' + + - add: + function: string + params: + key: actionResult + value: failed + where: 'oneOf("action", ["still present", "ignored", "no action", "reportOnly"])' + # Adding geolocation to origin ip - dynamic: plugin: com.utmstack.geolocation @@ -262,29 +590,34 @@ pipeline: - cast: fields: - origin.port + - target.port to: int - # Adding action result - - add: - function: string - params: - key: actionResult - value: "blocked" - where: 'oneOf("action", ["blocked", "quarantined", "deleted", "disinfected"])' - - # Removing unused fields + # Removing unused fields. - delete: fields: - log.0trash - log.1trash - log.2trash + - log.3trash - log.restData - log.irrelevant - - log.spt - - log.src + - log.cefVersion + - log.dvcFull + - log.dvcToParse + - log.requestToParse + - log.actToParse + - log.sprocToParse + - log.filePathToParse + - log.fnameToParse + - log.BitdefenderGZDetectionNameToParse + - log.BitdefenderGZMalwareNameToParse + - log.BitdefenderGZAttackTypesToParse + - log.suserToParse + - log.act - log.sproc - log.filePath - log.dvc - log.request - - log.dvcToParse - - log.cefVersion \ No newline at end of file + - log.suser + - log.fname \ No newline at end of file From 1bb771a2592cc2bf82671bf101db96ec04daeb21 Mon Sep 17 00:00:00 2001 From: JocLRojas Date: Fri, 14 Aug 2026 15:17:20 +0300 Subject: [PATCH 2/4] feat(rules/bitdefender_gz): update detection rules and add phishing_access_blocked --- .../antivirus_service_stopped.yaml | 44 ++++++------ .../bitdefender_gz/apt_detection.yaml | 59 ++++++++------- .../av_console_lateral_movement.yaml | 49 ++++++------- .../bitdefender_gz/av_policy_override.yaml | 53 +++++++------- .../bitdefender_gz/bootkit_detection.yaml | 56 ++++++++------- .../crypto_mining_detection.yaml | 38 ++++++---- .../email_threat_spreading.yaml | 56 ++++++--------- .../fileless_malware_detection.yaml | 56 ++++++++------- .../high_severity_threat_detection.yaml | 50 ++++++------- .../malware_outbreak_multiple_hosts.yaml | 64 +++++++++-------- .../memory_threat_detection.yaml | 49 +++++++------ .../multiple_malware_from_single_source.yaml | 68 ++++++++---------- .../network_threat_detection.yaml | 71 +++++++++---------- .../phishing_access_blocked.yaml | 41 +++++++++++ .../quarantine_failure_detection.yaml | 52 +++++++++----- .../ransomware_behavior_detection.yaml | 53 +++++++------- .../realtime_protection_disabled.yaml | 37 ++++------ .../bitdefender_gz/rootkit_detection.yaml | 42 +++++------ .../suspicious_exclusions_added.yaml | 31 ++++---- .../usb_malware_propagation.yaml | 58 ++++++++------- .../zero_day_malware_detection.yaml | 42 ++++++----- 21 files changed, 586 insertions(+), 483 deletions(-) create mode 100644 definitions/rules/antivirus/bitdefender_gz/phishing_access_blocked.yaml diff --git a/definitions/rules/antivirus/bitdefender_gz/antivirus_service_stopped.yaml b/definitions/rules/antivirus/bitdefender_gz/antivirus_service_stopped.yaml index 8c3921df3..d018da4c9 100644 --- a/definitions/rules/antivirus/bitdefender_gz/antivirus_service_stopped.yaml +++ b/definitions/rules/antivirus/bitdefender_gz/antivirus_service_stopped.yaml @@ -1,8 +1,8 @@ -# Rule version v1.0.0 +# Rule version v2.0.0 dataTypes: - antivirus-bitdefender-gz -name: Antivirus Service Stopped or Disabled +name: Bitdefender GravityZone Antivirus Service Stopped or Tampered impact: confidentiality: 2 integrity: 3 @@ -12,28 +12,30 @@ technique: "T1562.001 - Impair Defenses: Disable or Modify Tools" adversary: origin references: - https://www.bitdefender.com/business/support/en/77212-237089-event-types.html + - https://www.bitdefender.com/business/support/en/77212-237090-syslog-events.html - https://attack.mitre.org/techniques/T1562/001/ description: | - Detects when the Bitdefender antivirus service or critical security modules are stopped, disabled, or experiencing failures. This is a critical security event that could indicate malicious tampering or system issues. + Detects when the Bitdefender security agent is disabled, stopped, or under an integrity attack. Three independent signals, all directly emitted by the vendor: + + - Antitampering event with detection_technique "Callback Evasion". Bitdefender's own definition: a post-tampering incident where critical protection mechanisms have been disabled. This is the strongest possible signal that the agent is compromised. + - Antitampering event with detection_technique "Vulnerable Drivers". A driver exploitable against the security agent is present on the endpoint, which is the precursor to tampering. + - Product Modules Status event reporting that the Antimalware (malware_status) or Advanced Threat Control (avc_status) module has flipped to disabled (value 0). Next Steps: - - Verify if the service was intentionally stopped by authorized personnel - - Check system logs for any errors or crashes that may have caused the service to stop - - Look for signs of malware or unauthorized access attempts around the time of the event - - Review recent system changes or updates that might have affected the antivirus service - - If tampering is suspected, isolate the affected system and perform a forensic analysis - - Restart the Bitdefender service and ensure all modules are functioning properly - - Monitor for recurring issues that might indicate persistent threats + 1. Isolate the endpoint from the network. The agent is either disabled or being actively targeted, and normal telemetry from this host is now untrusted. + 2. Identify what changed: + - For antitampering events, log.BitdefenderGZDriverName / log.driverName names the driver and log.BitdefenderGZDetectionAction shows whether Bitdefender blocked it (deny/kill) or only observed it (reportOnly). reportOnly means the tampering succeeded. + - For modules events, log.BitdefenderGZMalwareStatus and log.BitdefenderGZAvcStatus show which protection was turned off. + 3. Correlate with logon and admin activity on the same target.host in the surrounding minutes. Legitimate module changes are rare and normally come from a scheduled policy push; ad-hoc changes deserve attention. + 4. Assume the endpoint is compromised until proven otherwise. Any threats that arrived while protection was down would not have been detected. + 5. Re-enable protection through GravityZone Control Center, do not rely on the local agent. If the module refuses to come back up, treat as a reimage candidate. where: | - (equals("log.eventType", "modules") || - equals("log.eventType", "Product ModulesStatus") || - equals("log.eventType", "registration")) && - (oneOf("log.severity", ["high", "5"]) || - contains("log.product", "disabled") || - contains("log.product", "stopped") || - (contains("log.restData", "module") && contains("log.restData", "stopped")) || - (contains("log.restData", "module") && contains("log.restData", "disabled")) || - (contains("log.restData", "av") && contains("log.restData", "failure"))) + equals("log.BitdefenderGZModule", "antitampering") || + (equals("log.BitdefenderGZModule", "modules") && + (equals("log.malware_status", "0") || + equals("log.avc_status", "0") || + equals("log.BitdefenderGZMalwareStatus", "0") || + equals("log.BitdefenderGZAvcStatus", "0"))) groupBy: - - lastEvent.log.eventType - - lastEvent.log.hostId + - target.host + - lastEvent.log.BitdefenderGZModule \ No newline at end of file diff --git a/definitions/rules/antivirus/bitdefender_gz/apt_detection.yaml b/definitions/rules/antivirus/bitdefender_gz/apt_detection.yaml index 56e8954c0..8d91eab8b 100644 --- a/definitions/rules/antivirus/bitdefender_gz/apt_detection.yaml +++ b/definitions/rules/antivirus/bitdefender_gz/apt_detection.yaml @@ -1,4 +1,4 @@ -# Rule version v1.0.0 +# Rule version v2.0.0 dataTypes: - antivirus-bitdefender-gz @@ -7,35 +7,46 @@ impact: confidentiality: 3 integrity: 3 availability: 2 -category: Command and Control -technique: "TA0011 - Application Layer Protocol" +category: Execution +technique: "T1204.002 - User Execution: Malicious File" adversary: origin references: - https://www.bitdefender.com/business/support/en/77212-237089-event-types.html - - https://attack.mitre.org/tactics/TA0011/ + - https://www.bitdefender.com/business/support/en/77212-237090-syslog-events.html + - https://attack.mitre.org/techniques/T1204/002/ + - https://attack.mitre.org/techniques/T1110/ description: | - Detects indicators of Advanced Persistent Threats including targeted attacks, sophisticated malware, and persistent threats detected by Bitdefender GravityZone's HyperDetect module. + Detects high-severity threats that Bitdefender itself classifies as targeted or sophisticated, rather than commodity malware. Three independent signals, all requiring CEF severity 8 or above: + + - HyperDetect reporting attack_type "targeted attack". HyperDetect is Bitdefender's machine-learning layer tuned specifically for targeted attacks and advanced threats, and it labels the detection itself. + - Sandbox Analyzer detection. A verdict here means an unknown payload was detonated and found malicious after evading signature-based detection, which is characteristic of tooling built for a specific target. + - Network Attack Defense reporting attack technique credentialAccess. Credential access is a core phase of a persistent intrusion, and covers Kerberos brute force and password-stealer traffic. + + Per-incident MITRE technique identifiers are carried by the vendor in log.BitdefenderGZAttCkId as an array, and are more precise than this rule's single technique tag. Next Steps: - - Investigate the affected endpoint to determine the scope of compromise - - Review process execution history and network connections from the affected system - - Check for lateral movement by examining authentication logs from the same source IP - - Isolate the affected system if active threat is confirmed - - Collect forensic artifacts including memory dumps and event logs - - Search for similar malware indicators across the environment - - Review user account activities for signs of credential compromise - - Contact security operations center if threat actors match known APT groups + 1. Determine the affected endpoint from target.host and the attacker from log.BitdefenderGZDetectionAttackerIp when the source is Network Attack Defense + 2. Read the vendor's own classification before assuming scope: + - log.BitdefenderGZAttCkId lists the MITRE techniques Bitdefender attributed to the incident + - log.BitdefenderGZDetectionName names the detection, for example Attack.Bruteforce.KERBEROS or PrivacyThreat.PasswordStealer + 3. For credentialAccess detections, treat the credentials as compromised: + - Identify the targeted accounts and force a password reset + - Review authentication logs from the attacker IP for any successful logon + - Check for Kerberos ticket anomalies if the detection names KERBEROS + 4. Establish persistence and lateral movement: + - Review process ancestry via log.BitdefenderGZDetectionName and target.path + - Correlate other events from the same target.host in the surrounding hours + - Search the environment for the same detection name on other hosts + 5. Collect forensic artifacts before remediating - memory image and endpoint logs - since a targeted intrusion warrants attribution work + 6. Isolate the endpoint if the detection action shows the threat was not blocked, then hunt for what ran while it was active where: | - equals("log.product", "Bitdefender GravityZone") && - greaterOrEqual("log.severity", 8) && + greaterOrEqual("severity", 8) && ( - contains("log.eventType", ["apt", "targeted", "advanced", "persistent", "hyperdetect"]) || - contains("log.restData", ["apt", "targeted attack", "advanced persistent", - "lazarus", "equation", "sofacy", "cozy bear", "fancy bear", - "panda", "kitten", "carbanak", "fin7", "fileless"]) || - equals("log.signatureID", "hyperdetect") - ) && - exists("log.hostId") + (equals("log.BitdefenderGZModule", "hd") && + regexMatch("log.BitdefenderGZAttackTypes", "(?i)targeted attack")) || + equals("log.BitdefenderGZModule", "network-sandboxing") || + equals("log.BitdefenderGZDetectionAttackTechnique", "credentialAccess") + ) groupBy: - - lastEvent.log.eventType - - lastEvent.log.hostId + - target.host + - lastEvent.log.BitdefenderGZDetectionName \ No newline at end of file diff --git a/definitions/rules/antivirus/bitdefender_gz/av_console_lateral_movement.yaml b/definitions/rules/antivirus/bitdefender_gz/av_console_lateral_movement.yaml index dae8107ed..57c52d9e7 100644 --- a/definitions/rules/antivirus/bitdefender_gz/av_console_lateral_movement.yaml +++ b/definitions/rules/antivirus/bitdefender_gz/av_console_lateral_movement.yaml @@ -1,8 +1,8 @@ -# Rule version v1.0.0 +# Rule version v2.0.0 dataTypes: - antivirus-bitdefender-gz -name: Bitdefender Console Used for Lateral Movement +name: Bitdefender GravityZone Task Burst Across Endpoints impact: confidentiality: 3 integrity: 3 @@ -11,31 +11,32 @@ category: Lateral Movement technique: "T1072 - Software Deployment Tools" adversary: origin references: - - https://attack.mitre.org/techniques/T1072/ - https://www.bitdefender.com/business/support/en/77212-237089-event-types.html + - https://www.bitdefender.com/business/support/en/77212-237090-syslog-events.html + - https://attack.mitre.org/techniques/T1072/ description: | - Detects when the Bitdefender GravityZone management console is potentially being used to push malicious policies, scripts, or tasks to managed endpoints, indicating a compromised admin account being leveraged for lateral movement. + Detects a burst of Bitdefender GravityZone task deployments across many endpoints in a short window, which is the observable trace of a compromised admin console being used to push activity to managed machines. Bitdefender's own management console is a first-class software deployment tool by MITRE's definition, so its abuse is T1072. + + A single task event is normal operational activity. Three or more distinct endpoints receiving tasks from the same admin identity within an hour is the shape of console-driven lateral movement. Next Steps: - 1. Review all recent task and policy deployments from the console - 2. Identify the admin account used and verify its legitimacy - 3. Check for unusual login patterns to the GravityZone console - 4. Review the content of pushed policies for malicious configurations - 5. Suspend the admin account if compromise is suspected - 6. Audit all managed endpoints for signs of compromise -where: | - (contains("log.message", ["remote task", "deploy", "push policy", "execute script"]) || - (contains("log.message", "task") && contains("log.message", "created") && - (contains("log.message", "scan") || contains("log.message", "install") || - contains("log.message", "uninstall") || contains("log.message", "execute")))) && - exists("log.severity") -afterEvents: - - with: - - field: log.hostId + 1. Identify the admin identity via log.BitdefenderGZUserName or the user object in the task. Correlate with authentication-audit events from the same identity for logon location and browser. + 2. Read log.BitdefenderGZTaskName and log.BitdefenderGZTaskType. Scan and update tasks are routine; script execution, arbitrary install, and uninstall tasks deserve scrutiny. + 3. List every target.host that received a task in this window and treat the set as the potentially-affected estate, not each host individually. + 4. Cross-check against the change control system. A legitimate task burst normally has a ticket; an ad-hoc burst outside a change window is the strongest indicator. + 5. Suspend the admin account and rotate its credentials before deciding whether it was compromised or misused. Then audit every endpoint that received a task for signs of the tasks having succeeded. + 6. Review Control Center authentication logs for the source IP behind the admin session. External or unusual geographies for the admin login argue for an account compromise rather than an insider. +where: equals("log.BitdefenderGZModule", "task-status") +correlation: + within: 1h + count: 3 + with: + - field: log.BitdefenderGZModule operator: filter_term - value: '{{.log.hostId}}' - within: 30m - count: 10 + value: "task-status" + - field: target.host + operator: must_not_term + value: "{{.target.host}}" groupBy: - - lastEvent.log.eventType - - lastEvent.log.hostId + - target.host + - lastEvent.log.BitdefenderGZTaskName \ No newline at end of file diff --git a/definitions/rules/antivirus/bitdefender_gz/av_policy_override.yaml b/definitions/rules/antivirus/bitdefender_gz/av_policy_override.yaml index 3593c685b..0ed5cdcaf 100644 --- a/definitions/rules/antivirus/bitdefender_gz/av_policy_override.yaml +++ b/definitions/rules/antivirus/bitdefender_gz/av_policy_override.yaml @@ -1,8 +1,8 @@ -# Rule version v1.0.0 +# Rule version v2.0.0 dataTypes: - antivirus-bitdefender-gz -name: Bitdefender AV Policy Weakened +name: Bitdefender GravityZone Protection Module Disabled impact: confidentiality: 3 integrity: 3 @@ -12,31 +12,36 @@ technique: "T1562.001 - Impair Defenses: Disable or Modify Tools" adversary: origin references: - https://www.bitdefender.com/business/support/en/77212-237089-event-types.html + - https://www.bitdefender.com/business/support/en/77212-237090-syslog-events.html - https://attack.mitre.org/techniques/T1562/001/ description: | - Detects when Bitdefender GravityZone antivirus policies are weakened by administrators, such as disabling real-time protection, reducing scan aggressiveness, or adding broad exclusions. This could indicate a compromised admin account or insider threat. + Detects a Bitdefender GravityZone protection module transitioning to disabled on an endpoint. The vendor reports this in two ways, both of which fire this rule: + + - Product Modules Status (module=modules) with any of the protection flags set to 0. The doc-defined status keys are malware_status (Antimalware on-access), avc_status (Advanced Threat Control), pu_status (Anti-Phishing), dlp_status (Data Protection), app_control_status (Application Control), patch_management, and the exchange_* variants. A 0 means the module is currently off. + - Antitampering (Callback Evasion) fires when critical protection mechanisms have been disabled by a post-tampering incident. + + This does not catch every policy edit - adding scan exclusions or narrowing content filtering categories only reaches the Control Center audit log. It catches the highest-impact edits: turning a whole protection module off. Next Steps: - 1. Identify the administrator who modified the policy - 2. Verify the policy change was authorized through change management - 3. Review the specific settings that were weakened - 4. Check for concurrent suspicious activity on managed endpoints - 5. Restore the previous policy configuration if unauthorized - 6. Review admin account access logs for compromise indicators + 1. Identify who was authorised to change the policy. Cross-check the modules-status timestamp against the Control Center audit log for policy pushes to this endpoint's group. + 2. Read which module was disabled: log.BitdefenderGZModule tells you the event, and the specific status key (log.malware_status, log.avc_status, etc.) tells you what turned off. Antimalware and ATC being off is a live-fire situation; the others are lower-severity but still deserve verification. + 3. If antitampering fired, treat the endpoint as actively targeted rather than mis-configured. detection_technique will be Callback Evasion or Vulnerable Drivers. + 4. Restore the previous policy configuration from the Control Center if the change was unauthorised. Do not rely on the local agent to accept a re-enable; verify with the next modules-status event. + 5. Review activity on the endpoint during the disabled window - anything that arrived while protection was off would not have been detected. + 6. Rotate the credentials of any admin account that could have pushed the change. where: | - (contains("log.message", ["policy", "configuration", "setting"]) && - (contains("log.message", ["disabled", "weakened", "reduced", "lowered", "excluded"]) || - (contains("log.message", "real-time") && contains("log.message", "off")) || - (contains("log.message", "exclusion") && contains("log.message", "added")) || - (contains("log.message", "protection") && contains("log.message", "disabled")))) && - exists("log.severity") -afterEvents: - - with: - - field: log.hostId - operator: filter_term - value: '{{.log.hostId}}' - within: 1h - count: 3 + equals("log.BitdefenderGZModule", "antitampering") || + (equals("log.BitdefenderGZModule", "modules") && + (equals("log.malware_status", "0") || + equals("log.avc_status", "0") || + equals("log.pu_status", "0") || + equals("log.dlp_status", "0") || + equals("log.app_control_status", "0") || + equals("log.BitdefenderGZMalwareStatus", "0") || + equals("log.BitdefenderGZAvcStatus", "0") || + equals("log.BitdefenderGZPuStatus", "0") || + equals("log.BitdefenderGZDlpStatus", "0") || + equals("log.BitdefenderGZAppControlStatus", "0"))) groupBy: - - lastEvent.log.eventType - - lastEvent.log.hostId + - target.host + - lastEvent.log.BitdefenderGZModule \ No newline at end of file diff --git a/definitions/rules/antivirus/bitdefender_gz/bootkit_detection.yaml b/definitions/rules/antivirus/bitdefender_gz/bootkit_detection.yaml index c4e7bdbe6..97ed5259f 100644 --- a/definitions/rules/antivirus/bitdefender_gz/bootkit_detection.yaml +++ b/definitions/rules/antivirus/bitdefender_gz/bootkit_detection.yaml @@ -1,39 +1,47 @@ -# Rule version v1.0.0 +# Rule version v2.0.0 dataTypes: - antivirus-bitdefender-gz -name: Bootkit/UEFI Threat Detection +name: Bitdefender GravityZone Bootkit or UEFI Threat Detected impact: confidentiality: 3 integrity: 3 availability: 3 -category: Defense Evasion, Persistence -technique: "T1542.001 - Boot or Logon Autostart Execution: System Firmware" +category: Defense Evasion +technique: "T1542.001 - Pre-OS Boot: System Firmware" adversary: origin references: + - https://www.bitdefender.com/business/support/en/77212-237089-event-types.html + - https://www.bitdefender.com/business/support/en/77212-237090-syslog-events.html - https://attack.mitre.org/techniques/T1542/001/ - - https://www.bitdefender.com/business/support/en/77209-135324-event-types.html description: | - Detects bootkit or UEFI-level threats that attempt to persist at the firmware level and compromise the boot process. These threats can survive system reinstalls and bypass traditional security measures by infecting the system firmware. + Detects a threat classified by Bitdefender as living at the boot layer: boot sector, UEFI/BIOS, or a kernel-mode rootkit. These persist across reinstalls and survive credential rotation, so a single hit is a full-endpoint incident. + + Three complementary signals, from any of the antimalware engines (Antimalware, Advanced Threat Control, HyperDetect): + - malwareType classified as "boot", which is a vendor-defined value for boot-sector threats. + - Detection name in a bootkit family: Bootkit.*, Rootkit.*, Trojan.Boot.*, TDSS.*, Alureon.*, ZeroAccess.*, Necurs.*, Sinowal.*. + - The artefact sits in a boot region: \EFI\, /EFI/, \boot\, /boot/, or references the Master Boot Record. Next Steps: - - Isolate the affected system immediately to prevent spread - - Review system boot logs and firmware settings for modifications - - Check for other malware detections on the same host in the past 24-48 hours - - Verify system integrity using offline scanning tools - - Consider reimaging the system and updating firmware/UEFI - - Enable Secure Boot if not already enabled - - Review user activity and recently installed software on the affected system - - Document the infection for incident response reporting - - Check if other systems with similar hardware/firmware versions are affected + 1. Isolate the endpoint immediately. Bootkits control the boot process; the running OS cannot be trusted to report accurately. + 2. Do not reboot into the local OS. If forensic capture is required, boot from external media. + 3. Determine what fired the detection: + - target.malware and log.BitdefenderGZDetectionName give the family name and align with public IOCs. + - target.path names the affected boot region. + - actionResult tells you whether Bitdefender removed the artefact. Boot region cleanup often fails from within the OS - actionResult "failed" is the expected outcome and does not mean the detection was wrong. + 4. Verify firmware integrity independently: dump BIOS/UEFI, compare against a known-good, check Secure Boot state. + 5. Reimage from trusted media and reflash firmware. Do not try to disinfect the running OS. + 6. Enable Secure Boot for all hosts with the same hardware baseline if it was not already on. Bootkit persistence relies on Secure Boot being off or being defeated. + 7. Hunt the estate for target.sha256 - any other endpoint reporting the same hash without firing this rule is a coverage gap, not proof of cleanliness. where: | - equals("log.eventType", "av") && - greaterOrEqual("log.severity", 8) && - ( - contains("log.requested", ["boot", "uefi", "rootkit", "firmware"]) || - contains("log.restData", ["boot", "uefi", "rootkit", "firmware", - "\\EFI\\", "/EFI/", "\\boot\\", "/boot/"]) - ) + oneOf("log.BitdefenderGZModule", ["av", "avc", "hd"]) && + (equals("log.BitdefenderGZMalwareType", "boot") || + regexMatch("log.BitdefenderGZDetectionName", + "(?i)(bootkit|rootkit|uefi|tdss|alureon|zeroaccess|necurs|rustock|sinowal|trojan\\.boot|master.?boot)") || + regexMatch("target.malware", + "(?i)(bootkit|rootkit|uefi|tdss|alureon|zeroaccess|necurs|rustock|sinowal|trojan\\.boot|master.?boot)") || + regexMatch("target.path", + "(?i)(\\\\efi\\\\|/efi/|\\\\boot\\\\|/boot/|master\\.?boot\\.?record|mbr)")) groupBy: - - lastEvent.log.hostId - - lastEvent.log.severity + - target.host + - target.malware \ No newline at end of file diff --git a/definitions/rules/antivirus/bitdefender_gz/crypto_mining_detection.yaml b/definitions/rules/antivirus/bitdefender_gz/crypto_mining_detection.yaml index e3d9b3cad..1b4a8f01e 100644 --- a/definitions/rules/antivirus/bitdefender_gz/crypto_mining_detection.yaml +++ b/definitions/rules/antivirus/bitdefender_gz/crypto_mining_detection.yaml @@ -1,8 +1,8 @@ -# Rule version v1.0.0 +# Rule version v2.0.0 dataTypes: - antivirus-bitdefender-gz -name: Crypto-Mining Detection +name: Bitdefender GravityZone Crypto Mining Detected impact: confidentiality: 2 integrity: 2 @@ -12,16 +12,30 @@ technique: "T1496 - Resource Hijacking" adversary: origin references: - https://www.bitdefender.com/business/support/en/77212-237089-event-types.html + - https://www.bitdefender.com/business/support/en/77212-237090-syslog-events.html - https://attack.mitre.org/techniques/T1496/ -description: "Detects cryptocurrency mining activities including miners, coin miners, and cryptojacking attempts detected by Bitdefender GravityZone.\n\nNext Steps:\n- Review the affected endpoint details (hostname, IP) to identify the compromised system\n- Check CPU and memory usage patterns on the affected system for unusual spikes\n- Look for network connections to known mining pools or suspicious outbound traffic\n- Search for related processes running with names like xmrig, minerd, cgminer, or bfgminer\n- Review recent file downloads and installations on the affected system\n- Check for persistence mechanisms (scheduled tasks, startup items, services)\n- Isolate the affected system if active mining is confirmed\n- Run a full system scan with updated definitions\n- Consider reimaging the system if compromise is extensive" +description: | + Detects cryptocurrency mining that Bitdefender itself classified as such, from any of three signals: + + - An antimalware, ATC or HyperDetect detection whose family name calls it a coin miner: CoinMiner, CryptoMiner, XMRig, Monero, Cryptonight, JsCoinminer, Coinhive. + - A HyperDetect verdict with attack_type "grayware" and a name matching the miner families above. HyperDetect's grayware label is where cryptojacking often lands because miners are technically not classical malware. + - Content Control blocking a URL for a known mining infrastructure host (coinhive, xmrig pools, minepool, nicehash, monerohash). + + Cryptojacking is not just theft of CPU. A running miner is confirmation that arbitrary code executed on the endpoint, so the operator can equally choose to run anything else next. + + Next Steps: + 1. Identify the process: target.process and target.path if the antimalware engine caught it, or origin.url if Content Control blocked the pool. + 2. Kill the miner process only after you have grabbed its command line - many droppers restart the miner under a new name. + 3. Look for persistence: scheduled tasks, run keys, services, cron jobs and startup items on the endpoint. The miner did not install itself; something else placed it there. + 4. Check every host the same target.user touched. Cryptojacking is opportunistic and often distributed via user-mode delivery. + 5. Verify that no data was staged for exfiltration in the same session. A "just mining" verdict without checking is unsafe. + 6. Block the mining pool host at the perimeter and add its hash to blocklists across the estate before closing. where: | - equals("log.productVendor", "Bitdefender") && - equals("log.product", "GravityZone") && - ( - contains("log.eventType", ["miner", "coin", "crypto", "CoinMiner"]) || - contains("log.requested", ["miner", "coin", "xmr", "monero", "bitcoin", - "ethereum", "xmrig", "minerd", "cgminer", "bfgminer", "coinhive"]) - ) + oneOf("log.BitdefenderGZModule", ["av", "avc", "hd"]) && + (regexMatch("log.BitdefenderGZDetectionName", "(?i)(coin.?miner|crypto.?miner|xmrig|monero|cryptonight|coinhive|jscoinminer|bitcoin.?miner)") || + regexMatch("target.malware", "(?i)(coin.?miner|crypto.?miner|xmrig|monero|cryptonight|coinhive|jscoinminer|bitcoin.?miner)")) || + (equals("log.BitdefenderGZModule", "uc") && + regexMatch("origin.url", "(?i)(coinhive|xmrig|minepool|nicehash|monerohash|nanopool|supportxmr)")) groupBy: - - adversary.host - - adversary.ip + - target.host + - target.malware \ No newline at end of file diff --git a/definitions/rules/antivirus/bitdefender_gz/email_threat_spreading.yaml b/definitions/rules/antivirus/bitdefender_gz/email_threat_spreading.yaml index 6301ed8ad..83d970860 100644 --- a/definitions/rules/antivirus/bitdefender_gz/email_threat_spreading.yaml +++ b/definitions/rules/antivirus/bitdefender_gz/email_threat_spreading.yaml @@ -1,47 +1,37 @@ -# Rule version v1.0.0 +# Rule version v2.0.0 dataTypes: - antivirus-bitdefender-gz -name: Email-Based Threat Spreading +name: Bitdefender GravityZone Malware Detected on Exchange Server impact: confidentiality: 3 integrity: 3 availability: 2 category: Initial Access -technique: "T1566 - Phishing" +technique: "T1566.001 - Phishing: Spearphishing Attachment" adversary: origin references: - - https://attack.mitre.org/techniques/T1566/ - - https://www.bitdefender.com/business/support/en/77209-135324-event-types.html + - https://www.bitdefender.com/business/support/en/77212-237089-event-types.html + - https://www.bitdefender.com/business/support/en/77212-237090-syslog-events.html + - https://attack.mitre.org/techniques/T1566/001/ description: | - Detects email-based malware spreading including phishing attempts, malicious attachments, and email-borne threats through Bitdefender's Exchange protection. This rule triggers on Exchange-specific malware events and monitors for patterns of email-based threats. + Detects malware found by Bitdefender on an Exchange server. A mail server detection is more urgent than the same malware on a workstation for two reasons: the message may already have been delivered to other recipients, and a mail server is a high-value target whose compromise exposes the organisation's correspondence. Next Steps: - 1. Investigate the affected email and sender: - - Check the sender's email address and domain reputation - - Review email headers for spoofing indicators - - Analyze attachment hash values if present in log.restData - - Check log.severity for threat level assessment - 2. Review related events: - - Look for similar events from the same sender or to other recipients - - Check if the email was delivered or blocked - - Verify if any users clicked links or opened attachments - - Search for the same signatureID across other hosts - 3. Remediation actions: - - If delivered, recall the email from all recipients immediately - - Reset credentials if phishing was successful - - Block sender domain/IP at email gateway - - Update email security policies if needed - - Scan affected endpoints for malware if attachments were opened - - Update Bitdefender Exchange protection rules - 4. Investigation commands: - - Check host status: Verify log.hostId endpoint protection status - - Review product version: Ensure log.productVersion is up to date - - Analyze event patterns: Look for unusual log.eventType combinations -where: | - oneOf("log.eventType", ["exchange-malware", "exchange-user-credentials", "exchange-organization-info"]) || - (contains("log.eventType", "exchange") && equals("log.severity", "High")) || - (contains("log.product", "Exchange") && contains("log.eventType", ["malware", "phishing"])) + 1. Determine the blast radius before cleaning anything: + - Identify the message and every recipient it reached, not just the one that triggered the detection + - A single detection on the server usually means the same attachment sits in several mailboxes + 2. Check whether the message was delivered or quarantined at the gateway - actionResult tells you whether Bitdefender stopped it + 3. Pull the message back from every mailbox it reached before notifying users, so nobody opens it while you are still working + 4. Identify who already opened it: + - Correlate endpoint AntiMalware detections for the same target.sha256 across the estate + - Any endpoint that reported the same hash is a confirmed opener and needs its own investigation + 5. Look at the sender and the campaign: + - A spoofed internal sender means someone's mailbox is already compromised + - Check whether other messages from the same source reached the organisation + 6. Review the Exchange server itself - a detection on the server is a reason to verify the server's own integrity, not only the message + 7. Feed the sender, subject and hash into mail gateway blocking before closing +where: equals("log.BitdefenderGZModule", "exchange-malware") groupBy: - - lastEvent.log.hostId - - lastEvent.log.signatureID + - target.host + - target.malware \ No newline at end of file diff --git a/definitions/rules/antivirus/bitdefender_gz/fileless_malware_detection.yaml b/definitions/rules/antivirus/bitdefender_gz/fileless_malware_detection.yaml index 9d03d55df..230e037db 100644 --- a/definitions/rules/antivirus/bitdefender_gz/fileless_malware_detection.yaml +++ b/definitions/rules/antivirus/bitdefender_gz/fileless_malware_detection.yaml @@ -1,42 +1,46 @@ -# Rule version v1.0.0 +# Rule version v2.0.0 dataTypes: - antivirus-bitdefender-gz -name: Fileless Malware Detection +name: Bitdefender GravityZone Fileless Attack Detected impact: - confidentiality: 2 - integrity: 2 + confidentiality: 3 + integrity: 3 availability: 2 -category: Defense Evasion, Privilege Escalation +category: Defense Evasion technique: "T1055 - Process Injection" adversary: origin references: - https://www.bitdefender.com/business/support/en/77212-237089-event-types.html + - https://www.bitdefender.com/business/support/en/77212-237090-syslog-events.html - https://attack.mitre.org/techniques/T1055/ - https://www.bitdefender.com/en-us/business/gravityzone-platform/fileless-attack-defense description: | - Detects fileless malware attacks including PowerShell-based attacks, memory injection, and living-off-the-land techniques using Bitdefender GravityZone's HyperDetect and Command-Line Scanner modules. These attacks execute malicious code directly in memory without writing to disk, making them harder to detect with traditional antivirus. + Detects fileless attacks that Bitdefender identified as such, from any of three signals: + + - HyperDetect (hd) with is_fileless_attack = true. This is a vendor-authoritative label. HyperDetect specifically inspects in-memory behaviour and the boolean is the flag it sets when memory-resident execution was observed. + - HyperDetect (hd) with attack_type in {exploits, targeted attack}. These categories cover memory injection, ROP chains and reflective loading even without the fileless boolean. + - Advanced Threat Control (avc) firing on a process whose command line invokes a living-off-the-land binary: powershell -enc, mshta, wscript/cscript, regsvr32, rundll32, Invoke- / IEX / DownloadString cmdlets. avc is behavioural, so a match on the extracted command line means the LOLBin actually ran. + + A fileless verdict is materially harder to remediate than a file-based one because there is nothing on disk to quarantine. The endpoint has to be treated as though the payload might still be resident until proven otherwise. Next Steps: - - Isolate the affected endpoint immediately to prevent lateral movement - - Review process tree to identify the parent process and initial attack vector - - Check for PowerShell command history and script blocks (Event ID 4104) - - Look for suspicious WMI activity or unusual process spawning patterns - - Examine network connections from the affected process - - Collect memory dump if the process is still running - - Review user activity to determine if account is compromised - - Apply security patches if exploitation of vulnerability is suspected + 1. Capture a memory image before rebooting or reconnecting. On reboot the residency is lost, and with it most of the forensic value. + 2. Read the vendor's classification: + - log.BitdefenderGZAttackType tells you how HyperDetect classified the payload. + - log.BitdefenderGZProcessCommandLine and log.BitdefenderGZProcessInfoPath show what actually ran. + - target.process is the caught process; log.BitdefenderGZParentProcessPath is where it came from. + 3. Look upstream from the parent process. Fileless payloads are almost always the second stage - the initial delivery is either a phishing document, an exploit, or credential-based access. + 4. Isolate the endpoint if the detection came from avc, since a behavioural verdict means the code actually executed. + 5. Search other endpoints for the same parent process ancestry, not the same hash. Fileless payloads reuse infrastructure and technique, not artefacts. + 6. Do not close on a clean scan alone. A signature-less on-disk scan does not disprove a memory-only threat. Verify with the memory image and confirm no anomalous processes remain on reboot. where: | - oneOf("log.eventType", ["fileless_attack", "hyperdetect_fileless", "command_line_scanner"]) || - ( - equals("log.eventType", "malware_detected") && - contains("log.restData", ["fileless", "memory injection", "powershell", - "wscript", "cscript", "mshta", "regsvr32", "rundll32"]) - ) || - ( - oneOf("log.severity", ["HIGH", "CRITICAL"]) && - contains("log.restData", "code injection") - ) + (equals("log.BitdefenderGZModule", "hd") && + (equals("log.is_fileless_attack", "true") || + equals("log.BitdefenderGZIsFilelessAttack", "true") || + regexMatch("log.BitdefenderGZAttackType", "(?i)(exploits|targeted attack|suspicious files)"))) || + (equals("log.BitdefenderGZModule", "avc") && + regexMatch("log.BitdefenderGZProcessCommandLine", "(?i)(powershell.*-e(nc|ncodedcommand)|mshta\\s|wscript\\s|cscript\\s|regsvr32\\s|rundll32\\s|invoke-|iex\\s|downloadstring|frombase64string)")) groupBy: - - lastEvent.log.eventType - - lastEvent.log.hostId + - target.host + - target.process \ No newline at end of file diff --git a/definitions/rules/antivirus/bitdefender_gz/high_severity_threat_detection.yaml b/definitions/rules/antivirus/bitdefender_gz/high_severity_threat_detection.yaml index 8f7ab21a6..c2626b7d8 100644 --- a/definitions/rules/antivirus/bitdefender_gz/high_severity_threat_detection.yaml +++ b/definitions/rules/antivirus/bitdefender_gz/high_severity_threat_detection.yaml @@ -1,8 +1,8 @@ -# Rule version v1.0.0 +# Rule version v2.0.0 dataTypes: - antivirus-bitdefender-gz -name: Bitdefender GravityZone High Severity Threat Detection +name: Bitdefender GravityZone High Severity Malware Detection impact: confidentiality: 3 integrity: 3 @@ -12,31 +12,31 @@ technique: "T1204.002 - User Execution: Malicious File" adversary: origin references: - https://www.bitdefender.com/business/support/en/77212-237089-event-types.html + - https://www.bitdefender.com/business/support/en/77212-237090-syslog-events.html - https://attack.mitre.org/techniques/T1204/002/ - - https://attack.mitre.org/techniques/T1055/ description: | - Detects high-severity malware threats identified by Bitdefender GravityZone that require immediate attention. This rule triggers on severity levels 8-10, which indicate critical threats such as trojans, ransomware, rootkits, or other advanced malware. + Detects a high-severity malware finding from any of Bitdefender's three antimalware engines: Antimalware (signature and on-access), Advanced Threat Control (behavioural) and HyperDetect (machine learning tuned for advanced threats). + + This is the baseline malware alert for the data source. Whether the threat was actually neutralised is a separate question, answered by actionResult: a value of "failed" means it is still on the endpoint, and that case has its own rule with a higher impact. Next Steps: - 1. Immediately isolate the affected endpoint(s) from the network to prevent lateral movement - 2. Review the threat details in Bitdefender GravityZone console: - - Check threat name and malware type from the event details - - Verify the affected file path and process information - - Review the action taken by Bitdefender (quarantine, delete, etc.) - 3. Investigate the source of infection: - - Check origin.ip and origin.path for the malware source - - Review recent user activity and email attachments - - Look for similar threats on other endpoints - 4. Perform forensic analysis: - - Collect memory dumps if rootkit or fileless malware is suspected - - Check for persistence mechanisms (registry, scheduled tasks, services) - - Review network connections from the affected host - 5. Remediation actions: - - Ensure Bitdefender has successfully cleaned/quarantined the threat - - Run full system scan on affected and neighboring systems - - Update antivirus signatures and security policies - - Consider reimaging if system integrity is compromised -where: oneOf("log.severity", ["8", "9", "10"]) && oneOf("log.eventType", ["avc", "malware_detected", "av"]) + 1. Read the outcome before deciding how urgent this is: + - actionResult "success" with action blocked, deleted, quarantined or disinfected means the control worked; treat this as an exposure and hygiene finding + - actionResult "failed" means the threat is live and the endpoint should be isolated immediately + 2. Identify what was found: + - target.malware and target.malwareType give the threat name and whether it is a file or a process + - target.sha256 and target.md5 let you pivot to threat intelligence and across the estate + - target.path is the artefact, target.process is the process that touched it + 3. Establish how it arrived: + - origin.url is populated when the threat came in over the web + - target.user identifies who was logged on, which usually explains the delivery path + - Correlate with Antiphishing events on the same target.host around deviceTime + 4. Look for related activity on the same host in the surrounding hours - a single detection is often one step of a longer chain + 5. Hunt the estate for the same target.sha256 to find endpoints where nothing was reported + 6. Follow up on the endpoint: + - Run a full scan and confirm it comes back clean + - Check that signatures were current at deviceTime, using log.BitdefenderGZSignaturesNumber +where: oneOf("log.BitdefenderGZModule", ["av", "avc", "hd"]) && greaterOrEqual("severity", 8) groupBy: - - lastEvent.log.signatureID - - lastEvent.log.syslogHostIP + - target.host + - target.malware \ No newline at end of file diff --git a/definitions/rules/antivirus/bitdefender_gz/malware_outbreak_multiple_hosts.yaml b/definitions/rules/antivirus/bitdefender_gz/malware_outbreak_multiple_hosts.yaml index 9b8021425..de21f25a7 100644 --- a/definitions/rules/antivirus/bitdefender_gz/malware_outbreak_multiple_hosts.yaml +++ b/definitions/rules/antivirus/bitdefender_gz/malware_outbreak_multiple_hosts.yaml @@ -1,47 +1,49 @@ -# Rule version v1.0.0 +# Rule version v2.0.0 dataTypes: - antivirus-bitdefender-gz -name: Malware Outbreak Detection - Multiple Hosts Infected +name: Bitdefender GravityZone Malware Outbreak Across Endpoints impact: confidentiality: 3 integrity: 3 availability: 3 -category: Command and Control -technique: "T1105 - Ingress Tool Transfer" +category: Lateral Movement +technique: "T1080 - Taint Shared Content" adversary: origin references: - https://www.bitdefender.com/business/support/en/77212-237089-event-types.html - - https://attack.mitre.org/techniques/T1105/ + - https://www.bitdefender.com/business/support/en/77212-237090-syslog-events.html + - https://attack.mitre.org/techniques/T1080/ description: | - Detects when the same malware signature or threat is detected on multiple endpoints within a short time window. This pattern indicates a potential malware outbreak spreading across the network environment. + Detects the same malware appearing on more than one endpoint within a day, which is the signature of something spreading rather than an isolated infection: a shared network location, a mass phishing campaign, tainted removable media, or genuine lateral movement. + + The correlation deliberately excludes the originating host, so repeated detections of one threat on a single machine do not look like an outbreak - that case belongs to multiple_malware_from_single_source. Next Steps: - 1. Immediately isolate affected endpoints to prevent further spread - 2. Identify the malware signature ID and research its capabilities and impact - 3. Check network logs for lateral movement patterns between infected hosts - 4. Review the initial infection vector - check email logs, web proxy logs, and USB device usage - 5. Verify antivirus definitions are up-to-date on all endpoints - 6. Conduct memory and disk forensics on patient zero if identifiable - 7. Check for persistence mechanisms on infected systems - 8. Review domain controller and authentication logs for credential compromise - 9. Document all affected systems and timeline for incident response - 10. Consider engaging incident response team if outbreak involves critical systems + 1. List every target.host reporting this target.malware and treat it as one incident, not several + 2. Identify the common vector by comparing the affected endpoints: + - A shared target.path, especially a UNC or mapped drive, points at a tainted network share that must be taken offline + - The same target.user across hosts points at a compromised account + - origin.url in common points at a web or phishing campaign + - Different departments with no shared resource suggests removable media or lateral movement + 3. Check the remediation state on each host: any event with actionResult "failed" is a live foothold and gets priority + 4. Contain the vector before cleaning the endpoints. Cleaning machines while the source stays reachable just resets the clock + 5. Hunt for the target.sha256 across the whole estate, including hosts that reported nothing - absence of a detection is not absence of the file + 6. Reassess coverage: if some endpoints detected it and others did not, check agent health and signature currency on the silent ones + 7. Keep the incident open until a full day passes with no new host reporting the same malware where: | - equals("log.eventType", "AntiMalware") && - oneOf("log.severity", ["4", "5"]) && - exists("log.signatureID") && - exists("log.syslogHostIP") -afterEvents: - - with: - - field: log.signatureID - operator: filter_term - value: '{{.log.signatureID}}' - - field: log.eventType + oneOf("log.BitdefenderGZModule", ["av", "avc", "hd"]) && + greaterOrEqual("severity", 8) && + exists("target.malware") +correlation: + within: 24h + count: 2 + with: + - field: target.malware operator: filter_term - value: "AntiMalware" - within: 2h - count: 10 + value: "{{.target.malware}}" + - field: target.host + operator: must_not_term + value: "{{.target.host}}" groupBy: - - lastEvent.log.signatureID - - lastEvent.log.syslogHostIP + - target.malware \ No newline at end of file diff --git a/definitions/rules/antivirus/bitdefender_gz/memory_threat_detection.yaml b/definitions/rules/antivirus/bitdefender_gz/memory_threat_detection.yaml index 4d2be2d93..caed21b4e 100644 --- a/definitions/rules/antivirus/bitdefender_gz/memory_threat_detection.yaml +++ b/definitions/rules/antivirus/bitdefender_gz/memory_threat_detection.yaml @@ -1,37 +1,44 @@ -# Rule version v1.0.0 +# Rule version v2.0.0 dataTypes: - antivirus-bitdefender-gz -name: Memory-Based Threat Detection +name: Bitdefender GravityZone Memory Exploit Detected impact: confidentiality: 3 integrity: 3 availability: 2 -category: Defense Evasion, Privilege Escalation +category: Defense Evasion technique: "T1055 - Process Injection" adversary: origin references: + - https://www.bitdefender.com/business/support/en/77212-237089-event-types.html + - https://www.bitdefender.com/business/support/en/77212-237090-syslog-events.html - https://attack.mitre.org/techniques/T1055/ - - https://www.bitdefender.com/business/support/en/77209-135324-event-types.html description: | - Detects memory-based threats including process injection, memory manipulation, and fileless malware executing in memory based on Bitdefender GravityZone event types. + Detects an in-memory exploit or memory-manipulation threat caught by Bitdefender, from two independent signals: + + - Advanced Anti-Exploit (antiexploit) module firing on any exploit technique. The vendor's per-event fields (detection_exploitTechnique, detection_pid, detection_path, detection_cve) name the vulnerability class targeted. + - HyperDetect (hd) with attack_type "exploits". HyperDetect's ML flags in-memory exploit chains that pass the on-disk scanners. + + Memory exploitation implies that the attacker got code execution in an existing process. This is more severe than a file-based detection because there is no artefact on disk to quarantine and the caught process may have already touched other systems. Next Steps: - 1. Identify the affected process and host using log.hostId and origin.path fields - 2. Check if the process is legitimate or if it shows signs of compromise - 3. Review the process tree to identify parent-child relationships - 4. Look for other suspicious activities on the same host in the last hour - 5. Collect memory dump if the process is still running - 6. Analyze network connections from the affected process - 7. Check for persistence mechanisms on the affected system - 8. Isolate the host if active malicious behavior is confirmed + 1. Capture the process memory before reboot. In-memory forensic value is time-critical. + 2. Read the vendor's classification: + - log.BitdefenderGZExploitType or the antiexploit detection_exploitTechnique names the class of exploit (ROP, process creation, obsolete child process, etc.). + - log.BitdefenderGZDetectionCve names the vulnerability if known. + - target.process and log.BitdefenderGZDetectionPath show the affected process. + - log.BitdefenderGZParentPid and log.BitdefenderGZParentPath show the delivery process. + 3. Patch or isolate the vulnerable software identified by the CVE across the estate. Other endpoints running the same version are exposed even if they have not fired the rule yet. + 4. Look for post-exploitation on the same target.host: process launches with anomalous ancestry, network connections from unusual processes, credential access artefacts. + 5. If actionResult is "failed" or the vendor detection_action was "reportOnly", treat the exploit as successful and hunt for the payload it delivered. + 6. Correlate with New Incident events on the same target.host - the antiexploit hit is often one node in a larger incident graph. where: | - exists("log.eventType") && - (oneOf("log.eventType", ["aph", "antiexploit", "hd"]) || - (exists("origin.path") && contains("origin.path", "memory"))) && - (oneOf("log.severity", ["critical", "high"]) || - exists("log.malwareName") || - exists("log.threatName")) + equals("log.BitdefenderGZModule", "antiexploit") || + (equals("log.BitdefenderGZModule", "hd") && + regexMatch("log.BitdefenderGZAttackType", "(?i)exploits")) || + (equals("log.BitdefenderGZMalwareType", "process") && + oneOf("log.BitdefenderGZModule", ["av", "avc", "hd"])) groupBy: - - lastEvent.log.hostId - - adversary.path + - target.host + - target.process \ No newline at end of file diff --git a/definitions/rules/antivirus/bitdefender_gz/multiple_malware_from_single_source.yaml b/definitions/rules/antivirus/bitdefender_gz/multiple_malware_from_single_source.yaml index bb760ee1c..391d7a45e 100644 --- a/definitions/rules/antivirus/bitdefender_gz/multiple_malware_from_single_source.yaml +++ b/definitions/rules/antivirus/bitdefender_gz/multiple_malware_from_single_source.yaml @@ -1,53 +1,45 @@ -# Rule version v1.0.0 +# Rule version v2.0.0 dataTypes: - antivirus-bitdefender-gz -name: Multiple Malware Detections from Single Source +name: Bitdefender GravityZone Repeated Malware Detections on One Endpoint impact: confidentiality: 3 integrity: 3 availability: 2 -category: Command and Control -technique: "T1105 - Ingress Tool Transfer" +category: Execution +technique: "T1204.002 - User Execution: Malicious File" adversary: origin references: - https://www.bitdefender.com/business/support/en/77212-237089-event-types.html - - https://attack.mitre.org/techniques/T1105/ + - https://www.bitdefender.com/business/support/en/77212-237090-syslog-events.html + - https://attack.mitre.org/techniques/T1204/002/ description: | - Detects when multiple malware threats are detected on a single host within a short time period. This could indicate a compromised system actively spreading malware or an attacker launching multiple malware variants. + Detects an endpoint accumulating malware detections quickly: three or more antimalware findings on the same host within an hour. One detection is routine, several in an hour is not - it usually means an active infection dropping payloads, a user repeatedly running the same malicious file, or an already-compromised machine being used as a staging point. + + This looks at the endpoint as the unit of compromise, unlike the outbreak rule which follows one malware name across hosts. Next Steps: - 1. Investigate the affected host: - - Identify the system using the hostId field - - Check if it's a critical system or server - - Review recent user activity on the host - 2. Analyze the detected malware: - - Review the malware types and names detected (signatureID field) - - Check file paths and processes involved - - Determine if malware was successfully quarantined - 3. Check for lateral movement: - - Look for connections from the affected host to other internal systems - - Review authentication logs for suspicious activity - - Check for file share access patterns - 4. Remediation actions: - - Isolate the affected system if confirmed compromised - - Run full system scans on potentially affected systems - - Update antivirus signatures and definitions - - Consider reimaging if system is severely compromised -where: | - equals("log.eventType", "AntiMalware") && - oneOf("log.severity", ["4", "5"]) && - exists("log.hostId") -afterEvents: - - with: - - field: log.hostId - operator: filter_term - value: '{{.log.hostId}}' - - field: log.eventType - operator: filter_term - value: "AntiMalware" + 1. Treat the endpoint as compromised rather than triaging each detection separately + 2. Build the picture across the grouped events: + - Collect every target.malware seen on this target.host in the window - several distinct families point at a dropper or a downloader rather than one bad file + - Check target.path and target.process for a common parent, which is usually the delivery mechanism + - Look at target.user to see whether one account is behind all of them + 3. Check whether any of them failed to remediate: an actionResult of "failed" on any event in the group means something is still live, and that changes the urgency + 4. Isolate the endpoint if detections are still arriving or if any remain unremediated + 5. Find the entry point: + - origin.url on related events shows web delivery + - Correlate with Antiphishing events for the same host and user + - Check whether removable media was involved via Device Control events + 6. Do not close on a clean scan alone. Confirm no new detections for a full day, and review persistence - scheduled tasks, run keys, services + 7. Reimage if the same host keeps reappearing in this rule across days +where: oneOf("log.BitdefenderGZModule", ["av", "avc", "hd"]) && greaterOrEqual("severity", 8) +correlation: within: 1h - count: 5 + count: 3 + with: + - field: target.host + operator: filter_term + value: "{{.target.host}}" groupBy: - - lastEvent.log.hostId - - lastEvent.log.signatureID + - target.host \ No newline at end of file diff --git a/definitions/rules/antivirus/bitdefender_gz/network_threat_detection.yaml b/definitions/rules/antivirus/bitdefender_gz/network_threat_detection.yaml index 7d3c9e14c..05e8b6ab6 100644 --- a/definitions/rules/antivirus/bitdefender_gz/network_threat_detection.yaml +++ b/definitions/rules/antivirus/bitdefender_gz/network_threat_detection.yaml @@ -1,55 +1,48 @@ -# Rule version v1.0.0 +# Rule version v2.0.0 dataTypes: - antivirus-bitdefender-gz -name: Network-Based Threat Detection +name: Bitdefender GravityZone Network Attack Blocked impact: confidentiality: 3 integrity: 2 - availability: 3 + availability: 2 category: Command and Control -technique: "T1071 - Application Layer Protocol: Command and Control" +technique: "T1071 - Application Layer Protocol" adversary: origin references: + - https://www.bitdefender.com/business/support/en/77212-237089-event-types.html + - https://www.bitdefender.com/business/support/en/77212-237090-syslog-events.html - https://attack.mitre.org/techniques/T1071/ - - https://www.bitdefender.com/business/support/en/77209-135324-event-types.html description: | - Detects network-based threats including C2 communications, malicious network activity, and suspicious network connections identified by Bitdefender GravityZone. + Detects network-layer attacks that Bitdefender blocked at the endpoint, from either Network Attack Defense (exploit attempts, brute force, credential-stealing traffic) or the endpoint Firewall (port scans and blocked connections). + + The rule fires on a single high-severity event, and the correlation step raises it when the same source keeps coming back: five or more events from the same origin.ip within two hours is a persistent adversary rather than a stray packet. + + origin.ip is the attacker and target.ip is the endpoint being attacked. target.port tells you what was targeted, which is often the fastest way to read intent - 88 is Kerberos, 445 is SMB, 3389 is RDP. Next Steps: - 1. Identify the affected host using log.hostId and check for other security events from this system - 2. Review origin.ip to determine if it's a known malicious IP or C2 server - 3. Check firewall logs for any blocked or allowed connections to/from the suspicious IP - 4. Investigate running processes on the affected host for signs of malware - 5. Review network traffic patterns for data exfiltration attempts - 6. If ransomware is detected, immediately isolate the affected system - 7. Collect network packet captures if available for deeper analysis - 8. Check if other hosts have communicated with the same external IP address - 9. Submit suspicious IPs to threat intelligence platforms for reputation checking - 10. Document findings and update firewall rules to block confirmed malicious IPs -where: | - (oneOf("log.eventType", ["network-sandboxing", "fw"]) && - oneOf("log.severity", ["high", "critical", "4", "5"])) || - (exists("origin.ip") && contains("log.eventType", "network") && - contains("log.restData", ["malware", "threat", "blocked", "c2", "botnet"])) || - (equals("log.severity", "critical") && contains("log.product", "network")) -afterEvents: - - with: - - field: origin.ip - operator: filter_term - value: '{{.origin.ip}}' + 1. Read the two sides: origin.ip is the source, target.host and target.ip are what it reached + 2. Decide whether the source is internal or external: + - An external origin.ip means perimeter exposure - check why that traffic reached the endpoint at all + - An internal origin.ip means an already-compromised host is attacking laterally, which is more urgent + 3. Read the intent from the detection: + - log.BitdefenderGZDetectionName names the attack, for example Attack.Bruteforce.KERBEROS + - log.BitdefenderGZDetectionAttackTechnique gives the MITRE-aligned phase, such as credentialAccess + - target.port identifies the targeted service + 4. For credential access, assume the credentials are at risk: + - Force a reset on the targeted accounts and review authentication logs from origin.ip for any success + - If the target is a domain controller, treat it as a domain-wide incident + 5. Check whether the same origin.ip reached other endpoints - the correlation step groups by source for exactly this reason + 6. Block the source at the perimeter, and only then close the alert. A blocked attempt means this attack failed, not that the attacker stopped +where: oneOf("log.BitdefenderGZModule", ["network-monitor", "fw"]) && greaterOrEqual("severity", 8) +correlation: within: 2h count: 5 - or: - - with: - - field: log.hostId - operator: filter_term - value: '{{.log.hostId}}' - - field: log.eventType - operator: filter_term - value: 'network-sandboxing' - within: 4h - count: 3 + with: + - field: origin.ip + operator: filter_term + value: "{{.origin.ip}}" groupBy: - - lastEvent.log.hostId - - adversary.ip + - target.host + - adversary.ip \ No newline at end of file diff --git a/definitions/rules/antivirus/bitdefender_gz/phishing_access_blocked.yaml b/definitions/rules/antivirus/bitdefender_gz/phishing_access_blocked.yaml new file mode 100644 index 000000000..bd21b6314 --- /dev/null +++ b/definitions/rules/antivirus/bitdefender_gz/phishing_access_blocked.yaml @@ -0,0 +1,41 @@ +# Rule version v1.0.0 + +dataTypes: + - antivirus-bitdefender-gz +name: Bitdefender GravityZone Phishing Page Loaded Without Blocking +impact: + confidentiality: 3 + integrity: 1 + availability: 0 +category: Credential Access +technique: "T1566.002 - Phishing: Spearphishing Link" +adversary: origin +references: + - https://www.bitdefender.com/business/support/en/77212-237089-event-types.html + - https://www.bitdefender.com/business/support/en/77212-237090-syslog-events.html + - https://attack.mitre.org/techniques/T1566/002/ +description: | + Detects a user actually loading a page Bitdefender classifies as phishing, fraud or untrusted, because Web Protection was in report-only mode rather than blocking. The URL is in origin.url, the user in target.user and the endpoint in target.host. + + This deliberately excludes blocked phishing. When Bitdefender blocks the page the user never sees it, there is no credential exposure, and an alert would only compete with real incidents. Blocked attempts are worth a periodic awareness report, not an alert. + + A page that loaded is different: the user reached a credential-harvesting form and may have filled it in. Treat it as a possible credential compromise, not as a web-filtering event. + + Next Steps: + 1. Treat the account in target.user as potentially compromised and reset the credentials, before investigating anything else + 2. Read the URL in origin.url: + - A brand-impersonating domain, especially a bank or the organisation's own name, indicates a targeted campaign rather than random adware + - log.BitdefenderGZEventType separates phishing from fraud and untrust, which carry different intent + 3. Establish how the user got there: + - target.process shows the browser or client that made the request + - A link in email means the message got past the mail gateway, which is its own finding + 4. Check whether other users hit the same origin.url - a shared URL across users is a campaign against the organisation + 5. Look for what followed on the same target.host: + - AntiMalware detections shortly after suggest the page also served a payload + - Network Attack Defense events with credentialAccess suggest the credentials were used + 6. Fix the policy that allowed it: find why Web Protection was in report-only mode for this endpoint or group, since every other user under that policy is equally exposed + 7. Submit the URL for blocking at the perimeter so the rest of the estate is covered +where: equals("log.BitdefenderGZModule", "aph") && equals("actionResult", "success") +groupBy: + - target.user + - adversary.url \ No newline at end of file diff --git a/definitions/rules/antivirus/bitdefender_gz/quarantine_failure_detection.yaml b/definitions/rules/antivirus/bitdefender_gz/quarantine_failure_detection.yaml index deb19170e..c6d60e4ad 100644 --- a/definitions/rules/antivirus/bitdefender_gz/quarantine_failure_detection.yaml +++ b/definitions/rules/antivirus/bitdefender_gz/quarantine_failure_detection.yaml @@ -1,8 +1,8 @@ -# Rule version v1.0.0 +# Rule version v2.0.0 dataTypes: - antivirus-bitdefender-gz -name: Bitdefender GravityZone Quarantine Failure Detection +name: Bitdefender GravityZone Malware Not Remediated impact: confidentiality: 3 integrity: 3 @@ -12,25 +12,41 @@ technique: "T1562.001 - Impair Defenses: Disable or Modify Tools" adversary: origin references: - https://www.bitdefender.com/business/support/en/77212-237089-event-types.html + - https://www.bitdefender.com/business/support/en/77212-237090-syslog-events.html - https://attack.mitre.org/techniques/T1562/001/ description: | - Detects when Bitdefender GravityZone fails to quarantine detected malware. This could indicate that the malware is actively resisting remediation attempts or that there are permission issues preventing proper quarantine. + Detects malware that Bitdefender identified but did not remediate: the file or process is still present on the endpoint after the detection. The endpoint should be treated as compromised, not as protected. + + Two equivalent signals, either of which fires the rule: + - actionResult "failed", derived by the filter from the vendor's final_status values "still present" and "ignored". + - The malware counters saying the same thing structurally: at least one threat still present, none quarantined and none cleaned. + + This is materially different from a normal detection. A blocked, deleted, quarantined or disinfected threat is a control that worked. A threat still present means the control detected and then failed to act, which usually points at insufficient agent privileges, a locked file, an active process defending itself, or quarantine storage problems. Next Steps: - - Immediately isolate the affected system from the network - - Check if the malware process is still running and attempt manual termination - - Verify antivirus permissions and ensure it has necessary privileges - - Review system logs for signs of privilege escalation or rootkit activity - - Consider reimaging the system if quarantine continues to fail - - Check for similar failures on other systems in the environment - - Investigate the specific malware detected and research its capabilities - - Review quarantine configuration and storage capacity + 1. Isolate the endpoint from the network before anything else - the threat is live, not contained + 2. Identify what is still running: + - target.malware and target.malwareType name the threat and whether it is a file or a process + - target.path and target.process point at the artefact and the process involved + - target.sha256 lets you pivot across the estate and to threat intelligence + 3. Establish why remediation failed: + - A process-type detection that is still present usually means the process resisted termination + - Check whether the agent has the privileges it needs, and whether the path is on a locked or network volume + - Review quarantine storage capacity in the GravityZone console + 4. Remediate manually and verify: + - Terminate the process, then remove the artefact and confirm a follow-up scan reports it gone + - Do not close the alert on the detection alone: confirm the counters changed + 5. Assess the exposure window - the endpoint ran with known live malware from deviceTime until remediation, so review what else it reported in that period + 6. Hunt the same threat elsewhere using target.sha256 and target.malware, since a failure to remediate on one host says nothing about the others + 7. If remediation keeps failing on the same endpoint, treat it as tampering rather than a product fault and consider reimaging where: | - oneOf("log.eventType", ["quarantine_failed", "quarantine_failure"]) || - (equals("log.eventType", "AntiMalware") && - (containsAll("log.requestToParse", ["quarantine", "fail"]) || - contains("log.restData", ["quarantine failed", "unable to quarantine", "failed to quarantine"]) || - (equals("log.severity", "failure") && contains("log.requestToParse", "quarantine")))) + equals("log.eventType", "AntiMalware") && + ( + equals("actionResult", "failed") || + (greaterOrEqual("log.BitdefenderGZPresentMalwareCnt", 1) && + equals("log.BitdefenderGZQuarantinedMalwareCnt", 0) && + equals("log.BitdefenderGZCleanedMalwareCnt", 0)) + ) groupBy: - - lastEvent.log.hostId - - lastEvent.log.signatureID + - target.host + - target.malware \ No newline at end of file diff --git a/definitions/rules/antivirus/bitdefender_gz/ransomware_behavior_detection.yaml b/definitions/rules/antivirus/bitdefender_gz/ransomware_behavior_detection.yaml index 27791ab85..a0f22efad 100644 --- a/definitions/rules/antivirus/bitdefender_gz/ransomware_behavior_detection.yaml +++ b/definitions/rules/antivirus/bitdefender_gz/ransomware_behavior_detection.yaml @@ -1,8 +1,8 @@ -# Rule version v1.0.0 +# Rule version v2.0.0 dataTypes: - antivirus-bitdefender-gz -name: Ransomware Behavior Detection +name: Bitdefender GravityZone Ransomware Detected impact: confidentiality: 3 integrity: 3 @@ -12,32 +12,35 @@ technique: "T1486 - Data Encrypted for Impact" adversary: origin references: - https://www.bitdefender.com/business/support/en/77212-237089-event-types.html + - https://www.bitdefender.com/business/support/en/77212-237090-syslog-events.html - https://attack.mitre.org/techniques/T1486/ description: | - Detects ransomware behavior patterns including file encryption attempts, mass file modifications, and ransomware-specific malware types detected by Bitdefender GravityZone. + Detects ransomware that Bitdefender classified as such, from any of three independent signals: + - An incident whose attack types include Ransomware, which is GravityZone's own classification of the attack chain. + - The Ransomware Mitigation module reporting activity, which is the vendor's dedicated anti-ransomware component. + - A threat or detection name containing Ransom, which covers signature-based identification. + + There is no severity floor and no correlation threshold on purpose. These events arrive at CEF severity 3 because GravityZone assigns severity by event type, not by how dangerous the threat is, and a single confirmed ransomware classification already justifies the highest-impact response. Next Steps: - 1. Immediately isolate the affected system from the network to prevent spread - 2. Check for recent backup availability and integrity - 3. Review process execution history on the affected host - 4. Look for suspicious file modifications or mass encryption activities - 5. Check for ransomware notes or changed file extensions - 6. Investigate the source of infection (email attachments, downloads, RDP compromise) - 7. Scan other systems for similar indicators - 8. Consider engaging incident response team for containment and recovery + 1. Isolate the endpoint immediately - before triage, before collecting anything. Every minute of network access is more files encrypted, potentially on shares + 2. Determine whether encryption already started: + - Check the file server and any shares the target.user could reach for recently modified files with unusual extensions + - log.BitdefenderGZAttackTypes and log.BitdefenderGZAttCkId show what stage GravityZone attributed + - actionResult tells you whether Bitdefender stopped it or only observed it + 3. Identify the entry point, because ransomware is the last stage of an intrusion, not the first: + - origin.url and target.process show how it arrived and what executed it + - target.user is the account whose access the malware inherited + - Look for credential access or lateral movement on this host in the preceding days + 4. Check whether Ransomware Mitigation restored anything - the module keeps copies of files it saw being encrypted + 5. Assume the whole estate is in scope until proven otherwise: hunt target.sha256 and check every host the same account touched + 6. Preserve evidence before reimaging - the ransom note, the sample and the memory image determine the family and whether a decryptor exists + 7. Escalate to whoever owns incident response and legal notification. Do not close this alert on a clean scan where: | - (contains("log.message", ["ransomware", "ransom", "locky", "cerber", - "wannacry", "petya", "ryuk", "sodinokibi", "maze"]) || - contains("log.signatureID", "ransomware") || - (equals("log.severity", "10") && contains("log.eventType", "malware"))) && - exists("log.severity") -afterEvents: - - with: - - field: log.hostId - operator: filter_term - value: '{{.log.hostId}}' - within: 10m - count: 5 + regexMatch("log.BitdefenderGZAttackTypes", "(?i)Ransomware") || + equals("log.BitdefenderGZModule", "ransomware-mitigation") || + contains("target.malware", "Ransom") || + contains("log.BitdefenderGZDetectionName", "Ransom") groupBy: - - lastEvent.log.hostId - - lastEvent.log.signatureID + - target.host + - lastEvent.log.BitdefenderGZIncidentId \ No newline at end of file diff --git a/definitions/rules/antivirus/bitdefender_gz/realtime_protection_disabled.yaml b/definitions/rules/antivirus/bitdefender_gz/realtime_protection_disabled.yaml index 924548840..29b1f6284 100644 --- a/definitions/rules/antivirus/bitdefender_gz/realtime_protection_disabled.yaml +++ b/definitions/rules/antivirus/bitdefender_gz/realtime_protection_disabled.yaml @@ -1,8 +1,8 @@ -# Rule version v1.0.0 +# Rule version v2.0.0 dataTypes: - antivirus-bitdefender-gz -name: Real-time Protection Disabled +name: Bitdefender GravityZone Real-Time Antimalware Disabled impact: confidentiality: 3 integrity: 3 @@ -12,29 +12,22 @@ technique: "T1562.001 - Impair Defenses: Disable or Modify Tools" adversary: origin references: - https://www.bitdefender.com/business/support/en/77212-237089-event-types.html + - https://www.bitdefender.com/business/support/en/77212-237090-syslog-events.html - https://attack.mitre.org/techniques/T1562/001/ description: | - Detects when real-time protection features are disabled on an endpoint. This is a critical security event as it leaves the system vulnerable to malware infections and requires immediate investigation. + Detects real-time (on-access) Antimalware protection being disabled on a Bitdefender GravityZone endpoint, from the vendor's own Product Modules Status event: malware_status = 0 means the on-access scanner is currently off. + + This is a narrow, high-fidelity signal. On-access scanning is Bitdefender's core defence; a machine running with it off cannot detect malware at execution time, only at scheduled scans. Next Steps: - 1. Immediately investigate who disabled the real-time protection and why - 2. Check if the action was authorized by IT security team - 3. Review recent activity on the affected endpoint for signs of compromise - 4. Re-enable real-time protection if the action was unauthorized - 5. Check for any malware infections that may have occurred while protection was disabled - 6. Review system logs for any suspicious activities during the protection downtime - 7. Consider implementing additional controls to prevent unauthorized disabling of security tools + 1. Correlate the deviceTime against the Control Center audit log for this endpoint's policy group. A legitimate change comes from a policy push; an unattributed change comes from local tampering. + 2. Look for any threats that arrived during the disabled window: nothing between the disable event and the next enable event will have been caught by real-time scanning. Trigger a full on-demand scan through the console before trusting the endpoint again. + 3. Check for concurrent antitampering events on the same target.host. A modules-status change plus an antitampering (Callback Evasion) event within minutes is the shape of an attacker with local admin trying to silence the agent. + 4. Restore the module through GravityZone Control Center. Do not rely on the local agent to accept the re-enable; verify with the next modules-status event. + 5. If the on-access module keeps going off despite a re-enable, treat the endpoint as tampered and consider reimaging. where: | - exists("log.syslogHostIP") && - ( - (equals("log.eventType", "modules") && - equals("log.product", "av") && - contains("log.restData", "real-time")) || - (equals("log.eventType", "Product ModulesStatus") && - oneOf("log.severity", ["4", "5"]) && - (contains("log.restData", "protection disabled") || - contains("log.restData", "real-time scanning disabled"))) - ) + equals("log.BitdefenderGZModule", "modules") && + (equals("log.malware_status", "0") || + equals("log.BitdefenderGZMalwareStatus", "0")) groupBy: - - lastEvent.log.eventType - - lastEvent.log.syslogHostIP + - target.host \ No newline at end of file diff --git a/definitions/rules/antivirus/bitdefender_gz/rootkit_detection.yaml b/definitions/rules/antivirus/bitdefender_gz/rootkit_detection.yaml index c4bf16564..c04d3aa43 100644 --- a/definitions/rules/antivirus/bitdefender_gz/rootkit_detection.yaml +++ b/definitions/rules/antivirus/bitdefender_gz/rootkit_detection.yaml @@ -1,8 +1,8 @@ -# Rule version v1.0.0 +# Rule version v2.0.0 dataTypes: - antivirus-bitdefender-gz -name: Rootkit Detection +name: Bitdefender GravityZone Rootkit Detected impact: confidentiality: 3 integrity: 3 @@ -12,28 +12,28 @@ technique: "T1014 - Rootkit" adversary: origin references: - https://www.bitdefender.com/business/support/en/77212-237089-event-types.html + - https://www.bitdefender.com/business/support/en/77212-237090-syslog-events.html - https://attack.mitre.org/techniques/T1014/ description: | - Detects rootkit infections and kernel-level threats that attempt to hide malicious activity at the system level using Bitdefender GravityZone's advanced detection capabilities. + Detects a rootkit or kernel-level threat that Bitdefender identified by name. Signal is a match on the vendor's own detection classification (log.BitdefenderGZDetectionName or target.malware) against known rootkit families - Rootkit, Trojan.Rootkit, TDSS, ZeroAccess, Necurs, Alureon, Rustock, Sinowal - from any antimalware engine (Antimalware, ATC, HyperDetect). + + A rootkit detection means the vendor believes something is hiding at or below the OS layer. The running OS on the endpoint cannot be trusted to report accurately after a rootkit verdict, so investigation from within the endpoint is unreliable. Next Steps: - 1. Immediately isolate the affected system from the network to prevent lateral movement - 2. Capture a memory dump and disk image for forensic analysis - 3. Check for signs of privilege escalation or kernel-level modifications - 4. Review system logs for any suspicious driver installations or kernel module loading - 5. Scan other systems in the same network segment for similar infections - 6. Consider rebuilding the system from a known clean state as rootkits can be difficult to fully remove - 7. Review how the rootkit was initially delivered (email attachment, exploit kit, etc.) - 8. Update all security software and operating system patches + 1. Isolate the endpoint before doing anything else. Rootkits control what other tools see; every second of network access is another opportunity for lateral movement or exfiltration from a position where forensic tools lie about the state. + 2. Do not investigate from the running OS. Boot from external media for imaging and forensic capture. + 3. Read the vendor's classification: + - log.BitdefenderGZDetectionName or target.malware names the family and aligns with public IOCs. + - log.BitdefenderGZMalwareType tells you whether it caught a file, a process (still resident), or a boot artefact. + - actionResult tells you whether Bitdefender removed it; rootkit removal from within the OS often fails and that is not the vendor's fault. + 4. Check for privilege escalation and driver installation events on the same target.host in the preceding hours - rootkits normally arrive through an existing privilege escalation. + 5. Reimage from trusted media. Do not try to disinfect a running rootkit-infected OS. + 6. Hunt the estate for target.sha256, the family name, and any driver names identified during forensics. A rootkit is a targeted delivery; the same delivery vector likely touched other endpoints. + 7. Rotate credentials that could have been captured while the rootkit was resident. Every credential the affected endpoint touched is potentially compromised. where: | - equals("log.eventType", "malware_detected") && - oneOf("log.severity", ["high", "critical"]) && - ( - contains("log.restData", ["rootkit", "kernel", "tdss", "zeroaccess", - "necurs", "bootkit", "alureon", "rustock", "sinowal"]) || - contains("log.requested", "rootkit") || - equals("log.signatureID", "rootkit") - ) + oneOf("log.BitdefenderGZModule", ["av", "avc", "hd"]) && + (regexMatch("log.BitdefenderGZDetectionName", "(?i)(rootkit|tdss|zeroaccess|necurs|alureon|rustock|sinowal|trojan\\.rootkit)") || + regexMatch("target.malware", "(?i)(rootkit|tdss|zeroaccess|necurs|alureon|rustock|sinowal|trojan\\.rootkit)")) groupBy: - - lastEvent.log.hostId - - lastEvent.log.signatureID + - target.host + - target.malware \ No newline at end of file diff --git a/definitions/rules/antivirus/bitdefender_gz/suspicious_exclusions_added.yaml b/definitions/rules/antivirus/bitdefender_gz/suspicious_exclusions_added.yaml index c32f6da32..09d3be2b0 100644 --- a/definitions/rules/antivirus/bitdefender_gz/suspicious_exclusions_added.yaml +++ b/definitions/rules/antivirus/bitdefender_gz/suspicious_exclusions_added.yaml @@ -1,8 +1,8 @@ -# Rule version v1.0.0 +# Rule version v2.0.0 dataTypes: - antivirus-bitdefender-gz -name: Bitdefender GravityZone Suspicious Exclusion Added +name: Bitdefender GravityZone Exclusion-Related Task Executed impact: confidentiality: 3 integrity: 3 @@ -12,21 +12,24 @@ technique: "T1562.001 - Impair Defenses: Disable or Modify Tools" adversary: origin references: - https://www.bitdefender.com/business/support/en/77212-237089-event-types.html + - https://www.bitdefender.com/business/support/en/77212-237090-syslog-events.html - https://attack.mitre.org/techniques/T1562/001/ description: | - Detects when exclusions are added to Bitdefender GravityZone that may allow malware to operate undetected. Attackers often add exclusions to antivirus software to prevent detection of their malicious tools and activities. + Detects a Bitdefender GravityZone task whose name or type identifies it as an exclusion-related administrative action. Attackers with admin console access add scan exclusions to blind the antivirus to their tools before running them. + + Coverage is partial by design: fine-grained exclusion changes (a single path added without a task) live in the Control Center's audit log (getAuditLog API) rather than in syslog. This rule catches the exclusion-related tasks that reach the endpoint event stream. For complete coverage, ingest the audit log via the API. Next Steps: - 1. Review the exclusion details to determine what files, folders, or processes were excluded - 2. Verify if the exclusion was authorized by security team or IT administrators - 3. Check if the excluded path contains any suspicious executables or scripts - 4. Review recent activity from the user who added the exclusion - 5. If unauthorized, immediately remove the exclusion and scan the excluded locations - 6. Consider implementing a change control process for antivirus exclusions + 1. Identify who triggered the task via log.BitdefenderGZUserName / user object. Cross-check against change control - a legitimate exclusion change has a ticket. + 2. Read what changed: log.BitdefenderGZTaskName and log.BitdefenderGZTaskType. Task types related to exclusion, scanning behaviour and policy application are the ones that matter. + 3. Pull the current exclusion list from GravityZone Control Center and diff against your baseline. Any newly-excluded path is a candidate for containing attacker tools. + 4. Scan the excluded paths from a machine with a policy that does NOT include the exclusion, to check for hidden artefacts. + 5. If the admin identity or session looks anomalous (unusual source IP, off-hours, not a scheduled change window), rotate that admin's credentials before doing anything else. + 6. Restore the previous exclusion policy if unauthorised. Then re-scan every endpoint that had the weakened policy applied. where: | - equals("log.eventType", "exclusion_added") || - (oneOf("log.eventType", ["policy_change", "configuration_change"]) && - contains("log.requested", "exclusion")) + equals("log.BitdefenderGZModule", "task-status") && + (regexMatch("log.BitdefenderGZTaskName", "(?i)(exclusion|exclude|policy|whitelist|allowlist|configuration)") || + regexMatch("log.taskName", "(?i)(exclusion|exclude|policy|whitelist|allowlist|configuration)")) groupBy: - - lastEvent.log.eventType - - lastEvent.log.hostId + - target.host + - lastEvent.log.BitdefenderGZTaskName \ No newline at end of file diff --git a/definitions/rules/antivirus/bitdefender_gz/usb_malware_propagation.yaml b/definitions/rules/antivirus/bitdefender_gz/usb_malware_propagation.yaml index 29b6c4ffe..648d857de 100644 --- a/definitions/rules/antivirus/bitdefender_gz/usb_malware_propagation.yaml +++ b/definitions/rules/antivirus/bitdefender_gz/usb_malware_propagation.yaml @@ -1,42 +1,50 @@ -# Rule version v1.0.0 +# Rule version v2.0.0 dataTypes: - antivirus-bitdefender-gz -name: USB-Based Malware Propagation +name: Bitdefender GravityZone USB-Borne Threat Activity impact: confidentiality: 3 integrity: 3 availability: 2 -category: Lateral Movement, Initial Access +category: Initial Access technique: "T1091 - Replication Through Removable Media" adversary: origin references: + - https://www.bitdefender.com/business/support/en/77212-237089-event-types.html + - https://www.bitdefender.com/business/support/en/77212-237090-syslog-events.html - https://attack.mitre.org/techniques/T1091/ - - https://www.bitdefender.com/business/support/en/77209-135324-event-types.html description: | - Detects USB-based malware propagation attempts including autorun infections, removable media threats, and device control violations. This rule monitors for device control events and removable media access patterns that may indicate malware attempting to spread via USB devices. + Detects USB or removable-media threat activity from two independent signals: + + - Device Control (device-control) with action "blocked" or "readonly". Bitdefender enforced the removable-media policy against a device. A single event is normal enforcement; a cluster of them across hosts is the shape of a campaign. + - Antimalware detection (av/avc/hd) where the artefact path indicates removable media: an autorun.inf reference, a removable-drive root, or a recycle bin on a non-fixed drive. + + The correlation raises the finding when three or more removable-media-related events reach the same target.host within 30 minutes, which is the shape of an active infection attempt rather than a stray insertion. Next Steps: - 1. Isolate the affected endpoint immediately to prevent further spread - 2. Check device control logs for unauthorized USB device connections - 3. Scan all removable media that were connected to the affected system - 4. Review file creation/modification events on removable drives (especially autorun.inf) - 5. Verify if similar events occurred on other endpoints in the network - 6. Update device control policies to restrict USB usage if necessary - 7. Consider implementing USB device whitelisting for critical systems + 1. Identify the device: log.BitdefenderGZDeviceName, log.BitdefenderGZDeviceId, log.BitdefenderGZVendorId. If the vendor/product IDs recur across hosts, the same physical device is moving between them. + 2. Read the block reason: action ("blocked" vs "readonly") tells you whether the endpoint policy rejected the device or only demoted it. + 3. If the second signal fires (antimalware detection on removable media), also read target.malware and log.BitdefenderGZDetectionName - autorun worms carry family names like Worm.Autoruner.*, INF/Autorun.*. + 4. Locate the device and, if possible, image it before returning it. The autorun payload is evidence. + 5. Check every endpoint the same device touched. Device Control keeps the device history in Control Center; use it to build the affected host list rather than guessing. + 6. Scan file shares reachable by the affected user account - USB worms that got in often propagate to shared folders next. + 7. Update Device Control policy to whitelist rather than blacklist for high-value hosts if this keeps happening. Blocking is downstream of an already-worse policy that allowed the device in the first place. where: | - (oneOf("log.eventType", ["device-control", "dp"]) && - (contains("log.restData", ["malware", "threat", "infection", "autorun", "suspicious"]) || - oneOf("log.severity", ["high", "critical", "4", "5"]))) || - (contains("log.requested", ["usb", "removable", "autorun"]) && - contains("log.restData", ["malware", "threat", "infection"])) -afterEvents: - - with: - - field: log.hostId - operator: filter_term - value: '{{.log.hostId}}' + (equals("log.BitdefenderGZModule", "device-control") && + oneOf("log.BitdefenderGZAction", ["blocked", "readonly"])) || + (equals("log.BitdefenderGZModule", "device-control") && + oneOf("action", ["blocked", "readonly"])) || + (oneOf("log.BitdefenderGZModule", ["av", "avc", "hd"]) && + (regexMatch("target.path", "(?i)(autorun\\.inf|\\\\\\$recycle\\.bin\\\\.*\\.(exe|scr|vbs|bat|cmd))") || + regexMatch("log.BitdefenderGZDetectionName", "(?i)(autorun|worm\\.autoruner|inf/autorun|usb\\.worm)"))) +correlation: within: 30m - count: 5 + count: 3 + with: + - field: target.host + operator: filter_term + value: "{{.target.host}}" groupBy: - - lastEvent.log.eventType - - lastEvent.log.hostId + - target.host + - lastEvent.log.BitdefenderGZDeviceName \ No newline at end of file diff --git a/definitions/rules/antivirus/bitdefender_gz/zero_day_malware_detection.yaml b/definitions/rules/antivirus/bitdefender_gz/zero_day_malware_detection.yaml index 782d2b69b..3bd47a883 100644 --- a/definitions/rules/antivirus/bitdefender_gz/zero_day_malware_detection.yaml +++ b/definitions/rules/antivirus/bitdefender_gz/zero_day_malware_detection.yaml @@ -1,32 +1,42 @@ -# Rule version v1.0.0 +# Rule version v2.0.0 dataTypes: - antivirus-bitdefender-gz -name: Bitdefender GravityZone Zero-Day Malware Detection +name: Bitdefender GravityZone Threat Detected Without a Signature impact: confidentiality: 3 integrity: 3 availability: 2 category: Execution -technique: "T1203 - Exploitation for Client Execution" +technique: "T1027 - Obfuscated Files or Information" adversary: origin references: - https://www.bitdefender.com/business/support/en/77212-237089-event-types.html - - https://attack.mitre.org/techniques/T1203/ + - https://www.bitdefender.com/business/support/en/77212-237090-syslog-events.html + - https://attack.mitre.org/techniques/T1027/ description: | - Detects potential zero-day malware identified by Bitdefender's advanced threat detection capabilities including HyperDetect and Sandbox Analyzer. These detection methods use behavioral analysis and machine learning to identify previously unknown threats. + Detects threats caught without a specific signature, which is what catches a new or repacked sample that signature matching would miss. + + Two kinds of signal: + - Bitdefender's signature-less engines: HyperDetect (machine learning tuned for targeted attacks), Sandbox Analyzer (detonation of unknown files) and Advanced Threat Control (runtime behaviour). + - Heuristic detection names, where the Heur. or GT: prefix says the verdict came from heuristics rather than a specific signature. + + A detection here deserves more attention than a routine signature hit, not less: the sample was unknown enough to require behavioural or machine-learning analysis, so there is no established remediation guidance for it and its capabilities are unverified. Next Steps: - 1. Immediately isolate the affected system from the network to prevent lateral movement - 2. Review the detection details including file path, process information, and threat indicators - 3. Check if similar detections occurred on other systems in the environment - 4. Collect the suspicious file/process for further analysis in a sandbox environment - 5. Review system logs for any suspicious activities before and after the detection - 6. Update security policies to block similar threats across the organization - 7. Consider submitting the sample to Bitdefender for further analysis + 1. Note which engine fired, from log.BitdefenderGZModule - hd, network-sandboxing and avc each mean something different: + - hd: machine learning flagged it before execution + - network-sandboxing: it was detonated and found malicious, so it evaded everything upstream + - avc: it was already running and its behaviour gave it away, which means execution occurred + 2. Treat the endpoint as potentially compromised when the engine was avc, since a behavioural verdict implies the code ran + 3. Collect the sample for analysis using target.sha256 and target.path - a signature-less detection is exactly what threat intelligence needs + 4. Check the outcome: actionResult "failed" plus a signature-less detection is the worst combination, an unknown threat still live + 5. Hunt the estate for target.sha256. Endpoints without HyperDetect or Sandbox Analyzer enabled would not have caught this at all, so absence of alerts there proves nothing + 6. Review coverage after the fact: if this fired on one endpoint, check which others have the same engines enabled where: | - oneOf("log.eventType", ["HyperDetect Activity", "Sandbox Analyzer Detection", "hyperdetect"]) || - (equals("log.eventType", "avc") && equals("log.severity", "High")) + oneOf("log.BitdefenderGZModule", ["hd", "network-sandboxing", "avc"]) || + startsWith("target.malware", ["Heur.", "GT:"]) || + contains("target.malware", ":Heur.") groupBy: - - lastEvent.log.hostId - - lastEvent.log.syslogHostIP + - target.host + - target.malware \ No newline at end of file From 105a6a5337057615c006df1f1583bf79b5f97b6e Mon Sep 17 00:00:00 2001 From: JocLRojas Date: Fri, 14 Aug 2026 15:17:28 +0300 Subject: [PATCH 3/4] feat(rules/windows): update adfs, certificate services, sid history and smbv1 rules --- definitions/rules/windows/adfs_authentication_anomalies.yaml | 2 +- definitions/rules/windows/certificate_services_abuse.yaml | 2 +- definitions/rules/windows/sid_history_injection.yaml | 2 +- definitions/rules/windows/smbv1_usage_detection.yaml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/definitions/rules/windows/adfs_authentication_anomalies.yaml b/definitions/rules/windows/adfs_authentication_anomalies.yaml index a7436976c..548abdd20 100644 --- a/definitions/rules/windows/adfs_authentication_anomalies.yaml +++ b/definitions/rules/windows/adfs_authentication_anomalies.yaml @@ -24,7 +24,7 @@ description: | 5. Consider implementing IP-based blocking if malicious activity is confirmed 6. Review ADFS configuration for security hardening opportunities 7. Correlate with other authentication events across the domain -where: equals("log.providerName", "AD FS") && (equals("log.eventId", "411") || equals("log.eventId", "342") || equals("log.eventId", "516")) && contains("log.message", "token validation failed") +where: equals("log.providerName", "AD FS") && (equals("log.eventCode", "342") || equals("log.eventCode", "516")) && contains("log.message", "token validation failed") afterEvents: - with: - field: origin.ip diff --git a/definitions/rules/windows/certificate_services_abuse.yaml b/definitions/rules/windows/certificate_services_abuse.yaml index 95c4d28b4..b336e9741 100644 --- a/definitions/rules/windows/certificate_services_abuse.yaml +++ b/definitions/rules/windows/certificate_services_abuse.yaml @@ -24,7 +24,7 @@ description: | 5. Examine the requesting host for signs of compromise 6. Consider revoking any suspicious certificates issued 7. Validate Certificate Authority security configurations and access controls -where: (equals("log.eventId", "4886") || equals("log.eventId", "4887")) && equals("log.providerName", "Microsoft-Windows-Security-Auditing") && (contains("log.eventDataSubjectUserName", "$") || equals("log.eventDataSubjectUserName", "ANONYMOUS LOGON")) +where: (equals("log.eventCode", "4886") || equals("log.eventCode", "4887")) && equals("log.providerName", "Microsoft-Windows-Security-Auditing") && (contains("log.eventDataSubjectUserName", "$") || equals("log.eventDataSubjectUserName", "ANONYMOUS LOGON")) groupBy: - lastEvent.log.eventDataSubjectUserName - adversary.host diff --git a/definitions/rules/windows/sid_history_injection.yaml b/definitions/rules/windows/sid_history_injection.yaml index b036073b5..d254cc1a7 100644 --- a/definitions/rules/windows/sid_history_injection.yaml +++ b/definitions/rules/windows/sid_history_injection.yaml @@ -27,7 +27,7 @@ description: | 6. Consider resetting the target account password and removing unauthorized SID History entries 7. Review domain administrator accounts and privileged group memberships for anomalies where: | - oneOf("log.eventId", ["4765", "4766"]) && + oneOf("log.eventCode", ["4765", "4766"]) && equals("log.channel", "Security") groupBy: - adversary.host diff --git a/definitions/rules/windows/smbv1_usage_detection.yaml b/definitions/rules/windows/smbv1_usage_detection.yaml index 8d3f4eab1..5b0eeee94 100644 --- a/definitions/rules/windows/smbv1_usage_detection.yaml +++ b/definitions/rules/windows/smbv1_usage_detection.yaml @@ -24,7 +24,7 @@ description: | 5. Plan migration to SMBv2/SMBv3 and disable SMBv1 on all systems where possible 6. Monitor for any lateral movement patterns that may indicate ongoing compromise 7. Consider implementing network segmentation to limit exposure if SMBv1 cannot be immediately disabled -where: equals("log.eventId", "3000") && equals("log.providerName", "Microsoft-Windows-SMBServer") && contains("log.message", "SMB1") +where: equals("log.eventCode", "3000") && equals("log.providerName", "Microsoft-Windows-SMBServer") && contains("log.message", "SMB1") groupBy: - adversary.host - adversary.ip From 4299e3b8bebfa32e559d94966802565538126b44 Mon Sep 17 00:00:00 2001 From: JocLRojas Date: Fri, 14 Aug 2026 15:17:34 +0300 Subject: [PATCH 4/4] refactor(sonicwall): revamp filter and correlation rules --- definitions/filters/sonicwall/sonic_wall.yaml | 1036 +++++++++++------ .../anti_spyware_detection.yaml | 35 +- .../sonicwall_firewall/botnet_detection.yaml | 29 +- .../capture_atp_verdicts.yaml | 35 +- .../capture_client_threats.yaml | 30 - .../encrypted_threats_detection.yaml | 40 - .../gateway_antivirus_detection.yaml | 31 +- .../intrusion_prevention_alert.yaml | 36 +- .../sonicwall_admin_auth_failures.yaml | 33 +- .../sonicwall_vpn_failures.yaml | 34 +- .../zero_day_threat_detection.yaml | 31 - 11 files changed, 806 insertions(+), 564 deletions(-) delete mode 100644 definitions/rules/sonicwall/sonicwall_firewall/capture_client_threats.yaml delete mode 100644 definitions/rules/sonicwall/sonicwall_firewall/encrypted_threats_detection.yaml delete mode 100644 definitions/rules/sonicwall/sonicwall_firewall/zero_day_threat_detection.yaml diff --git a/definitions/filters/sonicwall/sonic_wall.yaml b/definitions/filters/sonicwall/sonic_wall.yaml index af4918f2e..9d0cfac23 100644 --- a/definitions/filters/sonicwall/sonic_wall.yaml +++ b/definitions/filters/sonicwall/sonic_wall.yaml @@ -1,296 +1,482 @@ -# SonicWall Firewall, version 3.2.0 -# Based on docs -# Support Syslog CEF format +# SonicWall Firewall — version 4.0.0 # -# Documentations -# 1- https://www.sonicwall.com/de-de/techdocs/pdf/sonicos-6-5-4-log-events-reference-guide.pdf -# 2- https://www.sonicwall.com/de-de/techdocs/pdf/SonicOS-X_7.0.1_LogEvents_ReferenceGuide.pdf -# 3- https://docs.elastic.co/integrations/sonicwall_firewall -# 4- https://www.ossec.net/docs/log_samples/firewalls/sonicwall.html +# Formats supported +# - SonicOS syslog KV: id=firewall sn=... time="..." fw=... msg="..." src=IP:PORT:IF ... +# - SonicOS syslog CEF: CEF:0|SonicWall|SonicOS|...|EventID|EventName|Sev|extension +# where `extension` carries the same k=v pairs as the KV variant. # -# Implementation -# 1. Parsing the RAW field containing the PfSense -# 2. Parsing headers of syslog the message +# References +# - https://www.sonicwall.com/techdocs/pdf/sonicos-6-5-4-log-events-reference-guide.pdf +# - https://www.sonicwall.com/techdocs/pdf/SonicOS-X_7.0.1_LogEvents_ReferenceGuide.pdf pipeline: - dataTypes: [firewall-sonicwall] order: 27 # global pipeline order -- unique across all filters, customer-adjustable steps: - #......................................................................# - #......................................................................# - # Using grok to parse syslogHeader of the message - #......................................................................# + # ------------------------------------------------------------------- + # Syslog header () + # ------------------------------------------------------------------- - grok: + source: raw patterns: - - fieldName: log.priority - pattern: '\<{{.data}}\>' - - fieldName: log.syslogVersion - pattern: '{{.integer}}' - - fieldName: log.dvcTime - pattern: '{{.year}}-{{.monthNumber}}-{{.monthDay}}{{.space}}{{.time}}' - - fieldName: log.syslogHost - pattern: '{{.hostname}}' - - fieldName: log.irrelevant - pattern: '{{.word}}\=' - - fieldName: log.id + - fieldName: log.syslogPri + pattern: '\<{{.integer}}\>' + + - trim: + function: prefix + substring: "<" + fields: + - log.syslogPri + - trim: + function: suffix + substring: ">" + fields: + - log.syslogPri + + # ------------------------------------------------------------------- + # CEF header (only when the log line contains "CEF:") + # ------------------------------------------------------------------- + - grok: + source: raw + patterns: + - fieldName: "" + pattern: '{{.data}}CEF:' + - fieldName: log.cefVersion pattern: '{{.integer}}' - - fieldName: log.msgAll - pattern: '{{.greedy}}' + - fieldName: "" + pattern: '\|' + - fieldName: log.deviceVendor + pattern: '{{.data}}' + - fieldName: "" + pattern: '\|' + - fieldName: log.deviceProduct + pattern: '{{.data}}' + - fieldName: "" + pattern: '\|' + - fieldName: log.deviceVersion + pattern: '{{.data}}' + - fieldName: "" + pattern: '\|' + - fieldName: log.eventCode + pattern: '{{.data}}' + - fieldName: "" + pattern: '\|' + - fieldName: log.eventName + pattern: '{{.data}}' + - fieldName: "" + pattern: '\|' + - fieldName: log.cefSeverity + pattern: '{{.data}}' + - fieldName: "" + pattern: '\|' + where: contains("raw", "CEF:") + + # ------------------------------------------------------------------- + # Key/Value pass over raw + # ------------------------------------------------------------------- + - kv: source: raw + fieldSplit: " " + valueSplit: "=" + # ------------------------------------------------------------------- + # Rescue quoted / space-bearing values. + # ------------------------------------------------------------------- + - delete: + fields: + - log.msg + where: contains("raw", "msg=\"") - grok: + source: raw patterns: - - fieldName: log.dvcTime - pattern: '{{.monthName}}{{.space}}{{.monthDay}}{{.space}}{{.time}}' - - fieldName: log.srcIp - pattern: '{{.ipv4}}' - - fieldName: log.msgAll + - fieldName: log.grokTrash + pattern: '{{.data}}(msg=)' + - fieldName: log.message + pattern: '{{.data}}({{.word}}=)' + - fieldName: log.grokTrash pattern: '{{.greedy}}' - source: raw + where: contains("raw", "msg=\"") + - delete: + fields: + - log.note + where: contains("raw", "note=\"") - grok: + source: raw patterns: - - fieldName: log.priority - pattern: '\<{{.data}}\>' - - fieldName: log.irrelevant - pattern: '{{.data}}\=' - - fieldName: log.device - pattern: '{{.word}}' - - fieldName: log.irrelevant1 - pattern: '{{.data}}\=' - - fieldName: log.sn - pattern: '{{.word}}' - - fieldName: log.irrelevant2 - pattern: '{{.data}}\"' - - fieldName: log.dvcTime - pattern: '{{.year}}-{{.monthNumber}}-{{.monthDay}}{{.space}}{{.time}}' - - fieldName: log.irrelevant3 - pattern: '{{.data}}\=' - - fieldName: log.srcIp - pattern: '{{.ipv4}}' - - fieldName: log.msgAll + - fieldName: log.grokTrash + pattern: '{{.data}}(note=)' + - fieldName: log.note + pattern: '{{.data}}({{.word}}=)' + - fieldName: log.grokTrash pattern: '{{.greedy}}' - source: raw + where: contains("raw", "note=\"") - # ......................................................................# - # Checking if the log is in CEF format - #......................................................................# - # Using grok to parse syslogHeader of the message - # ......................................................................# + - delete: + fields: + - log.Category + where: contains("raw", "Category=\"") - grok: + source: raw patterns: - - fieldName: log.priority - pattern: '\<{{.data}}\>' - - fieldName: log.syslogVersion - pattern: '{{.integer}}' - - fieldName: log.dvcTime - pattern: '{{.year}}-{{.monthNumber}}-{{.monthDay}}{{.space}}{{.time}}' - - fieldName: log.syslogHost - pattern: '{{.hostname}}' - - fieldName: log.formatType - pattern: '(CEF:)' - - fieldName: log.formatVersion - pattern: '(\s)?{{.integer}}' - - fieldName: log.cefMsgAll + - fieldName: log.grokTrash + pattern: '{{.data}}(Category=)' + - fieldName: log.contentCategory + pattern: '{{.data}}({{.word}}=)' + - fieldName: log.grokTrash pattern: '{{.greedy}}' - source: log.msgAll - where: contains("log.msgAll", "CEF:") + where: contains("raw", "Category=\"") + - delete: + fields: + - log.rule + where: contains("raw", "rule=\"") - grok: + source: raw patterns: - - fieldName: log.dvcTime - pattern: '((?i)\b(?:jan(?:uary)?|feb(?:ruary)?|mar(?:ch)?|apr(?:il)?|may|jun(?:e)?|jul(?:y)?|aug(?:ust)?|sep(?:tember)?|oct(?:ober)?|nov(?:ember)?|dec(?:ember)?)\b){{.space}}{{.monthDay}}{{.space}}{{.year}}{{.space}}{{.time}}' - - fieldName: log.sn - pattern: '{{.word}}' - - fieldName: log.formatType - pattern: '(CEF:)' - - fieldName: log.formatVersion - pattern: '{{.integer}}' - - fieldName: log.cefMsgAll + - fieldName: log.grokTrash + pattern: '{{.data}}(rule=)' + - fieldName: log.rule + pattern: '{{.data}}({{.word}}=)' + - fieldName: log.grokTrash pattern: '{{.greedy}}' - source: log.msgAll - where: contains("log.msgAll", "CEF:") + where: contains("raw", "rule=\"") - #......................................................................# - # Removing unnecessary characters of the syslogHeader - #......................................................................# - - trim: - function: prefix - substring: "<" - fields: - - log.priority - - trim: - function: suffix - substring: ">" - fields: - - log.priority - - trim: - function: suffix - substring: ":" + - delete: fields: - - log.formatType - - #......................................................................# - # Using grok to parse CEF fields - #......................................................................# + - log.sess + where: contains("raw", "sess=\"") - grok: + source: raw patterns: - - fieldName: log.dvcVendor - pattern: '\|{{.data}}\|' - - fieldName: log.dvcProduct - pattern: '{{.data}}\|' - - fieldName: log.dvcVersion - pattern: '{{.data}}\|' - - fieldName: log.eventId - pattern: '{{.data}}\|' - - fieldName: log.eventName - pattern: '{{.data}}\|' - - fieldName: log.severity - pattern: '{{.data}}\|' - - fieldName: log.msgAll + - fieldName: log.grokTrash + pattern: '{{.data}}(sess=)' + - fieldName: log.sessionType + pattern: '{{.data}}({{.word}}=)' + - fieldName: log.grokTrash pattern: '{{.greedy}}' - source: log.cefMsgAll + where: contains("raw", "sess=\"") - - trim: - function: prefix - substring: "|" - fields: - - log.dvcVendor - - - trim: - function: suffix - substring: "|" + - delete: fields: - - log.dvcVendor - - log.dvcProduct - - log.dvcVersion - - log.eventId - - log.eventName - - log.severity - - # Using grok to extract values with spaces in fields + - log.vpnpolicy + where: contains("raw", "vpnpolicy=\"") - grok: + source: raw patterns: - - fieldName: log.trash - pattern: '{{.data}}msg=' - - fieldName: log.message - pattern: '\"{{.data}}\"' - - fieldName: log.trash2 + - fieldName: log.grokTrash + pattern: '{{.data}}(vpnpolicy=)' + - fieldName: log.vpnPolicy + pattern: '{{.data}}({{.word}}=)' + - fieldName: log.grokTrash pattern: '{{.greedy}}' - source: raw + where: contains("raw", "vpnpolicy=\"") + - delete: + fields: + - log.usr + where: contains("raw", "usr=\"") - grok: + source: raw patterns: - - fieldName: log.trash1 - pattern: '{{.data}}ipscat=' - - fieldName: log.ipscat1 - pattern: '\"{{.data}}\"' - - fieldName: log.trash3 + - fieldName: log.grokTrash + pattern: '{{.data}}(usr=)' + - fieldName: log.userRaw + pattern: '{{.data}}({{.word}}=)' + - fieldName: log.grokTrash pattern: '{{.greedy}}' - source: raw + where: contains("raw", "usr=\"") + - delete: + fields: + - log.uuid + where: contains("raw", "uuid=\"") - grok: + source: raw patterns: - - fieldName: log.trash4 - pattern: '{{.data}}cs6=' - - fieldName: log.cs61 - pattern: '\"{{.data}}\"' - - fieldName: log.trash5 + - fieldName: log.grokTrash + pattern: '{{.data}}(uuid=)' + - fieldName: log.eventUuid + pattern: '{{.data}}({{.word}}=)' + - fieldName: log.grokTrash pattern: '{{.greedy}}' - source: raw + where: contains("raw", "uuid=\"") + - delete: + fields: + - log.fwaction + where: contains("raw", "fw_action=\"") - grok: + source: raw patterns: - - fieldName: log.trash6 - pattern: '{{.data}}rule=' - - fieldName: log.rule1 - pattern: '\"{{.data}}\"' - - fieldName: log.trash7 + - fieldName: log.grokTrash + pattern: '{{.data}}(fw_action=)' + - fieldName: log.actionRaw + pattern: '{{.data}}({{.word}}=)' + - fieldName: log.grokTrash pattern: '{{.greedy}}' - source: raw + where: contains("raw", "fw_action=\"") + - delete: + fields: + - log.appName + where: contains("raw", "appName='") - grok: + source: raw patterns: - - fieldName: log.trash8 - pattern: '{{.data}}Category=' - - fieldName: log.category1 - pattern: '\"{{.data}}\"' - - fieldName: log.trash9 + - fieldName: log.grokTrash + pattern: '{{.data}}(appName=)' + - fieldName: log.appName + pattern: '{{.data}}({{.word}}=)' + - fieldName: log.grokTrash pattern: '{{.greedy}}' - source: raw + where: contains("raw", "appName='") + - delete: + fields: + - log.time + where: contains("raw", "time=\"") - grok: + source: raw patterns: - - fieldName: log.trash10 - pattern: '{{.data}}note=' - - fieldName: log.note1 - pattern: '\"{{.data}}\"' - - fieldName: log.trash11 + - fieldName: log.grokTrash + pattern: '{{.data}}(time=)' + - fieldName: log.deviceTimeRaw + pattern: '{{.data}}({{.word}}=)' + - fieldName: log.grokTrash pattern: '{{.greedy}}' - source: raw + where: contains("raw", "time=\"") - - trim: - function: prefix - substring: '"' - fields: - - log.message - - log.note1 - - log.ipscat1 - - log.cs61 - - log.rule1 - - log.category1 - - log.fwaction + # ------------------------------------------------------------------- + # Strip the trailing `word=` that the rescue groks include in + # the captured value. + # ------------------------------------------------------------------- + - grok: + source: log.message + patterns: + - fieldName: log.message + pattern: '{{.greedy}}{{.space}}' + - fieldName: log.grokTrash + pattern: '{{.word}}(=)' + where: exists("log.message") - - trim: - function: suffix - substring: '"' - fields: - - log.message - - log.note1 - - log.ipscat1 - - log.cs61 - - log.rule1 - - log.category1 - - log.fwaction + - grok: + source: log.note + patterns: + - fieldName: log.note + pattern: '{{.greedy}}{{.space}}' + - fieldName: log.grokTrash + pattern: '{{.word}}(=)' + where: exists("log.note") - #......................................................................# - # Using kv to parse msgAll components from syslog format only - #......................................................................# - - kv: - fieldSplit: " " - valueSplit: "=" - source: log.msgAll + - grok: + source: log.contentCategory + patterns: + - fieldName: log.contentCategory + pattern: '{{.greedy}}{{.space}}' + - fieldName: log.grokTrash + pattern: '{{.word}}(=)' + where: exists("log.contentCategory") + + - grok: + source: log.rule + patterns: + - fieldName: log.rule + pattern: '{{.greedy}}{{.space}}' + - fieldName: log.grokTrash + pattern: '{{.word}}(=)' + where: exists("log.rule") + + - grok: + source: log.sessionType + patterns: + - fieldName: log.sessionType + pattern: '{{.greedy}}{{.space}}' + - fieldName: log.grokTrash + pattern: '{{.word}}(=)' + where: exists("log.sessionType") + + - grok: + source: log.vpnPolicy + patterns: + - fieldName: log.vpnPolicy + pattern: '{{.greedy}}{{.space}}' + - fieldName: log.grokTrash + pattern: '{{.word}}(=)' + where: exists("log.vpnPolicy") + + - grok: + source: log.userRaw + patterns: + - fieldName: log.userRaw + pattern: '{{.greedy}}{{.space}}' + - fieldName: log.grokTrash + pattern: '{{.word}}(=)' + where: exists("log.userRaw") + + - grok: + source: log.eventUuid + patterns: + - fieldName: log.eventUuid + pattern: '{{.greedy}}{{.space}}' + - fieldName: log.grokTrash + pattern: '{{.word}}(=)' + where: exists("log.eventUuid") + + - grok: + source: log.actionRaw + patterns: + - fieldName: log.actionRaw + pattern: '{{.greedy}}{{.space}}' + - fieldName: log.grokTrash + pattern: '{{.word}}(=)' + where: exists("log.actionRaw") + + - grok: + source: log.appName + patterns: + - fieldName: log.appName + pattern: '{{.greedy}}{{.space}}' + - fieldName: log.grokTrash + pattern: '{{.word}}(=)' + where: exists("log.appName") + + - grok: + source: log.deviceTimeRaw + patterns: + - fieldName: log.deviceTimeRaw + pattern: '{{.greedy}}{{.space}}' + - fieldName: log.grokTrash + pattern: '{{.word}}(=)' + where: exists("log.deviceTimeRaw") + + # ------------------------------------------------------------------- + # Split src / dst => ip[:port[:iface]] + # ------------------------------------------------------------------- + - grok: + source: log.src + patterns: + - fieldName: origin.ip + pattern: '{{.ipv4}}' + - fieldName: "" + pattern: ':' + - fieldName: origin.port + pattern: '{{.integer}}' + - fieldName: "" + pattern: ':' + - fieldName: log.sourceInterface + pattern: '{{.word}}' + where: contains("log.src", ":") + + - delete: + fields: + - log.src + where: contains("log.src", ":") - # ................................................# - # Rename fields - # ................................................# - rename: from: + - log.src + to: origin.ip + + - grok: + source: log.dst + patterns: + - fieldName: target.ip + pattern: '{{.ipv4}}' + - fieldName: "" + pattern: ':' + - fieldName: target.port + pattern: '{{.integer}}' + - fieldName: "" + pattern: ':' + - fieldName: log.targetInterface + pattern: '{{.word}}' + where: contains("log.dst", ":") + + - delete: + fields: - log.dst - to: target.ip + where: contains("log.dst", ":") + - rename: from: - - log.dstname - to: target.host + - log.dst + to: target.ip + + - grok: + source: log.natSrc + patterns: + - fieldName: log.natSourceIp + pattern: '{{.ipv4}}' + - fieldName: "" + pattern: ':' + - fieldName: log.natSourcePort + pattern: '{{.integer}}' + where: contains("log.natSrc", ":") + + - delete: + fields: + - log.natSrc + where: contains("log.natSrc", ":") + + - grok: + source: log.natDst + patterns: + - fieldName: log.natTargetIp + pattern: '{{.ipv4}}' + - fieldName: "" + pattern: ':' + - fieldName: log.natTargetPort + pattern: '{{.integer}}' + where: contains("log.natDst", ":") + + - delete: + fields: + - log.natDst + where: contains("log.natDst", ":") + + # ------------------------------------------------------------------- + # Split protocol => transport / service + # ------------------------------------------------------------------- + - grok: + source: log.proto + patterns: + - fieldName: protocol + pattern: '{{.word}}' + - fieldName: "" + pattern: '/' + - fieldName: log.appProto + pattern: '{{.notSpace}}' + where: contains("log.proto", "/") + + - delete: + fields: + - log.proto + where: contains("log.proto", "/") + - rename: from: - log.proto to: protocol + + # ------------------------------------------------------------------- + # Canonical + human-readable renames + # ------------------------------------------------------------------- - rename: from: - - log.src - to: origin.ip + - log.dstname + to: target.host - rename: from: - - log.fwaction - to: action + - log.srcMac + to: origin.mac - rename: from: - log.dstMac to: target.mac - rename: from: - - log.srcMac + - log.smac to: origin.mac - rename: from: @@ -298,188 +484,358 @@ pipeline: to: target.mac - rename: from: - - log.smac - to: origin.mac + - log.sent + to: origin.bytesSent - rename: from: - - log.message - to: log.msg + - log.rcvd + to: origin.bytesReceived + - rename: + from: + - log.spkt + to: origin.packagesSent + - rename: + from: + - log.rpkt + to: origin.packagesReceived + - rename: + from: + - log.id + to: log.sourceId + - rename: + from: + - log.sn + to: log.deviceSerial + - rename: + from: + - log.fw + to: log.deviceIp + - rename: + from: + - log.pri + to: log.priority + - rename: + from: + - log.c + to: log.messageClass + - rename: + from: + - log.gcat + to: log.groupCategoryId + - rename: + from: + - log.m + to: log.eventCode + - rename: + from: + - log.n + to: log.eventSerial + - rename: + from: + - log.app + to: log.appId + - rename: + from: + - log.srcZone + to: log.sourceZone + - rename: + from: + - log.dstZone + to: log.targetZone + - rename: + from: + - log.code + to: log.contentCode + - rename: + from: + - log.arg + to: log.webPath + - rename: + from: + - log.dpi + to: log.dpiEnabled + - rename: + from: + - log.ipscat + to: log.ipsCategory + - rename: + from: + - log.ipspri + to: log.ipsPriority - rename: from: - - log.note1 - to: log.note + - log.spycat + to: log.spywareCategory - rename: from: - - log.ipscat1 - to: log.ipscat + - log.spypri + to: log.spywarePriority + - rename: + from: + - log.af_service + to: log.appFirewallService + - rename: + from: + - log.af_type + to: log.appFirewallType + - rename: + from: + - log.result + to: log.threatResult + - rename: + from: + - log.cs6 + to: log.threatContext + + # ------------------------------------------------------------------- + # Strip residual quotes / apostrophes from rescued values. + # ------------------------------------------------------------------- + - trim: + function: prefix + substring: '"' + fields: + - log.message + - log.note + - log.contentCategory + - log.rule + - log.sessionType + - log.vpnPolicy + - log.eventUuid + - log.deviceTimeRaw + - log.actionRaw + - log.userRaw + - trim: + function: suffix + substring: '"' + fields: + - log.message + - log.note + - log.contentCategory + - log.rule + - log.sessionType + - log.vpnPolicy + - log.eventUuid + - log.deviceTimeRaw + - log.actionRaw + - log.userRaw + - trim: + function: prefix + substring: "'" + fields: + - log.appName + - trim: + function: suffix + substring: "'" + fields: + - log.appName + - rename: from: - - log.cs61 - to: log.cs6 + - log.actionRaw + to: action - rename: from: - - log.rule1 - to: log.rule + - log.userRaw + to: origin.user + - rename: from: - - log.category1 - to: log.category + - log.fwaction + to: action - # .......................................................................# - # Fields conversions - # .......................................................................# + # ------------------------------------------------------------------- + # Type casts + # ------------------------------------------------------------------- - cast: fields: - - log.gcat + - origin.port + - target.port + - log.natSourcePort + - log.natTargetPort + to: int + - cast: + fields: + - origin.bytesSent + - origin.bytesReceived + to: float + - cast: + fields: + - origin.packagesSent + - origin.packagesReceived + to: int + - cast: + fields: + - log.groupCategoryId + - log.eventCode + - log.priority to: string - #......................................................................# - # Adding action result - #......................................................................# + # ------------------------------------------------------------------- + # actionResult (canonical vocabulary) + # ------------------------------------------------------------------- - add: function: string params: key: actionResult - value: "forward" - where: 'equals("action", "forward")' + value: success + where: equals("action", "forward") - add: function: string params: key: actionResult - value: "blocked" - where: 'equals("action", "drop")' + value: denied + where: oneOf("action", ["drop", "dropped", "deny", "denied", "block", "blocked"]) - #......................................................................# - # Define Syslog Group Category (gcat) Values - #......................................................................# + # ------------------------------------------------------------------- + # Group category human label from log.groupCategoryId (1..17) + # ------------------------------------------------------------------- - add: - function: 'string' + function: string params: key: log.groupCategory - value: 'System' - where: equals("log.gcat", "1") - + value: System + where: equals("log.groupCategoryId", "1") - add: - function: 'string' + function: string params: key: log.groupCategory - value: 'Log' - where: equals("log.gcat", "2") - + value: Log + where: equals("log.groupCategoryId", "2") - add: - function: 'string' + function: string params: key: log.groupCategory - value: 'Security Services' - where: equals("log.gcat", "3") - + value: Security Services + where: equals("log.groupCategoryId", "3") - add: - function: 'string' + function: string params: key: log.groupCategory - value: 'Users' - where: equals("log.gcat", "4") - + value: Users + where: equals("log.groupCategoryId", "4") - add: - function: 'string' + function: string params: key: log.groupCategory - value: 'Firewall Settings' - where: equals("log.gcat", "5") - + value: Firewall Settings + where: equals("log.groupCategoryId", "5") - add: - function: 'string' + function: string params: key: log.groupCategory - value: 'Network' - where: equals("log.gcat", "6") - + value: Network + where: equals("log.groupCategoryId", "6") - add: - function: 'string' + function: string params: key: log.groupCategory - value: 'VPN' - where: equals("log.gcat", "7") - + value: VPN + where: equals("log.groupCategoryId", "7") - add: - function: 'string' + function: string params: key: log.groupCategory - value: 'High Availability' - where: equals("log.gcat", "8") - + value: High Availability + where: equals("log.groupCategoryId", "8") - add: - function: 'string' + function: string params: key: log.groupCategory - value: '3G/4G, Modem, and Module' - where: equals("log.gcat", "9") - + value: 3G/4G, Modem, and Module + where: equals("log.groupCategoryId", "9") - add: - function: 'string' + function: string params: key: log.groupCategory - value: 'Firewall' - where: equals("log.gcat", "10") - + value: Firewall + where: equals("log.groupCategoryId", "10") - add: - function: 'string' + function: string params: key: log.groupCategory - value: 'Wireless' - where: equals("log.gcat", "11") - + value: Wireless + where: equals("log.groupCategoryId", "11") - add: - function: 'string' + function: string params: key: log.groupCategory - value: 'VoIP' - where: equals("log.gcat", "12") - + value: VoIP + where: equals("log.groupCategoryId", "12") - add: - function: 'string' + function: string params: key: log.groupCategory - value: 'SSL VPN' - where: equals("log.gcat", "13") - + value: SSL VPN + where: equals("log.groupCategoryId", "13") - add: - function: 'string' + function: string params: key: log.groupCategory - value: 'Anti-Spam' - where: equals("log.gcat", "14") - + value: Anti-Spam + where: equals("log.groupCategoryId", "14") - add: - function: 'string' + function: string params: key: log.groupCategory - value: 'WAN Acceleration' - where: equals("log.gcat", "15") - + value: WAN Acceleration + where: equals("log.groupCategoryId", "15") - add: - function: 'string' + function: string params: key: log.groupCategory - value: 'SD-WAN' - where: equals("log.gcat", "16") - + value: SD-WAN + where: equals("log.groupCategoryId", "16") - add: - function: 'string' + function: string params: key: log.groupCategory - value: 'Multi-Tenancy' - where: equals("log.gcat", "17") + value: Multi-Tenancy + where: equals("log.groupCategoryId", "17") - # Adding geolocation to origin.ip + # ------------------------------------------------------------------- + # Severity from syslog priority (SonicWall log.priority = 0..7) + # ------------------------------------------------------------------- + - add: + function: string + params: + key: severity + value: critical + where: oneOf("log.priority", ["0", "1", "2"]) + - add: + function: string + params: + key: severity + value: error + where: equals("log.priority", "3") + - add: + function: string + params: + key: severity + value: warning + where: equals("log.priority", "4") + - add: + function: string + params: + key: severity + value: info + where: oneOf("log.priority", ["5", "6"]) + - add: + function: string + params: + key: severity + value: debug + where: equals("log.priority", "7") + + # ------------------------------------------------------------------- + # Geolocation + # ------------------------------------------------------------------- - dynamic: plugin: com.utmstack.geolocation params: source: origin.ip destination: origin.geolocation where: exists("origin.ip") - - # Adding geolocation to target.ip + - dynamic: plugin: com.utmstack.geolocation params: @@ -487,56 +843,12 @@ pipeline: destination: target.geolocation where: exists("target.ip") - # .......................................................................# - # Adding severity based on log.pri - # .......................................................................# - - add: - function: 'string' - params: - key: severity - value: 'high' - where: oneOf("log.pri", ["0", "1", "2", "3"]) - - add: - function: 'string' - params: - key: severity - value: 'medium' - where: equals("log.pri", "4") - - add: - function: 'string' - params: - key: severity - value: 'low' - where: oneOf("log.pri", ["5", "6", "7"]) - - # ..........................................................................# - # Removing unnuse fields - #.........................................................................# + # ------------------------------------------------------------------- + # 13. Cleanup + # ------------------------------------------------------------------- - delete: fields: - - log.irrelevant - - log.irrelevant1 - - log.irrelevant2 - - log.irrelevant3 - - log.msgAll - - log.cefMsgAll - - log.pri - - log.gcat - - log.message - - log.note1 - - log.ipscat1 - - log.cs61 - - log.rule1 - - log.category1 - - log.trash - - log.trash1 - - log.trash2 - - log.trash3 - - log.trash4 - - log.trash5 - - log.trash6 - - log.trash7 - - log.trash8 - - log.trash9 - - log.trash10 - - log.trash11 \ No newline at end of file + - log.syslogPri + - log.cefVersion + - log.fwaction + - log.grokTrash \ No newline at end of file diff --git a/definitions/rules/sonicwall/sonicwall_firewall/anti_spyware_detection.yaml b/definitions/rules/sonicwall/sonicwall_firewall/anti_spyware_detection.yaml index 306b41fc3..c49ade83d 100644 --- a/definitions/rules/sonicwall/sonicwall_firewall/anti_spyware_detection.yaml +++ b/definitions/rules/sonicwall/sonicwall_firewall/anti_spyware_detection.yaml @@ -1,4 +1,4 @@ -# Rule version v1.0.0 +# Rule version v2.1.0 dataTypes: - firewall-sonicwall @@ -14,25 +14,28 @@ references: - https://www.sonicwall.com/techdocs/pdf/sonicos-6-5-4-log-events-reference-guide.pdf - https://attack.mitre.org/techniques/T1082/ description: | - Detects when SonicWall Anti-Spyware service identifies and blocks spyware, adware, or other potentially unwanted programs (PUPs) that may be attempting to collect sensitive information or establish persistence on the network. + Detects when SonicWall Anti-Spyware service identifies and blocks spyware, + adware or other potentially unwanted programs (PUPs) that may be attempting + to collect sensitive information or establish persistence on the network. Next Steps: - - Review the detected spyware category and priority level - - Investigate the source IP address for other malicious activities - - Check if the blocked spyware represents a targeted attack or widespread infection - - Verify that Anti-Spyware policies are properly configured and up-to-date - - Consider quarantining the affected host if multiple spyware detections occur - - Review network traffic patterns from the source to identify potential data exfiltration + - Review the detected spyware category and priority level. + - Investigate the source IP for other malicious activities. + - Check whether the blocked spyware represents a targeted attack or a + widespread infection. + - Verify Anti-Spyware policies are properly configured and signatures + up-to-date. + - Consider quarantining the affected host if multiple detections cluster + on the same source. where: | - (exists("log.spycat") || - contains("log.message", "spyware") || - contains("log.message", "Anti-Spyware") || - contains("log.eventName", "Anti-Spyware") || - contains("log.category", "Anti-Spyware") || - (exists("log.spypri") && !equals("log.spypri", "0"))) && - (equals("action", "blocked") || equals("log.fw_action", "drop")) + ( + oneOf("log.eventCode", ["1157", "1158", "1159"]) || + exists("log.spywareCategory") || + contains("log.message", ["spyware", "Anti-Spyware"]) || + contains("log.contentCategory", "Anti-Spyware") + ) && equals("actionResult", "denied") afterEvents: - - with: + with: - field: origin.ip operator: filter_term value: '{{.origin.ip}}' diff --git a/definitions/rules/sonicwall/sonicwall_firewall/botnet_detection.yaml b/definitions/rules/sonicwall/sonicwall_firewall/botnet_detection.yaml index 08bf12ec0..8f5a0c973 100644 --- a/definitions/rules/sonicwall/sonicwall_firewall/botnet_detection.yaml +++ b/definitions/rules/sonicwall/sonicwall_firewall/botnet_detection.yaml @@ -1,4 +1,4 @@ -# Rule version v1.0.0 +# Rule version v2.1.0 dataTypes: - firewall-sonicwall @@ -14,24 +14,29 @@ references: - https://www.sonicwall.com/support/knowledge-base/understanding-geo-ip-and-botnet-filter-diagnostics-options/200527122256150 - https://attack.mitre.org/techniques/T1071/ description: | - Detects potential botnet command and control (C2) communication or infected host behavior identified by SonicWall's botnet filter. This includes suspicious outbound connections, HTML infection chains, or known botnet signatures. + Detects potential botnet command and control (C2) communication identified + by the SonicWall Botnet Filter. Includes matches against SonicWall's Botnet + Filter signature codes and message text indicating known botnet endpoints. Next Steps: - 1. Investigate the source IP for additional suspicious activity - 2. Check network logs for other connections from the same host - 3. Analyze DNS queries from the affected host - 4. Review endpoint logs for signs of malware infection - 5. Consider isolating the affected host if infection is confirmed - 6. Update threat intelligence feeds and security signatures - 7. Scan the host with updated antivirus/anti-malware tools -where: (equals("log.category", "Botnet") || contains("log.message", "botnet") || contains("log.message", "infected") || contains("log.message", "C&C") || contains("log.message", "command and control") || equals("log.af_service", "botnet")) && (equals("action", "blocked") || equals("action", "dropped") || equals("log.fw_action", "drop")) + 1. Investigate the source IP for other suspicious behavior (DNS, beaconing). + 2. Check endpoint logs on the internal host for signs of infection. + 3. Isolate the affected host if infection is confirmed. + 4. Update threat intel feeds and blocklists with the observed C2 endpoint. +where: | + ( + oneOf("log.eventCode", ["1370", "1371"]) || + equals("log.appFirewallService", "botnet") || + contains("log.message", ["botnet", "Botnet", "infected", "C&C", "command and control"]) || + contains("log.contentCategory", "Botnet") + ) && equals("actionResult", "denied") afterEvents: - - with: + with: - field: origin.ip operator: filter_term value: '{{.origin.ip}}' within: 2h - count: 10 + count: 5 groupBy: - adversary.ip - target.ip diff --git a/definitions/rules/sonicwall/sonicwall_firewall/capture_atp_verdicts.yaml b/definitions/rules/sonicwall/sonicwall_firewall/capture_atp_verdicts.yaml index 8ba59ea91..46c2cc0a9 100644 --- a/definitions/rules/sonicwall/sonicwall_firewall/capture_atp_verdicts.yaml +++ b/definitions/rules/sonicwall/sonicwall_firewall/capture_atp_verdicts.yaml @@ -1,4 +1,4 @@ -# Rule version v1.0.0 +# Rule version v2.1.0 dataTypes: - firewall-sonicwall @@ -14,23 +14,36 @@ references: - https://www.sonicwall.com/support/knowledge-base/capture-atp-overview/170503785055490 - https://attack.mitre.org/techniques/T1204/ description: | - Detects when SonicWall Capture ATP (Advanced Threat Protection) identifies a file as malicious after sandbox analysis. This indicates an attempted malware delivery or execution that was blocked by the ATP service. + Detects when SonicWall Capture ATP (Advanced Threat Protection) sandboxes a + file and returns a malicious verdict. Indicates an attempted malware + delivery. Also covers RTDMI (Real-Time Deep Memory Inspection) verdicts + which share the ATP verdict pipeline on the firewall. Next Steps: - 1. Investigate the source IP address for additional malicious activity - 2. Review the file hash and name for threat intelligence correlation - 3. Check if the same file was delivered to other internal systems - 4. Verify ATP policies are properly configured and up to date - 5. Consider blocking the source IP at the perimeter if confirmed malicious - 6. Document the incident and update threat intelligence feeds -where: (contains("log.msg", "Capture ATP") || contains("log.msg", "Gateway Anti-Virus") || contains("log.msg", "Sandbox") || equals("log.category", "Anti-Virus") || equals("log.af_type", "ATP")) && (contains("log.msg", "malicious") || contains("log.msg", "blocked") || contains("log.msg", "threat detected") || equals("log.result", "malicious") || equals("action", "blocked")) + 1. Investigate the source IP for additional malicious activity. + 2. Pivot on the file hash / URL captured in `log.note` against threat intel. + 3. Check whether the same file reached other internal systems. + 4. Verify ATP policies and enforce automated blocking if not already set. +where: | + ( + oneOf("log.eventCode", ["1440", "1441"]) || + equals("log.appFirewallType", "ATP") || + contains("log.message", ["Capture ATP", "Sandbox", "RTDMI"]) || + contains("log.note", ["Capture ATP", "malicious verdict", "ATP verdict"]) + ) && + ( + equals("log.threatResult", "malicious") || + contains("log.message", ["malicious", "threat"]) || + contains("log.note", ["malicious", "threat"]) || + equals("actionResult", "denied") + ) afterEvents: - - with: + with: - field: origin.ip operator: filter_term value: '{{.origin.ip}}' within: 1h - count: 2 + count: 1 groupBy: - adversary.host - adversary.ip diff --git a/definitions/rules/sonicwall/sonicwall_firewall/capture_client_threats.yaml b/definitions/rules/sonicwall/sonicwall_firewall/capture_client_threats.yaml deleted file mode 100644 index e62d849db..000000000 --- a/definitions/rules/sonicwall/sonicwall_firewall/capture_client_threats.yaml +++ /dev/null @@ -1,30 +0,0 @@ -# Rule version v1.0.0 - -dataTypes: - - firewall-sonicwall -name: SonicWall Capture Client Threat Detection -impact: - confidentiality: 3 - integrity: 3 - availability: 2 -category: Defense Evasion, Privilege Escalation -technique: "T1055 - Process Injection" -adversary: origin -references: - - https://www.sonicwall.com/techdocs/pdf/sonicos-6-5-4-log-events-reference-guide.pdf - - https://attack.mitre.org/techniques/T1055/ -description: | - Detects threats identified by SonicWall Capture Client including advanced malware, zero-day exploits, and sophisticated attack techniques. Capture Client provides advanced threat protection through sandboxing and behavioral analysis. - - Next Steps: - 1. Immediately isolate the affected host to prevent lateral movement - 2. Review the specific threat details in SonicWall management console - 3. Analyze the malware sample if available for attribution and IOCs - 4. Check for any successful file downloads or executions on the host - 5. Scan the host with updated antivirus signatures - 6. Review network traffic for any data exfiltration attempts - 7. Update security policies if new attack vectors are identified -where: (contains("log.msg", "Capture Client") || contains("log.app", "Capture") || contains("log.category", "Capture")) && (exists("log.ipscat") || exists("log.ipspri") || exists("log.dpi") || equals("log.action", "drop")) -groupBy: - - adversary.host - - adversary.ip diff --git a/definitions/rules/sonicwall/sonicwall_firewall/encrypted_threats_detection.yaml b/definitions/rules/sonicwall/sonicwall_firewall/encrypted_threats_detection.yaml deleted file mode 100644 index 52698c4c7..000000000 --- a/definitions/rules/sonicwall/sonicwall_firewall/encrypted_threats_detection.yaml +++ /dev/null @@ -1,40 +0,0 @@ -# Rule version v1.0.0 - -dataTypes: - - firewall-sonicwall -name: SonicWall Encrypted Threats Detection -impact: - confidentiality: 3 - integrity: 3 - availability: 2 -category: Command and Control -technique: "T1573 - Encrypted Channel" -adversary: origin -references: - - https://www.sonicwall.com/solutions/advanced-threats/encrypted-threats/ - - https://attack.mitre.org/techniques/T1573/ -description: | - Detects threats hidden in encrypted traffic identified by SonicWall DPI-SSL (Deep Packet Inspection of SSL/TLS) including malware, exploits, and data exfiltration attempts over encrypted channels. This rule identifies when SonicWall's advanced threat protection has detected malicious activity within encrypted communications. - - Next Steps: - 1. Review the specific threat type and category identified in the event details - 2. Examine the source and destination IP addresses for indicators of compromise - 3. Check the SSL/TLS certificate details and validation status - 4. Investigate the application or service attempting the encrypted communication - 5. Review network traffic patterns to identify potential data exfiltration - 6. Consider temporarily blocking the source IP if malicious activity is confirmed - 7. Update security policies to prevent similar encrypted threats - 8. Document findings for threat intelligence and future prevention -where: | - (contains("log.eventName", "SSL") || contains("log.eventName", "TLS") || contains("log.eventName", "encrypted") || contains("log.eventName", "DPI-SSL") || contains("log.message", "SSL") || contains("log.message", "TLS") || contains("log.message", "encrypted") || contains("protocol", "SSL") || contains("protocol", "TLS")) && - (contains("log.eventName", "threat") || contains("log.eventName", "malware") || contains("log.eventName", "blocked") || contains("log.eventName", "violation") || contains("log.message", "threat") || contains("log.message", "malware") || contains("log.message", "blocked") || equals("log.result", "blocked") || equals("action", "blocked") || exists("log.ipscat") || exists("log.spycat")) -afterEvents: - - with: - - field: origin.ip - operator: filter_term - value: '{{.origin.ip}}' - within: 30m - count: 3 -groupBy: - - adversary.ip - - target.ip diff --git a/definitions/rules/sonicwall/sonicwall_firewall/gateway_antivirus_detection.yaml b/definitions/rules/sonicwall/sonicwall_firewall/gateway_antivirus_detection.yaml index 9f88ad4bc..589240c3c 100644 --- a/definitions/rules/sonicwall/sonicwall_firewall/gateway_antivirus_detection.yaml +++ b/definitions/rules/sonicwall/sonicwall_firewall/gateway_antivirus_detection.yaml @@ -1,4 +1,4 @@ -# Rule version v1.0.0 +# Rule version v2.1.0 dataTypes: - firewall-sonicwall @@ -14,25 +14,24 @@ references: - https://www.sonicwall.com/techdocs/pdf/sonicos-6-5-4-log-events-reference-guide.pdf - https://attack.mitre.org/techniques/T1105/ description: | - Detects when SonicWall Gateway Anti-Virus (GAV) identifies and blocks malicious content. This indicates potential malware attempting to enter the network through web traffic, email attachments, or file downloads. The Gateway Anti-Virus service scans HTTP, HTTPS, FTP, and SMTP traffic in real-time to detect and prevent malware from entering the network perimeter. + Detects when SonicWall Gateway Anti-Virus (GAV) identifies and blocks + malicious content in HTTP/HTTPS/FTP/SMTP traffic. Signals a malware delivery + attempt at the network perimeter. Next Steps: - 1. Review the specific malware signature or threat name in the log details - 2. Investigate the source IP address and geolocation for suspicious patterns - 3. Check if the same source has attempted other malicious activities - 4. Verify that the anti-virus definitions are up to date - 5. Consider implementing additional network segmentation if internal hosts are affected - 6. Review firewall policies to ensure proper traffic filtering - 7. Escalate to incident response team if part of a coordinated attack campaign + 1. Review the malware name/signature carried in `log.message` / `log.note`. + 2. Investigate the source IP and geolocation for correlated attempts. + 3. Confirm the AV definitions are current on the firewall. + 4. Escalate to incident response if the activity is part of a broader + campaign against the tenant. where: | - (contains("log.gcat", "Gateway Anti-Virus") || - contains("log.message", "virus") || - contains("log.message", "malware") || - contains("log.eventName", "Anti-Virus") || - contains("log.category", "Anti-Virus")) && - equals("action", "blocked") + ( + oneOf("log.eventCode", ["79", "608", "609", "1122"]) || + (equals("log.groupCategory", "Security Services") && contains("log.message", ["virus", "malware", "Anti-Virus"])) || + contains("log.contentCategory", "Anti-Virus") + ) && equals("actionResult", "denied") afterEvents: - - with: + with: - field: origin.ip operator: filter_term value: '{{.origin.ip}}' diff --git a/definitions/rules/sonicwall/sonicwall_firewall/intrusion_prevention_alert.yaml b/definitions/rules/sonicwall/sonicwall_firewall/intrusion_prevention_alert.yaml index 494559ff3..416563b3d 100644 --- a/definitions/rules/sonicwall/sonicwall_firewall/intrusion_prevention_alert.yaml +++ b/definitions/rules/sonicwall/sonicwall_firewall/intrusion_prevention_alert.yaml @@ -1,4 +1,4 @@ -# Rule version v1.0.0 +# Rule version v2.1.0 dataTypes: - firewall-sonicwall @@ -14,25 +14,29 @@ references: - https://www.sonicwall.com/techdocs/pdf/sonicos-6-5-4-log-events-reference-guide.pdf - https://attack.mitre.org/techniques/T1190/ description: | - Detects when SonicWall IPS identifies and blocks intrusion attempts, including buffer overflows, SQL injection, cross-site scripting, and other network-based attacks targeting vulnerabilities. This rule triggers when the SonicWall firewall's Intrusion Prevention System detects malicious traffic patterns or known attack signatures. + Detects when SonicWall Intrusion Prevention System (IPS) blocks an attack + matching a known signature — buffer overflow attempts, SQL injection, + cross-site scripting, exploit kits, etc. Reflects the IPS Prevention Alert + message family (event codes 88 / 89 / 100 / 785) as well as the descriptive + `log.message`, `log.contentCategory` and `log.ipsCategory` fields. Next Steps: - 1. Verify the blocked attack by reviewing the SonicWall logs for attack details and signatures matched - 2. Check if the attack was successfully blocked or if any traffic bypassed the IPS - 3. Investigate the source IP for additional malicious activity or patterns - 4. Review target systems for any signs of compromise if the attack was not fully blocked - 5. Update IPS signatures if new attack patterns are discovered - 6. Consider implementing additional network segmentation if attacks are targeting critical systems - 7. Review and update security policies if necessary to prevent similar attacks + 1. Review the matched signature and CVE (if any) in `log.message` / `log.note`. + 2. Confirm the block succeeded — check for follow-up connections from the + same source that bypassed IPS. + 3. Investigate the target for compromise signs if the signature was severity + high/critical. + 4. Update IPS profile if the target service is not supposed to expose that + surface. where: | - (exists("log.ipscat") || - contains("log.message", "IPS") || - contains("log.eventName", "Intrusion") || - contains("log.category", "Intrusion Prevention") || - (exists("log.ipspri") && !equals("log.ipspri", "0"))) && - (equals("action", "blocked") || equals("log.fw_action", "drop")) + ( + oneOf("log.eventCode", ["88", "89", "100", "785"]) || + exists("log.ipsCategory") || + contains("log.message", ["IPS Detection Alert", "IPS Prevention Alert", "Intrusion"]) || + contains("log.contentCategory", "Intrusion Prevention") + ) && equals("actionResult", "denied") afterEvents: - - with: + with: - field: origin.ip operator: filter_term value: '{{.origin.ip}}' diff --git a/definitions/rules/sonicwall/sonicwall_firewall/sonicwall_admin_auth_failures.yaml b/definitions/rules/sonicwall/sonicwall_firewall/sonicwall_admin_auth_failures.yaml index 565deb796..2d8e29957 100644 --- a/definitions/rules/sonicwall/sonicwall_firewall/sonicwall_admin_auth_failures.yaml +++ b/definitions/rules/sonicwall/sonicwall_firewall/sonicwall_admin_auth_failures.yaml @@ -1,4 +1,4 @@ -# Rule version v1.0.0 +# Rule version v2.1.0 dataTypes: - firewall-sonicwall @@ -14,28 +14,31 @@ references: - https://www.sonicwall.com/techdocs/pdf/sonicos-6-5-4-log-events-reference-guide.pdf - https://attack.mitre.org/techniques/T1110/ description: | - Detects multiple failed authentication attempts to the SonicWall management interface, indicating potential brute force attacks against administrative credentials. + Detects failed authentication attempts against the SonicWall management + interface (GUI/CLI/API). Repeated failures from a single source IP suggest + a brute-force or credential-stuffing attack targeting admin credentials. Next Steps: - 1. Investigate the source IP address attempting authentication - 2. Check if the source IP is from an authorized management network - 3. Review for successful logins from the same IP after failures - 4. Consider blocking the source IP on the management interface - 5. Restrict management access to specific IP addresses - 6. Enable account lockout and two-factor authentication + 1. Investigate the source IP — geolocation, reputation, previous activity. + 2. Confirm the source is NOT from an authorized management network. + 3. Search for a successful admin login from the same IP AFTER the failures + (indicator of a successful brute force). + 4. Restrict management access to specific IP ranges and enforce MFA. where: | - ((contains("log.message", ["admin", "management", "login"]) && - contains("log.message", ["fail", "denied", "invalid", "incorrect"])) || - contains("log.eventName", ["Administrator login failed", "Login failure"]) || - contains("log.category", "Authentication Access")) && - exists("origin.ip") + ( + oneOf("log.eventCode", ["29", "32", "33", "1246"]) || + ( + contains("log.message", ["admin", "administrator", "login", "management"]) && + contains("log.message", ["failed", "fail", "denied", "invalid", "incorrect"]) + ) + ) && exists("origin.ip") afterEvents: - - with: + with: - field: origin.ip operator: filter_term value: '{{.origin.ip}}' within: 15m - count: 10 + count: 5 groupBy: - adversary.ip - adversary.user diff --git a/definitions/rules/sonicwall/sonicwall_firewall/sonicwall_vpn_failures.yaml b/definitions/rules/sonicwall/sonicwall_firewall/sonicwall_vpn_failures.yaml index 0c42ec171..c7e8779f4 100644 --- a/definitions/rules/sonicwall/sonicwall_firewall/sonicwall_vpn_failures.yaml +++ b/definitions/rules/sonicwall/sonicwall_firewall/sonicwall_vpn_failures.yaml @@ -1,4 +1,4 @@ -# Rule version v1.0.0 +# Rule version v2.1.0 dataTypes: - firewall-sonicwall @@ -14,28 +14,32 @@ references: - https://www.sonicwall.com/techdocs/pdf/sonicos-6-5-4-log-events-reference-guide.pdf - https://attack.mitre.org/techniques/T1133/ description: | - Detects multiple SSL VPN authentication failures from the same source IP on SonicWall firewalls, indicating brute force or credential stuffing attacks against remote access services. + Detects failed SSL VPN / NetExtender authentication attempts on a SonicWall + firewall. Repeated failures from a single source IP indicate brute-force or + credential-stuffing attacks against the remote access surface. Next Steps: - 1. Investigate the source IP and check threat intelligence databases - 2. Verify if the targeted user accounts exist and are active - 3. Check for successful VPN connections from the same IP - 4. Consider geo-restricting VPN access - 5. Enable MFA for VPN access if not already configured - 6. Block the source IP if confirmed malicious + 1. Investigate the source IP against threat intel; check for scanning. + 2. Verify whether the targeted usernames exist and are enabled. + 3. Look for a successful VPN login from the same IP after the failures. + 4. Enforce MFA on VPN, geo-restrict where possible, and block confirmed + malicious sources at the perimeter. where: | - ((contains("log.message", ["VPN", "SSL-VPN", "NetExtender"]) && - contains("log.message", ["fail", "denied", "invalid", "rejected"])) || - contains("log.eventName", ["VPN login failed", "SSL VPN authentication failed"]) || - contains("log.category", "VPN Access")) && - exists("origin.ip") + ( + oneOf("log.eventCode", ["548", "549", "550"]) || + ( + contains("log.message", ["VPN", "SSL VPN", "SSL-VPN", "NetExtender"]) && + contains("log.message", ["failed", "fail", "denied", "invalid", "rejected"]) + ) || + (equals("log.groupCategory", "SSL VPN") && contains("log.message", ["failed", "denied", "rejected"])) + ) && exists("origin.ip") afterEvents: - - with: + with: - field: origin.ip operator: filter_term value: '{{.origin.ip}}' within: 15m - count: 10 + count: 5 groupBy: - adversary.ip - adversary.user diff --git a/definitions/rules/sonicwall/sonicwall_firewall/zero_day_threat_detection.yaml b/definitions/rules/sonicwall/sonicwall_firewall/zero_day_threat_detection.yaml deleted file mode 100644 index 71c754a89..000000000 --- a/definitions/rules/sonicwall/sonicwall_firewall/zero_day_threat_detection.yaml +++ /dev/null @@ -1,31 +0,0 @@ -# Rule version v1.0.0 - -dataTypes: - - firewall-sonicwall -name: SonicWall Zero-Day Threat Detection -impact: - confidentiality: 3 - integrity: 3 - availability: 3 -category: Initial Access -technique: "T1190 - Exploit Public-Facing Application" -adversary: origin -references: - - https://www.sonicwall.com/support/knowledge-base/capture-advanced-threat-protection-feature-overview/170504863294345 - - https://attack.mitre.org/techniques/T1190/ -description: | - Detects zero-day threats and unknown malware identified by SonicWall Capture ATP service including sandbox detonations and RTDMI (Real-Time Deep Memory Inspection) alerts. This rule triggers when the SonicWall firewall identifies previously unknown threats through advanced analysis techniques. - - Next Steps: - 1. Immediately isolate the affected system from the network if possible - 2. Review the full event details including file hashes, URLs, and source IPs - 3. Check if the threat was successfully blocked or if additional containment is needed - 4. Update threat intelligence feeds and IOCs based on the detected indicators - 5. Perform forensic analysis on any systems that may have been compromised - 6. Review firewall rules and security policies to ensure adequate protection - 7. Document the incident and update incident response procedures if necessary -where: | - (contains("log.eventName", "ATP") || contains("log.eventName", "zero-day") || contains("log.eventName", "unknown") || contains("log.eventName", "sandbox") || contains("log.eventName", "RTDMI") || contains("log.message", "ATP") || contains("log.message", "zero-day") || contains("log.message", "unknown malware") || contains("log.message", "sandbox")) && - (contains("log.eventName", "detected") || contains("log.eventName", "blocked") || contains("log.message", "detected") || contains("log.message", "blocked") || equals("log.result", "blocked") || equals("action", "blocked") || equals("log.severity", "critical") || equals("log.severity", "high")) -groupBy: - - adversary.ip