diff --git a/filters/sonicwall/sonic_wall.yml b/filters/sonicwall/sonic_wall.yml index 80b37971e..d20d7b247 100644 --- a/filters/sonicwall/sonic_wall.yml +++ b/filters/sonicwall/sonic_wall.yml @@ -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 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 diff --git a/rules/sonicwall/sonicwall_firewall/anti_spyware_detection.yml b/rules/sonicwall/sonicwall_firewall/anti_spyware_detection.yml index f0d6e5524..df5df3144 100644 --- a/rules/sonicwall/sonicwall_firewall/anti_spyware_detection.yml +++ b/rules/sonicwall/sonicwall_firewall/anti_spyware_detection.yml @@ -1,4 +1,4 @@ -# Rule version v1.0.0 +# Rule version v2.1.0 dataTypes: - firewall-sonicwall @@ -14,23 +14,26 @@ 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: - indexPattern: v11-log-firewall-sonicwall-* with: diff --git a/rules/sonicwall/sonicwall_firewall/botnet_detection.yml b/rules/sonicwall/sonicwall_firewall/botnet_detection.yml index fdedd55ab..2cc6fdf46 100644 --- a/rules/sonicwall/sonicwall_firewall/botnet_detection.yml +++ b/rules/sonicwall/sonicwall_firewall/botnet_detection.yml @@ -1,4 +1,4 @@ -# Rule version v1.0.0 +# Rule version v2.1.0 dataTypes: - firewall-sonicwall @@ -14,17 +14,22 @@ 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: - indexPattern: v11-log-firewall-sonicwall-* with: @@ -32,7 +37,7 @@ afterEvents: operator: filter_term value: '{{.origin.ip}}' within: 2h - count: 10 + count: 5 groupBy: - adversary.ip - target.ip diff --git a/rules/sonicwall/sonicwall_firewall/capture_atp_verdicts.yml b/rules/sonicwall/sonicwall_firewall/capture_atp_verdicts.yml index d61d78fa8..77138ab69 100644 --- a/rules/sonicwall/sonicwall_firewall/capture_atp_verdicts.yml +++ b/rules/sonicwall/sonicwall_firewall/capture_atp_verdicts.yml @@ -1,4 +1,4 @@ -# Rule version v1.0.0 +# Rule version v2.1.0 dataTypes: - firewall-sonicwall @@ -14,16 +14,29 @@ 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: - indexPattern: v11-log-firewall-sonicwall-* with: @@ -31,7 +44,7 @@ afterEvents: operator: filter_term value: '{{.origin.ip}}' within: 1h - count: 2 + count: 1 groupBy: - adversary.host - adversary.ip diff --git a/rules/sonicwall/sonicwall_firewall/capture_client_threats.yml b/rules/sonicwall/sonicwall_firewall/capture_client_threats.yml deleted file mode 100644 index e62d849db..000000000 --- a/rules/sonicwall/sonicwall_firewall/capture_client_threats.yml +++ /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/rules/sonicwall/sonicwall_firewall/encrypted_threats_detection.yml b/rules/sonicwall/sonicwall_firewall/encrypted_threats_detection.yml deleted file mode 100644 index 80eac950f..000000000 --- a/rules/sonicwall/sonicwall_firewall/encrypted_threats_detection.yml +++ /dev/null @@ -1,41 +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: - - indexPattern: v11-log-firewall-sonicwall-* - with: - - field: origin.ip - operator: filter_term - value: '{{.origin.ip}}' - within: 30m - count: 3 -groupBy: - - adversary.ip - - target.ip diff --git a/rules/sonicwall/sonicwall_firewall/gateway_antivirus_detection.yml b/rules/sonicwall/sonicwall_firewall/gateway_antivirus_detection.yml index 96638b3df..4928138bf 100644 --- a/rules/sonicwall/sonicwall_firewall/gateway_antivirus_detection.yml +++ b/rules/sonicwall/sonicwall_firewall/gateway_antivirus_detection.yml @@ -1,4 +1,4 @@ -# Rule version v1.0.0 +# Rule version v2.1.0 dataTypes: - firewall-sonicwall @@ -14,23 +14,22 @@ 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: - indexPattern: v11-log-firewall-sonicwall-* with: diff --git a/rules/sonicwall/sonicwall_firewall/intrusion_prevention_alert.yml b/rules/sonicwall/sonicwall_firewall/intrusion_prevention_alert.yml index 332538062..24084525d 100644 --- a/rules/sonicwall/sonicwall_firewall/intrusion_prevention_alert.yml +++ b/rules/sonicwall/sonicwall_firewall/intrusion_prevention_alert.yml @@ -1,4 +1,4 @@ -# Rule version v1.0.0 +# Rule version v2.1.0 dataTypes: - firewall-sonicwall @@ -14,23 +14,27 @@ 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: - indexPattern: v11-log-firewall-sonicwall-* with: diff --git a/rules/sonicwall/sonicwall_firewall/sonicwall_admin_auth_failures.yml b/rules/sonicwall/sonicwall_firewall/sonicwall_admin_auth_failures.yml index 837882ae0..1ba922bd0 100644 --- a/rules/sonicwall/sonicwall_firewall/sonicwall_admin_auth_failures.yml +++ b/rules/sonicwall/sonicwall_firewall/sonicwall_admin_auth_failures.yml @@ -1,4 +1,4 @@ -# Rule version v1.0.0 +# Rule version v2.1.0 dataTypes: - firewall-sonicwall @@ -14,21 +14,24 @@ 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: - indexPattern: v11-log-firewall-sonicwall-* with: @@ -36,7 +39,7 @@ afterEvents: operator: filter_term value: '{{.origin.ip}}' within: 15m - count: 10 + count: 5 groupBy: - adversary.ip - adversary.user diff --git a/rules/sonicwall/sonicwall_firewall/sonicwall_vpn_failures.yml b/rules/sonicwall/sonicwall_firewall/sonicwall_vpn_failures.yml index 3dc38d521..8bf7ee4fa 100644 --- a/rules/sonicwall/sonicwall_firewall/sonicwall_vpn_failures.yml +++ b/rules/sonicwall/sonicwall_firewall/sonicwall_vpn_failures.yml @@ -1,4 +1,4 @@ -# Rule version v1.0.0 +# Rule version v2.1.0 dataTypes: - firewall-sonicwall @@ -14,21 +14,25 @@ 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: - indexPattern: v11-log-firewall-sonicwall-* with: @@ -36,7 +40,7 @@ afterEvents: operator: filter_term value: '{{.origin.ip}}' within: 15m - count: 10 + count: 5 groupBy: - adversary.ip - adversary.user diff --git a/rules/sonicwall/sonicwall_firewall/zero_day_threat_detection.yml b/rules/sonicwall/sonicwall_firewall/zero_day_threat_detection.yml deleted file mode 100644 index 71c754a89..000000000 --- a/rules/sonicwall/sonicwall_firewall/zero_day_threat_detection.yml +++ /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