From 939fa6cad98df377fc044abddbd6a916865b8394 Mon Sep 17 00:00:00 2001 From: zedoraps Date: Mon, 22 Jun 2026 14:56:32 +0200 Subject: [PATCH 01/20] Add Cisco Secure Firewall ASA support Add ASA as a second product in the cisco package, parsing Cisco Secure Firewall ASA syslog messages and mapping them to OCSF. cisco::asa::parse extracts the %ASA-- frame from a configurable message field (default "content", as produced by read_syslog), tolerating both legacy and RFC 5424 timestamps and resolving the event time from the line or the syslog envelope. cisco::asa::ocsf::map dispatches by message ID to Network Activity (connections, denies, ACL hits, flagged traffic) and Authentication (VPN session and identity events), recording the message ID in metadata.event_code. Unsupported messages fall back to the OCSF Base Event with their original text preserved. Add parse and end-to-end OCSF mapping tests with anonymized fixtures, plus syslog-collection and OCSF-mapping examples. Co-authored-by: Claude Opus 4.8 --- .../unreleased/add-cisco-asa-support.md | 34 + cisco/examples/asa-from-syslog-tcp.tql | 13 + cisco/examples/asa-map-to-ocsf.tql | 13 + cisco/operators/asa/ocsf/base.tql | 14 + .../asa/ocsf/events/authentication.tql | 60 + cisco/operators/asa/ocsf/events/built.tql | 37 + cisco/operators/asa/ocsf/events/deny.tql | 47 + cisco/operators/asa/ocsf/events/network.tql | 17 + cisco/operators/asa/ocsf/events/teardown.tql | 34 + cisco/operators/asa/ocsf/map.tql | 61 + .../operators/asa/ocsf/network_endpoints.tql | 96 ++ cisco/operators/asa/parse.tql | 141 ++ cisco/package.yaml | 10 +- cisco/tests/asa/ocsf/inputs/built.txt | 2 + cisco/tests/asa/ocsf/inputs/built_sig.txt | 1 + cisco/tests/asa/ocsf/inputs/deny.txt | 2 + cisco/tests/asa/ocsf/inputs/deny_family.txt | 8 + cisco/tests/asa/ocsf/inputs/deny_variants.txt | 3 + cisco/tests/asa/ocsf/inputs/easy_wins.txt | 4 + cisco/tests/asa/ocsf/inputs/other.txt | 1 + cisco/tests/asa/ocsf/inputs/teardown.txt | 2 + cisco/tests/asa/ocsf/inputs/vpn.txt | 4 + cisco/tests/asa/ocsf/map.tql | 10 + cisco/tests/asa/ocsf/map.txt | 1386 +++++++++++++++++ cisco/tests/asa/parse.input | 8 + cisco/tests/asa/parse.tql | 6 + cisco/tests/asa/parse.txt | 149 ++ cisco/tests/asa/parse_content.tql | 9 + cisco/tests/asa/parse_content.txt | 24 + 29 files changed, 2193 insertions(+), 3 deletions(-) create mode 100644 cisco/changelog/unreleased/add-cisco-asa-support.md create mode 100644 cisco/examples/asa-from-syslog-tcp.tql create mode 100644 cisco/examples/asa-map-to-ocsf.tql create mode 100644 cisco/operators/asa/ocsf/base.tql create mode 100644 cisco/operators/asa/ocsf/events/authentication.tql create mode 100644 cisco/operators/asa/ocsf/events/built.tql create mode 100644 cisco/operators/asa/ocsf/events/deny.tql create mode 100644 cisco/operators/asa/ocsf/events/network.tql create mode 100644 cisco/operators/asa/ocsf/events/teardown.tql create mode 100644 cisco/operators/asa/ocsf/map.tql create mode 100644 cisco/operators/asa/ocsf/network_endpoints.tql create mode 100644 cisco/operators/asa/parse.tql create mode 100644 cisco/tests/asa/ocsf/inputs/built.txt create mode 100644 cisco/tests/asa/ocsf/inputs/built_sig.txt create mode 100644 cisco/tests/asa/ocsf/inputs/deny.txt create mode 100644 cisco/tests/asa/ocsf/inputs/deny_family.txt create mode 100644 cisco/tests/asa/ocsf/inputs/deny_variants.txt create mode 100644 cisco/tests/asa/ocsf/inputs/easy_wins.txt create mode 100644 cisco/tests/asa/ocsf/inputs/other.txt create mode 100644 cisco/tests/asa/ocsf/inputs/teardown.txt create mode 100644 cisco/tests/asa/ocsf/inputs/vpn.txt create mode 100644 cisco/tests/asa/ocsf/map.tql create mode 100644 cisco/tests/asa/ocsf/map.txt create mode 100644 cisco/tests/asa/parse.input create mode 100644 cisco/tests/asa/parse.tql create mode 100644 cisco/tests/asa/parse.txt create mode 100644 cisco/tests/asa/parse_content.tql create mode 100644 cisco/tests/asa/parse_content.txt diff --git a/cisco/changelog/unreleased/add-cisco-asa-support.md b/cisco/changelog/unreleased/add-cisco-asa-support.md new file mode 100644 index 00000000..11809764 --- /dev/null +++ b/cisco/changelog/unreleased/add-cisco-asa-support.md @@ -0,0 +1,34 @@ +--- +title: Add Cisco Secure Firewall ASA support +type: feature +authors: + - zedoraps +created: 2026-06-18T00:00:00Z +--- + +The `cisco` package now parses Cisco Secure Firewall ASA syslog messages and +maps supported message IDs to OCSF. + +`cisco::asa::parse` extracts the `%ASA--: ` frame +from a message field and parses the body of supported messages into structured +fields. It takes a `message` argument naming the field that holds the raw line +(default `content`, as produced by the built-in `read_syslog`), so it composes +with any transport: + +```tql +from_tcp "0.0.0.0:514" { + read_syslog +} +cisco::asa::parse message="content" +cisco::asa::ocsf::map +ocsf::derive +ocsf::cast +``` + +Point `message` at another field for other delivery methods, e.g. +`message="line"` after `read_lines`, or the body field a log shipper uses. + +`cisco::asa::ocsf::map` maps connection-built (302013/302015), connection- +teardown (302014/302016), and access-list deny (106023) messages to OCSF +Network Activity events. Unsupported messages map to the OCSF Base Event and +retain their original text. diff --git a/cisco/examples/asa-from-syslog-tcp.tql b/cisco/examples/asa-from-syslog-tcp.tql new file mode 100644 index 00000000..49505002 --- /dev/null +++ b/cisco/examples/asa-from-syslog-tcp.tql @@ -0,0 +1,13 @@ +--- +name: Onboard Cisco ASA logs via Syslog TCP +description: | + Receives Cisco Secure Firewall ASA logs over TCP syslog with the built-in + `read_syslog`, parses the ASA payload into normalized events, and publishes + them to the `cisco` topic. +--- + +from_tcp "0.0.0.0:514" { + read_syslog +} +cisco::asa::parse message="content" +publish "cisco" diff --git a/cisco/examples/asa-map-to-ocsf.tql b/cisco/examples/asa-map-to-ocsf.tql new file mode 100644 index 00000000..e2ed3214 --- /dev/null +++ b/cisco/examples/asa-map-to-ocsf.tql @@ -0,0 +1,13 @@ +--- +name: Cisco ASA → OCSF +description: | + Maps parsed Cisco ASA records from the `cisco` topic to OCSF events and + publishes them to the `ocsf` topic. +--- + +subscribe "cisco" +where @name == "cisco.asa" +cisco::asa::ocsf::map +ocsf::derive +ocsf::cast +publish "ocsf" diff --git a/cisco/operators/asa/ocsf/base.tql b/cisco/operators/asa/ocsf/base.tql new file mode 100644 index 00000000..e45901c5 --- /dev/null +++ b/cisco/operators/asa/ocsf/base.tql @@ -0,0 +1,14 @@ +--- +description: Cisco ASA unsupported messages → OCSF Base Event +args: + named: + - name: event + description: The field that holds the event to map. + type: field +--- + +@name = "ocsf.base_event" +$event.ocsf.category_uid = 0 +$event.ocsf.class_uid = 0 +$event.ocsf.activity_id = 0 +$event.ocsf.type_uid = 0 diff --git a/cisco/operators/asa/ocsf/events/authentication.tql b/cisco/operators/asa/ocsf/events/authentication.tql new file mode 100644 index 00000000..629e5c74 --- /dev/null +++ b/cisco/operators/asa/ocsf/events/authentication.tql @@ -0,0 +1,60 @@ +--- +description: "Cisco ASA VPN session / identity messages (722051 logon, 113019 & 746013 logoff) → OCSF Authentication (3002)" +args: + named: + - name: event + description: The field that holds the event to map. + type: field +--- + +@name = "ocsf.authentication" + +$event.ocsf.category_uid = 3 +$event.ocsf.class_uid = 3002 +// 722051 establishes a session; 113019 and 746013 end one. +if $event.asa.message_id == 722051 { + $event.ocsf.activity_id = 1 // Logon +} else { + $event.ocsf.activity_id = 2 // Logoff +} +$event.ocsf.type_uid = $event.ocsf.class_uid * 100 + $event.ocsf.activity_id + +if $event.asa.vpn_user? != null { + $event.ocsf.user = { + name: move $event.asa.vpn_user, + } +} +if $event.asa.domain? != null { + $event.ocsf.user.domain = move $event.asa.domain +} +if $event.asa.vpn_group? != null { + $event.ocsf.user.groups = [{name: move $event.asa.vpn_group}] +} + +// The client's public address is the source of the session. +if $event.asa.src_ip? != null { + $event.ocsf.src_endpoint = { + ip: move $event.asa.src_ip, + } +} + +if $event.asa.reason? != null { + $event.ocsf.status_detail = move $event.asa.reason +} + +// 746013 reports an explicit result, either "Succeeded" or "Failed". The +// session logon/logoff messages carry no status and always describe a +// completed action. An unexpected value maps to Other (99) with the source +// string preserved in the `status` sibling, per OCSF conventions. +if $event.asa.status? == "Succeeded" { + $event.ocsf.status_id = 1 // Success + drop $event.asa.status? +} else if $event.asa.status? == "Failed" { + $event.ocsf.status_id = 2 // Failure + drop $event.asa.status? +} else if $event.asa.status? != null { + $event.ocsf.status_id = 99 // Other + $event.ocsf.status = move $event.asa.status +} else { + $event.ocsf.status_id = 1 // Success +} diff --git a/cisco/operators/asa/ocsf/events/built.tql b/cisco/operators/asa/ocsf/events/built.tql new file mode 100644 index 00000000..c8a97561 --- /dev/null +++ b/cisco/operators/asa/ocsf/events/built.tql @@ -0,0 +1,37 @@ +--- +description: "Cisco ASA connection-built messages (302013/302015) → OCSF Network Activity (4001)" +args: + named: + - name: event + description: The field that holds the event to map. + type: field +--- + +@name = "ocsf.network_activity" + +$event.ocsf.category_uid = 4 +$event.ocsf.class_uid = 4001 +$event.ocsf.activity_id = 1 // Open +$event.ocsf.type_uid = $event.ocsf.class_uid * 100 + $event.ocsf.activity_id + +cisco::asa::ocsf::network_endpoints event=$event + +// `direction` is relative to the firewall: an inbound connection is initiated +// from the outside, an outbound one from the inside. +if $event.asa.direction? == "inbound" { + $event.ocsf.connection_info.direction_id = 1 +} else if $event.asa.direction? == "outbound" { + $event.ocsf.connection_info.direction_id = 2 +} else { + $event.ocsf.connection_info.direction_id = 0 +} +drop $event.asa.direction? + +if $event.asa.connection_id? != null { + $event.ocsf.connection_info.uid = (move $event.asa.connection_id).string() +} + +// The post-NAT (translated) addresses in parentheses are mapped to proxy +// endpoints by cisco::asa::ocsf::network_endpoints. + +$event.ocsf.disposition_id = 1 // Allowed diff --git a/cisco/operators/asa/ocsf/events/deny.tql b/cisco/operators/asa/ocsf/events/deny.tql new file mode 100644 index 00000000..249cbd0a --- /dev/null +++ b/cisco/operators/asa/ocsf/events/deny.tql @@ -0,0 +1,47 @@ +--- +description: "Cisco ASA deny / access-list messages (106023, 106001, 106006/7, 106010, 106014, 106100, 313004/8) → OCSF Network Activity (4001)" +args: + named: + - name: event + description: The field that holds the event to map. + type: field +--- + +@name = "ocsf.network_activity" + +$event.ocsf.category_uid = 4 +$event.ocsf.class_uid = 4001 +$event.ocsf.activity_id = 6 // Traffic +$event.ocsf.type_uid = $event.ocsf.class_uid * 100 + $event.ocsf.activity_id + +cisco::asa::ocsf::network_endpoints event=$event + +// The access-group name that produced the decision is the matched firewall rule. +if $event.asa.acl_id? != null { + $event.ocsf.firewall_rule = { + name: move $event.asa.acl_id, + } +} + +// Connection direction relative to the firewall, when the message states it. +if $event.asa.direction? == "inbound" { + $event.ocsf.connection_info.direction_id = 1 +} else if $event.asa.direction? == "outbound" { + $event.ocsf.connection_info.direction_id = 2 +} +drop $event.asa.direction? + +// `hit_count` (106100) is the number of times the rule matched in the interval. +if $event.asa.hit_count? != null { + $event.ocsf.count = move $event.asa.hit_count +} + +// 106100 logs both permits and denies via `action`; everything else is a deny. +if $event.asa.action? == "permitted" { + $event.ocsf.disposition_id = 1 // Allowed + $event.ocsf.action_id = 1 // Allowed +} else { + $event.ocsf.disposition_id = 2 // Blocked + $event.ocsf.action_id = 2 // Denied +} +drop $event.asa.action? diff --git a/cisco/operators/asa/ocsf/events/network.tql b/cisco/operators/asa/ocsf/events/network.tql new file mode 100644 index 00000000..b72902a9 --- /dev/null +++ b/cisco/operators/asa/ocsf/events/network.tql @@ -0,0 +1,17 @@ +--- +description: "Cisco ASA flagged traffic messages (419002 Duplicate TCP SYN) → OCSF Network Activity (4001)" +args: + named: + - name: event + description: The field that holds the event to map. + type: field +--- + +@name = "ocsf.network_activity" + +$event.ocsf.category_uid = 4 +$event.ocsf.class_uid = 4001 +$event.ocsf.activity_id = 6 // Traffic +$event.ocsf.type_uid = $event.ocsf.class_uid * 100 + $event.ocsf.activity_id + +cisco::asa::ocsf::network_endpoints event=$event diff --git a/cisco/operators/asa/ocsf/events/teardown.tql b/cisco/operators/asa/ocsf/events/teardown.tql new file mode 100644 index 00000000..96a0464e --- /dev/null +++ b/cisco/operators/asa/ocsf/events/teardown.tql @@ -0,0 +1,34 @@ +--- +description: "Cisco ASA connection-teardown messages (302014/302016) → OCSF Network Activity (4001)" +args: + named: + - name: event + description: The field that holds the event to map. + type: field +--- + +@name = "ocsf.network_activity" + +$event.ocsf.category_uid = 4 +$event.ocsf.class_uid = 4001 +$event.ocsf.activity_id = 2 // Close +$event.ocsf.type_uid = $event.ocsf.class_uid * 100 + $event.ocsf.activity_id + +cisco::asa::ocsf::network_endpoints event=$event + +if $event.asa.connection_id? != null { + $event.ocsf.connection_info.uid = (move $event.asa.connection_id).string() +} + +// Teardown messages summarize the closed session: total bytes and the reason +// the firewall tore the connection down. +if $event.asa.bytes? != null { + $event.ocsf.traffic = { + bytes: move $event.asa.bytes, + } +} +if $event.asa.reason? != null { + $event.ocsf.status_detail = move $event.asa.reason +} + +$event.ocsf.disposition_id = 1 // Allowed diff --git a/cisco/operators/asa/ocsf/map.tql b/cisco/operators/asa/ocsf/map.tql new file mode 100644 index 00000000..9accc693 --- /dev/null +++ b/cisco/operators/asa/ocsf/map.tql @@ -0,0 +1,61 @@ +--- +description: Cisco ASA → OCSF +args: + named: + - name: event + description: The field that holds the event to map. + type: field + default: this +--- + +$event = {...$event, asa: $event, ocsf: {}} + +$event.ocsf.metadata = { + log_name: "cisco.asa", + // The ASA syslog message ID identifies the event type in Cisco's taxonomy, + // which OCSF models as metadata.event_code (its example is "Cisco syslog + // code"). ASA provides no unique per-event identifier for original_event_uid. + event_code: $event.asa.message_id.string(), + processed_time: now(), + product: { + name: "Secure Firewall ASA", + vendor_name: "Cisco", + }, + profiles: ["host", "security_control"], + version: "1.8.0", +} + +// ASA stamps each message with the syslog timestamp when configured to do so. +$event.ocsf.time = move $event.asa.time? else $event.ocsf.metadata.processed_time + +if $event.asa.text? != null { + $event.ocsf.message = move $event.asa.text +} + +// Map the ASA severity level (0 = emergency … 7 = debug) to the OCSF severity. +let $severities = { + "0": 6, // Emergency → Fatal + "1": 5, // Alert → Critical + "2": 5, // Critical → Critical + "3": 4, // Error → High + "4": 3, // Warning → Medium + "5": 2, // Notice → Low + "6": 1, // Info → Informational + "7": 1, // Debug → Informational +} +if $event.asa.severity? != null { + $event.ocsf.severity_id = $severities[(move $event.asa.severity).string()]? else 0 +} else { + $event.ocsf.severity_id = 0 +} + +match $event.asa.message_id { + 302013 | 302015 => { cisco::asa::ocsf::events::built event=$event } + 302014 | 302016 | 302021 => { cisco::asa::ocsf::events::teardown event=$event } + 106023 | 106001 | 106006 | 106007 | 106010 | 106014 | 106100 | 313004 | 313008 | 710003 | 710005 => { cisco::asa::ocsf::events::deny event=$event } + 419002 => { cisco::asa::ocsf::events::network event=$event } + 722051 | 113019 | 746013 => { cisco::asa::ocsf::events::authentication event=$event } + _ => { cisco::asa::ocsf::base event=$event } +} + +$event = {...$event.ocsf, unmapped: $event.asa} diff --git a/cisco/operators/asa/ocsf/network_endpoints.tql b/cisco/operators/asa/ocsf/network_endpoints.tql new file mode 100644 index 00000000..ce1e79b0 --- /dev/null +++ b/cisco/operators/asa/ocsf/network_endpoints.tql @@ -0,0 +1,96 @@ +--- +description: >- + Common Cisco ASA src/dst endpoint fields → OCSF network endpoints. + Sets port and interface_name on both endpoints, classifies each logged + address as either an `ip` or a `hostname`, records any post-NAT (translated) + address as a proxy endpoint, and populates connection_info with the protocol + number and name. +args: + named: + - name: event + description: The field that holds the event to map. + type: field +--- + +// ASA logs an endpoint address as either an IP or a resolved hostname/label. +let $ipv4 = r"^\d{1,3}(\.\d{1,3}){3}$" +let $ipv6 = r"^[0-9A-Fa-f:]*:[0-9A-Fa-f:]+$" + +$event.ocsf.connection_info = {} + +// --- Source endpoint --- +$event.ocsf.src_endpoint = { + port: move $event.asa.src_port?, + interface_name: move $event.asa.src_interface?, +} +if $event.asa.src_host? != null { + if $event.asa.src_host.match_regex($ipv4) or $event.asa.src_host.match_regex($ipv6) { + $event.ocsf.src_endpoint.ip = $event.asa.src_host.ip() + } else { + $event.ocsf.src_endpoint.hostname = $event.asa.src_host + } +} +// Source NAT: the post-translation address on connection-built messages. +// Record it as a proxy endpoint when it differs from the real source. +if $event.asa.src_xlate_host? != null and $event.asa.src_xlate_host != $event.asa.src_host? { + $event.ocsf.src_endpoint.proxy_endpoint = { + port: move $event.asa.src_xlate_port?, + } + if $event.asa.src_xlate_host.match_regex($ipv4) or $event.asa.src_xlate_host.match_regex($ipv6) { + $event.ocsf.src_endpoint.proxy_endpoint.ip = $event.asa.src_xlate_host.ip() + } else { + $event.ocsf.src_endpoint.proxy_endpoint.hostname = $event.asa.src_xlate_host + } +} +drop $event.asa.src_host?, $event.asa.src_xlate_host?, $event.asa.src_xlate_port? + +// --- Destination endpoint --- +$event.ocsf.dst_endpoint = { + port: move $event.asa.dst_port?, + interface_name: move $event.asa.dst_interface?, +} +if $event.asa.dst_host? != null { + if $event.asa.dst_host.match_regex($ipv4) or $event.asa.dst_host.match_regex($ipv6) { + $event.ocsf.dst_endpoint.ip = $event.asa.dst_host.ip() + } else { + $event.ocsf.dst_endpoint.hostname = $event.asa.dst_host + } +} +if $event.asa.dst_xlate_host? != null and $event.asa.dst_xlate_host != $event.asa.dst_host? { + $event.ocsf.dst_endpoint.proxy_endpoint = { + port: move $event.asa.dst_xlate_port?, + } + if $event.asa.dst_xlate_host.match_regex($ipv4) or $event.asa.dst_xlate_host.match_regex($ipv6) { + $event.ocsf.dst_endpoint.proxy_endpoint.ip = $event.asa.dst_xlate_host.ip() + } else { + $event.ocsf.dst_endpoint.proxy_endpoint.hostname = $event.asa.dst_xlate_host + } +} +drop $event.asa.dst_host?, $event.asa.dst_xlate_host?, $event.asa.dst_xlate_port? + +// --- Protocol --- +// ASA spells the protocol either as a name (`tcp`, `udp`, `icmp`) or, for +// protocols without ports, as the literal `protocol` followed by its IANA +// number (e.g. `protocol 47` for GRE). +let $protocols = { + icmp: 1, + tcp: 6, + udp: 17, + gre: 47, + esp: 50, + ah: 51, + icmpv6: 58, +} +if $event.asa.protocol_num? != null { + $event.ocsf.connection_info.protocol_num = move $event.asa.protocol_num + // Keep a real protocol name, but not the `protocol` placeholder word. + if $event.asa.protocol? != null and $event.asa.protocol != "protocol" { + $event.ocsf.connection_info.protocol_name = $event.asa.protocol.to_lower() + } + drop $event.asa.protocol? +} else if $event.asa.protocol? != null { + $event.asa.protocol = $event.asa.protocol.to_lower() + $event.ocsf.connection_info.protocol_name = $event.asa.protocol + $event.ocsf.connection_info.protocol_num = $protocols[$event.asa.protocol]? else -1 + drop $event.asa.protocol +} diff --git a/cisco/operators/asa/parse.tql b/cisco/operators/asa/parse.tql new file mode 100644 index 00000000..a0612b5e --- /dev/null +++ b/cisco/operators/asa/parse.tql @@ -0,0 +1,141 @@ +--- +description: >- + Parses a Cisco Secure Firewall ASA syslog message into a normalized ASA event. + + Reads the raw message from the field named by `message` (default `content`, + as produced by the built-in `read_syslog`), extracts the + `%ASA--: ` frame regardless of any surrounding + syslog header, and parses the body of supported message IDs into structured + fields. Unsupported messages keep their free-form `text`. + + Point `message` at a different field for other delivery methods, e.g. + `message=line` after `read_lines`, or the body field a log shipper uses. +args: + named: + - name: message + description: The field that holds the raw ASA message line. + type: string + default: "content" +--- + +// Grok patterns. ASA messages are framed as `%ASA--: `, +// optionally prefixed by a syslog priority, timestamp, hostname, and a +// subsystem context (e.g. `%ASA-session-6-...`). The leading `.*?` tolerates +// any syslog header, so this works whether `message` holds the bare payload +// (`content` from `read_syslog`) or a full raw line (`line` from `read_lines`). +// `HOST` matches an endpoint address, which ASA logs as either an IP or a +// resolved hostname. We capture it as a string and let the OCSF mapper decide +// whether it is an `ip` or a `hostname`. +let $patterns = { + ASATS: r#"(%{MONTH} +%{MONTHDAY}(?: %{YEAR})? %{TIME}|%{TIMESTAMP_ISO8601})"#, + HOST: r#"[^/ ]+"#, +} +let $header = r#"^(<%{NONNEGINT:priority}>)? *(%{ASATS:event_timestamp:string})?.*?%ASA-(%{WORD:context}-)?%{INT:severity}-%{INT:message_id}: %{GREEDYDATA:text}"# + +// Built/Teardown share the `interface:host/port` endpoint shape. Built also +// carries the post-NAT (translated) address in parentheses, which can be an IP +// or a label (e.g. Umbrella SIG writes `(UMBRELLA-DOMAIN-BLOCK-HIT/443)`). The +// trailing `.*` tolerates extra fields some platforms append after the line. +let $built = r#"Built %{WORD:direction} %{WORD:protocol} connection %{INT:connection_id} for %{NOTSPACE:src_interface}:%{HOST:src_host:string}/%{INT:src_port} \(%{HOST:src_xlate_host:string}/%{INT:src_xlate_port}\) to %{NOTSPACE:dst_interface}:%{HOST:dst_host:string}/%{INT:dst_port} \(%{HOST:dst_xlate_host:string}/%{INT:dst_xlate_port}\).*"# +let $teardown = r#"Teardown %{WORD:protocol} connection %{INT:connection_id} for %{NOTSPACE:src_interface}:%{HOST:src_host:string}/%{INT:src_port} to %{NOTSPACE:dst_interface}:%{HOST:dst_host:string}/%{INT:dst_port} duration %{NOTSPACE:duration} bytes %{INT:bytes}( %{GREEDYDATA:reason})?"# +// Deny covers both the port-based form (`Deny tcp src IF:host/port …`) and the +// protocol-number form for protocols without ports (`Deny protocol 47 src +// IF:host …`, e.g. GRE/ESP). Ports and the ICMP type/code are optional. +// Unified `Deny [direction] src IF:host[/port] dst IF:host[/port] +// [type/code] [by access-group "acl"]` form, covering 106023, 106010, and +// 106014. The optional direction, ports, ICMP type/code (square brackets or +// round parens), and access-group absorb the per-message-ID differences. +let $deny = r#"Deny( %{WORD:direction})? %{WORD:protocol}( %{INT:protocol_num})? src %{NOTSPACE:src_interface}:%{HOST:src_host:string}(/%{INT:src_port})? dst %{NOTSPACE:dst_interface}:%{HOST:dst_host:string}(/%{INT:dst_port})?( [\[(]type %{INT:icmp_type}, code %{INT:icmp_code}[\])])?( by access-group "%{DATA:acl_id}")?.*"# +// 106001: ` connection denied from ip/port to ip/port +// [flags F] on interface IF`. +let $conn_denied = r#"%{WORD:direction} %{WORD:protocol} connection denied from %{HOST:src_host:string}/%{INT:src_port} to %{HOST:dst_host:string}/%{INT:dst_port}( flags %{DATA:tcp_flags})? +on interface %{NOTSPACE:src_interface}"# +// 106006/106007: `Deny from ip/port to ip/port on interface IF`. +let $deny_from = r#"Deny %{WORD:direction} %{WORD:protocol} from %{HOST:src_host:string}/%{INT:src_port} to %{HOST:dst_host:string}/%{INT:dst_port} on interface %{NOTSPACE:src_interface}.*"# +// 106100: `access-list acl IF/host(port) -> IF/host(port) hit-cnt N …`. +let $acl = r#"access-list %{NOTSPACE:acl_id} %{WORD:action} %{WORD:protocol:string} %{NOTSPACE:src_interface}/%{HOST:src_host:string}\(%{INT:src_port}\) -> %{NOTSPACE:dst_interface}/%{HOST:dst_host:string}\(%{INT:dst_port}\) hit-cnt %{INT:hit_count}.*"# +// 313004: `Denied ICMP type=N, from laddr ip on interface IF to ip: reason`. +let $denied_icmp = r#"Denied %{NOTSPACE:protocol} type=%{INT:icmp_type}, from laddr %{HOST:src_host:string} on interface %{NOTSPACE:src_interface} to %{HOST:dst_host:string}: %{GREEDYDATA:reason}"# +// 313008: `Denied IPv6-ICMP type=N, code=N from ip on interface IF` (source only). +let $denied_icmp6 = r#"Denied %{NOTSPACE:protocol} type=%{INT:icmp_type}, code=%{INT:icmp_code} from %{HOST:src_host:string} on interface %{NOTSPACE:src_interface}"# +// 419002: `Duplicate SYN from IF:host/port to IF:host/port …`. +let $duplicate_syn = r#"Duplicate %{WORD:protocol} SYN from %{NOTSPACE:src_interface}:%{HOST:src_host:string}/%{INT:src_port} to %{NOTSPACE:dst_interface}:%{HOST:dst_host:string}/%{INT:dst_port}.*"# +// 710003/710005: to-the-box denies, ` (access denied by ACL|request +// discarded) from host/port to IF:host/port` (no source interface). +let $denied_box = r#"%{WORD:protocol} (access denied by ACL|request discarded) from %{HOST:src_host:string}/%{INT:src_port} to %{NOTSPACE:dst_interface}:%{HOST:dst_host:string}/%{INT:dst_port}.*"# +// 302021: `Teardown ICMP connection for faddr gaddr laddr +// …`. faddr is the remote peer (dst), laddr the local host (src), and +// gaddr its post-NAT (global) address. +let $teardown_icmp = r#"Teardown %{WORD:protocol} connection for faddr %{HOST:dst_host:string}/%{INT:faddr_id} gaddr %{HOST:src_xlate_host:string}/%{INT:gaddr_id} laddr %{HOST:src_host:string}/%{INT:laddr_id}.*"# +// 722051: VPN address assigned to session (session logon). +let $vpn_assigned = r#"Group <%{DATA:vpn_group}> User <%{DATA:vpn_user}> IP <%{IP:src_ip}> IPv4 Address <%{DATA:assigned_ipv4}> IPv6 address <%{DATA:assigned_ipv6}> assigned to session"# +// 113019: VPN session disconnected (session logoff). +let $vpn_disconnect = r#"Group = %{DATA:vpn_group}, Username = %{DATA:vpn_user}, IP = %{IP:src_ip}, Session disconnected. Session Type: %{DATA:session_type}, Duration: %{DATA:duration}, Bytes xmt: %{INT:bytes_out}, Bytes rcv: %{INT:bytes_in}, Reason: %{GREEDYDATA:reason}"# +// 746013: user-identity IP↔user mapping deleted (e.g. on VPN logout). +let $identity_delete = r#"user-identity: Delete IP-User mapping %{IP:src_ip} - %{DATA:domain}\\%{DATA:vpn_user} %{WORD:status} - %{GREEDYDATA:reason}"# + +this = {...this, ...this[$message]?.parse_grok($header, pattern_definitions=$patterns)} + +// Drop lines that do not carry an ASA message frame. +where message_id? != null + +@name = "cisco.asa" + +// Resolve the event time. Prefer a timestamp embedded in the message line; +// otherwise fall back to a sibling `timestamp` field left by `read_syslog`. +// ASA emits either an ISO 8601 timestamp or the textual `Mon DD [YYYY] +// HH:MM:SS` form depending on the `logging timestamp` setting. Only parse a +// value that actually looks like one of these; this leaves `time` unset (with +// no warning) when the sibling `timestamp` is something else, such as the +// numeric epoch a log shipper like GELF puts in its own `timestamp` field — +// the caller supplies the time in that case. +if event_timestamp? == null and timestamp? != null { + event_timestamp = timestamp.string() +} +if event_timestamp? != null { + // On a match we consume the source: also drop the sibling `timestamp` so it + // does not linger in `unmapped`. On no match (e.g. a GELF epoch in + // `timestamp`) we leave that field for the caller to map. + if event_timestamp.match_regex(r"^\d{4}-\d{2}-\d{2}[T ]") { + time = event_timestamp.time() + drop timestamp? + } else if event_timestamp.match_regex(r"^\w{3}\s+\d{1,2}\s+\d{4}\s") { + time = event_timestamp.parse_time("%b %d %Y %H:%M:%S") + drop timestamp? + } else if event_timestamp.match_regex(r"^\w{3}\s+\d{1,2}\s+\d{2}:\d{2}:\d{2}") { + time = event_timestamp.parse_time("%b %e %H:%M:%S") + drop timestamp? + } +} +drop event_timestamp + +// Parse the message body of supported message IDs into structured fields. +match message_id { + 302013 | 302015 => { this = {...this, ...text.parse_grok($built, pattern_definitions=$patterns)} } + 302014 | 302016 => { this = {...this, ...text.parse_grok($teardown, pattern_definitions=$patterns)} } + 302021 => { this = {...this, ...text.parse_grok($teardown_icmp, pattern_definitions=$patterns)} } + 106023 | 106010 | 106014 => { this = {...this, ...text.parse_grok($deny, pattern_definitions=$patterns)} } + 106001 => { this = {...this, ...text.parse_grok($conn_denied, pattern_definitions=$patterns)} } + 106006 | 106007 => { this = {...this, ...text.parse_grok($deny_from, pattern_definitions=$patterns)} } + 106100 => { this = {...this, ...text.parse_grok($acl, pattern_definitions=$patterns)} } + 313004 => { this = {...this, ...text.parse_grok($denied_icmp, pattern_definitions=$patterns)} } + 313008 => { this = {...this, ...text.parse_grok($denied_icmp6, pattern_definitions=$patterns)} } + 419002 => { this = {...this, ...text.parse_grok($duplicate_syn, pattern_definitions=$patterns)} } + 710003 | 710005 => { this = {...this, ...text.parse_grok($denied_box, pattern_definitions=$patterns)} } + 722051 => { this = {...this, ...text.parse_grok($vpn_assigned, pattern_definitions=$patterns)} } + 113019 => { this = {...this, ...text.parse_grok($vpn_disconnect, pattern_definitions=$patterns)} } + 746013 => { this = {...this, ...text.parse_grok($identity_delete, pattern_definitions=$patterns)} } + _ => {} +} + +// Normalize across the message formats: lower-case the connection direction +// and fold a numeric protocol token into protocol_num. +if direction? != null { + direction = direction.to_lower() +} +if protocol? != null { + protocol = protocol.string() + if protocol.match_regex(r"^[0-9]+$") { + protocol_num = int(protocol) + drop protocol + } +} diff --git a/cisco/package.yaml b/cisco/package.yaml index 4216835a..ce2cb1ad 100644 --- a/cisco/package.yaml +++ b/cisco/package.yaml @@ -9,9 +9,13 @@ description: | activity telemetry for infrastructure, identity, and cloud security workflows. - This package currently provides reusable operators for Cisco Umbrella DNS - logs: reading the standard DNS CSV export from files or S3, publishing - normalized Umbrella events, and mapping them to OCSF DNS Activity events. + This package provides reusable operators for Cisco security products: + + - **Umbrella DNS**: reading the standard DNS CSV export from files or S3, + publishing normalized Umbrella events, and mapping them to OCSF DNS + Activity events. + - **Secure Firewall ASA**: parsing ASA syslog messages and mapping + supported message IDs to OCSF events. categories: - sources diff --git a/cisco/tests/asa/ocsf/inputs/built.txt b/cisco/tests/asa/ocsf/inputs/built.txt new file mode 100644 index 00000000..8785b43b --- /dev/null +++ b/cisco/tests/asa/ocsf/inputs/built.txt @@ -0,0 +1,2 @@ +<166>Jun 18 2025 11:37:47 asa-fw : %ASA-6-302013: Built outbound TCP connection 9 for outside:192.0.2.2/80 (192.0.2.2/80) to inside:10.1.1.2/4924 (203.0.113.10/4924) +<166>Jun 18 2025 11:37:48 asa-fw : %ASA-6-302015: Built inbound UDP connection 1005 for outside:198.51.100.5/53 (198.51.100.5/53) to inside:10.1.1.3/51000 (10.1.1.3/51000) diff --git a/cisco/tests/asa/ocsf/inputs/built_sig.txt b/cisco/tests/asa/ocsf/inputs/built_sig.txt new file mode 100644 index 00000000..e06766fc --- /dev/null +++ b/cisco/tests/asa/ocsf/inputs/built_sig.txt @@ -0,0 +1 @@ +<166>Jun 18 2025 11:37:48 asa-fw : %ASA-6-302013: Built inbound TCP connection 3332836331 for inside:10.1.1.9/50640 (198.51.100.20/50640) to umbrella:host.example/443 (UMBRELLA-DOMAIN-BLOCK-HIT/443) 0 24 diff --git a/cisco/tests/asa/ocsf/inputs/deny.txt b/cisco/tests/asa/ocsf/inputs/deny.txt new file mode 100644 index 00000000..795bd656 --- /dev/null +++ b/cisco/tests/asa/ocsf/inputs/deny.txt @@ -0,0 +1,2 @@ +<165>Jun 18 2025 11:38:00 asa-fw : %ASA-4-106023: Deny tcp src outside:198.51.100.7/4444 dst inside:10.1.1.5/3389 by access-group "outside_access_in" [0x0, 0x0] +<165>Jun 18 2025 11:38:01 asa-fw : %ASA-4-106023: Deny icmp src outside:198.51.100.8/0 dst inside:10.1.1.6/0 [type 8, code 0] by access-group "outside_access_in" [0x0, 0x0] diff --git a/cisco/tests/asa/ocsf/inputs/deny_family.txt b/cisco/tests/asa/ocsf/inputs/deny_family.txt new file mode 100644 index 00000000..c261391b --- /dev/null +++ b/cisco/tests/asa/ocsf/inputs/deny_family.txt @@ -0,0 +1,8 @@ +<162>Jun 18 2025 11:38:05 asa-fw : %ASA-2-106001: Inbound TCP connection denied from 198.51.100.42/49709 to 10.1.1.22/6022 flags SYN on interface outside +<162>Jun 18 2025 11:38:06 asa-fw : %ASA-2-106006: Deny inbound UDP from 198.51.100.43/137 to 10.1.1.23/137 on interface outside +<163>Jun 18 2025 11:38:07 asa-fw : %ASA-3-106010: Deny inbound protocol 47 src outside:198.51.100.41 dst outside:10.1.1.21 +<163>Jun 18 2025 11:38:08 asa-fw : %ASA-3-106014: Deny inbound icmp src dmz:198.51.100.40 dst inside:10.1.1.20 (type 8, code 0) +<166>Jun 18 2025 11:38:09 asa-fw : %ASA-6-106100: access-list acl_in permitted udp outside/198.51.100.45(49543) -> dmz/10.1.1.25(53) hit-cnt 105 300-second interval [0x0, 0x0] +<164>Jun 18 2025 11:38:10 asa-fw : %ASA-4-106100: access-list acl_in denied 47 outside/198.51.100.44(0) -> dmz/10.1.1.24(0) hit-cnt 1 first hit [0x0, 0x0] +<163>Jun 18 2025 11:38:11 asa-fw : %ASA-3-313004: Denied ICMP type=0, from laddr 10.1.1.26 on interface inside to 10.1.1.27: no matching session +<163>Jun 18 2025 11:38:12 asa-fw : %ASA-3-313008: Denied IPv6-ICMP type=136, code=0 from fe80::21a:2bff:fe3c:4d5e on interface inside diff --git a/cisco/tests/asa/ocsf/inputs/deny_variants.txt b/cisco/tests/asa/ocsf/inputs/deny_variants.txt new file mode 100644 index 00000000..60c101fb --- /dev/null +++ b/cisco/tests/asa/ocsf/inputs/deny_variants.txt @@ -0,0 +1,3 @@ +<165>Jun 18 2025 11:38:02 asa-fw : %ASA-4-106023: Deny protocol 47 src outside:198.51.100.9 dst inside:10.1.1.7 by access-group "outside_access_in" [0x0, 0x0] +<165>Jun 18 2025 11:38:03 asa-fw : %ASA-4-106023: Deny udp src dmz:fw-host/514 dst outside:10.1.1.8/514 by access-group "dmz_access" [0x0, 0x0] +<165>Jun 18 2025 11:38:04 asa-fw : %ASA-4-106023: Deny icmp src outside:198.51.100.30 dst inside:10.1.1.9 (type 8, code 0) by access-group "outside_access_in" [0x0, 0x0] diff --git a/cisco/tests/asa/ocsf/inputs/easy_wins.txt b/cisco/tests/asa/ocsf/inputs/easy_wins.txt new file mode 100644 index 00000000..123ec122 --- /dev/null +++ b/cisco/tests/asa/ocsf/inputs/easy_wins.txt @@ -0,0 +1,4 @@ +<164>Jun 18 2025 11:38:13 asa-fw : %ASA-4-419002: Duplicate TCP SYN from inside:198.51.100.50/22 to dmz:10.1.1.30/443 with different initial sequence number +<163>Jun 18 2025 11:38:14 asa-fw : %ASA-3-710003: TCP access denied by ACL from 198.51.100.51/65396 to crypto:host.example/80 +<163>Jun 18 2025 11:38:15 asa-fw : %ASA-3-710005: UDP request discarded from 198.51.100.52/60389 to outside:10.1.1.31/44861 +<166>Jun 18 2025 11:38:16 asa-fw : %ASA-6-302021: Teardown ICMP connection for faddr 10.1.1.32/45078 gaddr 192.168.0.69/0 laddr 192.168.0.69/0 type 8 code 0 Internal-Data0/-1:RX[-1] diff --git a/cisco/tests/asa/ocsf/inputs/other.txt b/cisco/tests/asa/ocsf/inputs/other.txt new file mode 100644 index 00000000..d6f11eae --- /dev/null +++ b/cisco/tests/asa/ocsf/inputs/other.txt @@ -0,0 +1 @@ +<165>Jun 18 2025 11:38:10 asa-fw : %ASA-5-111008: User 'enable_15' executed the 'configure terminal' command. diff --git a/cisco/tests/asa/ocsf/inputs/teardown.txt b/cisco/tests/asa/ocsf/inputs/teardown.txt new file mode 100644 index 00000000..25434945 --- /dev/null +++ b/cisco/tests/asa/ocsf/inputs/teardown.txt @@ -0,0 +1,2 @@ +<166>Jun 18 2025 11:37:50 asa-fw : %ASA-6-302014: Teardown TCP connection 9 for outside:192.0.2.2/80 to inside:10.1.1.2/4924 duration 0:00:03 bytes 2048 TCP FINs +<166>Jun 18 2025 11:37:55 asa-fw : %ASA-6-302016: Teardown UDP connection 1005 for outside:198.51.100.5/53 to inside:10.1.1.3/51000 duration 0:00:05 bytes 312 diff --git a/cisco/tests/asa/ocsf/inputs/vpn.txt b/cisco/tests/asa/ocsf/inputs/vpn.txt new file mode 100644 index 00000000..4c8cd087 --- /dev/null +++ b/cisco/tests/asa/ocsf/inputs/vpn.txt @@ -0,0 +1,4 @@ +<166>Jun 18 2025 11:38:17 asa-fw : %ASA-6-722051: Group User IP <198.51.100.60> IPv4 Address <10.8.0.5> IPv6 address <::> assigned to session +<166>Jun 18 2025 11:38:18 asa-fw : %ASA-6-113019: Group = vpn-group, Username = user02, IP = 198.51.100.61, Session disconnected. Session Type: SSL, Duration: 0h:52m:12s, Bytes xmt: 17932, Bytes rcv: 228, Reason: User Requested +<165>Jun 18 2025 11:38:19 asa-fw : %ASA-5-746013: user-identity: Delete IP-User mapping 10.1.1.40 - LOCAL\user03 Succeeded - VPN user logout +<165>Jun 18 2025 11:38:20 asa-fw : %ASA-5-746013: user-identity: Delete IP-User mapping 10.1.1.41 - LOCAL\user04 Failed - PIP notification diff --git a/cisco/tests/asa/ocsf/map.tql b/cisco/tests/asa/ocsf/map.tql new file mode 100644 index 00000000..8f717d2e --- /dev/null +++ b/cisco/tests/asa/ocsf/map.tql @@ -0,0 +1,10 @@ +from_file f"{env("TENZIR_INPUTS")}/*.txt" { + read_lines +} +cisco::asa::parse message="line" +drop line +cisco::asa::ocsf::map +ocsf::derive +ocsf::cast +drop metadata.processed_time +sort message diff --git a/cisco/tests/asa/ocsf/map.txt b/cisco/tests/asa/ocsf/map.txt new file mode 100644 index 00000000..4fe9fa36 --- /dev/null +++ b/cisco/tests/asa/ocsf/map.txt @@ -0,0 +1,1386 @@ +{ + activity_id: 1, + activity_name: "Open", + category_name: "Network Activity", + category_uid: 4, + class_name: "Network Activity", + class_uid: 4001, + connection_info: { + direction: "Inbound", + direction_id: 1, + protocol_name: "tcp", + protocol_num: 6, + uid: "3332836331", + }, + disposition: "Allowed", + disposition_id: 1, + dst_endpoint: { + hostname: "host.example", + interface_name: "umbrella", + port: 443, + proxy_endpoint: { + hostname: "UMBRELLA-DOMAIN-BLOCK-HIT", + port: 443, + }, + }, + message: "Built inbound TCP connection 3332836331 for inside:10.1.1.9/50640 (198.51.100.20/50640) to umbrella:host.example/443 (UMBRELLA-DOMAIN-BLOCK-HIT/443) 0 24", + metadata: { + event_code: "302013", + log_name: "cisco.asa", + product: { + name: "Secure Firewall ASA", + vendor_name: "Cisco", + }, + profiles: [ + "host", + "security_control", + ], + version: "1.8.0", + }, + severity: "Informational", + severity_id: 1, + src_endpoint: { + interface_name: "inside", + ip: 10.1.1.9, + port: 50640, + proxy_endpoint: { + ip: 198.51.100.20, + port: 50640, + }, + }, + time: 2025-06-18T11:37:48Z, + type_name: "Network Activity: Open", + type_uid: 400101, + unmapped: { + priority: 166, + context: null, + message_id: 302013, + }, +} +{ + activity_id: 1, + activity_name: "Open", + category_name: "Network Activity", + category_uid: 4, + class_name: "Network Activity", + class_uid: 4001, + connection_info: { + direction: "Inbound", + direction_id: 1, + protocol_name: "udp", + protocol_num: 17, + uid: "1005", + }, + disposition: "Allowed", + disposition_id: 1, + dst_endpoint: { + interface_name: "inside", + ip: 10.1.1.3, + port: 51000, + }, + message: "Built inbound UDP connection 1005 for outside:198.51.100.5/53 (198.51.100.5/53) to inside:10.1.1.3/51000 (10.1.1.3/51000)", + metadata: { + event_code: "302015", + log_name: "cisco.asa", + product: { + name: "Secure Firewall ASA", + vendor_name: "Cisco", + }, + profiles: [ + "host", + "security_control", + ], + version: "1.8.0", + }, + severity: "Informational", + severity_id: 1, + src_endpoint: { + interface_name: "outside", + ip: 198.51.100.5, + port: 53, + }, + time: 2025-06-18T11:37:48Z, + type_name: "Network Activity: Open", + type_uid: 400101, + unmapped: { + priority: 166, + context: null, + message_id: 302015, + }, +} +{ + activity_id: 1, + activity_name: "Open", + category_name: "Network Activity", + category_uid: 4, + class_name: "Network Activity", + class_uid: 4001, + connection_info: { + direction: "Outbound", + direction_id: 2, + protocol_name: "tcp", + protocol_num: 6, + uid: "9", + }, + disposition: "Allowed", + disposition_id: 1, + dst_endpoint: { + interface_name: "inside", + ip: 10.1.1.2, + port: 4924, + proxy_endpoint: { + ip: 203.0.113.10, + port: 4924, + }, + }, + message: "Built outbound TCP connection 9 for outside:192.0.2.2/80 (192.0.2.2/80) to inside:10.1.1.2/4924 (203.0.113.10/4924)", + metadata: { + event_code: "302013", + log_name: "cisco.asa", + product: { + name: "Secure Firewall ASA", + vendor_name: "Cisco", + }, + profiles: [ + "host", + "security_control", + ], + version: "1.8.0", + }, + severity: "Informational", + severity_id: 1, + src_endpoint: { + interface_name: "outside", + ip: 192.0.2.2, + port: 80, + }, + time: 2025-06-18T11:37:47Z, + type_name: "Network Activity: Open", + type_uid: 400101, + unmapped: { + priority: 166, + context: null, + message_id: 302013, + }, +} +{ + action: "Denied", + action_id: 2, + activity_id: 6, + activity_name: "Traffic", + category_name: "Network Activity", + category_uid: 4, + class_name: "Network Activity", + class_uid: 4001, + connection_info: { + protocol_name: "icmp", + protocol_num: 1, + }, + disposition: "Blocked", + disposition_id: 2, + dst_endpoint: { + interface_name: null, + ip: 10.1.1.27, + port: null, + }, + message: "Denied ICMP type=0, from laddr 10.1.1.26 on interface inside to 10.1.1.27: no matching session", + metadata: { + event_code: "313004", + log_name: "cisco.asa", + product: { + name: "Secure Firewall ASA", + vendor_name: "Cisco", + }, + profiles: [ + "host", + "security_control", + ], + version: "1.8.0", + }, + severity: "High", + severity_id: 4, + src_endpoint: { + interface_name: "inside", + ip: 10.1.1.26, + port: null, + }, + time: 2025-06-18T11:38:11Z, + type_name: "Network Activity: Traffic", + type_uid: 400106, + unmapped: { + priority: 163, + context: null, + message_id: 313004, + icmp_type: 0, + reason: "no matching session", + }, +} +{ + action: "Denied", + action_id: 2, + activity_id: 6, + activity_name: "Traffic", + category_name: "Network Activity", + category_uid: 4, + class_name: "Network Activity", + class_uid: 4001, + connection_info: { + protocol_name: "ipv6-icmp", + protocol_num: -1, + }, + disposition: "Blocked", + disposition_id: 2, + dst_endpoint: { + interface_name: null, + port: null, + }, + message: "Denied IPv6-ICMP type=136, code=0 from fe80::21a:2bff:fe3c:4d5e on interface inside", + metadata: { + event_code: "313008", + log_name: "cisco.asa", + product: { + name: "Secure Firewall ASA", + vendor_name: "Cisco", + }, + profiles: [ + "host", + "security_control", + ], + version: "1.8.0", + }, + severity: "High", + severity_id: 4, + src_endpoint: { + interface_name: "inside", + ip: fe80::21a:2bff:fe3c:4d5e, + port: null, + }, + time: 2025-06-18T11:38:12Z, + type_name: "Network Activity: Traffic", + type_uid: 400106, + unmapped: { + priority: 163, + context: null, + message_id: 313008, + icmp_type: 136, + icmp_code: 0, + }, +} +{ + action: "Denied", + action_id: 2, + activity_id: 6, + activity_name: "Traffic", + category_name: "Network Activity", + category_uid: 4, + class_name: "Network Activity", + class_uid: 4001, + connection_info: { + protocol_name: "icmp", + protocol_num: 1, + }, + disposition: "Blocked", + disposition_id: 2, + dst_endpoint: { + interface_name: "inside", + ip: 10.1.1.9, + port: null, + }, + firewall_rule: { + name: "outside_access_in", + }, + message: "Deny icmp src outside:198.51.100.30 dst inside:10.1.1.9 (type 8, code 0) by access-group \"outside_access_in\" [0x0, 0x0]", + metadata: { + event_code: "106023", + log_name: "cisco.asa", + product: { + name: "Secure Firewall ASA", + vendor_name: "Cisco", + }, + profiles: [ + "host", + "security_control", + ], + version: "1.8.0", + }, + severity: "Medium", + severity_id: 3, + src_endpoint: { + interface_name: "outside", + ip: 198.51.100.30, + port: null, + }, + time: 2025-06-18T11:38:04Z, + type_name: "Network Activity: Traffic", + type_uid: 400106, + unmapped: { + priority: 165, + context: null, + message_id: 106023, + protocol_num: null, + icmp_type: 8, + icmp_code: 0, + }, +} +{ + action: "Denied", + action_id: 2, + activity_id: 6, + activity_name: "Traffic", + category_name: "Network Activity", + category_uid: 4, + class_name: "Network Activity", + class_uid: 4001, + connection_info: { + protocol_name: "icmp", + protocol_num: 1, + }, + disposition: "Blocked", + disposition_id: 2, + dst_endpoint: { + interface_name: "inside", + ip: 10.1.1.6, + port: 0, + }, + firewall_rule: { + name: "outside_access_in", + }, + message: "Deny icmp src outside:198.51.100.8/0 dst inside:10.1.1.6/0 [type 8, code 0] by access-group \"outside_access_in\" [0x0, 0x0]", + metadata: { + event_code: "106023", + log_name: "cisco.asa", + product: { + name: "Secure Firewall ASA", + vendor_name: "Cisco", + }, + profiles: [ + "host", + "security_control", + ], + version: "1.8.0", + }, + severity: "Medium", + severity_id: 3, + src_endpoint: { + interface_name: "outside", + ip: 198.51.100.8, + port: 0, + }, + time: 2025-06-18T11:38:01Z, + type_name: "Network Activity: Traffic", + type_uid: 400106, + unmapped: { + priority: 165, + context: null, + message_id: 106023, + protocol_num: null, + icmp_type: 8, + icmp_code: 0, + }, +} +{ + action: "Denied", + action_id: 2, + activity_id: 6, + activity_name: "Traffic", + category_name: "Network Activity", + category_uid: 4, + class_name: "Network Activity", + class_uid: 4001, + connection_info: { + direction: "Inbound", + direction_id: 1, + protocol_name: "udp", + protocol_num: 17, + }, + disposition: "Blocked", + disposition_id: 2, + dst_endpoint: { + interface_name: null, + ip: 10.1.1.23, + port: 137, + }, + message: "Deny inbound UDP from 198.51.100.43/137 to 10.1.1.23/137 on interface outside", + metadata: { + event_code: "106006", + log_name: "cisco.asa", + product: { + name: "Secure Firewall ASA", + vendor_name: "Cisco", + }, + profiles: [ + "host", + "security_control", + ], + version: "1.8.0", + }, + severity: "Critical", + severity_id: 5, + src_endpoint: { + interface_name: "outside", + ip: 198.51.100.43, + port: 137, + }, + time: 2025-06-18T11:38:06Z, + type_name: "Network Activity: Traffic", + type_uid: 400106, + unmapped: { + priority: 162, + context: null, + message_id: 106006, + }, +} +{ + action: "Denied", + action_id: 2, + activity_id: 6, + activity_name: "Traffic", + category_name: "Network Activity", + category_uid: 4, + class_name: "Network Activity", + class_uid: 4001, + connection_info: { + direction: "Inbound", + direction_id: 1, + protocol_name: "icmp", + protocol_num: 1, + }, + disposition: "Blocked", + disposition_id: 2, + dst_endpoint: { + interface_name: "inside", + ip: 10.1.1.20, + port: null, + }, + message: "Deny inbound icmp src dmz:198.51.100.40 dst inside:10.1.1.20 (type 8, code 0)", + metadata: { + event_code: "106014", + log_name: "cisco.asa", + product: { + name: "Secure Firewall ASA", + vendor_name: "Cisco", + }, + profiles: [ + "host", + "security_control", + ], + version: "1.8.0", + }, + severity: "High", + severity_id: 4, + src_endpoint: { + interface_name: "dmz", + ip: 198.51.100.40, + port: null, + }, + time: 2025-06-18T11:38:08Z, + type_name: "Network Activity: Traffic", + type_uid: 400106, + unmapped: { + priority: 163, + context: null, + message_id: 106014, + protocol_num: null, + icmp_type: 8, + icmp_code: 0, + acl_id: null, + }, +} +{ + action: "Denied", + action_id: 2, + activity_id: 6, + activity_name: "Traffic", + category_name: "Network Activity", + category_uid: 4, + class_name: "Network Activity", + class_uid: 4001, + connection_info: { + direction: "Inbound", + direction_id: 1, + protocol_num: 47, + }, + disposition: "Blocked", + disposition_id: 2, + dst_endpoint: { + interface_name: "outside", + ip: 10.1.1.21, + port: null, + }, + message: "Deny inbound protocol 47 src outside:198.51.100.41 dst outside:10.1.1.21", + metadata: { + event_code: "106010", + log_name: "cisco.asa", + product: { + name: "Secure Firewall ASA", + vendor_name: "Cisco", + }, + profiles: [ + "host", + "security_control", + ], + version: "1.8.0", + }, + severity: "High", + severity_id: 4, + src_endpoint: { + interface_name: "outside", + ip: 198.51.100.41, + port: null, + }, + time: 2025-06-18T11:38:07Z, + type_name: "Network Activity: Traffic", + type_uid: 400106, + unmapped: { + priority: 163, + context: null, + message_id: 106010, + icmp_type: null, + icmp_code: null, + acl_id: null, + }, +} +{ + action: "Denied", + action_id: 2, + activity_id: 6, + activity_name: "Traffic", + category_name: "Network Activity", + category_uid: 4, + class_name: "Network Activity", + class_uid: 4001, + connection_info: { + protocol_num: 47, + }, + disposition: "Blocked", + disposition_id: 2, + dst_endpoint: { + interface_name: "inside", + ip: 10.1.1.7, + port: null, + }, + firewall_rule: { + name: "outside_access_in", + }, + message: "Deny protocol 47 src outside:198.51.100.9 dst inside:10.1.1.7 by access-group \"outside_access_in\" [0x0, 0x0]", + metadata: { + event_code: "106023", + log_name: "cisco.asa", + product: { + name: "Secure Firewall ASA", + vendor_name: "Cisco", + }, + profiles: [ + "host", + "security_control", + ], + version: "1.8.0", + }, + severity: "Medium", + severity_id: 3, + src_endpoint: { + interface_name: "outside", + ip: 198.51.100.9, + port: null, + }, + time: 2025-06-18T11:38:02Z, + type_name: "Network Activity: Traffic", + type_uid: 400106, + unmapped: { + priority: 165, + context: null, + message_id: 106023, + icmp_type: null, + icmp_code: null, + }, +} +{ + action: "Denied", + action_id: 2, + activity_id: 6, + activity_name: "Traffic", + category_name: "Network Activity", + category_uid: 4, + class_name: "Network Activity", + class_uid: 4001, + connection_info: { + protocol_name: "tcp", + protocol_num: 6, + }, + disposition: "Blocked", + disposition_id: 2, + dst_endpoint: { + interface_name: "inside", + ip: 10.1.1.5, + port: 3389, + }, + firewall_rule: { + name: "outside_access_in", + }, + message: "Deny tcp src outside:198.51.100.7/4444 dst inside:10.1.1.5/3389 by access-group \"outside_access_in\" [0x0, 0x0]", + metadata: { + event_code: "106023", + log_name: "cisco.asa", + product: { + name: "Secure Firewall ASA", + vendor_name: "Cisco", + }, + profiles: [ + "host", + "security_control", + ], + version: "1.8.0", + }, + severity: "Medium", + severity_id: 3, + src_endpoint: { + interface_name: "outside", + ip: 198.51.100.7, + port: 4444, + }, + time: 2025-06-18T11:38:00Z, + type_name: "Network Activity: Traffic", + type_uid: 400106, + unmapped: { + priority: 165, + context: null, + message_id: 106023, + protocol_num: null, + icmp_type: null, + icmp_code: null, + }, +} +{ + action: "Denied", + action_id: 2, + activity_id: 6, + activity_name: "Traffic", + category_name: "Network Activity", + category_uid: 4, + class_name: "Network Activity", + class_uid: 4001, + connection_info: { + protocol_name: "udp", + protocol_num: 17, + }, + disposition: "Blocked", + disposition_id: 2, + dst_endpoint: { + interface_name: "outside", + ip: 10.1.1.8, + port: 514, + }, + firewall_rule: { + name: "dmz_access", + }, + message: "Deny udp src dmz:fw-host/514 dst outside:10.1.1.8/514 by access-group \"dmz_access\" [0x0, 0x0]", + metadata: { + event_code: "106023", + log_name: "cisco.asa", + product: { + name: "Secure Firewall ASA", + vendor_name: "Cisco", + }, + profiles: [ + "host", + "security_control", + ], + version: "1.8.0", + }, + severity: "Medium", + severity_id: 3, + src_endpoint: { + hostname: "fw-host", + interface_name: "dmz", + port: 514, + }, + time: 2025-06-18T11:38:03Z, + type_name: "Network Activity: Traffic", + type_uid: 400106, + unmapped: { + priority: 165, + context: null, + message_id: 106023, + protocol_num: null, + icmp_type: null, + icmp_code: null, + }, +} +{ + activity_id: 6, + activity_name: "Traffic", + category_name: "Network Activity", + category_uid: 4, + class_name: "Network Activity", + class_uid: 4001, + connection_info: { + protocol_name: "tcp", + protocol_num: 6, + }, + dst_endpoint: { + interface_name: "dmz", + ip: 10.1.1.30, + port: 443, + }, + message: "Duplicate TCP SYN from inside:198.51.100.50/22 to dmz:10.1.1.30/443 with different initial sequence number", + metadata: { + event_code: "419002", + log_name: "cisco.asa", + product: { + name: "Secure Firewall ASA", + vendor_name: "Cisco", + }, + profiles: [ + "host", + "security_control", + ], + version: "1.8.0", + }, + severity: "Medium", + severity_id: 3, + src_endpoint: { + interface_name: "inside", + ip: 198.51.100.50, + port: 22, + }, + time: 2025-06-18T11:38:13Z, + type_name: "Network Activity: Traffic", + type_uid: 400106, + unmapped: { + priority: 164, + context: null, + message_id: 419002, + }, +} +{ + activity_id: 1, + activity_name: "Logon", + category_name: "Identity & Access Management", + category_uid: 3, + class_name: "Authentication", + class_uid: 3002, + message: "Group User IP <198.51.100.60> IPv4 Address <10.8.0.5> IPv6 address <::> assigned to session", + metadata: { + event_code: "722051", + log_name: "cisco.asa", + product: { + name: "Secure Firewall ASA", + vendor_name: "Cisco", + }, + profiles: [ + "host", + "security_control", + ], + version: "1.8.0", + }, + severity: "Informational", + severity_id: 1, + src_endpoint: { + ip: 198.51.100.60, + }, + status: "Success", + status_id: 1, + time: 2025-06-18T11:38:17Z, + type_name: "Authentication: Logon", + type_uid: 300201, + unmapped: { + priority: 166, + context: null, + message_id: 722051, + assigned_ipv4: 10.8.0.5, + assigned_ipv6: ::, + }, + user: { + groups: [ + { + name: "vpn-group", + }, + ], + name: "user01", + }, +} +{ + activity_id: 2, + activity_name: "Logoff", + category_name: "Identity & Access Management", + category_uid: 3, + class_name: "Authentication", + class_uid: 3002, + message: "Group = vpn-group, Username = user02, IP = 198.51.100.61, Session disconnected. Session Type: SSL, Duration: 0h:52m:12s, Bytes xmt: 17932, Bytes rcv: 228, Reason: User Requested", + metadata: { + event_code: "113019", + log_name: "cisco.asa", + product: { + name: "Secure Firewall ASA", + vendor_name: "Cisco", + }, + profiles: [ + "host", + "security_control", + ], + version: "1.8.0", + }, + severity: "Informational", + severity_id: 1, + src_endpoint: { + ip: 198.51.100.61, + }, + status: "Success", + status_detail: "User Requested", + status_id: 1, + time: 2025-06-18T11:38:18Z, + type_name: "Authentication: Logoff", + type_uid: 300202, + unmapped: { + priority: 166, + context: null, + message_id: 113019, + session_type: "SSL", + duration: "0h:52m:12s", + bytes_out: 17932, + bytes_in: 228, + }, + user: { + groups: [ + { + name: "vpn-group", + }, + ], + name: "user02", + }, +} +{ + action: "Denied", + action_id: 2, + activity_id: 6, + activity_name: "Traffic", + category_name: "Network Activity", + category_uid: 4, + class_name: "Network Activity", + class_uid: 4001, + connection_info: { + direction: "Inbound", + direction_id: 1, + protocol_name: "tcp", + protocol_num: 6, + }, + disposition: "Blocked", + disposition_id: 2, + dst_endpoint: { + interface_name: null, + ip: 10.1.1.22, + port: 6022, + }, + message: "Inbound TCP connection denied from 198.51.100.42/49709 to 10.1.1.22/6022 flags SYN on interface outside", + metadata: { + event_code: "106001", + log_name: "cisco.asa", + product: { + name: "Secure Firewall ASA", + vendor_name: "Cisco", + }, + profiles: [ + "host", + "security_control", + ], + version: "1.8.0", + }, + severity: "Critical", + severity_id: 5, + src_endpoint: { + interface_name: "outside", + ip: 198.51.100.42, + port: 49709, + }, + time: 2025-06-18T11:38:05Z, + type_name: "Network Activity: Traffic", + type_uid: 400106, + unmapped: { + priority: 162, + context: null, + message_id: 106001, + tcp_flags: "SYN", + }, +} +{ + action: "Denied", + action_id: 2, + activity_id: 6, + activity_name: "Traffic", + category_name: "Network Activity", + category_uid: 4, + class_name: "Network Activity", + class_uid: 4001, + connection_info: { + protocol_name: "tcp", + protocol_num: 6, + }, + disposition: "Blocked", + disposition_id: 2, + dst_endpoint: { + hostname: "host.example", + interface_name: "crypto", + port: 80, + }, + message: "TCP access denied by ACL from 198.51.100.51/65396 to crypto:host.example/80", + metadata: { + event_code: "710003", + log_name: "cisco.asa", + product: { + name: "Secure Firewall ASA", + vendor_name: "Cisco", + }, + profiles: [ + "host", + "security_control", + ], + version: "1.8.0", + }, + severity: "High", + severity_id: 4, + src_endpoint: { + interface_name: null, + ip: 198.51.100.51, + port: 65396, + }, + time: 2025-06-18T11:38:14Z, + type_name: "Network Activity: Traffic", + type_uid: 400106, + unmapped: { + priority: 163, + context: null, + message_id: 710003, + }, +} +{ + activity_id: 2, + activity_name: "Close", + category_name: "Network Activity", + category_uid: 4, + class_name: "Network Activity", + class_uid: 4001, + connection_info: { + protocol_name: "icmp", + protocol_num: 1, + }, + disposition: "Allowed", + disposition_id: 1, + dst_endpoint: { + interface_name: null, + ip: 10.1.1.32, + port: null, + }, + message: "Teardown ICMP connection for faddr 10.1.1.32/45078 gaddr 192.168.0.69/0 laddr 192.168.0.69/0 type 8 code 0 Internal-Data0/-1:RX[-1]", + metadata: { + event_code: "302021", + log_name: "cisco.asa", + product: { + name: "Secure Firewall ASA", + vendor_name: "Cisco", + }, + profiles: [ + "host", + "security_control", + ], + version: "1.8.0", + }, + severity: "Informational", + severity_id: 1, + src_endpoint: { + interface_name: null, + ip: 192.168.0.69, + port: null, + }, + time: 2025-06-18T11:38:16Z, + type_name: "Network Activity: Close", + type_uid: 400102, + unmapped: { + priority: 166, + context: null, + message_id: 302021, + faddr_id: 45078, + gaddr_id: 0, + laddr_id: 0, + }, +} +{ + activity_id: 2, + activity_name: "Close", + category_name: "Network Activity", + category_uid: 4, + class_name: "Network Activity", + class_uid: 4001, + connection_info: { + protocol_name: "tcp", + protocol_num: 6, + uid: "9", + }, + disposition: "Allowed", + disposition_id: 1, + dst_endpoint: { + interface_name: "inside", + ip: 10.1.1.2, + port: 4924, + }, + message: "Teardown TCP connection 9 for outside:192.0.2.2/80 to inside:10.1.1.2/4924 duration 0:00:03 bytes 2048 TCP FINs", + metadata: { + event_code: "302014", + log_name: "cisco.asa", + product: { + name: "Secure Firewall ASA", + vendor_name: "Cisco", + }, + profiles: [ + "host", + "security_control", + ], + version: "1.8.0", + }, + severity: "Informational", + severity_id: 1, + src_endpoint: { + interface_name: "outside", + ip: 192.0.2.2, + port: 80, + }, + status_detail: "TCP FINs", + time: 2025-06-18T11:37:50Z, + traffic: { + bytes: 2048, + }, + type_name: "Network Activity: Close", + type_uid: 400102, + unmapped: { + priority: 166, + context: null, + message_id: 302014, + duration: "0:00:03", + }, +} +{ + activity_id: 2, + activity_name: "Close", + category_name: "Network Activity", + category_uid: 4, + class_name: "Network Activity", + class_uid: 4001, + connection_info: { + protocol_name: "udp", + protocol_num: 17, + uid: "1005", + }, + disposition: "Allowed", + disposition_id: 1, + dst_endpoint: { + interface_name: "inside", + ip: 10.1.1.3, + port: 51000, + }, + message: "Teardown UDP connection 1005 for outside:198.51.100.5/53 to inside:10.1.1.3/51000 duration 0:00:05 bytes 312", + metadata: { + event_code: "302016", + log_name: "cisco.asa", + product: { + name: "Secure Firewall ASA", + vendor_name: "Cisco", + }, + profiles: [ + "host", + "security_control", + ], + version: "1.8.0", + }, + severity: "Informational", + severity_id: 1, + src_endpoint: { + interface_name: "outside", + ip: 198.51.100.5, + port: 53, + }, + time: 2025-06-18T11:37:55Z, + traffic: { + bytes: 312, + }, + type_name: "Network Activity: Close", + type_uid: 400102, + unmapped: { + priority: 166, + context: null, + message_id: 302016, + duration: "0:00:05", + reason: null, + }, +} +{ + action: "Denied", + action_id: 2, + activity_id: 6, + activity_name: "Traffic", + category_name: "Network Activity", + category_uid: 4, + class_name: "Network Activity", + class_uid: 4001, + connection_info: { + protocol_name: "udp", + protocol_num: 17, + }, + disposition: "Blocked", + disposition_id: 2, + dst_endpoint: { + interface_name: "outside", + ip: 10.1.1.31, + port: 44861, + }, + message: "UDP request discarded from 198.51.100.52/60389 to outside:10.1.1.31/44861", + metadata: { + event_code: "710005", + log_name: "cisco.asa", + product: { + name: "Secure Firewall ASA", + vendor_name: "Cisco", + }, + profiles: [ + "host", + "security_control", + ], + version: "1.8.0", + }, + severity: "High", + severity_id: 4, + src_endpoint: { + interface_name: null, + ip: 198.51.100.52, + port: 60389, + }, + time: 2025-06-18T11:38:15Z, + type_name: "Network Activity: Traffic", + type_uid: 400106, + unmapped: { + priority: 163, + context: null, + message_id: 710005, + }, +} +{ + activity_id: 0, + activity_name: "Unknown", + category_name: "Uncategorized", + category_uid: 0, + class_name: "Base Event", + class_uid: 0, + message: "User 'enable_15' executed the 'configure terminal' command.", + metadata: { + event_code: "111008", + log_name: "cisco.asa", + product: { + name: "Secure Firewall ASA", + vendor_name: "Cisco", + }, + profiles: [ + "host", + "security_control", + ], + version: "1.8.0", + }, + severity: "Low", + severity_id: 2, + time: 2025-06-18T11:38:10Z, + type_name: "Base Event: Unknown", + type_uid: 0, + unmapped: { + priority: 165, + context: null, + message_id: 111008, + }, +} +{ + action: "Denied", + action_id: 2, + activity_id: 6, + activity_name: "Traffic", + category_name: "Network Activity", + category_uid: 4, + class_name: "Network Activity", + class_uid: 4001, + connection_info: { + protocol_num: 47, + }, + count: 1, + disposition: "Blocked", + disposition_id: 2, + dst_endpoint: { + interface_name: "dmz", + ip: 10.1.1.24, + port: 0, + }, + firewall_rule: { + name: "acl_in", + }, + message: "access-list acl_in denied 47 outside/198.51.100.44(0) -> dmz/10.1.1.24(0) hit-cnt 1 first hit [0x0, 0x0]", + metadata: { + event_code: "106100", + log_name: "cisco.asa", + product: { + name: "Secure Firewall ASA", + vendor_name: "Cisco", + }, + profiles: [ + "host", + "security_control", + ], + version: "1.8.0", + }, + severity: "Medium", + severity_id: 3, + src_endpoint: { + interface_name: "outside", + ip: 198.51.100.44, + port: 0, + }, + time: 2025-06-18T11:38:10Z, + type_name: "Network Activity: Traffic", + type_uid: 400106, + unmapped: { + priority: 164, + context: null, + message_id: 106100, + }, +} +{ + action: "Allowed", + action_id: 1, + activity_id: 6, + activity_name: "Traffic", + category_name: "Network Activity", + category_uid: 4, + class_name: "Network Activity", + class_uid: 4001, + connection_info: { + protocol_name: "udp", + protocol_num: 17, + }, + count: 105, + disposition: "Allowed", + disposition_id: 1, + dst_endpoint: { + interface_name: "dmz", + ip: 10.1.1.25, + port: 53, + }, + firewall_rule: { + name: "acl_in", + }, + message: "access-list acl_in permitted udp outside/198.51.100.45(49543) -> dmz/10.1.1.25(53) hit-cnt 105 300-second interval [0x0, 0x0]", + metadata: { + event_code: "106100", + log_name: "cisco.asa", + product: { + name: "Secure Firewall ASA", + vendor_name: "Cisco", + }, + profiles: [ + "host", + "security_control", + ], + version: "1.8.0", + }, + severity: "Informational", + severity_id: 1, + src_endpoint: { + interface_name: "outside", + ip: 198.51.100.45, + port: 49543, + }, + time: 2025-06-18T11:38:09Z, + type_name: "Network Activity: Traffic", + type_uid: 400106, + unmapped: { + priority: 166, + context: null, + message_id: 106100, + }, +} +{ + activity_id: 2, + activity_name: "Logoff", + category_name: "Identity & Access Management", + category_uid: 3, + class_name: "Authentication", + class_uid: 3002, + message: "user-identity: Delete IP-User mapping 10.1.1.40 - LOCAL\\user03 Succeeded - VPN user logout", + metadata: { + event_code: "746013", + log_name: "cisco.asa", + product: { + name: "Secure Firewall ASA", + vendor_name: "Cisco", + }, + profiles: [ + "host", + "security_control", + ], + version: "1.8.0", + }, + severity: "Low", + severity_id: 2, + src_endpoint: { + ip: 10.1.1.40, + }, + status: "Success", + status_detail: "VPN user logout", + status_id: 1, + time: 2025-06-18T11:38:19Z, + type_name: "Authentication: Logoff", + type_uid: 300202, + unmapped: { + priority: 165, + context: null, + message_id: 746013, + }, + user: { + domain: "LOCAL", + name: "user03", + }, +} +{ + activity_id: 2, + activity_name: "Logoff", + category_name: "Identity & Access Management", + category_uid: 3, + class_name: "Authentication", + class_uid: 3002, + message: "user-identity: Delete IP-User mapping 10.1.1.41 - LOCAL\\user04 Failed - PIP notification", + metadata: { + event_code: "746013", + log_name: "cisco.asa", + product: { + name: "Secure Firewall ASA", + vendor_name: "Cisco", + }, + profiles: [ + "host", + "security_control", + ], + version: "1.8.0", + }, + severity: "Low", + severity_id: 2, + src_endpoint: { + ip: 10.1.1.41, + }, + status: "Failure", + status_detail: "PIP notification", + status_id: 2, + time: 2025-06-18T11:38:20Z, + type_name: "Authentication: Logoff", + type_uid: 300202, + unmapped: { + priority: 165, + context: null, + message_id: 746013, + }, + user: { + domain: "LOCAL", + name: "user04", + }, +} diff --git a/cisco/tests/asa/parse.input b/cisco/tests/asa/parse.input new file mode 100644 index 00000000..c62cd6c9 --- /dev/null +++ b/cisco/tests/asa/parse.input @@ -0,0 +1,8 @@ +<166>Jun 18 2025 11:37:47 asa-fw : %ASA-6-302013: Built outbound TCP connection 9 for outside:192.0.2.2/80 (192.0.2.2/80) to inside:10.1.1.2/4924 (203.0.113.10/4924) +<166>Jun 18 2025 11:37:50 asa-fw : %ASA-6-302014: Teardown TCP connection 9 for outside:192.0.2.2/80 to inside:10.1.1.2/4924 duration 0:00:03 bytes 2048 TCP FINs +<165>Jun 18 2025 11:38:00 asa-fw : %ASA-4-106023: Deny tcp src outside:198.51.100.7/4444 dst inside:10.1.1.5/3389 by access-group "outside_access_in" [0x0, 0x0] +<166>Jun 18 2025 11:37:48 asa-fw : %ASA-6-302013: Built inbound TCP connection 3332836331 for inside:10.1.1.9/50640 (198.51.100.20/50640) to umbrella:host.example/443 (UMBRELLA-DOMAIN-BLOCK-HIT/443) 0 24 +<165>Jun 18 2025 11:38:02 asa-fw : %ASA-4-106023: Deny protocol 47 src outside:198.51.100.9 dst inside:10.1.1.7 by access-group "outside_access_in" [0x0, 0x0] +<165>Jun 18 2025 11:38:03 asa-fw : %ASA-4-106023: Deny udp src dmz:fw-host/514 dst outside:10.1.1.8/514 by access-group "dmz_access" [0x0, 0x0] +<165>Jun 18 2025 11:38:10 asa-fw : %ASA-5-111008: User 'enable_15' executed the 'configure terminal' command. +<166>2018-06-27T12:17:46Z asa : %ASA-6-302013: Built outbound TCP connection 100 for outside:198.51.100.60/443 (198.51.100.60/443) to inside:10.1.1.40/52000 (10.1.1.40/52000) diff --git a/cisco/tests/asa/parse.tql b/cisco/tests/asa/parse.tql new file mode 100644 index 00000000..bdc2f44d --- /dev/null +++ b/cisco/tests/asa/parse.tql @@ -0,0 +1,6 @@ +from_file env("TENZIR_INPUT") { + read_lines +} +cisco::asa::parse message="line" +drop line +sort message_id diff --git a/cisco/tests/asa/parse.txt b/cisco/tests/asa/parse.txt new file mode 100644 index 00000000..8936f3b3 --- /dev/null +++ b/cisco/tests/asa/parse.txt @@ -0,0 +1,149 @@ +{ + priority: 165, + context: null, + severity: 4, + message_id: 106023, + text: "Deny tcp src outside:198.51.100.7/4444 dst inside:10.1.1.5/3389 by access-group \"outside_access_in\" [0x0, 0x0]", + time: 2025-06-18T11:38:00Z, + direction: null, + protocol: "tcp", + protocol_num: null, + src_interface: "outside", + src_host: "198.51.100.7", + src_port: 4444, + dst_interface: "inside", + dst_host: "10.1.1.5", + dst_port: 3389, + icmp_type: null, + icmp_code: null, + acl_id: "outside_access_in", +} +{ + priority: 165, + context: null, + severity: 4, + message_id: 106023, + text: "Deny udp src dmz:fw-host/514 dst outside:10.1.1.8/514 by access-group \"dmz_access\" [0x0, 0x0]", + time: 2025-06-18T11:38:03Z, + direction: null, + protocol: "udp", + protocol_num: null, + src_interface: "dmz", + src_host: "fw-host", + src_port: 514, + dst_interface: "outside", + dst_host: "10.1.1.8", + dst_port: 514, + icmp_type: null, + icmp_code: null, + acl_id: "dmz_access", +} +{ + priority: 165, + context: null, + severity: 4, + message_id: 106023, + text: "Deny protocol 47 src outside:198.51.100.9 dst inside:10.1.1.7 by access-group \"outside_access_in\" [0x0, 0x0]", + time: 2025-06-18T11:38:02Z, + direction: "protocol", + protocol_num: 47, + src_interface: "outside", + src_host: "198.51.100.9", + src_port: null, + dst_interface: "inside", + dst_host: "10.1.1.7", + dst_port: null, + icmp_type: null, + icmp_code: null, + acl_id: "outside_access_in", +} +{ + priority: 165, + context: null, + severity: 5, + message_id: 111008, + text: "User 'enable_15' executed the 'configure terminal' command.", + time: 2025-06-18T11:38:10Z, +} +{ + priority: 166, + context: null, + severity: 6, + message_id: 302013, + text: "Built outbound TCP connection 100 for outside:198.51.100.60/443 (198.51.100.60/443) to inside:10.1.1.40/52000 (10.1.1.40/52000)", + time: 2018-06-27T12:17:46Z, + direction: "outbound", + protocol: "TCP", + connection_id: 100, + src_interface: "outside", + src_host: "198.51.100.60", + src_port: 443, + src_xlate_host: "198.51.100.60", + src_xlate_port: 443, + dst_interface: "inside", + dst_host: "10.1.1.40", + dst_port: 52000, + dst_xlate_host: "10.1.1.40", + dst_xlate_port: 52000, +} +{ + priority: 166, + context: null, + severity: 6, + message_id: 302013, + text: "Built outbound TCP connection 9 for outside:192.0.2.2/80 (192.0.2.2/80) to inside:10.1.1.2/4924 (203.0.113.10/4924)", + time: 2025-06-18T11:37:47Z, + direction: "outbound", + protocol: "TCP", + connection_id: 9, + src_interface: "outside", + src_host: "192.0.2.2", + src_port: 80, + src_xlate_host: "192.0.2.2", + src_xlate_port: 80, + dst_interface: "inside", + dst_host: "10.1.1.2", + dst_port: 4924, + dst_xlate_host: "203.0.113.10", + dst_xlate_port: 4924, +} +{ + priority: 166, + context: null, + severity: 6, + message_id: 302013, + text: "Built inbound TCP connection 3332836331 for inside:10.1.1.9/50640 (198.51.100.20/50640) to umbrella:host.example/443 (UMBRELLA-DOMAIN-BLOCK-HIT/443) 0 24", + time: 2025-06-18T11:37:48Z, + direction: "inbound", + protocol: "TCP", + connection_id: 3332836331, + src_interface: "inside", + src_host: "10.1.1.9", + src_port: 50640, + src_xlate_host: "198.51.100.20", + src_xlate_port: 50640, + dst_interface: "umbrella", + dst_host: "host.example", + dst_port: 443, + dst_xlate_host: "UMBRELLA-DOMAIN-BLOCK-HIT", + dst_xlate_port: 443, +} +{ + priority: 166, + context: null, + severity: 6, + message_id: 302014, + text: "Teardown TCP connection 9 for outside:192.0.2.2/80 to inside:10.1.1.2/4924 duration 0:00:03 bytes 2048 TCP FINs", + time: 2025-06-18T11:37:50Z, + protocol: "TCP", + connection_id: 9, + src_interface: "outside", + src_host: "192.0.2.2", + src_port: 80, + dst_interface: "inside", + dst_host: "10.1.1.2", + dst_port: 4924, + duration: "0:00:03", + bytes: 2048, + reason: "TCP FINs", +} diff --git a/cisco/tests/asa/parse_content.tql b/cisco/tests/asa/parse_content.tql new file mode 100644 index 00000000..633f5562 --- /dev/null +++ b/cisco/tests/asa/parse_content.tql @@ -0,0 +1,9 @@ +// Exercises the primary `read_syslog` ingestion path end-to-end: `parse_syslog` +// produces the syslog envelope (severity, hostname, `content`, and a sibling +// `timestamp`), then `cisco::asa::parse` reads the ASA payload from the default +// `content` field and resolves the event time from that sibling timestamp. +from { + raw: "<166>Jun 18 2025 11:37:50 asa-fw : %ASA-6-302014: Teardown TCP connection 9 for outside:192.0.2.2/80 to inside:10.1.1.2/4924 duration 0:00:03 bytes 2048 TCP FINs", +} +this = raw.parse_syslog() +cisco::asa::parse diff --git a/cisco/tests/asa/parse_content.txt b/cisco/tests/asa/parse_content.txt new file mode 100644 index 00000000..c801ba6c --- /dev/null +++ b/cisco/tests/asa/parse_content.txt @@ -0,0 +1,24 @@ +{ + facility: 20, + severity: 6, + hostname: "asa-fw", + app_name: null, + process_id: null, + content: "%ASA-6-302014: Teardown TCP connection 9 for outside:192.0.2.2/80 to inside:10.1.1.2/4924 duration 0:00:03 bytes 2048 TCP FINs", + priority: null, + context: null, + message_id: 302014, + text: "Teardown TCP connection 9 for outside:192.0.2.2/80 to inside:10.1.1.2/4924 duration 0:00:03 bytes 2048 TCP FINs", + time: 2025-06-18T11:37:50Z, + protocol: "TCP", + connection_id: 9, + src_interface: "outside", + src_host: "192.0.2.2", + src_port: 80, + dst_interface: "inside", + dst_host: "10.1.1.2", + dst_port: 4924, + duration: "0:00:03", + bytes: 2048, + reason: "TCP FINs", +} From 68d5fca9db08a998af4cacc03d2ffb0b80be6a45 Mon Sep 17 00:00:00 2001 From: zedoraps Date: Mon, 22 Jun 2026 15:36:52 +0200 Subject: [PATCH 02/20] Expect the %ASA frame in the ASA parser read_syslog already strips the syslog envelope, so the parser no longer re-parses a priority, timestamp, or hostname from the message. It anchors on the %ASA frame and resolves the event time from the sibling timestamp that read_syslog leaves behind, covering both the legacy and RFC 5424 formats. The message handed to parse is expected to start at %ASA, which holds for read_syslog content, a reconstructed shipper message, and a file of bare %ASA lines. Tests now read their inputs with read_syslog. Co-authored-by: Claude Opus 4.8 --- cisco/operators/asa/parse.tql | 76 +++++++------- cisco/tests/asa/ocsf/map.tql | 5 +- cisco/tests/asa/ocsf/map.txt | 162 +++++++++++++++++++++++++----- cisco/tests/asa/parse.tql | 5 +- cisco/tests/asa/parse.txt | 64 +++++++++--- cisco/tests/asa/parse_content.txt | 1 - 6 files changed, 222 insertions(+), 91 deletions(-) diff --git a/cisco/operators/asa/parse.tql b/cisco/operators/asa/parse.tql index a0612b5e..b6f6341e 100644 --- a/cisco/operators/asa/parse.tql +++ b/cisco/operators/asa/parse.tql @@ -1,36 +1,33 @@ --- description: >- - Parses a Cisco Secure Firewall ASA syslog message into a normalized ASA event. + Parses a Cisco Secure Firewall ASA message into a normalized ASA event. - Reads the raw message from the field named by `message` (default `content`, - as produced by the built-in `read_syslog`), extracts the - `%ASA--: ` frame regardless of any surrounding - syslog header, and parses the body of supported message IDs into structured - fields. Unsupported messages keep their free-form `text`. + Reads the `%ASA--: ` frame from the field named by + `message` (default `content`, the message body that the built-in `read_syslog` + produces after stripping the syslog envelope) and parses the body of supported + message IDs into structured fields. Unsupported messages keep their free-form + `text`. The event time is taken from a sibling `timestamp` field if present. - Point `message` at a different field for other delivery methods, e.g. - `message=line` after `read_lines`, or the body field a log shipper uses. + The syslog envelope (priority, timestamp, hostname) is `read_syslog`'s job, + so `message` must already start at the `%ASA` frame. Point it at another + field for other delivery methods, e.g. the body field a log shipper provides. args: named: - name: message - description: The field that holds the raw ASA message line. + description: The field that holds the ASA message body (starting at `%ASA`). type: string default: "content" --- -// Grok patterns. ASA messages are framed as `%ASA--: `, -// optionally prefixed by a syslog priority, timestamp, hostname, and a -// subsystem context (e.g. `%ASA-session-6-...`). The leading `.*?` tolerates -// any syslog header, so this works whether `message` holds the bare payload -// (`content` from `read_syslog`) or a full raw line (`line` from `read_lines`). -// `HOST` matches an endpoint address, which ASA logs as either an IP or a -// resolved hostname. We capture it as a string and let the OCSF mapper decide -// whether it is an `ip` or a `hostname`. +// ASA messages are framed as `%ASA--: `, with an optional +// subsystem context (e.g. `%ASA-session-6-...`). `HOST` matches an endpoint +// address, which ASA logs as either an IP or a resolved hostname; we capture it +// as a string and let the OCSF mapper decide whether it is an `ip` or a +// `hostname`. let $patterns = { - ASATS: r#"(%{MONTH} +%{MONTHDAY}(?: %{YEAR})? %{TIME}|%{TIMESTAMP_ISO8601})"#, HOST: r#"[^/ ]+"#, } -let $header = r#"^(<%{NONNEGINT:priority}>)? *(%{ASATS:event_timestamp:string})?.*?%ASA-(%{WORD:context}-)?%{INT:severity}-%{INT:message_id}: %{GREEDYDATA:text}"# +let $header = r#" *%ASA-(%{WORD:context}-)?%{INT:severity}-%{INT:message_id}: %{GREEDYDATA:text}"# // Built/Teardown share the `interface:host/port` endpoint shape. Built also // carries the post-NAT (translated) address in parentheses, which can be an IP @@ -80,33 +77,30 @@ where message_id? != null @name = "cisco.asa" -// Resolve the event time. Prefer a timestamp embedded in the message line; -// otherwise fall back to a sibling `timestamp` field left by `read_syslog`. -// ASA emits either an ISO 8601 timestamp or the textual `Mon DD [YYYY] -// HH:MM:SS` form depending on the `logging timestamp` setting. Only parse a -// value that actually looks like one of these; this leaves `time` unset (with -// no warning) when the sibling `timestamp` is something else, such as the -// numeric epoch a log shipper like GELF puts in its own `timestamp` field — -// the caller supplies the time in that case. -if event_timestamp? == null and timestamp? != null { - event_timestamp = timestamp.string() -} -if event_timestamp? != null { - // On a match we consume the source: also drop the sibling `timestamp` so it - // does not linger in `unmapped`. On no match (e.g. a GELF epoch in - // `timestamp`) we leave that field for the caller to map. - if event_timestamp.match_regex(r"^\d{4}-\d{2}-\d{2}[T ]") { - time = event_timestamp.time() +// Resolve the event time from the syslog envelope timestamp that `read_syslog` +// leaves in a sibling `timestamp` field. ASA emits either an ISO 8601 timestamp +// or the textual `Mon DD [YYYY] HH:MM:SS` form depending on the +// `logging timestamp` setting. Only parse a value that actually looks like one +// of these, and consume it on a match so it does not linger in `unmapped`. A +// non-syslog `timestamp` (e.g. the numeric epoch a log shipper like GELF puts +// in its own `timestamp` field) is left untouched for the caller to map. +if timestamp? != null { + let $iso = r"^\d{4}-\d{2}-\d{2}[T ]" + let $dated = r"^\w{3}\s+\d{1,2}\s+\d{4}\s" + let $undated = r"^\w{3}\s+\d{1,2}\s+\d{2}:\d{2}:\d{2}" + ts = timestamp.string() + if ts.match_regex($iso) { + time = ts.time() drop timestamp? - } else if event_timestamp.match_regex(r"^\w{3}\s+\d{1,2}\s+\d{4}\s") { - time = event_timestamp.parse_time("%b %d %Y %H:%M:%S") + } else if ts.match_regex($dated) { + time = ts.parse_time("%b %d %Y %H:%M:%S") drop timestamp? - } else if event_timestamp.match_regex(r"^\w{3}\s+\d{1,2}\s+\d{2}:\d{2}:\d{2}") { - time = event_timestamp.parse_time("%b %e %H:%M:%S") + } else if ts.match_regex($undated) { + time = ts.parse_time("%b %e %H:%M:%S") drop timestamp? } + drop ts } -drop event_timestamp // Parse the message body of supported message IDs into structured fields. match message_id { diff --git a/cisco/tests/asa/ocsf/map.tql b/cisco/tests/asa/ocsf/map.tql index 8f717d2e..f8032691 100644 --- a/cisco/tests/asa/ocsf/map.tql +++ b/cisco/tests/asa/ocsf/map.tql @@ -1,8 +1,7 @@ from_file f"{env("TENZIR_INPUTS")}/*.txt" { - read_lines + read_syslog } -cisco::asa::parse message="line" -drop line +cisco::asa::parse cisco::asa::ocsf::map ocsf::derive ocsf::cast diff --git a/cisco/tests/asa/ocsf/map.txt b/cisco/tests/asa/ocsf/map.txt index 4fe9fa36..141d2ccb 100644 --- a/cisco/tests/asa/ocsf/map.txt +++ b/cisco/tests/asa/ocsf/map.txt @@ -52,7 +52,11 @@ type_name: "Network Activity: Open", type_uid: 400101, unmapped: { - priority: 166, + facility: 20, + hostname: "asa-fw", + app_name: null, + process_id: null, + content: "%ASA-6-302013: Built inbound TCP connection 3332836331 for inside:10.1.1.9/50640 (198.51.100.20/50640) to umbrella:host.example/443 (UMBRELLA-DOMAIN-BLOCK-HIT/443) 0 24", context: null, message_id: 302013, }, @@ -103,7 +107,11 @@ type_name: "Network Activity: Open", type_uid: 400101, unmapped: { - priority: 166, + facility: 20, + hostname: "asa-fw", + app_name: null, + process_id: null, + content: "%ASA-6-302015: Built inbound UDP connection 1005 for outside:198.51.100.5/53 (198.51.100.5/53) to inside:10.1.1.3/51000 (10.1.1.3/51000)", context: null, message_id: 302015, }, @@ -158,7 +166,11 @@ type_name: "Network Activity: Open", type_uid: 400101, unmapped: { - priority: 166, + facility: 20, + hostname: "asa-fw", + app_name: null, + process_id: null, + content: "%ASA-6-302013: Built outbound TCP connection 9 for outside:192.0.2.2/80 (192.0.2.2/80) to inside:10.1.1.2/4924 (203.0.113.10/4924)", context: null, message_id: 302013, }, @@ -208,7 +220,11 @@ type_name: "Network Activity: Traffic", type_uid: 400106, unmapped: { - priority: 163, + facility: 20, + hostname: "asa-fw", + app_name: null, + process_id: null, + content: "%ASA-3-313004: Denied ICMP type=0, from laddr 10.1.1.26 on interface inside to 10.1.1.27: no matching session", context: null, message_id: 313004, icmp_type: 0, @@ -259,7 +275,11 @@ type_name: "Network Activity: Traffic", type_uid: 400106, unmapped: { - priority: 163, + facility: 20, + hostname: "asa-fw", + app_name: null, + process_id: null, + content: "%ASA-3-313008: Denied IPv6-ICMP type=136, code=0 from fe80::21a:2bff:fe3c:4d5e on interface inside", context: null, message_id: 313008, icmp_type: 136, @@ -314,7 +334,11 @@ type_name: "Network Activity: Traffic", type_uid: 400106, unmapped: { - priority: 165, + facility: 20, + hostname: "asa-fw", + app_name: null, + process_id: null, + content: "%ASA-4-106023: Deny icmp src outside:198.51.100.30 dst inside:10.1.1.9 (type 8, code 0) by access-group \"outside_access_in\" [0x0, 0x0]", context: null, message_id: 106023, protocol_num: null, @@ -370,7 +394,11 @@ type_name: "Network Activity: Traffic", type_uid: 400106, unmapped: { - priority: 165, + facility: 20, + hostname: "asa-fw", + app_name: null, + process_id: null, + content: "%ASA-4-106023: Deny icmp src outside:198.51.100.8/0 dst inside:10.1.1.6/0 [type 8, code 0] by access-group \"outside_access_in\" [0x0, 0x0]", context: null, message_id: 106023, protocol_num: null, @@ -425,7 +453,11 @@ type_name: "Network Activity: Traffic", type_uid: 400106, unmapped: { - priority: 162, + facility: 20, + hostname: "asa-fw", + app_name: null, + process_id: null, + content: "%ASA-2-106006: Deny inbound UDP from 198.51.100.43/137 to 10.1.1.23/137 on interface outside", context: null, message_id: 106006, }, @@ -477,7 +509,11 @@ type_name: "Network Activity: Traffic", type_uid: 400106, unmapped: { - priority: 163, + facility: 20, + hostname: "asa-fw", + app_name: null, + process_id: null, + content: "%ASA-3-106014: Deny inbound icmp src dmz:198.51.100.40 dst inside:10.1.1.20 (type 8, code 0)", context: null, message_id: 106014, protocol_num: null, @@ -532,7 +568,11 @@ type_name: "Network Activity: Traffic", type_uid: 400106, unmapped: { - priority: 163, + facility: 20, + hostname: "asa-fw", + app_name: null, + process_id: null, + content: "%ASA-3-106010: Deny inbound protocol 47 src outside:198.51.100.41 dst outside:10.1.1.21", context: null, message_id: 106010, icmp_type: null, @@ -587,7 +627,11 @@ type_name: "Network Activity: Traffic", type_uid: 400106, unmapped: { - priority: 165, + facility: 20, + hostname: "asa-fw", + app_name: null, + process_id: null, + content: "%ASA-4-106023: Deny protocol 47 src outside:198.51.100.9 dst inside:10.1.1.7 by access-group \"outside_access_in\" [0x0, 0x0]", context: null, message_id: 106023, icmp_type: null, @@ -642,7 +686,11 @@ type_name: "Network Activity: Traffic", type_uid: 400106, unmapped: { - priority: 165, + facility: 20, + hostname: "asa-fw", + app_name: null, + process_id: null, + content: "%ASA-4-106023: Deny tcp src outside:198.51.100.7/4444 dst inside:10.1.1.5/3389 by access-group \"outside_access_in\" [0x0, 0x0]", context: null, message_id: 106023, protocol_num: null, @@ -698,7 +746,11 @@ type_name: "Network Activity: Traffic", type_uid: 400106, unmapped: { - priority: 165, + facility: 20, + hostname: "asa-fw", + app_name: null, + process_id: null, + content: "%ASA-4-106023: Deny udp src dmz:fw-host/514 dst outside:10.1.1.8/514 by access-group \"dmz_access\" [0x0, 0x0]", context: null, message_id: 106023, protocol_num: null, @@ -747,7 +799,11 @@ type_name: "Network Activity: Traffic", type_uid: 400106, unmapped: { - priority: 164, + facility: 20, + hostname: "asa-fw", + app_name: null, + process_id: null, + content: "%ASA-4-419002: Duplicate TCP SYN from inside:198.51.100.50/22 to dmz:10.1.1.30/443 with different initial sequence number", context: null, message_id: 419002, }, @@ -784,7 +840,11 @@ type_name: "Authentication: Logon", type_uid: 300201, unmapped: { - priority: 166, + facility: 20, + hostname: "asa-fw", + app_name: null, + process_id: null, + content: "%ASA-6-722051: Group User IP <198.51.100.60> IPv4 Address <10.8.0.5> IPv6 address <::> assigned to session", context: null, message_id: 722051, assigned_ipv4: 10.8.0.5, @@ -832,7 +892,11 @@ type_name: "Authentication: Logoff", type_uid: 300202, unmapped: { - priority: 166, + facility: 20, + hostname: "asa-fw", + app_name: null, + process_id: null, + content: "%ASA-6-113019: Group = vpn-group, Username = user02, IP = 198.51.100.61, Session disconnected. Session Type: SSL, Duration: 0h:52m:12s, Bytes xmt: 17932, Bytes rcv: 228, Reason: User Requested", context: null, message_id: 113019, session_type: "SSL", @@ -896,7 +960,11 @@ type_name: "Network Activity: Traffic", type_uid: 400106, unmapped: { - priority: 162, + facility: 20, + hostname: "asa-fw", + app_name: null, + process_id: null, + content: "%ASA-2-106001: Inbound TCP connection denied from 198.51.100.42/49709 to 10.1.1.22/6022 flags SYN on interface outside", context: null, message_id: 106001, tcp_flags: "SYN", @@ -947,7 +1015,11 @@ type_name: "Network Activity: Traffic", type_uid: 400106, unmapped: { - priority: 163, + facility: 20, + hostname: "asa-fw", + app_name: null, + process_id: null, + content: "%ASA-3-710003: TCP access denied by ACL from 198.51.100.51/65396 to crypto:host.example/80", context: null, message_id: 710003, }, @@ -995,7 +1067,11 @@ type_name: "Network Activity: Close", type_uid: 400102, unmapped: { - priority: 166, + facility: 20, + hostname: "asa-fw", + app_name: null, + process_id: null, + content: "%ASA-6-302021: Teardown ICMP connection for faddr 10.1.1.32/45078 gaddr 192.168.0.69/0 laddr 192.168.0.69/0 type 8 code 0 Internal-Data0/-1:RX[-1]", context: null, message_id: 302021, faddr_id: 45078, @@ -1051,7 +1127,11 @@ type_name: "Network Activity: Close", type_uid: 400102, unmapped: { - priority: 166, + facility: 20, + hostname: "asa-fw", + app_name: null, + process_id: null, + content: "%ASA-6-302014: Teardown TCP connection 9 for outside:192.0.2.2/80 to inside:10.1.1.2/4924 duration 0:00:03 bytes 2048 TCP FINs", context: null, message_id: 302014, duration: "0:00:03", @@ -1104,7 +1184,11 @@ type_name: "Network Activity: Close", type_uid: 400102, unmapped: { - priority: 166, + facility: 20, + hostname: "asa-fw", + app_name: null, + process_id: null, + content: "%ASA-6-302016: Teardown UDP connection 1005 for outside:198.51.100.5/53 to inside:10.1.1.3/51000 duration 0:00:05 bytes 312", context: null, message_id: 302016, duration: "0:00:05", @@ -1156,7 +1240,11 @@ type_name: "Network Activity: Traffic", type_uid: 400106, unmapped: { - priority: 163, + facility: 20, + hostname: "asa-fw", + app_name: null, + process_id: null, + content: "%ASA-3-710005: UDP request discarded from 198.51.100.52/60389 to outside:10.1.1.31/44861", context: null, message_id: 710005, }, @@ -1188,7 +1276,11 @@ type_name: "Base Event: Unknown", type_uid: 0, unmapped: { - priority: 165, + facility: 20, + hostname: "asa-fw", + app_name: null, + process_id: null, + content: "%ASA-5-111008: User 'enable_15' executed the 'configure terminal' command.", context: null, message_id: 111008, }, @@ -1241,7 +1333,11 @@ type_name: "Network Activity: Traffic", type_uid: 400106, unmapped: { - priority: 164, + facility: 20, + hostname: "asa-fw", + app_name: null, + process_id: null, + content: "%ASA-4-106100: access-list acl_in denied 47 outside/198.51.100.44(0) -> dmz/10.1.1.24(0) hit-cnt 1 first hit [0x0, 0x0]", context: null, message_id: 106100, }, @@ -1295,7 +1391,11 @@ type_name: "Network Activity: Traffic", type_uid: 400106, unmapped: { - priority: 166, + facility: 20, + hostname: "asa-fw", + app_name: null, + process_id: null, + content: "%ASA-6-106100: access-list acl_in permitted udp outside/198.51.100.45(49543) -> dmz/10.1.1.25(53) hit-cnt 105 300-second interval [0x0, 0x0]", context: null, message_id: 106100, }, @@ -1333,7 +1433,11 @@ type_name: "Authentication: Logoff", type_uid: 300202, unmapped: { - priority: 165, + facility: 20, + hostname: "asa-fw", + app_name: null, + process_id: null, + content: "%ASA-5-746013: user-identity: Delete IP-User mapping 10.1.1.40 - LOCAL\\user03 Succeeded - VPN user logout", context: null, message_id: 746013, }, @@ -1375,7 +1479,11 @@ type_name: "Authentication: Logoff", type_uid: 300202, unmapped: { - priority: 165, + facility: 20, + hostname: "asa-fw", + app_name: null, + process_id: null, + content: "%ASA-5-746013: user-identity: Delete IP-User mapping 10.1.1.41 - LOCAL\\user04 Failed - PIP notification", context: null, message_id: 746013, }, diff --git a/cisco/tests/asa/parse.tql b/cisco/tests/asa/parse.tql index bdc2f44d..e6751252 100644 --- a/cisco/tests/asa/parse.tql +++ b/cisco/tests/asa/parse.tql @@ -1,6 +1,5 @@ from_file env("TENZIR_INPUT") { - read_lines + read_syslog } -cisco::asa::parse message="line" -drop line +cisco::asa::parse sort message_id diff --git a/cisco/tests/asa/parse.txt b/cisco/tests/asa/parse.txt index 8936f3b3..26c5c12f 100644 --- a/cisco/tests/asa/parse.txt +++ b/cisco/tests/asa/parse.txt @@ -1,7 +1,11 @@ { - priority: 165, - context: null, + facility: 20, severity: 4, + hostname: "asa-fw", + app_name: null, + process_id: null, + content: "%ASA-4-106023: Deny tcp src outside:198.51.100.7/4444 dst inside:10.1.1.5/3389 by access-group \"outside_access_in\" [0x0, 0x0]", + context: null, message_id: 106023, text: "Deny tcp src outside:198.51.100.7/4444 dst inside:10.1.1.5/3389 by access-group \"outside_access_in\" [0x0, 0x0]", time: 2025-06-18T11:38:00Z, @@ -19,9 +23,13 @@ acl_id: "outside_access_in", } { - priority: 165, - context: null, + facility: 20, severity: 4, + hostname: "asa-fw", + app_name: null, + process_id: null, + content: "%ASA-4-106023: Deny udp src dmz:fw-host/514 dst outside:10.1.1.8/514 by access-group \"dmz_access\" [0x0, 0x0]", + context: null, message_id: 106023, text: "Deny udp src dmz:fw-host/514 dst outside:10.1.1.8/514 by access-group \"dmz_access\" [0x0, 0x0]", time: 2025-06-18T11:38:03Z, @@ -39,9 +47,13 @@ acl_id: "dmz_access", } { - priority: 165, - context: null, + facility: 20, severity: 4, + hostname: "asa-fw", + app_name: null, + process_id: null, + content: "%ASA-4-106023: Deny protocol 47 src outside:198.51.100.9 dst inside:10.1.1.7 by access-group \"outside_access_in\" [0x0, 0x0]", + context: null, message_id: 106023, text: "Deny protocol 47 src outside:198.51.100.9 dst inside:10.1.1.7 by access-group \"outside_access_in\" [0x0, 0x0]", time: 2025-06-18T11:38:02Z, @@ -58,17 +70,25 @@ acl_id: "outside_access_in", } { - priority: 165, - context: null, + facility: 20, severity: 5, + hostname: "asa-fw", + app_name: null, + process_id: null, + content: "%ASA-5-111008: User 'enable_15' executed the 'configure terminal' command.", + context: null, message_id: 111008, text: "User 'enable_15' executed the 'configure terminal' command.", time: 2025-06-18T11:38:10Z, } { - priority: 166, - context: null, + facility: 20, severity: 6, + hostname: "asa", + app_name: null, + process_id: null, + content: "%ASA-6-302013: Built outbound TCP connection 100 for outside:198.51.100.60/443 (198.51.100.60/443) to inside:10.1.1.40/52000 (10.1.1.40/52000)", + context: null, message_id: 302013, text: "Built outbound TCP connection 100 for outside:198.51.100.60/443 (198.51.100.60/443) to inside:10.1.1.40/52000 (10.1.1.40/52000)", time: 2018-06-27T12:17:46Z, @@ -87,9 +107,13 @@ dst_xlate_port: 52000, } { - priority: 166, - context: null, + facility: 20, severity: 6, + hostname: "asa-fw", + app_name: null, + process_id: null, + content: "%ASA-6-302013: Built outbound TCP connection 9 for outside:192.0.2.2/80 (192.0.2.2/80) to inside:10.1.1.2/4924 (203.0.113.10/4924)", + context: null, message_id: 302013, text: "Built outbound TCP connection 9 for outside:192.0.2.2/80 (192.0.2.2/80) to inside:10.1.1.2/4924 (203.0.113.10/4924)", time: 2025-06-18T11:37:47Z, @@ -108,9 +132,13 @@ dst_xlate_port: 4924, } { - priority: 166, - context: null, + facility: 20, severity: 6, + hostname: "asa-fw", + app_name: null, + process_id: null, + content: "%ASA-6-302013: Built inbound TCP connection 3332836331 for inside:10.1.1.9/50640 (198.51.100.20/50640) to umbrella:host.example/443 (UMBRELLA-DOMAIN-BLOCK-HIT/443) 0 24", + context: null, message_id: 302013, text: "Built inbound TCP connection 3332836331 for inside:10.1.1.9/50640 (198.51.100.20/50640) to umbrella:host.example/443 (UMBRELLA-DOMAIN-BLOCK-HIT/443) 0 24", time: 2025-06-18T11:37:48Z, @@ -129,9 +157,13 @@ dst_xlate_port: 443, } { - priority: 166, - context: null, + facility: 20, severity: 6, + hostname: "asa-fw", + app_name: null, + process_id: null, + content: "%ASA-6-302014: Teardown TCP connection 9 for outside:192.0.2.2/80 to inside:10.1.1.2/4924 duration 0:00:03 bytes 2048 TCP FINs", + context: null, message_id: 302014, text: "Teardown TCP connection 9 for outside:192.0.2.2/80 to inside:10.1.1.2/4924 duration 0:00:03 bytes 2048 TCP FINs", time: 2025-06-18T11:37:50Z, diff --git a/cisco/tests/asa/parse_content.txt b/cisco/tests/asa/parse_content.txt index c801ba6c..815fb178 100644 --- a/cisco/tests/asa/parse_content.txt +++ b/cisco/tests/asa/parse_content.txt @@ -5,7 +5,6 @@ app_name: null, process_id: null, content: "%ASA-6-302014: Teardown TCP connection 9 for outside:192.0.2.2/80 to inside:10.1.1.2/4924 duration 0:00:03 bytes 2048 TCP FINs", - priority: null, context: null, message_id: 302014, text: "Teardown TCP connection 9 for outside:192.0.2.2/80 to inside:10.1.1.2/4924 duration 0:00:03 bytes 2048 TCP FINs", From 64098731755d84065eb48bd82612282d58c71e93 Mon Sep 17 00:00:00 2001 From: zedoraps Date: Mon, 22 Jun 2026 15:41:25 +0200 Subject: [PATCH 03/20] Warn on non-ASA input in the ASA parser Replace the silent drop with an assert so a message that does not carry a %ASA-- frame is reported, helping users catch a wrong `message` field or non-ASA logs routed to the parser. A cheap starts_with pre-check gates the grok call so valid input stays warning-free and the generic grok match-failure warning no longer fires on unrelated input. Co-authored-by: Claude Opus 4.8 --- cisco/operators/asa/parse.tql | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/cisco/operators/asa/parse.tql b/cisco/operators/asa/parse.tql index b6f6341e..65d7e0e2 100644 --- a/cisco/operators/asa/parse.tql +++ b/cisco/operators/asa/parse.tql @@ -27,7 +27,7 @@ args: let $patterns = { HOST: r#"[^/ ]+"#, } -let $header = r#" *%ASA-(%{WORD:context}-)?%{INT:severity}-%{INT:message_id}: %{GREEDYDATA:text}"# +let $header = r#"%ASA-(%{WORD:context}-)?%{INT:severity}-%{INT:message_id}: %{GREEDYDATA:text}"# // Built/Teardown share the `interface:host/port` endpoint shape. Built also // carries the post-NAT (translated) address in parentheses, which can be an IP @@ -70,10 +70,16 @@ let $vpn_disconnect = r#"Group = %{DATA:vpn_group}, Username = %{DATA:vpn_user}, // 746013: user-identity IP↔user mapping deleted (e.g. on VPN logout). let $identity_delete = r#"user-identity: Delete IP-User mapping %{IP:src_ip} - %{DATA:domain}\\%{DATA:vpn_user} %{WORD:status} - %{GREEDYDATA:reason}"# -this = {...this, ...this[$message]?.parse_grok($header, pattern_definitions=$patterns)} +// Parse the %ASA frame only on messages that carry one; this keeps the grok +// parser from emitting a generic match-failure warning on unrelated input. +if this[$message]?.starts_with("%ASA-") == true { + this = {...this, ...this[$message].parse_grok($header, pattern_definitions=$patterns)} +} -// Drop lines that do not carry an ASA message frame. -where message_id? != null +// Warn on and drop anything without an ASA frame so the user notices misrouted +// input (e.g. a wrong `message` field, or non-ASA logs) instead of losing it +// silently. +assert message_id? != null, message="cisco::asa::parse: no %ASA-- frame in the message field" @name = "cisco.asa" From b0685169661cabedc6f33bc4330f49cba487e084 Mon Sep 17 00:00:00 2001 From: zedoraps Date: Mon, 22 Jun 2026 15:52:43 +0200 Subject: [PATCH 04/20] Take the ASA parser input as a field argument Change the `message` parameter from a string field name to a `field` argument, matching the parse operators in the paloalto and amazon packages. The body is read as `$message` instead of `this[$message]`, and callers pass a field reference (e.g. `message=content`) rather than a quoted field name. Co-authored-by: Claude Opus 4.8 --- cisco/examples/asa-from-syslog-tcp.tql | 2 +- cisco/operators/asa/parse.tql | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/cisco/examples/asa-from-syslog-tcp.tql b/cisco/examples/asa-from-syslog-tcp.tql index 49505002..2566a646 100644 --- a/cisco/examples/asa-from-syslog-tcp.tql +++ b/cisco/examples/asa-from-syslog-tcp.tql @@ -9,5 +9,5 @@ description: | from_tcp "0.0.0.0:514" { read_syslog } -cisco::asa::parse message="content" +cisco::asa::parse publish "cisco" diff --git a/cisco/operators/asa/parse.tql b/cisco/operators/asa/parse.tql index 65d7e0e2..fd1b298d 100644 --- a/cisco/operators/asa/parse.tql +++ b/cisco/operators/asa/parse.tql @@ -2,8 +2,8 @@ description: >- Parses a Cisco Secure Firewall ASA message into a normalized ASA event. - Reads the `%ASA--: ` frame from the field named by - `message` (default `content`, the message body that the built-in `read_syslog` + Reads the `%ASA--: ` frame from the `message` + field (default `content`, the message body that the built-in `read_syslog` produces after stripping the syslog envelope) and parses the body of supported message IDs into structured fields. Unsupported messages keep their free-form `text`. The event time is taken from a sibling `timestamp` field if present. @@ -15,8 +15,8 @@ args: named: - name: message description: The field that holds the ASA message body (starting at `%ASA`). - type: string - default: "content" + type: field + default: content --- // ASA messages are framed as `%ASA--: `, with an optional @@ -72,8 +72,8 @@ let $identity_delete = r#"user-identity: Delete IP-User mapping %{IP:src_ip} - % // Parse the %ASA frame only on messages that carry one; this keeps the grok // parser from emitting a generic match-failure warning on unrelated input. -if this[$message]?.starts_with("%ASA-") == true { - this = {...this, ...this[$message].parse_grok($header, pattern_definitions=$patterns)} +if $message != null and $message.starts_with("%ASA-") { + this = {...this, ...$message.parse_grok($header, pattern_definitions=$patterns)} } // Warn on and drop anything without an ASA frame so the user notices misrouted From 0de6cb89047b582a62f0414e5ee54b7e11284176 Mon Sep 17 00:00:00 2001 From: zedoraps Date: Mon, 22 Jun 2026 15:57:51 +0200 Subject: [PATCH 05/20] Merge parsed ASA body fields in one step Each match arm now assigns the parsed body to a `body` record and the fields merge into the event once after the match, instead of repeating the {...this, ...} spread in every arm. This mirrors the one-assignment-per-arm shape of the paloalto and amazon parse operators. Behavior is unchanged. Co-authored-by: Claude Opus 4.8 --- cisco/operators/asa/parse.tql | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/cisco/operators/asa/parse.tql b/cisco/operators/asa/parse.tql index fd1b298d..24708641 100644 --- a/cisco/operators/asa/parse.tql +++ b/cisco/operators/asa/parse.tql @@ -108,24 +108,28 @@ if timestamp? != null { drop ts } -// Parse the message body of supported message IDs into structured fields. +// Parse the body of the matched message ID, then merge the structured fields +// into the event once. Each body pattern is written against `text` alone. +body = {} match message_id { - 302013 | 302015 => { this = {...this, ...text.parse_grok($built, pattern_definitions=$patterns)} } - 302014 | 302016 => { this = {...this, ...text.parse_grok($teardown, pattern_definitions=$patterns)} } - 302021 => { this = {...this, ...text.parse_grok($teardown_icmp, pattern_definitions=$patterns)} } - 106023 | 106010 | 106014 => { this = {...this, ...text.parse_grok($deny, pattern_definitions=$patterns)} } - 106001 => { this = {...this, ...text.parse_grok($conn_denied, pattern_definitions=$patterns)} } - 106006 | 106007 => { this = {...this, ...text.parse_grok($deny_from, pattern_definitions=$patterns)} } - 106100 => { this = {...this, ...text.parse_grok($acl, pattern_definitions=$patterns)} } - 313004 => { this = {...this, ...text.parse_grok($denied_icmp, pattern_definitions=$patterns)} } - 313008 => { this = {...this, ...text.parse_grok($denied_icmp6, pattern_definitions=$patterns)} } - 419002 => { this = {...this, ...text.parse_grok($duplicate_syn, pattern_definitions=$patterns)} } - 710003 | 710005 => { this = {...this, ...text.parse_grok($denied_box, pattern_definitions=$patterns)} } - 722051 => { this = {...this, ...text.parse_grok($vpn_assigned, pattern_definitions=$patterns)} } - 113019 => { this = {...this, ...text.parse_grok($vpn_disconnect, pattern_definitions=$patterns)} } - 746013 => { this = {...this, ...text.parse_grok($identity_delete, pattern_definitions=$patterns)} } + 302013 | 302015 => { body = text.parse_grok($built, pattern_definitions=$patterns) } + 302014 | 302016 => { body = text.parse_grok($teardown, pattern_definitions=$patterns) } + 302021 => { body = text.parse_grok($teardown_icmp, pattern_definitions=$patterns) } + 106023 | 106010 | 106014 => { body = text.parse_grok($deny, pattern_definitions=$patterns) } + 106001 => { body = text.parse_grok($conn_denied, pattern_definitions=$patterns) } + 106006 | 106007 => { body = text.parse_grok($deny_from, pattern_definitions=$patterns) } + 106100 => { body = text.parse_grok($acl, pattern_definitions=$patterns) } + 313004 => { body = text.parse_grok($denied_icmp, pattern_definitions=$patterns) } + 313008 => { body = text.parse_grok($denied_icmp6, pattern_definitions=$patterns) } + 419002 => { body = text.parse_grok($duplicate_syn, pattern_definitions=$patterns) } + 710003 | 710005 => { body = text.parse_grok($denied_box, pattern_definitions=$patterns) } + 722051 => { body = text.parse_grok($vpn_assigned, pattern_definitions=$patterns) } + 113019 => { body = text.parse_grok($vpn_disconnect, pattern_definitions=$patterns) } + 746013 => { body = text.parse_grok($identity_delete, pattern_definitions=$patterns) } _ => {} } +this = {...this, ...body} +drop body // Normalize across the message formats: lower-case the connection direction // and fold a numeric protocol token into protocol_num. From 3ea40e00ba57c7be528a3486a2ae860667637654 Mon Sep 17 00:00:00 2001 From: zedoraps Date: Mon, 22 Jun 2026 16:03:31 +0200 Subject: [PATCH 06/20] Scope ASA OCSF profiles and harden the auth mapper Declare the security_control profile only in the event mappers that set firewall fields (built, teardown, deny) rather than globally, matching how the fortinet package adds it. Map the syslog hostname to the reporting logger (metadata.loggers[].device.hostname), as fortinet's syslog handling does, rather than the event's subject device, so the mapping no longer declares a profile it does not populate. In the authentication mapper, match the known message IDs explicitly for both activity_id (722051 logon, 113019/746013 logoff) and status_id (722051/113019 success), falling back to Unknown so a message unexpectedly routed here is not mislabeled. Co-authored-by: Claude Opus 4.8 --- .../asa/ocsf/events/authentication.tql | 24 +- cisco/operators/asa/ocsf/events/built.tql | 2 + cisco/operators/asa/ocsf/events/deny.tql | 3 + cisco/operators/asa/ocsf/events/teardown.tql | 2 + cisco/operators/asa/ocsf/map.tql | 14 +- cisco/tests/asa/ocsf/map.txt | 294 +++++++++++++----- 6 files changed, 256 insertions(+), 83 deletions(-) diff --git a/cisco/operators/asa/ocsf/events/authentication.tql b/cisco/operators/asa/ocsf/events/authentication.tql index 629e5c74..a7b13174 100644 --- a/cisco/operators/asa/ocsf/events/authentication.tql +++ b/cisco/operators/asa/ocsf/events/authentication.tql @@ -11,11 +11,12 @@ args: $event.ocsf.category_uid = 3 $event.ocsf.class_uid = 3002 -// 722051 establishes a session; 113019 and 746013 end one. -if $event.asa.message_id == 722051 { - $event.ocsf.activity_id = 1 // Logon -} else { - $event.ocsf.activity_id = 2 // Logoff +// 722051 establishes a session; 113019 and 746013 end one. Match the known IDs +// explicitly so an unexpected message routed here is not mislabeled. +match $event.asa.message_id { + 722051 => { $event.ocsf.activity_id = 1 } // Logon + 113019 | 746013 => { $event.ocsf.activity_id = 2 } // Logoff + _ => { $event.ocsf.activity_id = 0 } // Unknown } $event.ocsf.type_uid = $event.ocsf.class_uid * 100 + $event.ocsf.activity_id @@ -42,10 +43,11 @@ if $event.asa.reason? != null { $event.ocsf.status_detail = move $event.asa.reason } -// 746013 reports an explicit result, either "Succeeded" or "Failed". The -// session logon/logoff messages carry no status and always describe a -// completed action. An unexpected value maps to Other (99) with the source -// string preserved in the `status` sibling, per OCSF conventions. +// 746013 reports an explicit result, either "Succeeded" or "Failed", which maps +// to Success/Failure (an unexpected value maps to Other (99) with the source +// string preserved in `status`, per OCSF conventions). The session logon +// (722051) and logoff (113019) messages carry no status but always describe a +// completed action, so they map to Success. Anything else stays Unknown. if $event.asa.status? == "Succeeded" { $event.ocsf.status_id = 1 // Success drop $event.asa.status? @@ -55,6 +57,8 @@ if $event.asa.status? == "Succeeded" { } else if $event.asa.status? != null { $event.ocsf.status_id = 99 // Other $event.ocsf.status = move $event.asa.status -} else { +} else if $event.asa.message_id == 722051 or $event.asa.message_id == 113019 { $event.ocsf.status_id = 1 // Success +} else { + $event.ocsf.status_id = 0 // Unknown } diff --git a/cisco/operators/asa/ocsf/events/built.tql b/cisco/operators/asa/ocsf/events/built.tql index c8a97561..72da9ec4 100644 --- a/cisco/operators/asa/ocsf/events/built.tql +++ b/cisco/operators/asa/ocsf/events/built.tql @@ -34,4 +34,6 @@ if $event.asa.connection_id? != null { // The post-NAT (translated) addresses in parentheses are mapped to proxy // endpoints by cisco::asa::ocsf::network_endpoints. +// Connection decisions populate the security_control profile. +$event.ocsf.metadata.profiles = $event.ocsf.metadata.profiles.add("security_control") $event.ocsf.disposition_id = 1 // Allowed diff --git a/cisco/operators/asa/ocsf/events/deny.tql b/cisco/operators/asa/ocsf/events/deny.tql index 249cbd0a..a0edfc56 100644 --- a/cisco/operators/asa/ocsf/events/deny.tql +++ b/cisco/operators/asa/ocsf/events/deny.tql @@ -36,6 +36,9 @@ if $event.asa.hit_count? != null { $event.ocsf.count = move $event.asa.hit_count } +// Access-list decisions populate the security_control profile. +$event.ocsf.metadata.profiles = $event.ocsf.metadata.profiles.add("security_control") + // 106100 logs both permits and denies via `action`; everything else is a deny. if $event.asa.action? == "permitted" { $event.ocsf.disposition_id = 1 // Allowed diff --git a/cisco/operators/asa/ocsf/events/teardown.tql b/cisco/operators/asa/ocsf/events/teardown.tql index 96a0464e..bed036b3 100644 --- a/cisco/operators/asa/ocsf/events/teardown.tql +++ b/cisco/operators/asa/ocsf/events/teardown.tql @@ -31,4 +31,6 @@ if $event.asa.reason? != null { $event.ocsf.status_detail = move $event.asa.reason } +// Connection decisions populate the security_control profile. +$event.ocsf.metadata.profiles = $event.ocsf.metadata.profiles.add("security_control") $event.ocsf.disposition_id = 1 // Allowed diff --git a/cisco/operators/asa/ocsf/map.tql b/cisco/operators/asa/ocsf/map.tql index 9accc693..55583e4c 100644 --- a/cisco/operators/asa/ocsf/map.tql +++ b/cisco/operators/asa/ocsf/map.tql @@ -21,10 +21,22 @@ $event.ocsf.metadata = { name: "Secure Firewall ASA", vendor_name: "Cisco", }, - profiles: ["host", "security_control"], + // security_control is added by the event mappers that set firewall fields. + profiles: [], version: "1.8.0", } +// The syslog hostname is the ASA that reported the event. OCSF models the +// reporting system as a logger, not the event's subject device. +if $event.asa.hostname? != null { + $event.ocsf.metadata.loggers = [{ + device: { + hostname: move $event.asa.hostname, + }, + log_format: "syslog", + }] +} + // ASA stamps each message with the syslog timestamp when configured to do so. $event.ocsf.time = move $event.asa.time? else $event.ocsf.metadata.processed_time diff --git a/cisco/tests/asa/ocsf/map.txt b/cisco/tests/asa/ocsf/map.txt index 141d2ccb..7fc0e5fc 100644 --- a/cisco/tests/asa/ocsf/map.txt +++ b/cisco/tests/asa/ocsf/map.txt @@ -27,12 +27,19 @@ metadata: { event_code: "302013", log_name: "cisco.asa", + loggers: [ + { + device: { + hostname: "asa-fw", + }, + log_format: "syslog", + }, + ], product: { name: "Secure Firewall ASA", vendor_name: "Cisco", }, profiles: [ - "host", "security_control", ], version: "1.8.0", @@ -53,7 +60,6 @@ type_uid: 400101, unmapped: { facility: 20, - hostname: "asa-fw", app_name: null, process_id: null, content: "%ASA-6-302013: Built inbound TCP connection 3332836331 for inside:10.1.1.9/50640 (198.51.100.20/50640) to umbrella:host.example/443 (UMBRELLA-DOMAIN-BLOCK-HIT/443) 0 24", @@ -86,12 +92,19 @@ metadata: { event_code: "302015", log_name: "cisco.asa", + loggers: [ + { + device: { + hostname: "asa-fw", + }, + log_format: "syslog", + }, + ], product: { name: "Secure Firewall ASA", vendor_name: "Cisco", }, profiles: [ - "host", "security_control", ], version: "1.8.0", @@ -108,7 +121,6 @@ type_uid: 400101, unmapped: { facility: 20, - hostname: "asa-fw", app_name: null, process_id: null, content: "%ASA-6-302015: Built inbound UDP connection 1005 for outside:198.51.100.5/53 (198.51.100.5/53) to inside:10.1.1.3/51000 (10.1.1.3/51000)", @@ -145,12 +157,19 @@ metadata: { event_code: "302013", log_name: "cisco.asa", + loggers: [ + { + device: { + hostname: "asa-fw", + }, + log_format: "syslog", + }, + ], product: { name: "Secure Firewall ASA", vendor_name: "Cisco", }, profiles: [ - "host", "security_control", ], version: "1.8.0", @@ -167,7 +186,6 @@ type_uid: 400101, unmapped: { facility: 20, - hostname: "asa-fw", app_name: null, process_id: null, content: "%ASA-6-302013: Built outbound TCP connection 9 for outside:192.0.2.2/80 (192.0.2.2/80) to inside:10.1.1.2/4924 (203.0.113.10/4924)", @@ -199,12 +217,19 @@ metadata: { event_code: "313004", log_name: "cisco.asa", + loggers: [ + { + device: { + hostname: "asa-fw", + }, + log_format: "syslog", + }, + ], product: { name: "Secure Firewall ASA", vendor_name: "Cisco", }, profiles: [ - "host", "security_control", ], version: "1.8.0", @@ -221,7 +246,6 @@ type_uid: 400106, unmapped: { facility: 20, - hostname: "asa-fw", app_name: null, process_id: null, content: "%ASA-3-313004: Denied ICMP type=0, from laddr 10.1.1.26 on interface inside to 10.1.1.27: no matching session", @@ -254,12 +278,19 @@ metadata: { event_code: "313008", log_name: "cisco.asa", + loggers: [ + { + device: { + hostname: "asa-fw", + }, + log_format: "syslog", + }, + ], product: { name: "Secure Firewall ASA", vendor_name: "Cisco", }, profiles: [ - "host", "security_control", ], version: "1.8.0", @@ -276,7 +307,6 @@ type_uid: 400106, unmapped: { facility: 20, - hostname: "asa-fw", app_name: null, process_id: null, content: "%ASA-3-313008: Denied IPv6-ICMP type=136, code=0 from fe80::21a:2bff:fe3c:4d5e on interface inside", @@ -313,12 +343,19 @@ metadata: { event_code: "106023", log_name: "cisco.asa", + loggers: [ + { + device: { + hostname: "asa-fw", + }, + log_format: "syslog", + }, + ], product: { name: "Secure Firewall ASA", vendor_name: "Cisco", }, profiles: [ - "host", "security_control", ], version: "1.8.0", @@ -335,7 +372,6 @@ type_uid: 400106, unmapped: { facility: 20, - hostname: "asa-fw", app_name: null, process_id: null, content: "%ASA-4-106023: Deny icmp src outside:198.51.100.30 dst inside:10.1.1.9 (type 8, code 0) by access-group \"outside_access_in\" [0x0, 0x0]", @@ -373,12 +409,19 @@ metadata: { event_code: "106023", log_name: "cisco.asa", + loggers: [ + { + device: { + hostname: "asa-fw", + }, + log_format: "syslog", + }, + ], product: { name: "Secure Firewall ASA", vendor_name: "Cisco", }, profiles: [ - "host", "security_control", ], version: "1.8.0", @@ -395,7 +438,6 @@ type_uid: 400106, unmapped: { facility: 20, - hostname: "asa-fw", app_name: null, process_id: null, content: "%ASA-4-106023: Deny icmp src outside:198.51.100.8/0 dst inside:10.1.1.6/0 [type 8, code 0] by access-group \"outside_access_in\" [0x0, 0x0]", @@ -432,12 +474,19 @@ metadata: { event_code: "106006", log_name: "cisco.asa", + loggers: [ + { + device: { + hostname: "asa-fw", + }, + log_format: "syslog", + }, + ], product: { name: "Secure Firewall ASA", vendor_name: "Cisco", }, profiles: [ - "host", "security_control", ], version: "1.8.0", @@ -454,7 +503,6 @@ type_uid: 400106, unmapped: { facility: 20, - hostname: "asa-fw", app_name: null, process_id: null, content: "%ASA-2-106006: Deny inbound UDP from 198.51.100.43/137 to 10.1.1.23/137 on interface outside", @@ -488,12 +536,19 @@ metadata: { event_code: "106014", log_name: "cisco.asa", + loggers: [ + { + device: { + hostname: "asa-fw", + }, + log_format: "syslog", + }, + ], product: { name: "Secure Firewall ASA", vendor_name: "Cisco", }, profiles: [ - "host", "security_control", ], version: "1.8.0", @@ -510,7 +565,6 @@ type_uid: 400106, unmapped: { facility: 20, - hostname: "asa-fw", app_name: null, process_id: null, content: "%ASA-3-106014: Deny inbound icmp src dmz:198.51.100.40 dst inside:10.1.1.20 (type 8, code 0)", @@ -547,12 +601,19 @@ metadata: { event_code: "106010", log_name: "cisco.asa", + loggers: [ + { + device: { + hostname: "asa-fw", + }, + log_format: "syslog", + }, + ], product: { name: "Secure Firewall ASA", vendor_name: "Cisco", }, profiles: [ - "host", "security_control", ], version: "1.8.0", @@ -569,7 +630,6 @@ type_uid: 400106, unmapped: { facility: 20, - hostname: "asa-fw", app_name: null, process_id: null, content: "%ASA-3-106010: Deny inbound protocol 47 src outside:198.51.100.41 dst outside:10.1.1.21", @@ -606,12 +666,19 @@ metadata: { event_code: "106023", log_name: "cisco.asa", + loggers: [ + { + device: { + hostname: "asa-fw", + }, + log_format: "syslog", + }, + ], product: { name: "Secure Firewall ASA", vendor_name: "Cisco", }, profiles: [ - "host", "security_control", ], version: "1.8.0", @@ -628,7 +695,6 @@ type_uid: 400106, unmapped: { facility: 20, - hostname: "asa-fw", app_name: null, process_id: null, content: "%ASA-4-106023: Deny protocol 47 src outside:198.51.100.9 dst inside:10.1.1.7 by access-group \"outside_access_in\" [0x0, 0x0]", @@ -665,12 +731,19 @@ metadata: { event_code: "106023", log_name: "cisco.asa", + loggers: [ + { + device: { + hostname: "asa-fw", + }, + log_format: "syslog", + }, + ], product: { name: "Secure Firewall ASA", vendor_name: "Cisco", }, profiles: [ - "host", "security_control", ], version: "1.8.0", @@ -687,7 +760,6 @@ type_uid: 400106, unmapped: { facility: 20, - hostname: "asa-fw", app_name: null, process_id: null, content: "%ASA-4-106023: Deny tcp src outside:198.51.100.7/4444 dst inside:10.1.1.5/3389 by access-group \"outside_access_in\" [0x0, 0x0]", @@ -725,12 +797,19 @@ metadata: { event_code: "106023", log_name: "cisco.asa", + loggers: [ + { + device: { + hostname: "asa-fw", + }, + log_format: "syslog", + }, + ], product: { name: "Secure Firewall ASA", vendor_name: "Cisco", }, profiles: [ - "host", "security_control", ], version: "1.8.0", @@ -747,7 +826,6 @@ type_uid: 400106, unmapped: { facility: 20, - hostname: "asa-fw", app_name: null, process_id: null, content: "%ASA-4-106023: Deny udp src dmz:fw-host/514 dst outside:10.1.1.8/514 by access-group \"dmz_access\" [0x0, 0x0]", @@ -778,14 +856,19 @@ metadata: { event_code: "419002", log_name: "cisco.asa", + loggers: [ + { + device: { + hostname: "asa-fw", + }, + log_format: "syslog", + }, + ], product: { name: "Secure Firewall ASA", vendor_name: "Cisco", }, - profiles: [ - "host", - "security_control", - ], + profiles: [], version: "1.8.0", }, severity: "Medium", @@ -800,7 +883,6 @@ type_uid: 400106, unmapped: { facility: 20, - hostname: "asa-fw", app_name: null, process_id: null, content: "%ASA-4-419002: Duplicate TCP SYN from inside:198.51.100.50/22 to dmz:10.1.1.30/443 with different initial sequence number", @@ -819,14 +901,19 @@ metadata: { event_code: "722051", log_name: "cisco.asa", + loggers: [ + { + device: { + hostname: "asa-fw", + }, + log_format: "syslog", + }, + ], product: { name: "Secure Firewall ASA", vendor_name: "Cisco", }, - profiles: [ - "host", - "security_control", - ], + profiles: [], version: "1.8.0", }, severity: "Informational", @@ -841,7 +928,6 @@ type_uid: 300201, unmapped: { facility: 20, - hostname: "asa-fw", app_name: null, process_id: null, content: "%ASA-6-722051: Group User IP <198.51.100.60> IPv4 Address <10.8.0.5> IPv6 address <::> assigned to session", @@ -870,14 +956,19 @@ metadata: { event_code: "113019", log_name: "cisco.asa", + loggers: [ + { + device: { + hostname: "asa-fw", + }, + log_format: "syslog", + }, + ], product: { name: "Secure Firewall ASA", vendor_name: "Cisco", }, - profiles: [ - "host", - "security_control", - ], + profiles: [], version: "1.8.0", }, severity: "Informational", @@ -893,7 +984,6 @@ type_uid: 300202, unmapped: { facility: 20, - hostname: "asa-fw", app_name: null, process_id: null, content: "%ASA-6-113019: Group = vpn-group, Username = user02, IP = 198.51.100.61, Session disconnected. Session Type: SSL, Duration: 0h:52m:12s, Bytes xmt: 17932, Bytes rcv: 228, Reason: User Requested", @@ -939,12 +1029,19 @@ metadata: { event_code: "106001", log_name: "cisco.asa", + loggers: [ + { + device: { + hostname: "asa-fw", + }, + log_format: "syslog", + }, + ], product: { name: "Secure Firewall ASA", vendor_name: "Cisco", }, profiles: [ - "host", "security_control", ], version: "1.8.0", @@ -961,7 +1058,6 @@ type_uid: 400106, unmapped: { facility: 20, - hostname: "asa-fw", app_name: null, process_id: null, content: "%ASA-2-106001: Inbound TCP connection denied from 198.51.100.42/49709 to 10.1.1.22/6022 flags SYN on interface outside", @@ -994,12 +1090,19 @@ metadata: { event_code: "710003", log_name: "cisco.asa", + loggers: [ + { + device: { + hostname: "asa-fw", + }, + log_format: "syslog", + }, + ], product: { name: "Secure Firewall ASA", vendor_name: "Cisco", }, profiles: [ - "host", "security_control", ], version: "1.8.0", @@ -1016,7 +1119,6 @@ type_uid: 400106, unmapped: { facility: 20, - hostname: "asa-fw", app_name: null, process_id: null, content: "%ASA-3-710003: TCP access denied by ACL from 198.51.100.51/65396 to crypto:host.example/80", @@ -1046,12 +1148,19 @@ metadata: { event_code: "302021", log_name: "cisco.asa", + loggers: [ + { + device: { + hostname: "asa-fw", + }, + log_format: "syslog", + }, + ], product: { name: "Secure Firewall ASA", vendor_name: "Cisco", }, profiles: [ - "host", "security_control", ], version: "1.8.0", @@ -1068,7 +1177,6 @@ type_uid: 400102, unmapped: { facility: 20, - hostname: "asa-fw", app_name: null, process_id: null, content: "%ASA-6-302021: Teardown ICMP connection for faddr 10.1.1.32/45078 gaddr 192.168.0.69/0 laddr 192.168.0.69/0 type 8 code 0 Internal-Data0/-1:RX[-1]", @@ -1102,12 +1210,19 @@ metadata: { event_code: "302014", log_name: "cisco.asa", + loggers: [ + { + device: { + hostname: "asa-fw", + }, + log_format: "syslog", + }, + ], product: { name: "Secure Firewall ASA", vendor_name: "Cisco", }, profiles: [ - "host", "security_control", ], version: "1.8.0", @@ -1128,7 +1243,6 @@ type_uid: 400102, unmapped: { facility: 20, - hostname: "asa-fw", app_name: null, process_id: null, content: "%ASA-6-302014: Teardown TCP connection 9 for outside:192.0.2.2/80 to inside:10.1.1.2/4924 duration 0:00:03 bytes 2048 TCP FINs", @@ -1160,12 +1274,19 @@ metadata: { event_code: "302016", log_name: "cisco.asa", + loggers: [ + { + device: { + hostname: "asa-fw", + }, + log_format: "syslog", + }, + ], product: { name: "Secure Firewall ASA", vendor_name: "Cisco", }, profiles: [ - "host", "security_control", ], version: "1.8.0", @@ -1185,7 +1306,6 @@ type_uid: 400102, unmapped: { facility: 20, - hostname: "asa-fw", app_name: null, process_id: null, content: "%ASA-6-302016: Teardown UDP connection 1005 for outside:198.51.100.5/53 to inside:10.1.1.3/51000 duration 0:00:05 bytes 312", @@ -1219,12 +1339,19 @@ metadata: { event_code: "710005", log_name: "cisco.asa", + loggers: [ + { + device: { + hostname: "asa-fw", + }, + log_format: "syslog", + }, + ], product: { name: "Secure Firewall ASA", vendor_name: "Cisco", }, profiles: [ - "host", "security_control", ], version: "1.8.0", @@ -1241,7 +1368,6 @@ type_uid: 400106, unmapped: { facility: 20, - hostname: "asa-fw", app_name: null, process_id: null, content: "%ASA-3-710005: UDP request discarded from 198.51.100.52/60389 to outside:10.1.1.31/44861", @@ -1260,14 +1386,19 @@ metadata: { event_code: "111008", log_name: "cisco.asa", + loggers: [ + { + device: { + hostname: "asa-fw", + }, + log_format: "syslog", + }, + ], product: { name: "Secure Firewall ASA", vendor_name: "Cisco", }, - profiles: [ - "host", - "security_control", - ], + profiles: [], version: "1.8.0", }, severity: "Low", @@ -1277,7 +1408,6 @@ type_uid: 0, unmapped: { facility: 20, - hostname: "asa-fw", app_name: null, process_id: null, content: "%ASA-5-111008: User 'enable_15' executed the 'configure terminal' command.", @@ -1312,12 +1442,19 @@ metadata: { event_code: "106100", log_name: "cisco.asa", + loggers: [ + { + device: { + hostname: "asa-fw", + }, + log_format: "syslog", + }, + ], product: { name: "Secure Firewall ASA", vendor_name: "Cisco", }, profiles: [ - "host", "security_control", ], version: "1.8.0", @@ -1334,7 +1471,6 @@ type_uid: 400106, unmapped: { facility: 20, - hostname: "asa-fw", app_name: null, process_id: null, content: "%ASA-4-106100: access-list acl_in denied 47 outside/198.51.100.44(0) -> dmz/10.1.1.24(0) hit-cnt 1 first hit [0x0, 0x0]", @@ -1370,12 +1506,19 @@ metadata: { event_code: "106100", log_name: "cisco.asa", + loggers: [ + { + device: { + hostname: "asa-fw", + }, + log_format: "syslog", + }, + ], product: { name: "Secure Firewall ASA", vendor_name: "Cisco", }, profiles: [ - "host", "security_control", ], version: "1.8.0", @@ -1392,7 +1535,6 @@ type_uid: 400106, unmapped: { facility: 20, - hostname: "asa-fw", app_name: null, process_id: null, content: "%ASA-6-106100: access-list acl_in permitted udp outside/198.51.100.45(49543) -> dmz/10.1.1.25(53) hit-cnt 105 300-second interval [0x0, 0x0]", @@ -1411,14 +1553,19 @@ metadata: { event_code: "746013", log_name: "cisco.asa", + loggers: [ + { + device: { + hostname: "asa-fw", + }, + log_format: "syslog", + }, + ], product: { name: "Secure Firewall ASA", vendor_name: "Cisco", }, - profiles: [ - "host", - "security_control", - ], + profiles: [], version: "1.8.0", }, severity: "Low", @@ -1434,7 +1581,6 @@ type_uid: 300202, unmapped: { facility: 20, - hostname: "asa-fw", app_name: null, process_id: null, content: "%ASA-5-746013: user-identity: Delete IP-User mapping 10.1.1.40 - LOCAL\\user03 Succeeded - VPN user logout", @@ -1457,14 +1603,19 @@ metadata: { event_code: "746013", log_name: "cisco.asa", + loggers: [ + { + device: { + hostname: "asa-fw", + }, + log_format: "syslog", + }, + ], product: { name: "Secure Firewall ASA", vendor_name: "Cisco", }, - profiles: [ - "host", - "security_control", - ], + profiles: [], version: "1.8.0", }, severity: "Low", @@ -1480,7 +1631,6 @@ type_uid: 300202, unmapped: { facility: 20, - hostname: "asa-fw", app_name: null, process_id: null, content: "%ASA-5-746013: user-identity: Delete IP-User mapping 10.1.1.41 - LOCAL\\user04 Failed - PIP notification", From edc9cce032d32f3d082f67e28bcd142690073c60 Mon Sep 17 00:00:00 2001 From: zedoraps Date: Mon, 22 Jun 2026 16:17:38 +0200 Subject: [PATCH 07/20] Keep the ASA parser focused on the %ASA frame Resolve the event time in the OCSF mapper rather than the parser. The syslog timestamp is an envelope field that read_syslog provides, like the hostname, so the mapper parses it into ocsf.time (legacy and RFC 5424 forms) and the parser leaves it untouched. Merge each parsed body record inline, the same way the frame is merged, instead of via a temp that has to be dropped. This matches the one-assignment-per-match-arm shape of the paloalto parse operator and keeps the frame and body parsing consistent. Co-authored-by: Claude Opus 4.8 --- cisco/operators/asa/ocsf/map.tql | 20 ++++++++- cisco/operators/asa/parse.tql | 63 +++++++++----------------- cisco/tests/asa/ocsf/inputs/built.txt | 1 + cisco/tests/asa/ocsf/map.txt | 61 +++++++++++++++++++++++++ cisco/tests/asa/parse.txt | 64 +++++++++++++-------------- cisco/tests/asa/parse_content.txt | 2 +- 6 files changed, 133 insertions(+), 78 deletions(-) diff --git a/cisco/operators/asa/ocsf/map.tql b/cisco/operators/asa/ocsf/map.tql index 55583e4c..6b21b68d 100644 --- a/cisco/operators/asa/ocsf/map.tql +++ b/cisco/operators/asa/ocsf/map.tql @@ -37,8 +37,24 @@ if $event.asa.hostname? != null { }] } -// ASA stamps each message with the syslog timestamp when configured to do so. -$event.ocsf.time = move $event.asa.time? else $event.ocsf.metadata.processed_time +// Resolve the event time from the syslog timestamp (read_syslog provides it as +// a string). ASA uses RFC 5424 or the textual `Mon DD [YYYY] HH:MM:SS` form, +// depending on the `logging timestamp` setting. A non-syslog value (e.g. the +// numeric epoch a log shipper like GELF puts in its own `timestamp` field) is +// left for the caller to map; default to the processing time. +$event.ocsf.time = $event.ocsf.metadata.processed_time +if $event.asa.timestamp? != null { + let $iso = r"^\d{4}-\d{2}-\d{2}[T ]" + let $dated = r"^\w{3}\s+\d{1,2}\s+\d{4}\s" + let $undated = r"^\w{3}\s+\d{1,2}\s+\d{2}:\d{2}:\d{2}" + if $event.asa.timestamp.string().match_regex($iso) { + $event.ocsf.time = (move $event.asa.timestamp).string().time() + } else if $event.asa.timestamp.string().match_regex($dated) { + $event.ocsf.time = (move $event.asa.timestamp).string().parse_time("%b %d %Y %H:%M:%S") + } else if $event.asa.timestamp.string().match_regex($undated) { + $event.ocsf.time = (move $event.asa.timestamp).string().parse_time("%b %e %H:%M:%S") + } +} if $event.asa.text? != null { $event.ocsf.message = move $event.asa.text diff --git a/cisco/operators/asa/parse.tql b/cisco/operators/asa/parse.tql index 24708641..b2c787d3 100644 --- a/cisco/operators/asa/parse.tql +++ b/cisco/operators/asa/parse.tql @@ -83,53 +83,30 @@ assert message_id? != null, message="cisco::asa::parse: no %ASA-- @name = "cisco.asa" -// Resolve the event time from the syslog envelope timestamp that `read_syslog` -// leaves in a sibling `timestamp` field. ASA emits either an ISO 8601 timestamp -// or the textual `Mon DD [YYYY] HH:MM:SS` form depending on the -// `logging timestamp` setting. Only parse a value that actually looks like one -// of these, and consume it on a match so it does not linger in `unmapped`. A -// non-syslog `timestamp` (e.g. the numeric epoch a log shipper like GELF puts -// in its own `timestamp` field) is left untouched for the caller to map. -if timestamp? != null { - let $iso = r"^\d{4}-\d{2}-\d{2}[T ]" - let $dated = r"^\w{3}\s+\d{1,2}\s+\d{4}\s" - let $undated = r"^\w{3}\s+\d{1,2}\s+\d{2}:\d{2}:\d{2}" - ts = timestamp.string() - if ts.match_regex($iso) { - time = ts.time() - drop timestamp? - } else if ts.match_regex($dated) { - time = ts.parse_time("%b %d %Y %H:%M:%S") - drop timestamp? - } else if ts.match_regex($undated) { - time = ts.parse_time("%b %e %H:%M:%S") - drop timestamp? - } - drop ts -} +// The syslog envelope timestamp stays in `timestamp` for the OCSF mapper to +// resolve into the event time; parsing here is concerned only with the ASA +// `%ASA-...` frame. -// Parse the body of the matched message ID, then merge the structured fields -// into the event once. Each body pattern is written against `text` alone. -body = {} +// Parse the body of the matched message ID into structured fields. Each body +// pattern is written against `text` alone, and merges into the event the same +// way the frame does above. match message_id { - 302013 | 302015 => { body = text.parse_grok($built, pattern_definitions=$patterns) } - 302014 | 302016 => { body = text.parse_grok($teardown, pattern_definitions=$patterns) } - 302021 => { body = text.parse_grok($teardown_icmp, pattern_definitions=$patterns) } - 106023 | 106010 | 106014 => { body = text.parse_grok($deny, pattern_definitions=$patterns) } - 106001 => { body = text.parse_grok($conn_denied, pattern_definitions=$patterns) } - 106006 | 106007 => { body = text.parse_grok($deny_from, pattern_definitions=$patterns) } - 106100 => { body = text.parse_grok($acl, pattern_definitions=$patterns) } - 313004 => { body = text.parse_grok($denied_icmp, pattern_definitions=$patterns) } - 313008 => { body = text.parse_grok($denied_icmp6, pattern_definitions=$patterns) } - 419002 => { body = text.parse_grok($duplicate_syn, pattern_definitions=$patterns) } - 710003 | 710005 => { body = text.parse_grok($denied_box, pattern_definitions=$patterns) } - 722051 => { body = text.parse_grok($vpn_assigned, pattern_definitions=$patterns) } - 113019 => { body = text.parse_grok($vpn_disconnect, pattern_definitions=$patterns) } - 746013 => { body = text.parse_grok($identity_delete, pattern_definitions=$patterns) } + 302013 | 302015 => { this = {...this, ...text.parse_grok($built, pattern_definitions=$patterns)} } + 302014 | 302016 => { this = {...this, ...text.parse_grok($teardown, pattern_definitions=$patterns)} } + 302021 => { this = {...this, ...text.parse_grok($teardown_icmp, pattern_definitions=$patterns)} } + 106023 | 106010 | 106014 => { this = {...this, ...text.parse_grok($deny, pattern_definitions=$patterns)} } + 106001 => { this = {...this, ...text.parse_grok($conn_denied, pattern_definitions=$patterns)} } + 106006 | 106007 => { this = {...this, ...text.parse_grok($deny_from, pattern_definitions=$patterns)} } + 106100 => { this = {...this, ...text.parse_grok($acl, pattern_definitions=$patterns)} } + 313004 => { this = {...this, ...text.parse_grok($denied_icmp, pattern_definitions=$patterns)} } + 313008 => { this = {...this, ...text.parse_grok($denied_icmp6, pattern_definitions=$patterns)} } + 419002 => { this = {...this, ...text.parse_grok($duplicate_syn, pattern_definitions=$patterns)} } + 710003 | 710005 => { this = {...this, ...text.parse_grok($denied_box, pattern_definitions=$patterns)} } + 722051 => { this = {...this, ...text.parse_grok($vpn_assigned, pattern_definitions=$patterns)} } + 113019 => { this = {...this, ...text.parse_grok($vpn_disconnect, pattern_definitions=$patterns)} } + 746013 => { this = {...this, ...text.parse_grok($identity_delete, pattern_definitions=$patterns)} } _ => {} } -this = {...this, ...body} -drop body // Normalize across the message formats: lower-case the connection direction // and fold a numeric protocol token into protocol_num. diff --git a/cisco/tests/asa/ocsf/inputs/built.txt b/cisco/tests/asa/ocsf/inputs/built.txt index 8785b43b..d8b39cf0 100644 --- a/cisco/tests/asa/ocsf/inputs/built.txt +++ b/cisco/tests/asa/ocsf/inputs/built.txt @@ -1,2 +1,3 @@ <166>Jun 18 2025 11:37:47 asa-fw : %ASA-6-302013: Built outbound TCP connection 9 for outside:192.0.2.2/80 (192.0.2.2/80) to inside:10.1.1.2/4924 (203.0.113.10/4924) <166>Jun 18 2025 11:37:48 asa-fw : %ASA-6-302015: Built inbound UDP connection 1005 for outside:198.51.100.5/53 (198.51.100.5/53) to inside:10.1.1.3/51000 (10.1.1.3/51000) +<166>2018-06-27T12:17:46Z asa : %ASA-6-302013: Built outbound TCP connection 100 for outside:198.51.100.60/443 (198.51.100.60/443) to inside:10.1.1.40/52000 (10.1.1.40/52000) diff --git a/cisco/tests/asa/ocsf/map.txt b/cisco/tests/asa/ocsf/map.txt index 7fc0e5fc..21399dbe 100644 --- a/cisco/tests/asa/ocsf/map.txt +++ b/cisco/tests/asa/ocsf/map.txt @@ -128,6 +128,67 @@ message_id: 302015, }, } +{ + activity_id: 1, + activity_name: "Open", + category_name: "Network Activity", + category_uid: 4, + class_name: "Network Activity", + class_uid: 4001, + connection_info: { + direction: "Outbound", + direction_id: 2, + protocol_name: "tcp", + protocol_num: 6, + uid: "100", + }, + disposition: "Allowed", + disposition_id: 1, + dst_endpoint: { + interface_name: "inside", + ip: 10.1.1.40, + port: 52000, + }, + message: "Built outbound TCP connection 100 for outside:198.51.100.60/443 (198.51.100.60/443) to inside:10.1.1.40/52000 (10.1.1.40/52000)", + metadata: { + event_code: "302013", + log_name: "cisco.asa", + loggers: [ + { + device: { + hostname: "asa", + }, + log_format: "syslog", + }, + ], + product: { + name: "Secure Firewall ASA", + vendor_name: "Cisco", + }, + profiles: [ + "security_control", + ], + version: "1.8.0", + }, + severity: "Informational", + severity_id: 1, + src_endpoint: { + interface_name: "outside", + ip: 198.51.100.60, + port: 443, + }, + time: 2018-06-27T12:17:46Z, + type_name: "Network Activity: Open", + type_uid: 400101, + unmapped: { + facility: 20, + app_name: null, + process_id: null, + content: "%ASA-6-302013: Built outbound TCP connection 100 for outside:198.51.100.60/443 (198.51.100.60/443) to inside:10.1.1.40/52000 (10.1.1.40/52000)", + context: null, + message_id: 302013, + }, +} { activity_id: 1, activity_name: "Open", diff --git a/cisco/tests/asa/parse.txt b/cisco/tests/asa/parse.txt index 26c5c12f..693032ad 100644 --- a/cisco/tests/asa/parse.txt +++ b/cisco/tests/asa/parse.txt @@ -1,6 +1,7 @@ { facility: 20, severity: 4, + timestamp: "Jun 18 2025 11:38:00", hostname: "asa-fw", app_name: null, process_id: null, @@ -8,7 +9,6 @@ context: null, message_id: 106023, text: "Deny tcp src outside:198.51.100.7/4444 dst inside:10.1.1.5/3389 by access-group \"outside_access_in\" [0x0, 0x0]", - time: 2025-06-18T11:38:00Z, direction: null, protocol: "tcp", protocol_num: null, @@ -25,6 +25,7 @@ { facility: 20, severity: 4, + timestamp: "Jun 18 2025 11:38:03", hostname: "asa-fw", app_name: null, process_id: null, @@ -32,7 +33,6 @@ context: null, message_id: 106023, text: "Deny udp src dmz:fw-host/514 dst outside:10.1.1.8/514 by access-group \"dmz_access\" [0x0, 0x0]", - time: 2025-06-18T11:38:03Z, direction: null, protocol: "udp", protocol_num: null, @@ -49,6 +49,7 @@ { facility: 20, severity: 4, + timestamp: "Jun 18 2025 11:38:02", hostname: "asa-fw", app_name: null, process_id: null, @@ -56,7 +57,6 @@ context: null, message_id: 106023, text: "Deny protocol 47 src outside:198.51.100.9 dst inside:10.1.1.7 by access-group \"outside_access_in\" [0x0, 0x0]", - time: 2025-06-18T11:38:02Z, direction: "protocol", protocol_num: 47, src_interface: "outside", @@ -72,6 +72,7 @@ { facility: 20, severity: 5, + timestamp: "Jun 18 2025 11:38:10", hostname: "asa-fw", app_name: null, process_id: null, @@ -79,36 +80,11 @@ context: null, message_id: 111008, text: "User 'enable_15' executed the 'configure terminal' command.", - time: 2025-06-18T11:38:10Z, -} -{ - facility: 20, - severity: 6, - hostname: "asa", - app_name: null, - process_id: null, - content: "%ASA-6-302013: Built outbound TCP connection 100 for outside:198.51.100.60/443 (198.51.100.60/443) to inside:10.1.1.40/52000 (10.1.1.40/52000)", - context: null, - message_id: 302013, - text: "Built outbound TCP connection 100 for outside:198.51.100.60/443 (198.51.100.60/443) to inside:10.1.1.40/52000 (10.1.1.40/52000)", - time: 2018-06-27T12:17:46Z, - direction: "outbound", - protocol: "TCP", - connection_id: 100, - src_interface: "outside", - src_host: "198.51.100.60", - src_port: 443, - src_xlate_host: "198.51.100.60", - src_xlate_port: 443, - dst_interface: "inside", - dst_host: "10.1.1.40", - dst_port: 52000, - dst_xlate_host: "10.1.1.40", - dst_xlate_port: 52000, } { facility: 20, severity: 6, + timestamp: "Jun 18 2025 11:37:47", hostname: "asa-fw", app_name: null, process_id: null, @@ -116,7 +92,6 @@ context: null, message_id: 302013, text: "Built outbound TCP connection 9 for outside:192.0.2.2/80 (192.0.2.2/80) to inside:10.1.1.2/4924 (203.0.113.10/4924)", - time: 2025-06-18T11:37:47Z, direction: "outbound", protocol: "TCP", connection_id: 9, @@ -134,6 +109,7 @@ { facility: 20, severity: 6, + timestamp: "Jun 18 2025 11:37:48", hostname: "asa-fw", app_name: null, process_id: null, @@ -141,7 +117,6 @@ context: null, message_id: 302013, text: "Built inbound TCP connection 3332836331 for inside:10.1.1.9/50640 (198.51.100.20/50640) to umbrella:host.example/443 (UMBRELLA-DOMAIN-BLOCK-HIT/443) 0 24", - time: 2025-06-18T11:37:48Z, direction: "inbound", protocol: "TCP", connection_id: 3332836331, @@ -159,6 +134,32 @@ { facility: 20, severity: 6, + timestamp: "2018-06-27T12:17:46Z", + hostname: "asa", + app_name: null, + process_id: null, + content: "%ASA-6-302013: Built outbound TCP connection 100 for outside:198.51.100.60/443 (198.51.100.60/443) to inside:10.1.1.40/52000 (10.1.1.40/52000)", + context: null, + message_id: 302013, + text: "Built outbound TCP connection 100 for outside:198.51.100.60/443 (198.51.100.60/443) to inside:10.1.1.40/52000 (10.1.1.40/52000)", + direction: "outbound", + protocol: "TCP", + connection_id: 100, + src_interface: "outside", + src_host: "198.51.100.60", + src_port: 443, + src_xlate_host: "198.51.100.60", + src_xlate_port: 443, + dst_interface: "inside", + dst_host: "10.1.1.40", + dst_port: 52000, + dst_xlate_host: "10.1.1.40", + dst_xlate_port: 52000, +} +{ + facility: 20, + severity: 6, + timestamp: "Jun 18 2025 11:37:50", hostname: "asa-fw", app_name: null, process_id: null, @@ -166,7 +167,6 @@ context: null, message_id: 302014, text: "Teardown TCP connection 9 for outside:192.0.2.2/80 to inside:10.1.1.2/4924 duration 0:00:03 bytes 2048 TCP FINs", - time: 2025-06-18T11:37:50Z, protocol: "TCP", connection_id: 9, src_interface: "outside", diff --git a/cisco/tests/asa/parse_content.txt b/cisco/tests/asa/parse_content.txt index 815fb178..5f11d1c4 100644 --- a/cisco/tests/asa/parse_content.txt +++ b/cisco/tests/asa/parse_content.txt @@ -1,6 +1,7 @@ { facility: 20, severity: 6, + timestamp: "Jun 18 2025 11:37:50", hostname: "asa-fw", app_name: null, process_id: null, @@ -8,7 +9,6 @@ context: null, message_id: 302014, text: "Teardown TCP connection 9 for outside:192.0.2.2/80 to inside:10.1.1.2/4924 duration 0:00:03 bytes 2048 TCP FINs", - time: 2025-06-18T11:37:50Z, protocol: "TCP", connection_id: 9, src_interface: "outside", From 3f2ea56221e71be58a5212058561a0fabfd4187c Mon Sep 17 00:00:00 2001 From: zedoraps Date: Mon, 22 Jun 2026 16:19:47 +0200 Subject: [PATCH 08/20] Drop the redundant string() cast in ASA time parsing read_syslog already provides the timestamp as a string, so coercing it again before time()/parse_time() is unnecessary. Also remove a stray comment in the built mapper that described logic living in network_endpoints. Co-authored-by: Claude Opus 4.8 --- cisco/operators/asa/ocsf/events/built.tql | 3 --- cisco/operators/asa/ocsf/map.tql | 6 +++--- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/cisco/operators/asa/ocsf/events/built.tql b/cisco/operators/asa/ocsf/events/built.tql index 72da9ec4..64ef1673 100644 --- a/cisco/operators/asa/ocsf/events/built.tql +++ b/cisco/operators/asa/ocsf/events/built.tql @@ -31,9 +31,6 @@ if $event.asa.connection_id? != null { $event.ocsf.connection_info.uid = (move $event.asa.connection_id).string() } -// The post-NAT (translated) addresses in parentheses are mapped to proxy -// endpoints by cisco::asa::ocsf::network_endpoints. - // Connection decisions populate the security_control profile. $event.ocsf.metadata.profiles = $event.ocsf.metadata.profiles.add("security_control") $event.ocsf.disposition_id = 1 // Allowed diff --git a/cisco/operators/asa/ocsf/map.tql b/cisco/operators/asa/ocsf/map.tql index 6b21b68d..af574dab 100644 --- a/cisco/operators/asa/ocsf/map.tql +++ b/cisco/operators/asa/ocsf/map.tql @@ -48,11 +48,11 @@ if $event.asa.timestamp? != null { let $dated = r"^\w{3}\s+\d{1,2}\s+\d{4}\s" let $undated = r"^\w{3}\s+\d{1,2}\s+\d{2}:\d{2}:\d{2}" if $event.asa.timestamp.string().match_regex($iso) { - $event.ocsf.time = (move $event.asa.timestamp).string().time() + $event.ocsf.time = (move $event.asa.timestamp).time() } else if $event.asa.timestamp.string().match_regex($dated) { - $event.ocsf.time = (move $event.asa.timestamp).string().parse_time("%b %d %Y %H:%M:%S") + $event.ocsf.time = (move $event.asa.timestamp).parse_time("%b %d %Y %H:%M:%S") } else if $event.asa.timestamp.string().match_regex($undated) { - $event.ocsf.time = (move $event.asa.timestamp).string().parse_time("%b %e %H:%M:%S") + $event.ocsf.time = (move $event.asa.timestamp).parse_time("%b %e %H:%M:%S") } } From 3dbd8d7a6c5e5fc7a1188fec81fd67dd10ff2f70 Mon Sep 17 00:00:00 2001 From: zedoraps Date: Mon, 22 Jun 2026 16:26:40 +0200 Subject: [PATCH 09/20] Consolidate connection id and protocol logic in network_endpoints Move the connection_id -> connection_info.uid mapping out of the built and teardown mappers into network_endpoints, which both call and which already owns connection_info, removing the duplication. Collapse the two mirrored protocol branches into one: set a real protocol name, then take the IANA number from the message if it gave one (the `protocol N` form) or look it up by name. Co-authored-by: Claude Opus 4.8 --- cisco/operators/asa/ocsf/events/built.tql | 4 --- cisco/operators/asa/ocsf/events/teardown.tql | 4 --- .../operators/asa/ocsf/network_endpoints.tql | 25 ++++++++++--------- 3 files changed, 13 insertions(+), 20 deletions(-) diff --git a/cisco/operators/asa/ocsf/events/built.tql b/cisco/operators/asa/ocsf/events/built.tql index 64ef1673..9cbc4051 100644 --- a/cisco/operators/asa/ocsf/events/built.tql +++ b/cisco/operators/asa/ocsf/events/built.tql @@ -27,10 +27,6 @@ if $event.asa.direction? == "inbound" { } drop $event.asa.direction? -if $event.asa.connection_id? != null { - $event.ocsf.connection_info.uid = (move $event.asa.connection_id).string() -} - // Connection decisions populate the security_control profile. $event.ocsf.metadata.profiles = $event.ocsf.metadata.profiles.add("security_control") $event.ocsf.disposition_id = 1 // Allowed diff --git a/cisco/operators/asa/ocsf/events/teardown.tql b/cisco/operators/asa/ocsf/events/teardown.tql index bed036b3..6e3e6e45 100644 --- a/cisco/operators/asa/ocsf/events/teardown.tql +++ b/cisco/operators/asa/ocsf/events/teardown.tql @@ -16,10 +16,6 @@ $event.ocsf.type_uid = $event.ocsf.class_uid * 100 + $event.ocsf.activity_id cisco::asa::ocsf::network_endpoints event=$event -if $event.asa.connection_id? != null { - $event.ocsf.connection_info.uid = (move $event.asa.connection_id).string() -} - // Teardown messages summarize the closed session: total bytes and the reason // the firewall tore the connection down. if $event.asa.bytes? != null { diff --git a/cisco/operators/asa/ocsf/network_endpoints.tql b/cisco/operators/asa/ocsf/network_endpoints.tql index ce1e79b0..fc9d2ebb 100644 --- a/cisco/operators/asa/ocsf/network_endpoints.tql +++ b/cisco/operators/asa/ocsf/network_endpoints.tql @@ -3,8 +3,8 @@ description: >- Common Cisco ASA src/dst endpoint fields → OCSF network endpoints. Sets port and interface_name on both endpoints, classifies each logged address as either an `ip` or a `hostname`, records any post-NAT (translated) - address as a proxy endpoint, and populates connection_info with the protocol - number and name. + address as a proxy endpoint, and populates connection_info with the + connection id, protocol number, and name. args: named: - name: event @@ -17,6 +17,9 @@ let $ipv4 = r"^\d{1,3}(\.\d{1,3}){3}$" let $ipv6 = r"^[0-9A-Fa-f:]*:[0-9A-Fa-f:]+$" $event.ocsf.connection_info = {} +if $event.asa.connection_id? != null { + $event.ocsf.connection_info.uid = (move $event.asa.connection_id).string() +} // --- Source endpoint --- $event.ocsf.src_endpoint = { @@ -81,16 +84,14 @@ let $protocols = { ah: 51, icmpv6: 58, } +// Keep a real protocol name (but not the `protocol` placeholder word), and take +// the number from the message if it gave one, otherwise look it up by name. +if $event.asa.protocol? != null and $event.asa.protocol != "protocol" { + $event.ocsf.connection_info.protocol_name = $event.asa.protocol.to_lower() +} if $event.asa.protocol_num? != null { $event.ocsf.connection_info.protocol_num = move $event.asa.protocol_num - // Keep a real protocol name, but not the `protocol` placeholder word. - if $event.asa.protocol? != null and $event.asa.protocol != "protocol" { - $event.ocsf.connection_info.protocol_name = $event.asa.protocol.to_lower() - } - drop $event.asa.protocol? -} else if $event.asa.protocol? != null { - $event.asa.protocol = $event.asa.protocol.to_lower() - $event.ocsf.connection_info.protocol_name = $event.asa.protocol - $event.ocsf.connection_info.protocol_num = $protocols[$event.asa.protocol]? else -1 - drop $event.asa.protocol +} else if $event.ocsf.connection_info.protocol_name? != null { + $event.ocsf.connection_info.protocol_num = $protocols[$event.ocsf.connection_info.protocol_name]? else -1 } +drop $event.asa.protocol? From eb8d9a388fbd427f940fdf3973ae4c6cab503893 Mon Sep 17 00:00:00 2001 From: zedoraps Date: Mon, 22 Jun 2026 16:29:17 +0200 Subject: [PATCH 10/20] Describe the full ASA OCSF mapping scope in the changelog The entry listed only three message families; spell out the full Network Activity coverage and the new Authentication mapping so readers do not underestimate the scope. Co-authored-by: Claude Opus 4.8 --- .../unreleased/add-cisco-asa-support.md | 31 ++++++++++++------- 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/cisco/changelog/unreleased/add-cisco-asa-support.md b/cisco/changelog/unreleased/add-cisco-asa-support.md index 11809764..0ff0e00c 100644 --- a/cisco/changelog/unreleased/add-cisco-asa-support.md +++ b/cisco/changelog/unreleased/add-cisco-asa-support.md @@ -7,28 +7,35 @@ created: 2026-06-18T00:00:00Z --- The `cisco` package now parses Cisco Secure Firewall ASA syslog messages and -maps supported message IDs to OCSF. +maps them to OCSF. `cisco::asa::parse` extracts the `%ASA--: ` frame -from a message field and parses the body of supported messages into structured -fields. It takes a `message` argument naming the field that holds the raw line -(default `content`, as produced by the built-in `read_syslog`), so it composes -with any transport: +from a field and parses the body of supported messages into structured fields. +It takes a `message` field argument (default `content`, as produced by the +built-in `read_syslog`), so it composes with any transport: ```tql from_tcp "0.0.0.0:514" { read_syslog } -cisco::asa::parse message="content" +cisco::asa::parse cisco::asa::ocsf::map ocsf::derive ocsf::cast ``` -Point `message` at another field for other delivery methods, e.g. -`message="line"` after `read_lines`, or the body field a log shipper uses. +Point `message` at another field for other delivery methods, e.g. `message=line` +after `read_lines`, or the body field a log shipper provides. -`cisco::asa::ocsf::map` maps connection-built (302013/302015), connection- -teardown (302014/302016), and access-list deny (106023) messages to OCSF -Network Activity events. Unsupported messages map to the OCSF Base Event and -retain their original text. +`cisco::asa::ocsf::map` maps the common firewall messages by ID: + +- **OCSF Network Activity (4001)**: connection setup and teardown + (302013/302015, 302014/302016/302021); access-list, protocol, and ICMP denies + plus access-list hit-count logs (106001, 106006/106007, 106010, 106014, + 106023, 106100, 313004/313008, 710003/710005); and duplicate TCP SYN (419002). +- **OCSF Authentication (3002)**: VPN session logon and logoff and + identity-mapping changes (722051, 113019, 746013). + +Every other message maps to the OCSF Base Event with its original text +preserved. The ASA message ID is recorded in `metadata.event_code`, and the +reporting host in `metadata.loggers`. From 37ae08fc8f341853220fdb79869c9523fddecc3a Mon Sep 17 00:00:00 2001 From: zedoraps Date: Mon, 22 Jun 2026 16:30:09 +0200 Subject: [PATCH 11/20] Rename the ASA deny mapper to access_control The mapper also handles 106100 access-list logs, which record permits as well as denies, so `deny` misnamed the allowed case. `access_control` covers both firewall verdicts. Co-authored-by: Claude Opus 4.8 --- .../operators/asa/ocsf/events/{deny.tql => access_control.tql} | 2 +- cisco/operators/asa/ocsf/map.tql | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename cisco/operators/asa/ocsf/events/{deny.tql => access_control.tql} (88%) diff --git a/cisco/operators/asa/ocsf/events/deny.tql b/cisco/operators/asa/ocsf/events/access_control.tql similarity index 88% rename from cisco/operators/asa/ocsf/events/deny.tql rename to cisco/operators/asa/ocsf/events/access_control.tql index a0edfc56..bf2f3210 100644 --- a/cisco/operators/asa/ocsf/events/deny.tql +++ b/cisco/operators/asa/ocsf/events/access_control.tql @@ -1,5 +1,5 @@ --- -description: "Cisco ASA deny / access-list messages (106023, 106001, 106006/7, 106010, 106014, 106100, 313004/8) → OCSF Network Activity (4001)" +description: "Cisco ASA access-control decisions — denies and access-list permit/deny logs (106001, 106006/7, 106010, 106014, 106023, 106100, 313004/8, 710003/5) → OCSF Network Activity (4001)" args: named: - name: event diff --git a/cisco/operators/asa/ocsf/map.tql b/cisco/operators/asa/ocsf/map.tql index af574dab..e97f423f 100644 --- a/cisco/operators/asa/ocsf/map.tql +++ b/cisco/operators/asa/ocsf/map.tql @@ -80,7 +80,7 @@ if $event.asa.severity? != null { match $event.asa.message_id { 302013 | 302015 => { cisco::asa::ocsf::events::built event=$event } 302014 | 302016 | 302021 => { cisco::asa::ocsf::events::teardown event=$event } - 106023 | 106001 | 106006 | 106007 | 106010 | 106014 | 106100 | 313004 | 313008 | 710003 | 710005 => { cisco::asa::ocsf::events::deny event=$event } + 106023 | 106001 | 106006 | 106007 | 106010 | 106014 | 106100 | 313004 | 313008 | 710003 | 710005 => { cisco::asa::ocsf::events::access_control event=$event } 419002 => { cisco::asa::ocsf::events::network event=$event } 722051 | 113019 | 746013 => { cisco::asa::ocsf::events::authentication event=$event } _ => { cisco::asa::ocsf::base event=$event } From 514c5ef63da9ba8dfba730fa0b4fe8203c8f10be Mon Sep 17 00:00:00 2001 From: zedoraps Date: Mon, 22 Jun 2026 16:34:28 +0200 Subject: [PATCH 12/20] Omit empty profiles from ASA metadata No other package emits profiles: []; zscaler and sophos omit the field when there are no profiles. Drop it from the base metadata and have the firewall-decision mappers set profiles: ["security_control"] directly, so only events that populate a profile carry the field. Co-authored-by: Claude Opus 4.8 --- cisco/operators/asa/ocsf/events/access_control.tql | 2 +- cisco/operators/asa/ocsf/events/built.tql | 2 +- cisco/operators/asa/ocsf/events/teardown.tql | 2 +- cisco/operators/asa/ocsf/map.tql | 3 +-- cisco/tests/asa/ocsf/map.txt | 6 ------ 5 files changed, 4 insertions(+), 11 deletions(-) diff --git a/cisco/operators/asa/ocsf/events/access_control.tql b/cisco/operators/asa/ocsf/events/access_control.tql index bf2f3210..af180ce5 100644 --- a/cisco/operators/asa/ocsf/events/access_control.tql +++ b/cisco/operators/asa/ocsf/events/access_control.tql @@ -37,7 +37,7 @@ if $event.asa.hit_count? != null { } // Access-list decisions populate the security_control profile. -$event.ocsf.metadata.profiles = $event.ocsf.metadata.profiles.add("security_control") +$event.ocsf.metadata.profiles = ["security_control"] // 106100 logs both permits and denies via `action`; everything else is a deny. if $event.asa.action? == "permitted" { diff --git a/cisco/operators/asa/ocsf/events/built.tql b/cisco/operators/asa/ocsf/events/built.tql index 9cbc4051..b1e0d8df 100644 --- a/cisco/operators/asa/ocsf/events/built.tql +++ b/cisco/operators/asa/ocsf/events/built.tql @@ -28,5 +28,5 @@ if $event.asa.direction? == "inbound" { drop $event.asa.direction? // Connection decisions populate the security_control profile. -$event.ocsf.metadata.profiles = $event.ocsf.metadata.profiles.add("security_control") +$event.ocsf.metadata.profiles = ["security_control"] $event.ocsf.disposition_id = 1 // Allowed diff --git a/cisco/operators/asa/ocsf/events/teardown.tql b/cisco/operators/asa/ocsf/events/teardown.tql index 6e3e6e45..60cdde75 100644 --- a/cisco/operators/asa/ocsf/events/teardown.tql +++ b/cisco/operators/asa/ocsf/events/teardown.tql @@ -28,5 +28,5 @@ if $event.asa.reason? != null { } // Connection decisions populate the security_control profile. -$event.ocsf.metadata.profiles = $event.ocsf.metadata.profiles.add("security_control") +$event.ocsf.metadata.profiles = ["security_control"] $event.ocsf.disposition_id = 1 // Allowed diff --git a/cisco/operators/asa/ocsf/map.tql b/cisco/operators/asa/ocsf/map.tql index e97f423f..6bd38159 100644 --- a/cisco/operators/asa/ocsf/map.tql +++ b/cisco/operators/asa/ocsf/map.tql @@ -21,8 +21,7 @@ $event.ocsf.metadata = { name: "Secure Firewall ASA", vendor_name: "Cisco", }, - // security_control is added by the event mappers that set firewall fields. - profiles: [], + // The event mappers that set firewall fields add the security_control profile. version: "1.8.0", } diff --git a/cisco/tests/asa/ocsf/map.txt b/cisco/tests/asa/ocsf/map.txt index 21399dbe..2bd46dac 100644 --- a/cisco/tests/asa/ocsf/map.txt +++ b/cisco/tests/asa/ocsf/map.txt @@ -929,7 +929,6 @@ name: "Secure Firewall ASA", vendor_name: "Cisco", }, - profiles: [], version: "1.8.0", }, severity: "Medium", @@ -974,7 +973,6 @@ name: "Secure Firewall ASA", vendor_name: "Cisco", }, - profiles: [], version: "1.8.0", }, severity: "Informational", @@ -1029,7 +1027,6 @@ name: "Secure Firewall ASA", vendor_name: "Cisco", }, - profiles: [], version: "1.8.0", }, severity: "Informational", @@ -1459,7 +1456,6 @@ name: "Secure Firewall ASA", vendor_name: "Cisco", }, - profiles: [], version: "1.8.0", }, severity: "Low", @@ -1626,7 +1622,6 @@ name: "Secure Firewall ASA", vendor_name: "Cisco", }, - profiles: [], version: "1.8.0", }, severity: "Low", @@ -1676,7 +1671,6 @@ name: "Secure Firewall ASA", vendor_name: "Cisco", }, - profiles: [], version: "1.8.0", }, severity: "Low", From 096035ff8152f3dd502dfcd060fb4cd4b49a6a33 Mon Sep 17 00:00:00 2001 From: zedoraps Date: Mon, 22 Jun 2026 16:37:19 +0200 Subject: [PATCH 13/20] Drop the message ID from ASA unmapped fields It is already recorded in metadata.event_code, so keeping it in unmapped duplicated the value. Co-authored-by: Claude Opus 4.8 --- cisco/operators/asa/ocsf/map.tql | 3 +++ cisco/tests/asa/ocsf/map.txt | 28 ---------------------------- 2 files changed, 3 insertions(+), 28 deletions(-) diff --git a/cisco/operators/asa/ocsf/map.tql b/cisco/operators/asa/ocsf/map.tql index 6bd38159..95fc78c6 100644 --- a/cisco/operators/asa/ocsf/map.tql +++ b/cisco/operators/asa/ocsf/map.tql @@ -85,4 +85,7 @@ match $event.asa.message_id { _ => { cisco::asa::ocsf::base event=$event } } +// The message ID is recorded in metadata.event_code, so drop it from unmapped. +drop $event.asa.message_id? + $event = {...$event.ocsf, unmapped: $event.asa} diff --git a/cisco/tests/asa/ocsf/map.txt b/cisco/tests/asa/ocsf/map.txt index 2bd46dac..eb4cc439 100644 --- a/cisco/tests/asa/ocsf/map.txt +++ b/cisco/tests/asa/ocsf/map.txt @@ -64,7 +64,6 @@ process_id: null, content: "%ASA-6-302013: Built inbound TCP connection 3332836331 for inside:10.1.1.9/50640 (198.51.100.20/50640) to umbrella:host.example/443 (UMBRELLA-DOMAIN-BLOCK-HIT/443) 0 24", context: null, - message_id: 302013, }, } { @@ -125,7 +124,6 @@ process_id: null, content: "%ASA-6-302015: Built inbound UDP connection 1005 for outside:198.51.100.5/53 (198.51.100.5/53) to inside:10.1.1.3/51000 (10.1.1.3/51000)", context: null, - message_id: 302015, }, } { @@ -186,7 +184,6 @@ process_id: null, content: "%ASA-6-302013: Built outbound TCP connection 100 for outside:198.51.100.60/443 (198.51.100.60/443) to inside:10.1.1.40/52000 (10.1.1.40/52000)", context: null, - message_id: 302013, }, } { @@ -251,7 +248,6 @@ process_id: null, content: "%ASA-6-302013: Built outbound TCP connection 9 for outside:192.0.2.2/80 (192.0.2.2/80) to inside:10.1.1.2/4924 (203.0.113.10/4924)", context: null, - message_id: 302013, }, } { @@ -311,7 +307,6 @@ process_id: null, content: "%ASA-3-313004: Denied ICMP type=0, from laddr 10.1.1.26 on interface inside to 10.1.1.27: no matching session", context: null, - message_id: 313004, icmp_type: 0, reason: "no matching session", }, @@ -372,7 +367,6 @@ process_id: null, content: "%ASA-3-313008: Denied IPv6-ICMP type=136, code=0 from fe80::21a:2bff:fe3c:4d5e on interface inside", context: null, - message_id: 313008, icmp_type: 136, icmp_code: 0, }, @@ -437,7 +431,6 @@ process_id: null, content: "%ASA-4-106023: Deny icmp src outside:198.51.100.30 dst inside:10.1.1.9 (type 8, code 0) by access-group \"outside_access_in\" [0x0, 0x0]", context: null, - message_id: 106023, protocol_num: null, icmp_type: 8, icmp_code: 0, @@ -503,7 +496,6 @@ process_id: null, content: "%ASA-4-106023: Deny icmp src outside:198.51.100.8/0 dst inside:10.1.1.6/0 [type 8, code 0] by access-group \"outside_access_in\" [0x0, 0x0]", context: null, - message_id: 106023, protocol_num: null, icmp_type: 8, icmp_code: 0, @@ -568,7 +560,6 @@ process_id: null, content: "%ASA-2-106006: Deny inbound UDP from 198.51.100.43/137 to 10.1.1.23/137 on interface outside", context: null, - message_id: 106006, }, } { @@ -630,7 +621,6 @@ process_id: null, content: "%ASA-3-106014: Deny inbound icmp src dmz:198.51.100.40 dst inside:10.1.1.20 (type 8, code 0)", context: null, - message_id: 106014, protocol_num: null, icmp_type: 8, icmp_code: 0, @@ -695,7 +685,6 @@ process_id: null, content: "%ASA-3-106010: Deny inbound protocol 47 src outside:198.51.100.41 dst outside:10.1.1.21", context: null, - message_id: 106010, icmp_type: null, icmp_code: null, acl_id: null, @@ -760,7 +749,6 @@ process_id: null, content: "%ASA-4-106023: Deny protocol 47 src outside:198.51.100.9 dst inside:10.1.1.7 by access-group \"outside_access_in\" [0x0, 0x0]", context: null, - message_id: 106023, icmp_type: null, icmp_code: null, }, @@ -825,7 +813,6 @@ process_id: null, content: "%ASA-4-106023: Deny tcp src outside:198.51.100.7/4444 dst inside:10.1.1.5/3389 by access-group \"outside_access_in\" [0x0, 0x0]", context: null, - message_id: 106023, protocol_num: null, icmp_type: null, icmp_code: null, @@ -891,7 +878,6 @@ process_id: null, content: "%ASA-4-106023: Deny udp src dmz:fw-host/514 dst outside:10.1.1.8/514 by access-group \"dmz_access\" [0x0, 0x0]", context: null, - message_id: 106023, protocol_num: null, icmp_type: null, icmp_code: null, @@ -947,7 +933,6 @@ process_id: null, content: "%ASA-4-419002: Duplicate TCP SYN from inside:198.51.100.50/22 to dmz:10.1.1.30/443 with different initial sequence number", context: null, - message_id: 419002, }, } { @@ -991,7 +976,6 @@ process_id: null, content: "%ASA-6-722051: Group User IP <198.51.100.60> IPv4 Address <10.8.0.5> IPv6 address <::> assigned to session", context: null, - message_id: 722051, assigned_ipv4: 10.8.0.5, assigned_ipv6: ::, }, @@ -1046,7 +1030,6 @@ process_id: null, content: "%ASA-6-113019: Group = vpn-group, Username = user02, IP = 198.51.100.61, Session disconnected. Session Type: SSL, Duration: 0h:52m:12s, Bytes xmt: 17932, Bytes rcv: 228, Reason: User Requested", context: null, - message_id: 113019, session_type: "SSL", duration: "0h:52m:12s", bytes_out: 17932, @@ -1120,7 +1103,6 @@ process_id: null, content: "%ASA-2-106001: Inbound TCP connection denied from 198.51.100.42/49709 to 10.1.1.22/6022 flags SYN on interface outside", context: null, - message_id: 106001, tcp_flags: "SYN", }, } @@ -1181,7 +1163,6 @@ process_id: null, content: "%ASA-3-710003: TCP access denied by ACL from 198.51.100.51/65396 to crypto:host.example/80", context: null, - message_id: 710003, }, } { @@ -1239,7 +1220,6 @@ process_id: null, content: "%ASA-6-302021: Teardown ICMP connection for faddr 10.1.1.32/45078 gaddr 192.168.0.69/0 laddr 192.168.0.69/0 type 8 code 0 Internal-Data0/-1:RX[-1]", context: null, - message_id: 302021, faddr_id: 45078, gaddr_id: 0, laddr_id: 0, @@ -1305,7 +1285,6 @@ process_id: null, content: "%ASA-6-302014: Teardown TCP connection 9 for outside:192.0.2.2/80 to inside:10.1.1.2/4924 duration 0:00:03 bytes 2048 TCP FINs", context: null, - message_id: 302014, duration: "0:00:03", }, } @@ -1368,7 +1347,6 @@ process_id: null, content: "%ASA-6-302016: Teardown UDP connection 1005 for outside:198.51.100.5/53 to inside:10.1.1.3/51000 duration 0:00:05 bytes 312", context: null, - message_id: 302016, duration: "0:00:05", reason: null, }, @@ -1430,7 +1408,6 @@ process_id: null, content: "%ASA-3-710005: UDP request discarded from 198.51.100.52/60389 to outside:10.1.1.31/44861", context: null, - message_id: 710005, }, } { @@ -1469,7 +1446,6 @@ process_id: null, content: "%ASA-5-111008: User 'enable_15' executed the 'configure terminal' command.", context: null, - message_id: 111008, }, } { @@ -1532,7 +1508,6 @@ process_id: null, content: "%ASA-4-106100: access-list acl_in denied 47 outside/198.51.100.44(0) -> dmz/10.1.1.24(0) hit-cnt 1 first hit [0x0, 0x0]", context: null, - message_id: 106100, }, } { @@ -1596,7 +1571,6 @@ process_id: null, content: "%ASA-6-106100: access-list acl_in permitted udp outside/198.51.100.45(49543) -> dmz/10.1.1.25(53) hit-cnt 105 300-second interval [0x0, 0x0]", context: null, - message_id: 106100, }, } { @@ -1641,7 +1615,6 @@ process_id: null, content: "%ASA-5-746013: user-identity: Delete IP-User mapping 10.1.1.40 - LOCAL\\user03 Succeeded - VPN user logout", context: null, - message_id: 746013, }, user: { domain: "LOCAL", @@ -1690,7 +1663,6 @@ process_id: null, content: "%ASA-5-746013: user-identity: Delete IP-User mapping 10.1.1.41 - LOCAL\\user04 Failed - PIP notification", context: null, - message_id: 746013, }, user: { domain: "LOCAL", From 7d96eb489f1c137f6096ba9d4e592050c1581b57 Mon Sep 17 00:00:00 2001 From: zedoraps Date: Mon, 22 Jun 2026 16:41:04 +0200 Subject: [PATCH 14/20] Split the ASA OCSF test by mapper Replace the single globbed map test with one test per OCSF mapper (built, teardown, access_control, network, authentication, base), each reading its own input file, matching the sophos and suricata packages. A failure now isolates the affected mapper, and the baselines are smaller and easier to review. Co-authored-by: Claude Opus 4.8 --- cisco/tests/asa/ocsf/access_control.tql | 9 + .../asa/ocsf/{map.txt => access_control.txt} | 843 ++---------------- cisco/tests/asa/ocsf/authentication.tql | 9 + cisco/tests/asa/ocsf/authentication.txt | 205 +++++ cisco/tests/asa/ocsf/{map.tql => base.tql} | 2 +- cisco/tests/asa/ocsf/base.txt | 76 ++ cisco/tests/asa/ocsf/built.tql | 9 + cisco/tests/asa/ocsf/built.txt | 252 ++++++ .../{deny_family.txt => access_control.txt} | 7 + .../inputs/{vpn.txt => authentication.txt} | 0 cisco/tests/asa/ocsf/inputs/base.txt | 2 + cisco/tests/asa/ocsf/inputs/built.txt | 1 + cisco/tests/asa/ocsf/inputs/built_sig.txt | 1 - cisco/tests/asa/ocsf/inputs/deny.txt | 2 - cisco/tests/asa/ocsf/inputs/deny_variants.txt | 3 - cisco/tests/asa/ocsf/inputs/easy_wins.txt | 4 - cisco/tests/asa/ocsf/inputs/network.txt | 1 + cisco/tests/asa/ocsf/inputs/other.txt | 1 - cisco/tests/asa/ocsf/inputs/teardown.txt | 1 + cisco/tests/asa/ocsf/network.tql | 9 + cisco/tests/asa/ocsf/network.txt | 52 ++ cisco/tests/asa/ocsf/teardown.tql | 9 + cisco/tests/asa/ocsf/teardown.txt | 186 ++++ 23 files changed, 884 insertions(+), 800 deletions(-) create mode 100644 cisco/tests/asa/ocsf/access_control.tql rename cisco/tests/asa/ocsf/{map.txt => access_control.txt} (55%) create mode 100644 cisco/tests/asa/ocsf/authentication.tql create mode 100644 cisco/tests/asa/ocsf/authentication.txt rename cisco/tests/asa/ocsf/{map.tql => base.tql} (72%) create mode 100644 cisco/tests/asa/ocsf/base.txt create mode 100644 cisco/tests/asa/ocsf/built.tql create mode 100644 cisco/tests/asa/ocsf/built.txt rename cisco/tests/asa/ocsf/inputs/{deny_family.txt => access_control.txt} (51%) rename cisco/tests/asa/ocsf/inputs/{vpn.txt => authentication.txt} (100%) create mode 100644 cisco/tests/asa/ocsf/inputs/base.txt delete mode 100644 cisco/tests/asa/ocsf/inputs/built_sig.txt delete mode 100644 cisco/tests/asa/ocsf/inputs/deny.txt delete mode 100644 cisco/tests/asa/ocsf/inputs/deny_variants.txt delete mode 100644 cisco/tests/asa/ocsf/inputs/easy_wins.txt create mode 100644 cisco/tests/asa/ocsf/inputs/network.txt delete mode 100644 cisco/tests/asa/ocsf/inputs/other.txt create mode 100644 cisco/tests/asa/ocsf/network.tql create mode 100644 cisco/tests/asa/ocsf/network.txt create mode 100644 cisco/tests/asa/ocsf/teardown.tql create mode 100644 cisco/tests/asa/ocsf/teardown.txt diff --git a/cisco/tests/asa/ocsf/access_control.tql b/cisco/tests/asa/ocsf/access_control.tql new file mode 100644 index 00000000..bcfbb85b --- /dev/null +++ b/cisco/tests/asa/ocsf/access_control.tql @@ -0,0 +1,9 @@ +from_file f"{env("TENZIR_INPUTS")}/access_control.txt" { + read_syslog +} +cisco::asa::parse +cisco::asa::ocsf::map +ocsf::derive +ocsf::cast +drop metadata.processed_time +sort message diff --git a/cisco/tests/asa/ocsf/map.txt b/cisco/tests/asa/ocsf/access_control.txt similarity index 55% rename from cisco/tests/asa/ocsf/map.txt rename to cisco/tests/asa/ocsf/access_control.txt index eb4cc439..32b90345 100644 --- a/cisco/tests/asa/ocsf/map.txt +++ b/cisco/tests/asa/ocsf/access_control.txt @@ -1,255 +1,3 @@ -{ - activity_id: 1, - activity_name: "Open", - category_name: "Network Activity", - category_uid: 4, - class_name: "Network Activity", - class_uid: 4001, - connection_info: { - direction: "Inbound", - direction_id: 1, - protocol_name: "tcp", - protocol_num: 6, - uid: "3332836331", - }, - disposition: "Allowed", - disposition_id: 1, - dst_endpoint: { - hostname: "host.example", - interface_name: "umbrella", - port: 443, - proxy_endpoint: { - hostname: "UMBRELLA-DOMAIN-BLOCK-HIT", - port: 443, - }, - }, - message: "Built inbound TCP connection 3332836331 for inside:10.1.1.9/50640 (198.51.100.20/50640) to umbrella:host.example/443 (UMBRELLA-DOMAIN-BLOCK-HIT/443) 0 24", - metadata: { - event_code: "302013", - log_name: "cisco.asa", - loggers: [ - { - device: { - hostname: "asa-fw", - }, - log_format: "syslog", - }, - ], - product: { - name: "Secure Firewall ASA", - vendor_name: "Cisco", - }, - profiles: [ - "security_control", - ], - version: "1.8.0", - }, - severity: "Informational", - severity_id: 1, - src_endpoint: { - interface_name: "inside", - ip: 10.1.1.9, - port: 50640, - proxy_endpoint: { - ip: 198.51.100.20, - port: 50640, - }, - }, - time: 2025-06-18T11:37:48Z, - type_name: "Network Activity: Open", - type_uid: 400101, - unmapped: { - facility: 20, - app_name: null, - process_id: null, - content: "%ASA-6-302013: Built inbound TCP connection 3332836331 for inside:10.1.1.9/50640 (198.51.100.20/50640) to umbrella:host.example/443 (UMBRELLA-DOMAIN-BLOCK-HIT/443) 0 24", - context: null, - }, -} -{ - activity_id: 1, - activity_name: "Open", - category_name: "Network Activity", - category_uid: 4, - class_name: "Network Activity", - class_uid: 4001, - connection_info: { - direction: "Inbound", - direction_id: 1, - protocol_name: "udp", - protocol_num: 17, - uid: "1005", - }, - disposition: "Allowed", - disposition_id: 1, - dst_endpoint: { - interface_name: "inside", - ip: 10.1.1.3, - port: 51000, - }, - message: "Built inbound UDP connection 1005 for outside:198.51.100.5/53 (198.51.100.5/53) to inside:10.1.1.3/51000 (10.1.1.3/51000)", - metadata: { - event_code: "302015", - log_name: "cisco.asa", - loggers: [ - { - device: { - hostname: "asa-fw", - }, - log_format: "syslog", - }, - ], - product: { - name: "Secure Firewall ASA", - vendor_name: "Cisco", - }, - profiles: [ - "security_control", - ], - version: "1.8.0", - }, - severity: "Informational", - severity_id: 1, - src_endpoint: { - interface_name: "outside", - ip: 198.51.100.5, - port: 53, - }, - time: 2025-06-18T11:37:48Z, - type_name: "Network Activity: Open", - type_uid: 400101, - unmapped: { - facility: 20, - app_name: null, - process_id: null, - content: "%ASA-6-302015: Built inbound UDP connection 1005 for outside:198.51.100.5/53 (198.51.100.5/53) to inside:10.1.1.3/51000 (10.1.1.3/51000)", - context: null, - }, -} -{ - activity_id: 1, - activity_name: "Open", - category_name: "Network Activity", - category_uid: 4, - class_name: "Network Activity", - class_uid: 4001, - connection_info: { - direction: "Outbound", - direction_id: 2, - protocol_name: "tcp", - protocol_num: 6, - uid: "100", - }, - disposition: "Allowed", - disposition_id: 1, - dst_endpoint: { - interface_name: "inside", - ip: 10.1.1.40, - port: 52000, - }, - message: "Built outbound TCP connection 100 for outside:198.51.100.60/443 (198.51.100.60/443) to inside:10.1.1.40/52000 (10.1.1.40/52000)", - metadata: { - event_code: "302013", - log_name: "cisco.asa", - loggers: [ - { - device: { - hostname: "asa", - }, - log_format: "syslog", - }, - ], - product: { - name: "Secure Firewall ASA", - vendor_name: "Cisco", - }, - profiles: [ - "security_control", - ], - version: "1.8.0", - }, - severity: "Informational", - severity_id: 1, - src_endpoint: { - interface_name: "outside", - ip: 198.51.100.60, - port: 443, - }, - time: 2018-06-27T12:17:46Z, - type_name: "Network Activity: Open", - type_uid: 400101, - unmapped: { - facility: 20, - app_name: null, - process_id: null, - content: "%ASA-6-302013: Built outbound TCP connection 100 for outside:198.51.100.60/443 (198.51.100.60/443) to inside:10.1.1.40/52000 (10.1.1.40/52000)", - context: null, - }, -} -{ - activity_id: 1, - activity_name: "Open", - category_name: "Network Activity", - category_uid: 4, - class_name: "Network Activity", - class_uid: 4001, - connection_info: { - direction: "Outbound", - direction_id: 2, - protocol_name: "tcp", - protocol_num: 6, - uid: "9", - }, - disposition: "Allowed", - disposition_id: 1, - dst_endpoint: { - interface_name: "inside", - ip: 10.1.1.2, - port: 4924, - proxy_endpoint: { - ip: 203.0.113.10, - port: 4924, - }, - }, - message: "Built outbound TCP connection 9 for outside:192.0.2.2/80 (192.0.2.2/80) to inside:10.1.1.2/4924 (203.0.113.10/4924)", - metadata: { - event_code: "302013", - log_name: "cisco.asa", - loggers: [ - { - device: { - hostname: "asa-fw", - }, - log_format: "syslog", - }, - ], - product: { - name: "Secure Firewall ASA", - vendor_name: "Cisco", - }, - profiles: [ - "security_control", - ], - version: "1.8.0", - }, - severity: "Informational", - severity_id: 1, - src_endpoint: { - interface_name: "outside", - ip: 192.0.2.2, - port: 80, - }, - time: 2025-06-18T11:37:47Z, - type_name: "Network Activity: Open", - type_uid: 400101, - unmapped: { - facility: 20, - app_name: null, - process_id: null, - content: "%ASA-6-302013: Built outbound TCP connection 9 for outside:192.0.2.2/80 (192.0.2.2/80) to inside:10.1.1.2/4924 (203.0.113.10/4924)", - context: null, - }, -} { action: "Denied", action_id: 2, @@ -884,6 +632,8 @@ }, } { + action: "Denied", + action_id: 2, activity_id: 6, activity_name: "Traffic", category_name: "Network Activity", @@ -891,17 +641,21 @@ class_name: "Network Activity", class_uid: 4001, connection_info: { + direction: "Inbound", + direction_id: 1, protocol_name: "tcp", protocol_num: 6, }, + disposition: "Blocked", + disposition_id: 2, dst_endpoint: { - interface_name: "dmz", - ip: 10.1.1.30, - port: 443, + interface_name: null, + ip: 10.1.1.22, + port: 6022, }, - message: "Duplicate TCP SYN from inside:198.51.100.50/22 to dmz:10.1.1.30/443 with different initial sequence number", + message: "Inbound TCP connection denied from 198.51.100.42/49709 to 10.1.1.22/6022 flags SYN on interface outside", metadata: { - event_code: "419002", + event_code: "106001", log_name: "cisco.asa", loggers: [ { @@ -915,36 +669,53 @@ name: "Secure Firewall ASA", vendor_name: "Cisco", }, + profiles: [ + "security_control", + ], version: "1.8.0", }, - severity: "Medium", - severity_id: 3, + severity: "Critical", + severity_id: 5, src_endpoint: { - interface_name: "inside", - ip: 198.51.100.50, - port: 22, + interface_name: "outside", + ip: 198.51.100.42, + port: 49709, }, - time: 2025-06-18T11:38:13Z, + time: 2025-06-18T11:38:05Z, type_name: "Network Activity: Traffic", type_uid: 400106, unmapped: { facility: 20, app_name: null, process_id: null, - content: "%ASA-4-419002: Duplicate TCP SYN from inside:198.51.100.50/22 to dmz:10.1.1.30/443 with different initial sequence number", + content: "%ASA-2-106001: Inbound TCP connection denied from 198.51.100.42/49709 to 10.1.1.22/6022 flags SYN on interface outside", context: null, + tcp_flags: "SYN", }, } { - activity_id: 1, - activity_name: "Logon", - category_name: "Identity & Access Management", - category_uid: 3, - class_name: "Authentication", - class_uid: 3002, - message: "Group User IP <198.51.100.60> IPv4 Address <10.8.0.5> IPv6 address <::> assigned to session", + action: "Denied", + action_id: 2, + activity_id: 6, + activity_name: "Traffic", + category_name: "Network Activity", + category_uid: 4, + class_name: "Network Activity", + class_uid: 4001, + connection_info: { + protocol_name: "tcp", + protocol_num: 6, + }, + disposition: "Blocked", + disposition_id: 2, + dst_endpoint: { + hostname: "host.example", + interface_name: "crypto", + port: 80, + }, + message: "TCP access denied by ACL from 198.51.100.51/65396 to crypto:host.example/80", metadata: { - event_code: "722051", + event_code: "710003", log_name: "cisco.asa", loggers: [ { @@ -958,397 +729,27 @@ name: "Secure Firewall ASA", vendor_name: "Cisco", }, + profiles: [ + "security_control", + ], version: "1.8.0", }, - severity: "Informational", - severity_id: 1, + severity: "High", + severity_id: 4, src_endpoint: { - ip: 198.51.100.60, + interface_name: null, + ip: 198.51.100.51, + port: 65396, }, - status: "Success", - status_id: 1, - time: 2025-06-18T11:38:17Z, - type_name: "Authentication: Logon", - type_uid: 300201, + time: 2025-06-18T11:38:14Z, + type_name: "Network Activity: Traffic", + type_uid: 400106, unmapped: { facility: 20, app_name: null, process_id: null, - content: "%ASA-6-722051: Group User IP <198.51.100.60> IPv4 Address <10.8.0.5> IPv6 address <::> assigned to session", + content: "%ASA-3-710003: TCP access denied by ACL from 198.51.100.51/65396 to crypto:host.example/80", context: null, - assigned_ipv4: 10.8.0.5, - assigned_ipv6: ::, - }, - user: { - groups: [ - { - name: "vpn-group", - }, - ], - name: "user01", - }, -} -{ - activity_id: 2, - activity_name: "Logoff", - category_name: "Identity & Access Management", - category_uid: 3, - class_name: "Authentication", - class_uid: 3002, - message: "Group = vpn-group, Username = user02, IP = 198.51.100.61, Session disconnected. Session Type: SSL, Duration: 0h:52m:12s, Bytes xmt: 17932, Bytes rcv: 228, Reason: User Requested", - metadata: { - event_code: "113019", - log_name: "cisco.asa", - loggers: [ - { - device: { - hostname: "asa-fw", - }, - log_format: "syslog", - }, - ], - product: { - name: "Secure Firewall ASA", - vendor_name: "Cisco", - }, - version: "1.8.0", - }, - severity: "Informational", - severity_id: 1, - src_endpoint: { - ip: 198.51.100.61, - }, - status: "Success", - status_detail: "User Requested", - status_id: 1, - time: 2025-06-18T11:38:18Z, - type_name: "Authentication: Logoff", - type_uid: 300202, - unmapped: { - facility: 20, - app_name: null, - process_id: null, - content: "%ASA-6-113019: Group = vpn-group, Username = user02, IP = 198.51.100.61, Session disconnected. Session Type: SSL, Duration: 0h:52m:12s, Bytes xmt: 17932, Bytes rcv: 228, Reason: User Requested", - context: null, - session_type: "SSL", - duration: "0h:52m:12s", - bytes_out: 17932, - bytes_in: 228, - }, - user: { - groups: [ - { - name: "vpn-group", - }, - ], - name: "user02", - }, -} -{ - action: "Denied", - action_id: 2, - activity_id: 6, - activity_name: "Traffic", - category_name: "Network Activity", - category_uid: 4, - class_name: "Network Activity", - class_uid: 4001, - connection_info: { - direction: "Inbound", - direction_id: 1, - protocol_name: "tcp", - protocol_num: 6, - }, - disposition: "Blocked", - disposition_id: 2, - dst_endpoint: { - interface_name: null, - ip: 10.1.1.22, - port: 6022, - }, - message: "Inbound TCP connection denied from 198.51.100.42/49709 to 10.1.1.22/6022 flags SYN on interface outside", - metadata: { - event_code: "106001", - log_name: "cisco.asa", - loggers: [ - { - device: { - hostname: "asa-fw", - }, - log_format: "syslog", - }, - ], - product: { - name: "Secure Firewall ASA", - vendor_name: "Cisco", - }, - profiles: [ - "security_control", - ], - version: "1.8.0", - }, - severity: "Critical", - severity_id: 5, - src_endpoint: { - interface_name: "outside", - ip: 198.51.100.42, - port: 49709, - }, - time: 2025-06-18T11:38:05Z, - type_name: "Network Activity: Traffic", - type_uid: 400106, - unmapped: { - facility: 20, - app_name: null, - process_id: null, - content: "%ASA-2-106001: Inbound TCP connection denied from 198.51.100.42/49709 to 10.1.1.22/6022 flags SYN on interface outside", - context: null, - tcp_flags: "SYN", - }, -} -{ - action: "Denied", - action_id: 2, - activity_id: 6, - activity_name: "Traffic", - category_name: "Network Activity", - category_uid: 4, - class_name: "Network Activity", - class_uid: 4001, - connection_info: { - protocol_name: "tcp", - protocol_num: 6, - }, - disposition: "Blocked", - disposition_id: 2, - dst_endpoint: { - hostname: "host.example", - interface_name: "crypto", - port: 80, - }, - message: "TCP access denied by ACL from 198.51.100.51/65396 to crypto:host.example/80", - metadata: { - event_code: "710003", - log_name: "cisco.asa", - loggers: [ - { - device: { - hostname: "asa-fw", - }, - log_format: "syslog", - }, - ], - product: { - name: "Secure Firewall ASA", - vendor_name: "Cisco", - }, - profiles: [ - "security_control", - ], - version: "1.8.0", - }, - severity: "High", - severity_id: 4, - src_endpoint: { - interface_name: null, - ip: 198.51.100.51, - port: 65396, - }, - time: 2025-06-18T11:38:14Z, - type_name: "Network Activity: Traffic", - type_uid: 400106, - unmapped: { - facility: 20, - app_name: null, - process_id: null, - content: "%ASA-3-710003: TCP access denied by ACL from 198.51.100.51/65396 to crypto:host.example/80", - context: null, - }, -} -{ - activity_id: 2, - activity_name: "Close", - category_name: "Network Activity", - category_uid: 4, - class_name: "Network Activity", - class_uid: 4001, - connection_info: { - protocol_name: "icmp", - protocol_num: 1, - }, - disposition: "Allowed", - disposition_id: 1, - dst_endpoint: { - interface_name: null, - ip: 10.1.1.32, - port: null, - }, - message: "Teardown ICMP connection for faddr 10.1.1.32/45078 gaddr 192.168.0.69/0 laddr 192.168.0.69/0 type 8 code 0 Internal-Data0/-1:RX[-1]", - metadata: { - event_code: "302021", - log_name: "cisco.asa", - loggers: [ - { - device: { - hostname: "asa-fw", - }, - log_format: "syslog", - }, - ], - product: { - name: "Secure Firewall ASA", - vendor_name: "Cisco", - }, - profiles: [ - "security_control", - ], - version: "1.8.0", - }, - severity: "Informational", - severity_id: 1, - src_endpoint: { - interface_name: null, - ip: 192.168.0.69, - port: null, - }, - time: 2025-06-18T11:38:16Z, - type_name: "Network Activity: Close", - type_uid: 400102, - unmapped: { - facility: 20, - app_name: null, - process_id: null, - content: "%ASA-6-302021: Teardown ICMP connection for faddr 10.1.1.32/45078 gaddr 192.168.0.69/0 laddr 192.168.0.69/0 type 8 code 0 Internal-Data0/-1:RX[-1]", - context: null, - faddr_id: 45078, - gaddr_id: 0, - laddr_id: 0, - }, -} -{ - activity_id: 2, - activity_name: "Close", - category_name: "Network Activity", - category_uid: 4, - class_name: "Network Activity", - class_uid: 4001, - connection_info: { - protocol_name: "tcp", - protocol_num: 6, - uid: "9", - }, - disposition: "Allowed", - disposition_id: 1, - dst_endpoint: { - interface_name: "inside", - ip: 10.1.1.2, - port: 4924, - }, - message: "Teardown TCP connection 9 for outside:192.0.2.2/80 to inside:10.1.1.2/4924 duration 0:00:03 bytes 2048 TCP FINs", - metadata: { - event_code: "302014", - log_name: "cisco.asa", - loggers: [ - { - device: { - hostname: "asa-fw", - }, - log_format: "syslog", - }, - ], - product: { - name: "Secure Firewall ASA", - vendor_name: "Cisco", - }, - profiles: [ - "security_control", - ], - version: "1.8.0", - }, - severity: "Informational", - severity_id: 1, - src_endpoint: { - interface_name: "outside", - ip: 192.0.2.2, - port: 80, - }, - status_detail: "TCP FINs", - time: 2025-06-18T11:37:50Z, - traffic: { - bytes: 2048, - }, - type_name: "Network Activity: Close", - type_uid: 400102, - unmapped: { - facility: 20, - app_name: null, - process_id: null, - content: "%ASA-6-302014: Teardown TCP connection 9 for outside:192.0.2.2/80 to inside:10.1.1.2/4924 duration 0:00:03 bytes 2048 TCP FINs", - context: null, - duration: "0:00:03", - }, -} -{ - activity_id: 2, - activity_name: "Close", - category_name: "Network Activity", - category_uid: 4, - class_name: "Network Activity", - class_uid: 4001, - connection_info: { - protocol_name: "udp", - protocol_num: 17, - uid: "1005", - }, - disposition: "Allowed", - disposition_id: 1, - dst_endpoint: { - interface_name: "inside", - ip: 10.1.1.3, - port: 51000, - }, - message: "Teardown UDP connection 1005 for outside:198.51.100.5/53 to inside:10.1.1.3/51000 duration 0:00:05 bytes 312", - metadata: { - event_code: "302016", - log_name: "cisco.asa", - loggers: [ - { - device: { - hostname: "asa-fw", - }, - log_format: "syslog", - }, - ], - product: { - name: "Secure Firewall ASA", - vendor_name: "Cisco", - }, - profiles: [ - "security_control", - ], - version: "1.8.0", - }, - severity: "Informational", - severity_id: 1, - src_endpoint: { - interface_name: "outside", - ip: 198.51.100.5, - port: 53, - }, - time: 2025-06-18T11:37:55Z, - traffic: { - bytes: 312, - }, - type_name: "Network Activity: Close", - type_uid: 400102, - unmapped: { - facility: 20, - app_name: null, - process_id: null, - content: "%ASA-6-302016: Teardown UDP connection 1005 for outside:198.51.100.5/53 to inside:10.1.1.3/51000 duration 0:00:05 bytes 312", - context: null, - duration: "0:00:05", - reason: null, }, } { @@ -1410,44 +811,6 @@ context: null, }, } -{ - activity_id: 0, - activity_name: "Unknown", - category_name: "Uncategorized", - category_uid: 0, - class_name: "Base Event", - class_uid: 0, - message: "User 'enable_15' executed the 'configure terminal' command.", - metadata: { - event_code: "111008", - log_name: "cisco.asa", - loggers: [ - { - device: { - hostname: "asa-fw", - }, - log_format: "syslog", - }, - ], - product: { - name: "Secure Firewall ASA", - vendor_name: "Cisco", - }, - version: "1.8.0", - }, - severity: "Low", - severity_id: 2, - time: 2025-06-18T11:38:10Z, - type_name: "Base Event: Unknown", - type_uid: 0, - unmapped: { - facility: 20, - app_name: null, - process_id: null, - content: "%ASA-5-111008: User 'enable_15' executed the 'configure terminal' command.", - context: null, - }, -} { action: "Denied", action_id: 2, @@ -1573,99 +936,3 @@ context: null, }, } -{ - activity_id: 2, - activity_name: "Logoff", - category_name: "Identity & Access Management", - category_uid: 3, - class_name: "Authentication", - class_uid: 3002, - message: "user-identity: Delete IP-User mapping 10.1.1.40 - LOCAL\\user03 Succeeded - VPN user logout", - metadata: { - event_code: "746013", - log_name: "cisco.asa", - loggers: [ - { - device: { - hostname: "asa-fw", - }, - log_format: "syslog", - }, - ], - product: { - name: "Secure Firewall ASA", - vendor_name: "Cisco", - }, - version: "1.8.0", - }, - severity: "Low", - severity_id: 2, - src_endpoint: { - ip: 10.1.1.40, - }, - status: "Success", - status_detail: "VPN user logout", - status_id: 1, - time: 2025-06-18T11:38:19Z, - type_name: "Authentication: Logoff", - type_uid: 300202, - unmapped: { - facility: 20, - app_name: null, - process_id: null, - content: "%ASA-5-746013: user-identity: Delete IP-User mapping 10.1.1.40 - LOCAL\\user03 Succeeded - VPN user logout", - context: null, - }, - user: { - domain: "LOCAL", - name: "user03", - }, -} -{ - activity_id: 2, - activity_name: "Logoff", - category_name: "Identity & Access Management", - category_uid: 3, - class_name: "Authentication", - class_uid: 3002, - message: "user-identity: Delete IP-User mapping 10.1.1.41 - LOCAL\\user04 Failed - PIP notification", - metadata: { - event_code: "746013", - log_name: "cisco.asa", - loggers: [ - { - device: { - hostname: "asa-fw", - }, - log_format: "syslog", - }, - ], - product: { - name: "Secure Firewall ASA", - vendor_name: "Cisco", - }, - version: "1.8.0", - }, - severity: "Low", - severity_id: 2, - src_endpoint: { - ip: 10.1.1.41, - }, - status: "Failure", - status_detail: "PIP notification", - status_id: 2, - time: 2025-06-18T11:38:20Z, - type_name: "Authentication: Logoff", - type_uid: 300202, - unmapped: { - facility: 20, - app_name: null, - process_id: null, - content: "%ASA-5-746013: user-identity: Delete IP-User mapping 10.1.1.41 - LOCAL\\user04 Failed - PIP notification", - context: null, - }, - user: { - domain: "LOCAL", - name: "user04", - }, -} diff --git a/cisco/tests/asa/ocsf/authentication.tql b/cisco/tests/asa/ocsf/authentication.tql new file mode 100644 index 00000000..06f0ddc9 --- /dev/null +++ b/cisco/tests/asa/ocsf/authentication.tql @@ -0,0 +1,9 @@ +from_file f"{env("TENZIR_INPUTS")}/authentication.txt" { + read_syslog +} +cisco::asa::parse +cisco::asa::ocsf::map +ocsf::derive +ocsf::cast +drop metadata.processed_time +sort message diff --git a/cisco/tests/asa/ocsf/authentication.txt b/cisco/tests/asa/ocsf/authentication.txt new file mode 100644 index 00000000..be9f0016 --- /dev/null +++ b/cisco/tests/asa/ocsf/authentication.txt @@ -0,0 +1,205 @@ +{ + activity_id: 1, + activity_name: "Logon", + category_name: "Identity & Access Management", + category_uid: 3, + class_name: "Authentication", + class_uid: 3002, + message: "Group User IP <198.51.100.60> IPv4 Address <10.8.0.5> IPv6 address <::> assigned to session", + metadata: { + event_code: "722051", + log_name: "cisco.asa", + loggers: [ + { + device: { + hostname: "asa-fw", + }, + log_format: "syslog", + }, + ], + product: { + name: "Secure Firewall ASA", + vendor_name: "Cisco", + }, + version: "1.8.0", + }, + severity: "Informational", + severity_id: 1, + src_endpoint: { + ip: 198.51.100.60, + }, + status: "Success", + status_id: 1, + time: 2025-06-18T11:38:17Z, + type_name: "Authentication: Logon", + type_uid: 300201, + unmapped: { + facility: 20, + app_name: null, + process_id: null, + content: "%ASA-6-722051: Group User IP <198.51.100.60> IPv4 Address <10.8.0.5> IPv6 address <::> assigned to session", + context: null, + assigned_ipv4: 10.8.0.5, + assigned_ipv6: ::, + }, + user: { + groups: [ + { + name: "vpn-group", + }, + ], + name: "user01", + }, +} +{ + activity_id: 2, + activity_name: "Logoff", + category_name: "Identity & Access Management", + category_uid: 3, + class_name: "Authentication", + class_uid: 3002, + message: "Group = vpn-group, Username = user02, IP = 198.51.100.61, Session disconnected. Session Type: SSL, Duration: 0h:52m:12s, Bytes xmt: 17932, Bytes rcv: 228, Reason: User Requested", + metadata: { + event_code: "113019", + log_name: "cisco.asa", + loggers: [ + { + device: { + hostname: "asa-fw", + }, + log_format: "syslog", + }, + ], + product: { + name: "Secure Firewall ASA", + vendor_name: "Cisco", + }, + version: "1.8.0", + }, + severity: "Informational", + severity_id: 1, + src_endpoint: { + ip: 198.51.100.61, + }, + status: "Success", + status_detail: "User Requested", + status_id: 1, + time: 2025-06-18T11:38:18Z, + type_name: "Authentication: Logoff", + type_uid: 300202, + unmapped: { + facility: 20, + app_name: null, + process_id: null, + content: "%ASA-6-113019: Group = vpn-group, Username = user02, IP = 198.51.100.61, Session disconnected. Session Type: SSL, Duration: 0h:52m:12s, Bytes xmt: 17932, Bytes rcv: 228, Reason: User Requested", + context: null, + session_type: "SSL", + duration: "0h:52m:12s", + bytes_out: 17932, + bytes_in: 228, + }, + user: { + groups: [ + { + name: "vpn-group", + }, + ], + name: "user02", + }, +} +{ + activity_id: 2, + activity_name: "Logoff", + category_name: "Identity & Access Management", + category_uid: 3, + class_name: "Authentication", + class_uid: 3002, + message: "user-identity: Delete IP-User mapping 10.1.1.40 - LOCAL\\user03 Succeeded - VPN user logout", + metadata: { + event_code: "746013", + log_name: "cisco.asa", + loggers: [ + { + device: { + hostname: "asa-fw", + }, + log_format: "syslog", + }, + ], + product: { + name: "Secure Firewall ASA", + vendor_name: "Cisco", + }, + version: "1.8.0", + }, + severity: "Low", + severity_id: 2, + src_endpoint: { + ip: 10.1.1.40, + }, + status: "Success", + status_detail: "VPN user logout", + status_id: 1, + time: 2025-06-18T11:38:19Z, + type_name: "Authentication: Logoff", + type_uid: 300202, + unmapped: { + facility: 20, + app_name: null, + process_id: null, + content: "%ASA-5-746013: user-identity: Delete IP-User mapping 10.1.1.40 - LOCAL\\user03 Succeeded - VPN user logout", + context: null, + }, + user: { + domain: "LOCAL", + name: "user03", + }, +} +{ + activity_id: 2, + activity_name: "Logoff", + category_name: "Identity & Access Management", + category_uid: 3, + class_name: "Authentication", + class_uid: 3002, + message: "user-identity: Delete IP-User mapping 10.1.1.41 - LOCAL\\user04 Failed - PIP notification", + metadata: { + event_code: "746013", + log_name: "cisco.asa", + loggers: [ + { + device: { + hostname: "asa-fw", + }, + log_format: "syslog", + }, + ], + product: { + name: "Secure Firewall ASA", + vendor_name: "Cisco", + }, + version: "1.8.0", + }, + severity: "Low", + severity_id: 2, + src_endpoint: { + ip: 10.1.1.41, + }, + status: "Failure", + status_detail: "PIP notification", + status_id: 2, + time: 2025-06-18T11:38:20Z, + type_name: "Authentication: Logoff", + type_uid: 300202, + unmapped: { + facility: 20, + app_name: null, + process_id: null, + content: "%ASA-5-746013: user-identity: Delete IP-User mapping 10.1.1.41 - LOCAL\\user04 Failed - PIP notification", + context: null, + }, + user: { + domain: "LOCAL", + name: "user04", + }, +} diff --git a/cisco/tests/asa/ocsf/map.tql b/cisco/tests/asa/ocsf/base.tql similarity index 72% rename from cisco/tests/asa/ocsf/map.tql rename to cisco/tests/asa/ocsf/base.tql index f8032691..45627114 100644 --- a/cisco/tests/asa/ocsf/map.tql +++ b/cisco/tests/asa/ocsf/base.tql @@ -1,4 +1,4 @@ -from_file f"{env("TENZIR_INPUTS")}/*.txt" { +from_file f"{env("TENZIR_INPUTS")}/base.txt" { read_syslog } cisco::asa::parse diff --git a/cisco/tests/asa/ocsf/base.txt b/cisco/tests/asa/ocsf/base.txt new file mode 100644 index 00000000..200e8687 --- /dev/null +++ b/cisco/tests/asa/ocsf/base.txt @@ -0,0 +1,76 @@ +{ + activity_id: 0, + activity_name: "Unknown", + category_name: "Uncategorized", + category_uid: 0, + class_name: "Base Event", + class_uid: 0, + message: "Local: 198.51.100.1:500 Remote: 203.0.113.9:4500 Username: user1 Negotiation aborted due to ERROR: error", + metadata: { + event_code: "750003", + log_name: "cisco.asa", + loggers: [ + { + device: { + hostname: "asa-fw", + }, + log_format: "syslog", + }, + ], + product: { + name: "Secure Firewall ASA", + vendor_name: "Cisco", + }, + version: "1.8.0", + }, + severity: "Medium", + severity_id: 3, + time: 2025-06-18T11:40:00Z, + type_name: "Base Event: Unknown", + type_uid: 0, + unmapped: { + facility: 20, + app_name: null, + process_id: null, + content: "%ASA-4-750003: Local: 198.51.100.1:500 Remote: 203.0.113.9:4500 Username: user1 Negotiation aborted due to ERROR: error", + context: null, + }, +} +{ + activity_id: 0, + activity_name: "Unknown", + category_name: "Uncategorized", + category_uid: 0, + class_name: "Base Event", + class_uid: 0, + message: "User 'enable_15' executed the 'configure terminal' command.", + metadata: { + event_code: "111008", + log_name: "cisco.asa", + loggers: [ + { + device: { + hostname: "asa-fw", + }, + log_format: "syslog", + }, + ], + product: { + name: "Secure Firewall ASA", + vendor_name: "Cisco", + }, + version: "1.8.0", + }, + severity: "Low", + severity_id: 2, + time: 2025-06-18T11:38:10Z, + type_name: "Base Event: Unknown", + type_uid: 0, + unmapped: { + facility: 20, + app_name: null, + process_id: null, + content: "%ASA-5-111008: User 'enable_15' executed the 'configure terminal' command.", + context: null, + }, +} diff --git a/cisco/tests/asa/ocsf/built.tql b/cisco/tests/asa/ocsf/built.tql new file mode 100644 index 00000000..ce60827f --- /dev/null +++ b/cisco/tests/asa/ocsf/built.tql @@ -0,0 +1,9 @@ +from_file f"{env("TENZIR_INPUTS")}/built.txt" { + read_syslog +} +cisco::asa::parse +cisco::asa::ocsf::map +ocsf::derive +ocsf::cast +drop metadata.processed_time +sort message diff --git a/cisco/tests/asa/ocsf/built.txt b/cisco/tests/asa/ocsf/built.txt new file mode 100644 index 00000000..d352dc40 --- /dev/null +++ b/cisco/tests/asa/ocsf/built.txt @@ -0,0 +1,252 @@ +{ + activity_id: 1, + activity_name: "Open", + category_name: "Network Activity", + category_uid: 4, + class_name: "Network Activity", + class_uid: 4001, + connection_info: { + direction: "Inbound", + direction_id: 1, + protocol_name: "tcp", + protocol_num: 6, + uid: "3332836331", + }, + disposition: "Allowed", + disposition_id: 1, + dst_endpoint: { + hostname: "host.example", + interface_name: "umbrella", + port: 443, + proxy_endpoint: { + hostname: "UMBRELLA-DOMAIN-BLOCK-HIT", + port: 443, + }, + }, + message: "Built inbound TCP connection 3332836331 for inside:10.1.1.9/50640 (198.51.100.20/50640) to umbrella:host.example/443 (UMBRELLA-DOMAIN-BLOCK-HIT/443) 0 24", + metadata: { + event_code: "302013", + log_name: "cisco.asa", + loggers: [ + { + device: { + hostname: "asa-fw", + }, + log_format: "syslog", + }, + ], + product: { + name: "Secure Firewall ASA", + vendor_name: "Cisco", + }, + profiles: [ + "security_control", + ], + version: "1.8.0", + }, + severity: "Informational", + severity_id: 1, + src_endpoint: { + interface_name: "inside", + ip: 10.1.1.9, + port: 50640, + proxy_endpoint: { + ip: 198.51.100.20, + port: 50640, + }, + }, + time: 2025-06-18T11:37:48Z, + type_name: "Network Activity: Open", + type_uid: 400101, + unmapped: { + facility: 20, + app_name: null, + process_id: null, + content: "%ASA-6-302013: Built inbound TCP connection 3332836331 for inside:10.1.1.9/50640 (198.51.100.20/50640) to umbrella:host.example/443 (UMBRELLA-DOMAIN-BLOCK-HIT/443) 0 24", + context: null, + }, +} +{ + activity_id: 1, + activity_name: "Open", + category_name: "Network Activity", + category_uid: 4, + class_name: "Network Activity", + class_uid: 4001, + connection_info: { + direction: "Inbound", + direction_id: 1, + protocol_name: "udp", + protocol_num: 17, + uid: "1005", + }, + disposition: "Allowed", + disposition_id: 1, + dst_endpoint: { + interface_name: "inside", + ip: 10.1.1.3, + port: 51000, + }, + message: "Built inbound UDP connection 1005 for outside:198.51.100.5/53 (198.51.100.5/53) to inside:10.1.1.3/51000 (10.1.1.3/51000)", + metadata: { + event_code: "302015", + log_name: "cisco.asa", + loggers: [ + { + device: { + hostname: "asa-fw", + }, + log_format: "syslog", + }, + ], + product: { + name: "Secure Firewall ASA", + vendor_name: "Cisco", + }, + profiles: [ + "security_control", + ], + version: "1.8.0", + }, + severity: "Informational", + severity_id: 1, + src_endpoint: { + interface_name: "outside", + ip: 198.51.100.5, + port: 53, + }, + time: 2025-06-18T11:37:48Z, + type_name: "Network Activity: Open", + type_uid: 400101, + unmapped: { + facility: 20, + app_name: null, + process_id: null, + content: "%ASA-6-302015: Built inbound UDP connection 1005 for outside:198.51.100.5/53 (198.51.100.5/53) to inside:10.1.1.3/51000 (10.1.1.3/51000)", + context: null, + }, +} +{ + activity_id: 1, + activity_name: "Open", + category_name: "Network Activity", + category_uid: 4, + class_name: "Network Activity", + class_uid: 4001, + connection_info: { + direction: "Outbound", + direction_id: 2, + protocol_name: "tcp", + protocol_num: 6, + uid: "100", + }, + disposition: "Allowed", + disposition_id: 1, + dst_endpoint: { + interface_name: "inside", + ip: 10.1.1.40, + port: 52000, + }, + message: "Built outbound TCP connection 100 for outside:198.51.100.60/443 (198.51.100.60/443) to inside:10.1.1.40/52000 (10.1.1.40/52000)", + metadata: { + event_code: "302013", + log_name: "cisco.asa", + loggers: [ + { + device: { + hostname: "asa", + }, + log_format: "syslog", + }, + ], + product: { + name: "Secure Firewall ASA", + vendor_name: "Cisco", + }, + profiles: [ + "security_control", + ], + version: "1.8.0", + }, + severity: "Informational", + severity_id: 1, + src_endpoint: { + interface_name: "outside", + ip: 198.51.100.60, + port: 443, + }, + time: 2018-06-27T12:17:46Z, + type_name: "Network Activity: Open", + type_uid: 400101, + unmapped: { + facility: 20, + app_name: null, + process_id: null, + content: "%ASA-6-302013: Built outbound TCP connection 100 for outside:198.51.100.60/443 (198.51.100.60/443) to inside:10.1.1.40/52000 (10.1.1.40/52000)", + context: null, + }, +} +{ + activity_id: 1, + activity_name: "Open", + category_name: "Network Activity", + category_uid: 4, + class_name: "Network Activity", + class_uid: 4001, + connection_info: { + direction: "Outbound", + direction_id: 2, + protocol_name: "tcp", + protocol_num: 6, + uid: "9", + }, + disposition: "Allowed", + disposition_id: 1, + dst_endpoint: { + interface_name: "inside", + ip: 10.1.1.2, + port: 4924, + proxy_endpoint: { + ip: 203.0.113.10, + port: 4924, + }, + }, + message: "Built outbound TCP connection 9 for outside:192.0.2.2/80 (192.0.2.2/80) to inside:10.1.1.2/4924 (203.0.113.10/4924)", + metadata: { + event_code: "302013", + log_name: "cisco.asa", + loggers: [ + { + device: { + hostname: "asa-fw", + }, + log_format: "syslog", + }, + ], + product: { + name: "Secure Firewall ASA", + vendor_name: "Cisco", + }, + profiles: [ + "security_control", + ], + version: "1.8.0", + }, + severity: "Informational", + severity_id: 1, + src_endpoint: { + interface_name: "outside", + ip: 192.0.2.2, + port: 80, + }, + time: 2025-06-18T11:37:47Z, + type_name: "Network Activity: Open", + type_uid: 400101, + unmapped: { + facility: 20, + app_name: null, + process_id: null, + content: "%ASA-6-302013: Built outbound TCP connection 9 for outside:192.0.2.2/80 (192.0.2.2/80) to inside:10.1.1.2/4924 (203.0.113.10/4924)", + context: null, + }, +} diff --git a/cisco/tests/asa/ocsf/inputs/deny_family.txt b/cisco/tests/asa/ocsf/inputs/access_control.txt similarity index 51% rename from cisco/tests/asa/ocsf/inputs/deny_family.txt rename to cisco/tests/asa/ocsf/inputs/access_control.txt index c261391b..25d1d650 100644 --- a/cisco/tests/asa/ocsf/inputs/deny_family.txt +++ b/cisco/tests/asa/ocsf/inputs/access_control.txt @@ -1,3 +1,8 @@ +<165>Jun 18 2025 11:38:00 asa-fw : %ASA-4-106023: Deny tcp src outside:198.51.100.7/4444 dst inside:10.1.1.5/3389 by access-group "outside_access_in" [0x0, 0x0] +<165>Jun 18 2025 11:38:01 asa-fw : %ASA-4-106023: Deny icmp src outside:198.51.100.8/0 dst inside:10.1.1.6/0 [type 8, code 0] by access-group "outside_access_in" [0x0, 0x0] +<165>Jun 18 2025 11:38:02 asa-fw : %ASA-4-106023: Deny protocol 47 src outside:198.51.100.9 dst inside:10.1.1.7 by access-group "outside_access_in" [0x0, 0x0] +<165>Jun 18 2025 11:38:03 asa-fw : %ASA-4-106023: Deny udp src dmz:fw-host/514 dst outside:10.1.1.8/514 by access-group "dmz_access" [0x0, 0x0] +<165>Jun 18 2025 11:38:04 asa-fw : %ASA-4-106023: Deny icmp src outside:198.51.100.30 dst inside:10.1.1.9 (type 8, code 0) by access-group "outside_access_in" [0x0, 0x0] <162>Jun 18 2025 11:38:05 asa-fw : %ASA-2-106001: Inbound TCP connection denied from 198.51.100.42/49709 to 10.1.1.22/6022 flags SYN on interface outside <162>Jun 18 2025 11:38:06 asa-fw : %ASA-2-106006: Deny inbound UDP from 198.51.100.43/137 to 10.1.1.23/137 on interface outside <163>Jun 18 2025 11:38:07 asa-fw : %ASA-3-106010: Deny inbound protocol 47 src outside:198.51.100.41 dst outside:10.1.1.21 @@ -6,3 +11,5 @@ <164>Jun 18 2025 11:38:10 asa-fw : %ASA-4-106100: access-list acl_in denied 47 outside/198.51.100.44(0) -> dmz/10.1.1.24(0) hit-cnt 1 first hit [0x0, 0x0] <163>Jun 18 2025 11:38:11 asa-fw : %ASA-3-313004: Denied ICMP type=0, from laddr 10.1.1.26 on interface inside to 10.1.1.27: no matching session <163>Jun 18 2025 11:38:12 asa-fw : %ASA-3-313008: Denied IPv6-ICMP type=136, code=0 from fe80::21a:2bff:fe3c:4d5e on interface inside +<163>Jun 18 2025 11:38:14 asa-fw : %ASA-3-710003: TCP access denied by ACL from 198.51.100.51/65396 to crypto:host.example/80 +<163>Jun 18 2025 11:38:15 asa-fw : %ASA-3-710005: UDP request discarded from 198.51.100.52/60389 to outside:10.1.1.31/44861 diff --git a/cisco/tests/asa/ocsf/inputs/vpn.txt b/cisco/tests/asa/ocsf/inputs/authentication.txt similarity index 100% rename from cisco/tests/asa/ocsf/inputs/vpn.txt rename to cisco/tests/asa/ocsf/inputs/authentication.txt diff --git a/cisco/tests/asa/ocsf/inputs/base.txt b/cisco/tests/asa/ocsf/inputs/base.txt new file mode 100644 index 00000000..e6ab25f8 --- /dev/null +++ b/cisco/tests/asa/ocsf/inputs/base.txt @@ -0,0 +1,2 @@ +<165>Jun 18 2025 11:38:10 asa-fw : %ASA-5-111008: User 'enable_15' executed the 'configure terminal' command. +<164>Jun 18 2025 11:40:00 asa-fw : %ASA-4-750003: Local: 198.51.100.1:500 Remote: 203.0.113.9:4500 Username: user1 Negotiation aborted due to ERROR: error diff --git a/cisco/tests/asa/ocsf/inputs/built.txt b/cisco/tests/asa/ocsf/inputs/built.txt index d8b39cf0..89044bf0 100644 --- a/cisco/tests/asa/ocsf/inputs/built.txt +++ b/cisco/tests/asa/ocsf/inputs/built.txt @@ -1,3 +1,4 @@ <166>Jun 18 2025 11:37:47 asa-fw : %ASA-6-302013: Built outbound TCP connection 9 for outside:192.0.2.2/80 (192.0.2.2/80) to inside:10.1.1.2/4924 (203.0.113.10/4924) <166>Jun 18 2025 11:37:48 asa-fw : %ASA-6-302015: Built inbound UDP connection 1005 for outside:198.51.100.5/53 (198.51.100.5/53) to inside:10.1.1.3/51000 (10.1.1.3/51000) <166>2018-06-27T12:17:46Z asa : %ASA-6-302013: Built outbound TCP connection 100 for outside:198.51.100.60/443 (198.51.100.60/443) to inside:10.1.1.40/52000 (10.1.1.40/52000) +<166>Jun 18 2025 11:37:48 asa-fw : %ASA-6-302013: Built inbound TCP connection 3332836331 for inside:10.1.1.9/50640 (198.51.100.20/50640) to umbrella:host.example/443 (UMBRELLA-DOMAIN-BLOCK-HIT/443) 0 24 diff --git a/cisco/tests/asa/ocsf/inputs/built_sig.txt b/cisco/tests/asa/ocsf/inputs/built_sig.txt deleted file mode 100644 index e06766fc..00000000 --- a/cisco/tests/asa/ocsf/inputs/built_sig.txt +++ /dev/null @@ -1 +0,0 @@ -<166>Jun 18 2025 11:37:48 asa-fw : %ASA-6-302013: Built inbound TCP connection 3332836331 for inside:10.1.1.9/50640 (198.51.100.20/50640) to umbrella:host.example/443 (UMBRELLA-DOMAIN-BLOCK-HIT/443) 0 24 diff --git a/cisco/tests/asa/ocsf/inputs/deny.txt b/cisco/tests/asa/ocsf/inputs/deny.txt deleted file mode 100644 index 795bd656..00000000 --- a/cisco/tests/asa/ocsf/inputs/deny.txt +++ /dev/null @@ -1,2 +0,0 @@ -<165>Jun 18 2025 11:38:00 asa-fw : %ASA-4-106023: Deny tcp src outside:198.51.100.7/4444 dst inside:10.1.1.5/3389 by access-group "outside_access_in" [0x0, 0x0] -<165>Jun 18 2025 11:38:01 asa-fw : %ASA-4-106023: Deny icmp src outside:198.51.100.8/0 dst inside:10.1.1.6/0 [type 8, code 0] by access-group "outside_access_in" [0x0, 0x0] diff --git a/cisco/tests/asa/ocsf/inputs/deny_variants.txt b/cisco/tests/asa/ocsf/inputs/deny_variants.txt deleted file mode 100644 index 60c101fb..00000000 --- a/cisco/tests/asa/ocsf/inputs/deny_variants.txt +++ /dev/null @@ -1,3 +0,0 @@ -<165>Jun 18 2025 11:38:02 asa-fw : %ASA-4-106023: Deny protocol 47 src outside:198.51.100.9 dst inside:10.1.1.7 by access-group "outside_access_in" [0x0, 0x0] -<165>Jun 18 2025 11:38:03 asa-fw : %ASA-4-106023: Deny udp src dmz:fw-host/514 dst outside:10.1.1.8/514 by access-group "dmz_access" [0x0, 0x0] -<165>Jun 18 2025 11:38:04 asa-fw : %ASA-4-106023: Deny icmp src outside:198.51.100.30 dst inside:10.1.1.9 (type 8, code 0) by access-group "outside_access_in" [0x0, 0x0] diff --git a/cisco/tests/asa/ocsf/inputs/easy_wins.txt b/cisco/tests/asa/ocsf/inputs/easy_wins.txt deleted file mode 100644 index 123ec122..00000000 --- a/cisco/tests/asa/ocsf/inputs/easy_wins.txt +++ /dev/null @@ -1,4 +0,0 @@ -<164>Jun 18 2025 11:38:13 asa-fw : %ASA-4-419002: Duplicate TCP SYN from inside:198.51.100.50/22 to dmz:10.1.1.30/443 with different initial sequence number -<163>Jun 18 2025 11:38:14 asa-fw : %ASA-3-710003: TCP access denied by ACL from 198.51.100.51/65396 to crypto:host.example/80 -<163>Jun 18 2025 11:38:15 asa-fw : %ASA-3-710005: UDP request discarded from 198.51.100.52/60389 to outside:10.1.1.31/44861 -<166>Jun 18 2025 11:38:16 asa-fw : %ASA-6-302021: Teardown ICMP connection for faddr 10.1.1.32/45078 gaddr 192.168.0.69/0 laddr 192.168.0.69/0 type 8 code 0 Internal-Data0/-1:RX[-1] diff --git a/cisco/tests/asa/ocsf/inputs/network.txt b/cisco/tests/asa/ocsf/inputs/network.txt new file mode 100644 index 00000000..1c22c4b5 --- /dev/null +++ b/cisco/tests/asa/ocsf/inputs/network.txt @@ -0,0 +1 @@ +<164>Jun 18 2025 11:38:13 asa-fw : %ASA-4-419002: Duplicate TCP SYN from inside:198.51.100.50/22 to dmz:10.1.1.30/443 with different initial sequence number diff --git a/cisco/tests/asa/ocsf/inputs/other.txt b/cisco/tests/asa/ocsf/inputs/other.txt deleted file mode 100644 index d6f11eae..00000000 --- a/cisco/tests/asa/ocsf/inputs/other.txt +++ /dev/null @@ -1 +0,0 @@ -<165>Jun 18 2025 11:38:10 asa-fw : %ASA-5-111008: User 'enable_15' executed the 'configure terminal' command. diff --git a/cisco/tests/asa/ocsf/inputs/teardown.txt b/cisco/tests/asa/ocsf/inputs/teardown.txt index 25434945..1ca99947 100644 --- a/cisco/tests/asa/ocsf/inputs/teardown.txt +++ b/cisco/tests/asa/ocsf/inputs/teardown.txt @@ -1,2 +1,3 @@ <166>Jun 18 2025 11:37:50 asa-fw : %ASA-6-302014: Teardown TCP connection 9 for outside:192.0.2.2/80 to inside:10.1.1.2/4924 duration 0:00:03 bytes 2048 TCP FINs <166>Jun 18 2025 11:37:55 asa-fw : %ASA-6-302016: Teardown UDP connection 1005 for outside:198.51.100.5/53 to inside:10.1.1.3/51000 duration 0:00:05 bytes 312 +<166>Jun 18 2025 11:38:16 asa-fw : %ASA-6-302021: Teardown ICMP connection for faddr 10.1.1.32/45078 gaddr 192.168.0.69/0 laddr 192.168.0.69/0 type 8 code 0 Internal-Data0/-1:RX[-1] diff --git a/cisco/tests/asa/ocsf/network.tql b/cisco/tests/asa/ocsf/network.tql new file mode 100644 index 00000000..27d27b67 --- /dev/null +++ b/cisco/tests/asa/ocsf/network.tql @@ -0,0 +1,9 @@ +from_file f"{env("TENZIR_INPUTS")}/network.txt" { + read_syslog +} +cisco::asa::parse +cisco::asa::ocsf::map +ocsf::derive +ocsf::cast +drop metadata.processed_time +sort message diff --git a/cisco/tests/asa/ocsf/network.txt b/cisco/tests/asa/ocsf/network.txt new file mode 100644 index 00000000..c9a52b73 --- /dev/null +++ b/cisco/tests/asa/ocsf/network.txt @@ -0,0 +1,52 @@ +{ + activity_id: 6, + activity_name: "Traffic", + category_name: "Network Activity", + category_uid: 4, + class_name: "Network Activity", + class_uid: 4001, + connection_info: { + protocol_name: "tcp", + protocol_num: 6, + }, + dst_endpoint: { + interface_name: "dmz", + ip: 10.1.1.30, + port: 443, + }, + message: "Duplicate TCP SYN from inside:198.51.100.50/22 to dmz:10.1.1.30/443 with different initial sequence number", + metadata: { + event_code: "419002", + log_name: "cisco.asa", + loggers: [ + { + device: { + hostname: "asa-fw", + }, + log_format: "syslog", + }, + ], + product: { + name: "Secure Firewall ASA", + vendor_name: "Cisco", + }, + version: "1.8.0", + }, + severity: "Medium", + severity_id: 3, + src_endpoint: { + interface_name: "inside", + ip: 198.51.100.50, + port: 22, + }, + time: 2025-06-18T11:38:13Z, + type_name: "Network Activity: Traffic", + type_uid: 400106, + unmapped: { + facility: 20, + app_name: null, + process_id: null, + content: "%ASA-4-419002: Duplicate TCP SYN from inside:198.51.100.50/22 to dmz:10.1.1.30/443 with different initial sequence number", + context: null, + }, +} diff --git a/cisco/tests/asa/ocsf/teardown.tql b/cisco/tests/asa/ocsf/teardown.tql new file mode 100644 index 00000000..aa1f9d96 --- /dev/null +++ b/cisco/tests/asa/ocsf/teardown.tql @@ -0,0 +1,9 @@ +from_file f"{env("TENZIR_INPUTS")}/teardown.txt" { + read_syslog +} +cisco::asa::parse +cisco::asa::ocsf::map +ocsf::derive +ocsf::cast +drop metadata.processed_time +sort message diff --git a/cisco/tests/asa/ocsf/teardown.txt b/cisco/tests/asa/ocsf/teardown.txt new file mode 100644 index 00000000..2d1f34a2 --- /dev/null +++ b/cisco/tests/asa/ocsf/teardown.txt @@ -0,0 +1,186 @@ +{ + activity_id: 2, + activity_name: "Close", + category_name: "Network Activity", + category_uid: 4, + class_name: "Network Activity", + class_uid: 4001, + connection_info: { + protocol_name: "icmp", + protocol_num: 1, + }, + disposition: "Allowed", + disposition_id: 1, + dst_endpoint: { + interface_name: null, + ip: 10.1.1.32, + port: null, + }, + message: "Teardown ICMP connection for faddr 10.1.1.32/45078 gaddr 192.168.0.69/0 laddr 192.168.0.69/0 type 8 code 0 Internal-Data0/-1:RX[-1]", + metadata: { + event_code: "302021", + log_name: "cisco.asa", + loggers: [ + { + device: { + hostname: "asa-fw", + }, + log_format: "syslog", + }, + ], + product: { + name: "Secure Firewall ASA", + vendor_name: "Cisco", + }, + profiles: [ + "security_control", + ], + version: "1.8.0", + }, + severity: "Informational", + severity_id: 1, + src_endpoint: { + interface_name: null, + ip: 192.168.0.69, + port: null, + }, + time: 2025-06-18T11:38:16Z, + type_name: "Network Activity: Close", + type_uid: 400102, + unmapped: { + facility: 20, + app_name: null, + process_id: null, + content: "%ASA-6-302021: Teardown ICMP connection for faddr 10.1.1.32/45078 gaddr 192.168.0.69/0 laddr 192.168.0.69/0 type 8 code 0 Internal-Data0/-1:RX[-1]", + context: null, + faddr_id: 45078, + gaddr_id: 0, + laddr_id: 0, + }, +} +{ + activity_id: 2, + activity_name: "Close", + category_name: "Network Activity", + category_uid: 4, + class_name: "Network Activity", + class_uid: 4001, + connection_info: { + protocol_name: "tcp", + protocol_num: 6, + uid: "9", + }, + disposition: "Allowed", + disposition_id: 1, + dst_endpoint: { + interface_name: "inside", + ip: 10.1.1.2, + port: 4924, + }, + message: "Teardown TCP connection 9 for outside:192.0.2.2/80 to inside:10.1.1.2/4924 duration 0:00:03 bytes 2048 TCP FINs", + metadata: { + event_code: "302014", + log_name: "cisco.asa", + loggers: [ + { + device: { + hostname: "asa-fw", + }, + log_format: "syslog", + }, + ], + product: { + name: "Secure Firewall ASA", + vendor_name: "Cisco", + }, + profiles: [ + "security_control", + ], + version: "1.8.0", + }, + severity: "Informational", + severity_id: 1, + src_endpoint: { + interface_name: "outside", + ip: 192.0.2.2, + port: 80, + }, + status_detail: "TCP FINs", + time: 2025-06-18T11:37:50Z, + traffic: { + bytes: 2048, + }, + type_name: "Network Activity: Close", + type_uid: 400102, + unmapped: { + facility: 20, + app_name: null, + process_id: null, + content: "%ASA-6-302014: Teardown TCP connection 9 for outside:192.0.2.2/80 to inside:10.1.1.2/4924 duration 0:00:03 bytes 2048 TCP FINs", + context: null, + duration: "0:00:03", + }, +} +{ + activity_id: 2, + activity_name: "Close", + category_name: "Network Activity", + category_uid: 4, + class_name: "Network Activity", + class_uid: 4001, + connection_info: { + protocol_name: "udp", + protocol_num: 17, + uid: "1005", + }, + disposition: "Allowed", + disposition_id: 1, + dst_endpoint: { + interface_name: "inside", + ip: 10.1.1.3, + port: 51000, + }, + message: "Teardown UDP connection 1005 for outside:198.51.100.5/53 to inside:10.1.1.3/51000 duration 0:00:05 bytes 312", + metadata: { + event_code: "302016", + log_name: "cisco.asa", + loggers: [ + { + device: { + hostname: "asa-fw", + }, + log_format: "syslog", + }, + ], + product: { + name: "Secure Firewall ASA", + vendor_name: "Cisco", + }, + profiles: [ + "security_control", + ], + version: "1.8.0", + }, + severity: "Informational", + severity_id: 1, + src_endpoint: { + interface_name: "outside", + ip: 198.51.100.5, + port: 53, + }, + time: 2025-06-18T11:37:55Z, + traffic: { + bytes: 312, + }, + type_name: "Network Activity: Close", + type_uid: 400102, + unmapped: { + facility: 20, + app_name: null, + process_id: null, + content: "%ASA-6-302016: Teardown UDP connection 1005 for outside:198.51.100.5/53 to inside:10.1.1.3/51000 duration 0:00:05 bytes 312", + context: null, + duration: "0:00:05", + reason: null, + }, +} From 2fa2936c9c68930ea950114351371d4c8ab4c19c Mon Sep 17 00:00:00 2001 From: zedoraps Date: Mon, 22 Jun 2026 16:47:27 +0200 Subject: [PATCH 15/20] Drop null fields from ASA unmapped read_syslog always emits app_name and process_id, which ASA leaves empty, and the ASA subsystem context is usually absent. Run drop_null_fields on the source record so unmapped carries only values that are present instead of read_syslog's null placeholders. Co-authored-by: Claude Opus 4.8 --- cisco/operators/asa/ocsf/map.tql | 5 ++- cisco/tests/asa/ocsf/access_control.txt | 60 ------------------------- cisco/tests/asa/ocsf/authentication.txt | 12 ----- cisco/tests/asa/ocsf/base.txt | 6 --- cisco/tests/asa/ocsf/built.txt | 12 ----- cisco/tests/asa/ocsf/network.txt | 3 -- cisco/tests/asa/ocsf/teardown.txt | 10 ----- 7 files changed, 4 insertions(+), 104 deletions(-) diff --git a/cisco/operators/asa/ocsf/map.tql b/cisco/operators/asa/ocsf/map.tql index 95fc78c6..28d059f5 100644 --- a/cisco/operators/asa/ocsf/map.tql +++ b/cisco/operators/asa/ocsf/map.tql @@ -88,4 +88,7 @@ match $event.asa.message_id { // The message ID is recorded in metadata.event_code, so drop it from unmapped. drop $event.asa.message_id? -$event = {...$event.ocsf, unmapped: $event.asa} +// read_syslog always emits app_name/process_id (empty for ASA), and the ASA +// subsystem context is usually absent. Drop such null fields so unmapped holds +// only values that are actually present. +$event = {...$event.ocsf, unmapped: $event.asa.drop_null_fields()} diff --git a/cisco/tests/asa/ocsf/access_control.txt b/cisco/tests/asa/ocsf/access_control.txt index 32b90345..479db454 100644 --- a/cisco/tests/asa/ocsf/access_control.txt +++ b/cisco/tests/asa/ocsf/access_control.txt @@ -51,10 +51,7 @@ type_uid: 400106, unmapped: { facility: 20, - app_name: null, - process_id: null, content: "%ASA-3-313004: Denied ICMP type=0, from laddr 10.1.1.26 on interface inside to 10.1.1.27: no matching session", - context: null, icmp_type: 0, reason: "no matching session", }, @@ -111,10 +108,7 @@ type_uid: 400106, unmapped: { facility: 20, - app_name: null, - process_id: null, content: "%ASA-3-313008: Denied IPv6-ICMP type=136, code=0 from fe80::21a:2bff:fe3c:4d5e on interface inside", - context: null, icmp_type: 136, icmp_code: 0, }, @@ -175,11 +169,7 @@ type_uid: 400106, unmapped: { facility: 20, - app_name: null, - process_id: null, content: "%ASA-4-106023: Deny icmp src outside:198.51.100.30 dst inside:10.1.1.9 (type 8, code 0) by access-group \"outside_access_in\" [0x0, 0x0]", - context: null, - protocol_num: null, icmp_type: 8, icmp_code: 0, }, @@ -240,11 +230,7 @@ type_uid: 400106, unmapped: { facility: 20, - app_name: null, - process_id: null, content: "%ASA-4-106023: Deny icmp src outside:198.51.100.8/0 dst inside:10.1.1.6/0 [type 8, code 0] by access-group \"outside_access_in\" [0x0, 0x0]", - context: null, - protocol_num: null, icmp_type: 8, icmp_code: 0, }, @@ -304,10 +290,7 @@ type_uid: 400106, unmapped: { facility: 20, - app_name: null, - process_id: null, content: "%ASA-2-106006: Deny inbound UDP from 198.51.100.43/137 to 10.1.1.23/137 on interface outside", - context: null, }, } { @@ -365,14 +348,9 @@ type_uid: 400106, unmapped: { facility: 20, - app_name: null, - process_id: null, content: "%ASA-3-106014: Deny inbound icmp src dmz:198.51.100.40 dst inside:10.1.1.20 (type 8, code 0)", - context: null, - protocol_num: null, icmp_type: 8, icmp_code: 0, - acl_id: null, }, } { @@ -429,13 +407,7 @@ type_uid: 400106, unmapped: { facility: 20, - app_name: null, - process_id: null, content: "%ASA-3-106010: Deny inbound protocol 47 src outside:198.51.100.41 dst outside:10.1.1.21", - context: null, - icmp_type: null, - icmp_code: null, - acl_id: null, }, } { @@ -493,12 +465,7 @@ type_uid: 400106, unmapped: { facility: 20, - app_name: null, - process_id: null, content: "%ASA-4-106023: Deny protocol 47 src outside:198.51.100.9 dst inside:10.1.1.7 by access-group \"outside_access_in\" [0x0, 0x0]", - context: null, - icmp_type: null, - icmp_code: null, }, } { @@ -557,13 +524,7 @@ type_uid: 400106, unmapped: { facility: 20, - app_name: null, - process_id: null, content: "%ASA-4-106023: Deny tcp src outside:198.51.100.7/4444 dst inside:10.1.1.5/3389 by access-group \"outside_access_in\" [0x0, 0x0]", - context: null, - protocol_num: null, - icmp_type: null, - icmp_code: null, }, } { @@ -622,13 +583,7 @@ type_uid: 400106, unmapped: { facility: 20, - app_name: null, - process_id: null, content: "%ASA-4-106023: Deny udp src dmz:fw-host/514 dst outside:10.1.1.8/514 by access-group \"dmz_access\" [0x0, 0x0]", - context: null, - protocol_num: null, - icmp_type: null, - icmp_code: null, }, } { @@ -686,10 +641,7 @@ type_uid: 400106, unmapped: { facility: 20, - app_name: null, - process_id: null, content: "%ASA-2-106001: Inbound TCP connection denied from 198.51.100.42/49709 to 10.1.1.22/6022 flags SYN on interface outside", - context: null, tcp_flags: "SYN", }, } @@ -746,10 +698,7 @@ type_uid: 400106, unmapped: { facility: 20, - app_name: null, - process_id: null, content: "%ASA-3-710003: TCP access denied by ACL from 198.51.100.51/65396 to crypto:host.example/80", - context: null, }, } { @@ -805,10 +754,7 @@ type_uid: 400106, unmapped: { facility: 20, - app_name: null, - process_id: null, content: "%ASA-3-710005: UDP request discarded from 198.51.100.52/60389 to outside:10.1.1.31/44861", - context: null, }, } { @@ -867,10 +813,7 @@ type_uid: 400106, unmapped: { facility: 20, - app_name: null, - process_id: null, content: "%ASA-4-106100: access-list acl_in denied 47 outside/198.51.100.44(0) -> dmz/10.1.1.24(0) hit-cnt 1 first hit [0x0, 0x0]", - context: null, }, } { @@ -930,9 +873,6 @@ type_uid: 400106, unmapped: { facility: 20, - app_name: null, - process_id: null, content: "%ASA-6-106100: access-list acl_in permitted udp outside/198.51.100.45(49543) -> dmz/10.1.1.25(53) hit-cnt 105 300-second interval [0x0, 0x0]", - context: null, }, } diff --git a/cisco/tests/asa/ocsf/authentication.txt b/cisco/tests/asa/ocsf/authentication.txt index be9f0016..db5b768e 100644 --- a/cisco/tests/asa/ocsf/authentication.txt +++ b/cisco/tests/asa/ocsf/authentication.txt @@ -35,10 +35,7 @@ type_uid: 300201, unmapped: { facility: 20, - app_name: null, - process_id: null, content: "%ASA-6-722051: Group User IP <198.51.100.60> IPv4 Address <10.8.0.5> IPv6 address <::> assigned to session", - context: null, assigned_ipv4: 10.8.0.5, assigned_ipv6: ::, }, @@ -89,10 +86,7 @@ type_uid: 300202, unmapped: { facility: 20, - app_name: null, - process_id: null, content: "%ASA-6-113019: Group = vpn-group, Username = user02, IP = 198.51.100.61, Session disconnected. Session Type: SSL, Duration: 0h:52m:12s, Bytes xmt: 17932, Bytes rcv: 228, Reason: User Requested", - context: null, session_type: "SSL", duration: "0h:52m:12s", bytes_out: 17932, @@ -145,10 +139,7 @@ type_uid: 300202, unmapped: { facility: 20, - app_name: null, - process_id: null, content: "%ASA-5-746013: user-identity: Delete IP-User mapping 10.1.1.40 - LOCAL\\user03 Succeeded - VPN user logout", - context: null, }, user: { domain: "LOCAL", @@ -193,10 +184,7 @@ type_uid: 300202, unmapped: { facility: 20, - app_name: null, - process_id: null, content: "%ASA-5-746013: user-identity: Delete IP-User mapping 10.1.1.41 - LOCAL\\user04 Failed - PIP notification", - context: null, }, user: { domain: "LOCAL", diff --git a/cisco/tests/asa/ocsf/base.txt b/cisco/tests/asa/ocsf/base.txt index 200e8687..36414924 100644 --- a/cisco/tests/asa/ocsf/base.txt +++ b/cisco/tests/asa/ocsf/base.txt @@ -30,10 +30,7 @@ type_uid: 0, unmapped: { facility: 20, - app_name: null, - process_id: null, content: "%ASA-4-750003: Local: 198.51.100.1:500 Remote: 203.0.113.9:4500 Username: user1 Negotiation aborted due to ERROR: error", - context: null, }, } { @@ -68,9 +65,6 @@ type_uid: 0, unmapped: { facility: 20, - app_name: null, - process_id: null, content: "%ASA-5-111008: User 'enable_15' executed the 'configure terminal' command.", - context: null, }, } diff --git a/cisco/tests/asa/ocsf/built.txt b/cisco/tests/asa/ocsf/built.txt index d352dc40..58d25ea6 100644 --- a/cisco/tests/asa/ocsf/built.txt +++ b/cisco/tests/asa/ocsf/built.txt @@ -60,10 +60,7 @@ type_uid: 400101, unmapped: { facility: 20, - app_name: null, - process_id: null, content: "%ASA-6-302013: Built inbound TCP connection 3332836331 for inside:10.1.1.9/50640 (198.51.100.20/50640) to umbrella:host.example/443 (UMBRELLA-DOMAIN-BLOCK-HIT/443) 0 24", - context: null, }, } { @@ -120,10 +117,7 @@ type_uid: 400101, unmapped: { facility: 20, - app_name: null, - process_id: null, content: "%ASA-6-302015: Built inbound UDP connection 1005 for outside:198.51.100.5/53 (198.51.100.5/53) to inside:10.1.1.3/51000 (10.1.1.3/51000)", - context: null, }, } { @@ -180,10 +174,7 @@ type_uid: 400101, unmapped: { facility: 20, - app_name: null, - process_id: null, content: "%ASA-6-302013: Built outbound TCP connection 100 for outside:198.51.100.60/443 (198.51.100.60/443) to inside:10.1.1.40/52000 (10.1.1.40/52000)", - context: null, }, } { @@ -244,9 +235,6 @@ type_uid: 400101, unmapped: { facility: 20, - app_name: null, - process_id: null, content: "%ASA-6-302013: Built outbound TCP connection 9 for outside:192.0.2.2/80 (192.0.2.2/80) to inside:10.1.1.2/4924 (203.0.113.10/4924)", - context: null, }, } diff --git a/cisco/tests/asa/ocsf/network.txt b/cisco/tests/asa/ocsf/network.txt index c9a52b73..98a7953f 100644 --- a/cisco/tests/asa/ocsf/network.txt +++ b/cisco/tests/asa/ocsf/network.txt @@ -44,9 +44,6 @@ type_uid: 400106, unmapped: { facility: 20, - app_name: null, - process_id: null, content: "%ASA-4-419002: Duplicate TCP SYN from inside:198.51.100.50/22 to dmz:10.1.1.30/443 with different initial sequence number", - context: null, }, } diff --git a/cisco/tests/asa/ocsf/teardown.txt b/cisco/tests/asa/ocsf/teardown.txt index 2d1f34a2..25a6e685 100644 --- a/cisco/tests/asa/ocsf/teardown.txt +++ b/cisco/tests/asa/ocsf/teardown.txt @@ -49,10 +49,7 @@ type_uid: 400102, unmapped: { facility: 20, - app_name: null, - process_id: null, content: "%ASA-6-302021: Teardown ICMP connection for faddr 10.1.1.32/45078 gaddr 192.168.0.69/0 laddr 192.168.0.69/0 type 8 code 0 Internal-Data0/-1:RX[-1]", - context: null, faddr_id: 45078, gaddr_id: 0, laddr_id: 0, @@ -114,10 +111,7 @@ type_uid: 400102, unmapped: { facility: 20, - app_name: null, - process_id: null, content: "%ASA-6-302014: Teardown TCP connection 9 for outside:192.0.2.2/80 to inside:10.1.1.2/4924 duration 0:00:03 bytes 2048 TCP FINs", - context: null, duration: "0:00:03", }, } @@ -176,11 +170,7 @@ type_uid: 400102, unmapped: { facility: 20, - app_name: null, - process_id: null, content: "%ASA-6-302016: Teardown UDP connection 1005 for outside:198.51.100.5/53 to inside:10.1.1.3/51000 duration 0:00:05 bytes 312", - context: null, duration: "0:00:05", - reason: null, }, } From 89da8adf12756491777da71f5388fa152c7624fa Mon Sep 17 00:00:00 2001 From: zedoraps Date: Mon, 22 Jun 2026 16:50:34 +0200 Subject: [PATCH 16/20] Add bare-frame and rejection variants to the ASA parse tests Cover two cases the read_syslog parse tests miss: a bare %ASA frame with no syslog envelope (parsed via read_lines + message=line) and a line that is not an ASA frame (rejected by the parser's assertion and dropped). Co-authored-by: Claude Opus 4.8 --- cisco/tests/asa/parse_line.input | 2 ++ cisco/tests/asa/parse_line.tql | 6 ++++++ cisco/tests/asa/parse_line.txt | 8 ++++++++ 3 files changed, 16 insertions(+) create mode 100644 cisco/tests/asa/parse_line.input create mode 100644 cisco/tests/asa/parse_line.tql create mode 100644 cisco/tests/asa/parse_line.txt diff --git a/cisco/tests/asa/parse_line.input b/cisco/tests/asa/parse_line.input new file mode 100644 index 00000000..ae5c1f40 --- /dev/null +++ b/cisco/tests/asa/parse_line.input @@ -0,0 +1,2 @@ +%ASA-7-111009: User 'aaaa' executed cmd: show access-list aaa_out brief +Built local-host net:10.10.10.10 diff --git a/cisco/tests/asa/parse_line.tql b/cisco/tests/asa/parse_line.tql new file mode 100644 index 00000000..cc5529ef --- /dev/null +++ b/cisco/tests/asa/parse_line.tql @@ -0,0 +1,6 @@ +// Bare `%ASA-...` frames (no syslog envelope) via read_lines + message=line. +// A line that is not an ASA frame must be rejected by the parser. +from_file env("TENZIR_INPUT") { + read_lines +} +cisco::asa::parse message=line diff --git a/cisco/tests/asa/parse_line.txt b/cisco/tests/asa/parse_line.txt new file mode 100644 index 00000000..4a8fbf29 --- /dev/null +++ b/cisco/tests/asa/parse_line.txt @@ -0,0 +1,8 @@ +{ + line: "%ASA-7-111009: User 'aaaa' executed cmd: show access-list aaa_out brief", + context: null, + severity: 7, + message_id: 111009, + text: "User 'aaaa' executed cmd: show access-list aaa_out brief", +} +warning: assertion failed: "cisco::asa::parse: no %ASA-- frame in the message field" From d02ebf8c7979787aab990be2a472fe2e324edd31 Mon Sep 17 00:00:00 2001 From: zedoraps Date: Mon, 22 Jun 2026 16:54:14 +0200 Subject: [PATCH 17/20] Reference PR #162 in the ASA changelog entry Co-authored-by: Claude Opus 4.8 --- cisco/changelog/unreleased/add-cisco-asa-support.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cisco/changelog/unreleased/add-cisco-asa-support.md b/cisco/changelog/unreleased/add-cisco-asa-support.md index 0ff0e00c..d39adb09 100644 --- a/cisco/changelog/unreleased/add-cisco-asa-support.md +++ b/cisco/changelog/unreleased/add-cisco-asa-support.md @@ -3,6 +3,8 @@ title: Add Cisco Secure Firewall ASA support type: feature authors: - zedoraps +prs: + - 162 created: 2026-06-18T00:00:00Z --- From 2eec34bddc0935980c689853ae99b535b49e1315 Mon Sep 17 00:00:00 2001 From: zedoraps Date: Mon, 22 Jun 2026 18:17:23 +0200 Subject: [PATCH 18/20] Fix Cisco ASA edge mappings Infer years for undated ASA syslog timestamps, clean null endpoint fields, map IPv6 ICMP correctly, and avoid treating numeric-protocol denies as a direction. The updated ASA tests cover the timestamp regression and refresh the affected parser and OCSF fixtures. Assisted-by: GPT-5 (Codex) --- .../asa/ocsf/events/access_control.tql | 12 ++- .../asa/ocsf/events/authentication.tql | 32 ++++--- cisco/operators/asa/ocsf/events/built.tql | 10 +- cisco/operators/asa/ocsf/map.tql | 12 ++- .../operators/asa/ocsf/network_endpoints.tql | 11 +++ cisco/operators/asa/parse.tql | 5 +- cisco/tests/asa/ocsf/access_control.txt | 22 +---- .../asa/ocsf/inputs/undated_timestamp.txt | 1 + cisco/tests/asa/ocsf/teardown.txt | 4 - cisco/tests/asa/ocsf/undated_timestamp.tql | 12 +++ cisco/tests/asa/ocsf/undated_timestamp.txt | 3 + cisco/tests/asa/parse.tql | 2 +- cisco/tests/asa/parse.txt | 96 +++++++++---------- 13 files changed, 121 insertions(+), 101 deletions(-) create mode 100644 cisco/tests/asa/ocsf/inputs/undated_timestamp.txt create mode 100644 cisco/tests/asa/ocsf/undated_timestamp.tql create mode 100644 cisco/tests/asa/ocsf/undated_timestamp.txt diff --git a/cisco/operators/asa/ocsf/events/access_control.tql b/cisco/operators/asa/ocsf/events/access_control.tql index af180ce5..d0201e2d 100644 --- a/cisco/operators/asa/ocsf/events/access_control.tql +++ b/cisco/operators/asa/ocsf/events/access_control.tql @@ -24,10 +24,14 @@ if $event.asa.acl_id? != null { } // Connection direction relative to the firewall, when the message states it. -if $event.asa.direction? == "inbound" { - $event.ocsf.connection_info.direction_id = 1 -} else if $event.asa.direction? == "outbound" { - $event.ocsf.connection_info.direction_id = 2 +if $event.asa.direction? != null { + let $directions = { + inbound: 1, + outbound: 2, + } + if $directions[$event.asa.direction]? != null { + $event.ocsf.connection_info.direction_id = $directions[$event.asa.direction] + } } drop $event.asa.direction? diff --git a/cisco/operators/asa/ocsf/events/authentication.tql b/cisco/operators/asa/ocsf/events/authentication.tql index a7b13174..19ed56c0 100644 --- a/cisco/operators/asa/ocsf/events/authentication.tql +++ b/cisco/operators/asa/ocsf/events/authentication.tql @@ -11,13 +11,13 @@ args: $event.ocsf.category_uid = 3 $event.ocsf.class_uid = 3002 -// 722051 establishes a session; 113019 and 746013 end one. Match the known IDs -// explicitly so an unexpected message routed here is not mislabeled. -match $event.asa.message_id { - 722051 => { $event.ocsf.activity_id = 1 } // Logon - 113019 | 746013 => { $event.ocsf.activity_id = 2 } // Logoff - _ => { $event.ocsf.activity_id = 0 } // Unknown +// 722051 establishes a session; 113019 and 746013 end one. +let $activities = { + "722051": 1, // Logon + "113019": 2, // Logoff + "746013": 2, // Logoff } +$event.ocsf.activity_id = $activities[$event.asa.message_id.string()]? else 0 $event.ocsf.type_uid = $event.ocsf.class_uid * 100 + $event.ocsf.activity_id if $event.asa.vpn_user? != null { @@ -48,15 +48,17 @@ if $event.asa.reason? != null { // string preserved in `status`, per OCSF conventions). The session logon // (722051) and logoff (113019) messages carry no status but always describe a // completed action, so they map to Success. Anything else stays Unknown. -if $event.asa.status? == "Succeeded" { - $event.ocsf.status_id = 1 // Success - drop $event.asa.status? -} else if $event.asa.status? == "Failed" { - $event.ocsf.status_id = 2 // Failure - drop $event.asa.status? -} else if $event.asa.status? != null { - $event.ocsf.status_id = 99 // Other - $event.ocsf.status = move $event.asa.status +if $event.asa.status? != null { + let $statuses = { + Succeeded: 1, // Success + Failed: 2, // Failure + } + $event.ocsf.status_id = $statuses[$event.asa.status]? else 99 + if $event.ocsf.status_id == 99 { + $event.ocsf.status = move $event.asa.status + } else { + drop $event.asa.status? + } } else if $event.asa.message_id == 722051 or $event.asa.message_id == 113019 { $event.ocsf.status_id = 1 // Success } else { diff --git a/cisco/operators/asa/ocsf/events/built.tql b/cisco/operators/asa/ocsf/events/built.tql index b1e0d8df..95cc09ad 100644 --- a/cisco/operators/asa/ocsf/events/built.tql +++ b/cisco/operators/asa/ocsf/events/built.tql @@ -18,13 +18,11 @@ cisco::asa::ocsf::network_endpoints event=$event // `direction` is relative to the firewall: an inbound connection is initiated // from the outside, an outbound one from the inside. -if $event.asa.direction? == "inbound" { - $event.ocsf.connection_info.direction_id = 1 -} else if $event.asa.direction? == "outbound" { - $event.ocsf.connection_info.direction_id = 2 -} else { - $event.ocsf.connection_info.direction_id = 0 +let $directions = { + inbound: 1, + outbound: 2, } +$event.ocsf.connection_info.direction_id = $directions[$event.asa.direction?]? else 0 drop $event.asa.direction? // Connection decisions populate the security_control profile. diff --git a/cisco/operators/asa/ocsf/map.tql b/cisco/operators/asa/ocsf/map.tql index 28d059f5..670a4757 100644 --- a/cisco/operators/asa/ocsf/map.tql +++ b/cisco/operators/asa/ocsf/map.tql @@ -51,7 +51,17 @@ if $event.asa.timestamp? != null { } else if $event.asa.timestamp.string().match_regex($dated) { $event.ocsf.time = (move $event.asa.timestamp).parse_time("%b %d %Y %H:%M:%S") } else if $event.asa.timestamp.string().match_regex($undated) { - $event.ocsf.time = (move $event.asa.timestamp).parse_time("%b %e %H:%M:%S") + // ASA may omit the year. Use the processing year, with a one-year + // correction around New Year for delayed December or early January logs. + $event.asa.event_month = $event.asa.timestamp.parse_time("%b %e %H:%M:%S").month() + $event.asa.event_year = $event.ocsf.metadata.processed_time.year() + if $event.asa.event_month == 12 and $event.ocsf.metadata.processed_time.month() == 1 { + $event.asa.event_year = $event.asa.event_year - 1 + } else if $event.asa.event_month == 1 and $event.ocsf.metadata.processed_time.month() == 12 { + $event.asa.event_year = $event.asa.event_year + 1 + } + $event.ocsf.time = ($event.asa.event_year.string() + " " + move $event.asa.timestamp).parse_time("%Y %b %e %H:%M:%S") + drop $event.asa.event_month, $event.asa.event_year } } diff --git a/cisco/operators/asa/ocsf/network_endpoints.tql b/cisco/operators/asa/ocsf/network_endpoints.tql index fc9d2ebb..3f525376 100644 --- a/cisco/operators/asa/ocsf/network_endpoints.tql +++ b/cisco/operators/asa/ocsf/network_endpoints.tql @@ -44,6 +44,11 @@ if $event.asa.src_xlate_host? != null and $event.asa.src_xlate_host != $event.as } else { $event.ocsf.src_endpoint.proxy_endpoint.hostname = $event.asa.src_xlate_host } + $event.ocsf.src_endpoint.proxy_endpoint = $event.ocsf.src_endpoint.proxy_endpoint.drop_null_fields() +} +$event.ocsf.src_endpoint = $event.ocsf.src_endpoint.drop_null_fields() +if $event.ocsf.src_endpoint.is_empty() { + drop $event.ocsf.src_endpoint } drop $event.asa.src_host?, $event.asa.src_xlate_host?, $event.asa.src_xlate_port? @@ -68,6 +73,11 @@ if $event.asa.dst_xlate_host? != null and $event.asa.dst_xlate_host != $event.as } else { $event.ocsf.dst_endpoint.proxy_endpoint.hostname = $event.asa.dst_xlate_host } + $event.ocsf.dst_endpoint.proxy_endpoint = $event.ocsf.dst_endpoint.proxy_endpoint.drop_null_fields() +} +$event.ocsf.dst_endpoint = $event.ocsf.dst_endpoint.drop_null_fields() +if $event.ocsf.dst_endpoint.is_empty() { + drop $event.ocsf.dst_endpoint } drop $event.asa.dst_host?, $event.asa.dst_xlate_host?, $event.asa.dst_xlate_port? @@ -83,6 +93,7 @@ let $protocols = { esp: 50, ah: 51, icmpv6: 58, + "ipv6-icmp": 58, } // Keep a real protocol name (but not the `protocol` placeholder word), and take // the number from the message if it gave one, otherwise look it up by name. diff --git a/cisco/operators/asa/parse.tql b/cisco/operators/asa/parse.tql index b2c787d3..64d6af7f 100644 --- a/cisco/operators/asa/parse.tql +++ b/cisco/operators/asa/parse.tql @@ -25,6 +25,7 @@ args: // as a string and let the OCSF mapper decide whether it is an `ip` or a // `hostname`. let $patterns = { + DIRECTION: r#"(inbound|outbound)"#, HOST: r#"[^/ ]+"#, } let $header = r#"%ASA-(%{WORD:context}-)?%{INT:severity}-%{INT:message_id}: %{GREEDYDATA:text}"# @@ -42,7 +43,7 @@ let $teardown = r#"Teardown %{WORD:protocol} connection %{INT:connection_id} for // [type/code] [by access-group "acl"]` form, covering 106023, 106010, and // 106014. The optional direction, ports, ICMP type/code (square brackets or // round parens), and access-group absorb the per-message-ID differences. -let $deny = r#"Deny( %{WORD:direction})? %{WORD:protocol}( %{INT:protocol_num})? src %{NOTSPACE:src_interface}:%{HOST:src_host:string}(/%{INT:src_port})? dst %{NOTSPACE:dst_interface}:%{HOST:dst_host:string}(/%{INT:dst_port})?( [\[(]type %{INT:icmp_type}, code %{INT:icmp_code}[\])])?( by access-group "%{DATA:acl_id}")?.*"# +let $deny = r#"Deny( %{DIRECTION:direction})? %{WORD:protocol}( %{INT:protocol_num})? src %{NOTSPACE:src_interface}:%{HOST:src_host:string}(/%{INT:src_port})? dst %{NOTSPACE:dst_interface}:%{HOST:dst_host:string}(/%{INT:dst_port})?( [\[(]type %{INT:icmp_type}, code %{INT:icmp_code}[\])])?( by access-group "%{DATA:acl_id}")?.*"# // 106001: ` connection denied from ip/port to ip/port // [flags F] on interface IF`. let $conn_denied = r#"%{WORD:direction} %{WORD:protocol} connection denied from %{HOST:src_host:string}/%{INT:src_port} to %{HOST:dst_host:string}/%{INT:dst_port}( flags %{DATA:tcp_flags})? +on interface %{NOTSPACE:src_interface}"# @@ -118,5 +119,7 @@ if protocol? != null { if protocol.match_regex(r"^[0-9]+$") { protocol_num = int(protocol) drop protocol + } else if protocol == "protocol" and protocol_num? != null { + drop protocol } } diff --git a/cisco/tests/asa/ocsf/access_control.txt b/cisco/tests/asa/ocsf/access_control.txt index 479db454..e5132493 100644 --- a/cisco/tests/asa/ocsf/access_control.txt +++ b/cisco/tests/asa/ocsf/access_control.txt @@ -14,9 +14,7 @@ disposition: "Blocked", disposition_id: 2, dst_endpoint: { - interface_name: null, ip: 10.1.1.27, - port: null, }, message: "Denied ICMP type=0, from laddr 10.1.1.26 on interface inside to 10.1.1.27: no matching session", metadata: { @@ -44,7 +42,6 @@ src_endpoint: { interface_name: "inside", ip: 10.1.1.26, - port: null, }, time: 2025-06-18T11:38:11Z, type_name: "Network Activity: Traffic", @@ -67,14 +64,10 @@ class_uid: 4001, connection_info: { protocol_name: "ipv6-icmp", - protocol_num: -1, + protocol_num: 58, }, disposition: "Blocked", disposition_id: 2, - dst_endpoint: { - interface_name: null, - port: null, - }, message: "Denied IPv6-ICMP type=136, code=0 from fe80::21a:2bff:fe3c:4d5e on interface inside", metadata: { event_code: "313008", @@ -101,7 +94,6 @@ src_endpoint: { interface_name: "inside", ip: fe80::21a:2bff:fe3c:4d5e, - port: null, }, time: 2025-06-18T11:38:12Z, type_name: "Network Activity: Traffic", @@ -131,7 +123,6 @@ dst_endpoint: { interface_name: "inside", ip: 10.1.1.9, - port: null, }, firewall_rule: { name: "outside_access_in", @@ -162,7 +153,6 @@ src_endpoint: { interface_name: "outside", ip: 198.51.100.30, - port: null, }, time: 2025-06-18T11:38:04Z, type_name: "Network Activity: Traffic", @@ -253,7 +243,6 @@ disposition: "Blocked", disposition_id: 2, dst_endpoint: { - interface_name: null, ip: 10.1.1.23, port: 137, }, @@ -313,7 +302,6 @@ dst_endpoint: { interface_name: "inside", ip: 10.1.1.20, - port: null, }, message: "Deny inbound icmp src dmz:198.51.100.40 dst inside:10.1.1.20 (type 8, code 0)", metadata: { @@ -341,7 +329,6 @@ src_endpoint: { interface_name: "dmz", ip: 198.51.100.40, - port: null, }, time: 2025-06-18T11:38:08Z, type_name: "Network Activity: Traffic", @@ -372,7 +359,6 @@ dst_endpoint: { interface_name: "outside", ip: 10.1.1.21, - port: null, }, message: "Deny inbound protocol 47 src outside:198.51.100.41 dst outside:10.1.1.21", metadata: { @@ -400,7 +386,6 @@ src_endpoint: { interface_name: "outside", ip: 198.51.100.41, - port: null, }, time: 2025-06-18T11:38:07Z, type_name: "Network Activity: Traffic", @@ -427,7 +412,6 @@ dst_endpoint: { interface_name: "inside", ip: 10.1.1.7, - port: null, }, firewall_rule: { name: "outside_access_in", @@ -458,7 +442,6 @@ src_endpoint: { interface_name: "outside", ip: 198.51.100.9, - port: null, }, time: 2025-06-18T11:38:02Z, type_name: "Network Activity: Traffic", @@ -604,7 +587,6 @@ disposition: "Blocked", disposition_id: 2, dst_endpoint: { - interface_name: null, ip: 10.1.1.22, port: 6022, }, @@ -689,7 +671,6 @@ severity: "High", severity_id: 4, src_endpoint: { - interface_name: null, ip: 198.51.100.51, port: 65396, }, @@ -745,7 +726,6 @@ severity: "High", severity_id: 4, src_endpoint: { - interface_name: null, ip: 198.51.100.52, port: 60389, }, diff --git a/cisco/tests/asa/ocsf/inputs/undated_timestamp.txt b/cisco/tests/asa/ocsf/inputs/undated_timestamp.txt new file mode 100644 index 00000000..d683cc89 --- /dev/null +++ b/cisco/tests/asa/ocsf/inputs/undated_timestamp.txt @@ -0,0 +1 @@ +<166>Jun 18 11:37:47 asa-fw : %ASA-6-302013: Built outbound TCP connection 9 for outside:192.0.2.2/80 (192.0.2.2/80) to inside:10.1.1.2/4924 (203.0.113.10/4924) diff --git a/cisco/tests/asa/ocsf/teardown.txt b/cisco/tests/asa/ocsf/teardown.txt index 25a6e685..2af8fae0 100644 --- a/cisco/tests/asa/ocsf/teardown.txt +++ b/cisco/tests/asa/ocsf/teardown.txt @@ -12,9 +12,7 @@ disposition: "Allowed", disposition_id: 1, dst_endpoint: { - interface_name: null, ip: 10.1.1.32, - port: null, }, message: "Teardown ICMP connection for faddr 10.1.1.32/45078 gaddr 192.168.0.69/0 laddr 192.168.0.69/0 type 8 code 0 Internal-Data0/-1:RX[-1]", metadata: { @@ -40,9 +38,7 @@ severity: "Informational", severity_id: 1, src_endpoint: { - interface_name: null, ip: 192.168.0.69, - port: null, }, time: 2025-06-18T11:38:16Z, type_name: "Network Activity: Close", diff --git a/cisco/tests/asa/ocsf/undated_timestamp.tql b/cisco/tests/asa/ocsf/undated_timestamp.tql new file mode 100644 index 00000000..c770aef1 --- /dev/null +++ b/cisco/tests/asa/ocsf/undated_timestamp.tql @@ -0,0 +1,12 @@ +from_file f"{env("TENZIR_INPUTS")}/undated_timestamp.txt" { + read_syslog +} +cisco::asa::parse +cisco::asa::ocsf::map +assert time.year() != 1970 +assert time.month() == 6 +assert time.day() == 18 +assert time.hour() == 11 +assert time.minute() == 37 +assert time.second() == 47 +select ok=true diff --git a/cisco/tests/asa/ocsf/undated_timestamp.txt b/cisco/tests/asa/ocsf/undated_timestamp.txt new file mode 100644 index 00000000..d971ed8f --- /dev/null +++ b/cisco/tests/asa/ocsf/undated_timestamp.txt @@ -0,0 +1,3 @@ +{ + ok: true, +} diff --git a/cisco/tests/asa/parse.tql b/cisco/tests/asa/parse.tql index e6751252..6d35e745 100644 --- a/cisco/tests/asa/parse.tql +++ b/cisco/tests/asa/parse.tql @@ -2,4 +2,4 @@ from_file env("TENZIR_INPUT") { read_syslog } cisco::asa::parse -sort message_id +sort message_id, text diff --git a/cisco/tests/asa/parse.txt b/cisco/tests/asa/parse.txt index 693032ad..8228b2f8 100644 --- a/cisco/tests/asa/parse.txt +++ b/cisco/tests/asa/parse.txt @@ -1,3 +1,26 @@ +{ + facility: 20, + severity: 4, + timestamp: "Jun 18 2025 11:38:02", + hostname: "asa-fw", + app_name: null, + process_id: null, + content: "%ASA-4-106023: Deny protocol 47 src outside:198.51.100.9 dst inside:10.1.1.7 by access-group \"outside_access_in\" [0x0, 0x0]", + context: null, + message_id: 106023, + text: "Deny protocol 47 src outside:198.51.100.9 dst inside:10.1.1.7 by access-group \"outside_access_in\" [0x0, 0x0]", + direction: null, + protocol_num: 47, + src_interface: "outside", + src_host: "198.51.100.9", + src_port: null, + dst_interface: "inside", + dst_host: "10.1.1.7", + dst_port: null, + icmp_type: null, + icmp_code: null, + acl_id: "outside_access_in", +} { facility: 20, severity: 4, @@ -46,29 +69,6 @@ icmp_code: null, acl_id: "dmz_access", } -{ - facility: 20, - severity: 4, - timestamp: "Jun 18 2025 11:38:02", - hostname: "asa-fw", - app_name: null, - process_id: null, - content: "%ASA-4-106023: Deny protocol 47 src outside:198.51.100.9 dst inside:10.1.1.7 by access-group \"outside_access_in\" [0x0, 0x0]", - context: null, - message_id: 106023, - text: "Deny protocol 47 src outside:198.51.100.9 dst inside:10.1.1.7 by access-group \"outside_access_in\" [0x0, 0x0]", - direction: "protocol", - protocol_num: 47, - src_interface: "outside", - src_host: "198.51.100.9", - src_port: null, - dst_interface: "inside", - dst_host: "10.1.1.7", - dst_port: null, - icmp_type: null, - icmp_code: null, - acl_id: "outside_access_in", -} { facility: 20, severity: 5, @@ -81,31 +81,6 @@ message_id: 111008, text: "User 'enable_15' executed the 'configure terminal' command.", } -{ - facility: 20, - severity: 6, - timestamp: "Jun 18 2025 11:37:47", - hostname: "asa-fw", - app_name: null, - process_id: null, - content: "%ASA-6-302013: Built outbound TCP connection 9 for outside:192.0.2.2/80 (192.0.2.2/80) to inside:10.1.1.2/4924 (203.0.113.10/4924)", - context: null, - message_id: 302013, - text: "Built outbound TCP connection 9 for outside:192.0.2.2/80 (192.0.2.2/80) to inside:10.1.1.2/4924 (203.0.113.10/4924)", - direction: "outbound", - protocol: "TCP", - connection_id: 9, - src_interface: "outside", - src_host: "192.0.2.2", - src_port: 80, - src_xlate_host: "192.0.2.2", - src_xlate_port: 80, - dst_interface: "inside", - dst_host: "10.1.1.2", - dst_port: 4924, - dst_xlate_host: "203.0.113.10", - dst_xlate_port: 4924, -} { facility: 20, severity: 6, @@ -156,6 +131,31 @@ dst_xlate_host: "10.1.1.40", dst_xlate_port: 52000, } +{ + facility: 20, + severity: 6, + timestamp: "Jun 18 2025 11:37:47", + hostname: "asa-fw", + app_name: null, + process_id: null, + content: "%ASA-6-302013: Built outbound TCP connection 9 for outside:192.0.2.2/80 (192.0.2.2/80) to inside:10.1.1.2/4924 (203.0.113.10/4924)", + context: null, + message_id: 302013, + text: "Built outbound TCP connection 9 for outside:192.0.2.2/80 (192.0.2.2/80) to inside:10.1.1.2/4924 (203.0.113.10/4924)", + direction: "outbound", + protocol: "TCP", + connection_id: 9, + src_interface: "outside", + src_host: "192.0.2.2", + src_port: 80, + src_xlate_host: "192.0.2.2", + src_xlate_port: 80, + dst_interface: "inside", + dst_host: "10.1.1.2", + dst_port: 4924, + dst_xlate_host: "203.0.113.10", + dst_xlate_port: 4924, +} { facility: 20, severity: 6, From df9c98e37acebb0a8e0791000499accdfecdd7b5 Mon Sep 17 00:00:00 2001 From: zedoraps Date: Mon, 22 Jun 2026 18:44:47 +0200 Subject: [PATCH 19/20] Cover more Cisco ASA variants Parse additional ASA access-control and connection message shapes, including endpoint annotations, Land Attack denies, user-qualified access-list logs, and invalid ICMP denies. Add anonymized PRI-prefixed examples that document how these variants map to OCSF, while keeping SFR and IKE messages as Base Event for now. Assisted-by: GPT-5 (Codex) --- .../asa/ocsf/events/access_control.tql | 11 + cisco/operators/asa/ocsf/map.tql | 2 +- cisco/operators/asa/parse.tql | 17 +- cisco/tests/asa/ocsf/access_control.txt | 756 ++++++++++++++++-- cisco/tests/asa/ocsf/base.txt | 308 +++++++ cisco/tests/asa/ocsf/built.txt | 171 ++++ .../tests/asa/ocsf/inputs/access_control.txt | 11 + cisco/tests/asa/ocsf/inputs/base.txt | 9 + cisco/tests/asa/ocsf/inputs/built.txt | 3 + cisco/tests/asa/ocsf/inputs/teardown.txt | 1 + cisco/tests/asa/ocsf/teardown.txt | 60 ++ 11 files changed, 1297 insertions(+), 52 deletions(-) diff --git a/cisco/operators/asa/ocsf/events/access_control.tql b/cisco/operators/asa/ocsf/events/access_control.tql index d0201e2d..67da17f2 100644 --- a/cisco/operators/asa/ocsf/events/access_control.tql +++ b/cisco/operators/asa/ocsf/events/access_control.tql @@ -23,6 +23,14 @@ if $event.asa.acl_id? != null { } } +if $event.asa.user? != null { + $event.ocsf.actor.user.name = move $event.asa.user +} + +if $event.asa.reason? != null { + $event.ocsf.status_detail = move $event.asa.reason +} + // Connection direction relative to the firewall, when the message states it. if $event.asa.direction? != null { let $directions = { @@ -42,6 +50,9 @@ if $event.asa.hit_count? != null { // Access-list decisions populate the security_control profile. $event.ocsf.metadata.profiles = ["security_control"] +if $event.ocsf.actor? != null { + $event.ocsf.metadata.profiles = $event.ocsf.metadata.profiles.add("host") +} // 106100 logs both permits and denies via `action`; everything else is a deny. if $event.asa.action? == "permitted" { diff --git a/cisco/operators/asa/ocsf/map.tql b/cisco/operators/asa/ocsf/map.tql index 670a4757..9bac74f9 100644 --- a/cisco/operators/asa/ocsf/map.tql +++ b/cisco/operators/asa/ocsf/map.tql @@ -89,7 +89,7 @@ if $event.asa.severity? != null { match $event.asa.message_id { 302013 | 302015 => { cisco::asa::ocsf::events::built event=$event } 302014 | 302016 | 302021 => { cisco::asa::ocsf::events::teardown event=$event } - 106023 | 106001 | 106006 | 106007 | 106010 | 106014 | 106100 | 313004 | 313008 | 710003 | 710005 => { cisco::asa::ocsf::events::access_control event=$event } + 106023 | 106001 | 106006 | 106007 | 106010 | 106014 | 106017 | 106100 | 106102 | 106103 | 313004 | 313008 | 313009 | 710003 | 710005 => { cisco::asa::ocsf::events::access_control event=$event } 419002 => { cisco::asa::ocsf::events::network event=$event } 722051 | 113019 | 746013 => { cisco::asa::ocsf::events::authentication event=$event } _ => { cisco::asa::ocsf::base event=$event } diff --git a/cisco/operators/asa/parse.tql b/cisco/operators/asa/parse.tql index 64d6af7f..1440db65 100644 --- a/cisco/operators/asa/parse.tql +++ b/cisco/operators/asa/parse.tql @@ -26,6 +26,7 @@ args: // `hostname`. let $patterns = { DIRECTION: r#"(inbound|outbound)"#, + ENDPOINT_TAG: r#"(?:\([^)]*\))*"#, HOST: r#"[^/ ]+"#, } let $header = r#"%ASA-(%{WORD:context}-)?%{INT:severity}-%{INT:message_id}: %{GREEDYDATA:text}"# @@ -34,8 +35,8 @@ let $header = r#"%ASA-(%{WORD:context}-)?%{INT:severity}-%{INT:message_id}: %{GR // carries the post-NAT (translated) address in parentheses, which can be an IP // or a label (e.g. Umbrella SIG writes `(UMBRELLA-DOMAIN-BLOCK-HIT/443)`). The // trailing `.*` tolerates extra fields some platforms append after the line. -let $built = r#"Built %{WORD:direction} %{WORD:protocol} connection %{INT:connection_id} for %{NOTSPACE:src_interface}:%{HOST:src_host:string}/%{INT:src_port} \(%{HOST:src_xlate_host:string}/%{INT:src_xlate_port}\) to %{NOTSPACE:dst_interface}:%{HOST:dst_host:string}/%{INT:dst_port} \(%{HOST:dst_xlate_host:string}/%{INT:dst_xlate_port}\).*"# -let $teardown = r#"Teardown %{WORD:protocol} connection %{INT:connection_id} for %{NOTSPACE:src_interface}:%{HOST:src_host:string}/%{INT:src_port} to %{NOTSPACE:dst_interface}:%{HOST:dst_host:string}/%{INT:dst_port} duration %{NOTSPACE:duration} bytes %{INT:bytes}( %{GREEDYDATA:reason})?"# +let $built = r#"Built %{WORD:direction} %{WORD:protocol} connection %{INT:connection_id} for %{NOTSPACE:src_interface}:%{HOST:src_host:string}/%{INT:src_port} \(%{HOST:src_xlate_host:string}/%{INT:src_xlate_port}\)%{ENDPOINT_TAG} to %{NOTSPACE:dst_interface}:%{HOST:dst_host:string}/%{INT:dst_port} \(%{HOST:dst_xlate_host:string}/%{INT:dst_xlate_port}\)%{ENDPOINT_TAG}.*"# +let $teardown = r#"Teardown %{WORD:protocol} connection %{INT:connection_id} for %{NOTSPACE:src_interface}:%{HOST:src_host:string}/%{INT:src_port}%{ENDPOINT_TAG} to %{NOTSPACE:dst_interface}:%{HOST:dst_host:string}/%{INT:dst_port}%{ENDPOINT_TAG} duration %{NOTSPACE:duration} bytes %{INT:bytes}( %{GREEDYDATA:reason})?"# // Deny covers both the port-based form (`Deny tcp src IF:host/port …`) and the // protocol-number form for protocols without ports (`Deny protocol 47 src // IF:host …`, e.g. GRE/ESP). Ports and the ICMP type/code are optional. @@ -43,18 +44,23 @@ let $teardown = r#"Teardown %{WORD:protocol} connection %{INT:connection_id} for // [type/code] [by access-group "acl"]` form, covering 106023, 106010, and // 106014. The optional direction, ports, ICMP type/code (square brackets or // round parens), and access-group absorb the per-message-ID differences. -let $deny = r#"Deny( %{DIRECTION:direction})? %{WORD:protocol}( %{INT:protocol_num})? src %{NOTSPACE:src_interface}:%{HOST:src_host:string}(/%{INT:src_port})? dst %{NOTSPACE:dst_interface}:%{HOST:dst_host:string}(/%{INT:dst_port})?( [\[(]type %{INT:icmp_type}, code %{INT:icmp_code}[\])])?( by access-group "%{DATA:acl_id}")?.*"# +let $deny = r#"Deny( %{DIRECTION:direction})? %{WORD:protocol}( %{INT:protocol_num})? src %{NOTSPACE:src_interface}:%{HOST:src_host:string}(/%{INT:src_port})?%{ENDPOINT_TAG} dst %{NOTSPACE:dst_interface}:%{HOST:dst_host:string}(/%{INT:dst_port})?%{ENDPOINT_TAG}( (?:[\[(])?type %{INT:icmp_type}, code %{INT:icmp_code}(?:[\])])?,?)?(,? by access-group "%{DATA:acl_id}")?.*"# +// 106017: `Deny IP due to Land Attack from ip to ip`. +let $land_attack = r#"Deny %{WORD:protocol} due to %{DATA:reason} from %{HOST:src_host:string} to %{HOST:dst_host:string}"# // 106001: ` connection denied from ip/port to ip/port // [flags F] on interface IF`. let $conn_denied = r#"%{WORD:direction} %{WORD:protocol} connection denied from %{HOST:src_host:string}/%{INT:src_port} to %{HOST:dst_host:string}/%{INT:dst_port}( flags %{DATA:tcp_flags})? +on interface %{NOTSPACE:src_interface}"# // 106006/106007: `Deny from ip/port to ip/port on interface IF`. let $deny_from = r#"Deny %{WORD:direction} %{WORD:protocol} from %{HOST:src_host:string}/%{INT:src_port} to %{HOST:dst_host:string}/%{INT:dst_port} on interface %{NOTSPACE:src_interface}.*"# // 106100: `access-list acl IF/host(port) -> IF/host(port) hit-cnt N …`. -let $acl = r#"access-list %{NOTSPACE:acl_id} %{WORD:action} %{WORD:protocol:string} %{NOTSPACE:src_interface}/%{HOST:src_host:string}\(%{INT:src_port}\) -> %{NOTSPACE:dst_interface}/%{HOST:dst_host:string}\(%{INT:dst_port}\) hit-cnt %{INT:hit_count}.*"# +let $acl = r#"access-list %{NOTSPACE:acl_id} %{WORD:action} %{WORD:protocol:string} %{NOTSPACE:src_interface}/%{HOST:src_host:string}\(%{INT:src_port}\)%{ENDPOINT_TAG} -> %{NOTSPACE:dst_interface}/%{HOST:dst_host:string}\(%{INT:dst_port}\)%{ENDPOINT_TAG} hit-cnt %{INT:hit_count}.*"# +let $acl_user = r#"access-list %{NOTSPACE:acl_id} %{WORD:action} %{WORD:protocol:string} for user '?%{DATA:user}'? %{NOTSPACE:src_interface}/%{HOST:src_host:string}\(%{INT:src_port}\)%{ENDPOINT_TAG} -> %{NOTSPACE:dst_interface}/%{HOST:dst_host:string}\(%{INT:dst_port}\)%{ENDPOINT_TAG} hit-cnt %{INT:hit_count}.*"# // 313004: `Denied ICMP type=N, from laddr ip on interface IF to ip: reason`. let $denied_icmp = r#"Denied %{NOTSPACE:protocol} type=%{INT:icmp_type}, from laddr %{HOST:src_host:string} on interface %{NOTSPACE:src_interface} to %{HOST:dst_host:string}: %{GREEDYDATA:reason}"# // 313008: `Denied IPv6-ICMP type=N, code=N from ip on interface IF` (source only). let $denied_icmp6 = r#"Denied %{NOTSPACE:protocol} type=%{INT:icmp_type}, code=%{INT:icmp_code} from %{HOST:src_host:string} on interface %{NOTSPACE:src_interface}"# +// 313009: `Denied invalid ICMP code N, for IF:host/port (xlate/port) to ...`. +let $denied_invalid_icmp = r#"Denied invalid %{WORD:protocol} code %{INT:icmp_code}, for %{NOTSPACE:src_interface}:%{HOST:src_host:string}/%{INT:src_port} \(%{HOST:src_xlate_host:string}/%{INT:src_xlate_port}\) to %{NOTSPACE:dst_interface}:%{HOST:dst_host:string}/%{INT:dst_port} \(%{HOST:dst_xlate_host:string}/%{INT:dst_xlate_port}\), ICMP id %{INT:icmp_id}, ICMP type %{INT:icmp_type}"# // 419002: `Duplicate SYN from IF:host/port to IF:host/port …`. let $duplicate_syn = r#"Duplicate %{WORD:protocol} SYN from %{NOTSPACE:src_interface}:%{HOST:src_host:string}/%{INT:src_port} to %{NOTSPACE:dst_interface}:%{HOST:dst_host:string}/%{INT:dst_port}.*"# // 710003/710005: to-the-box denies, ` (access denied by ACL|request @@ -96,11 +102,14 @@ match message_id { 302014 | 302016 => { this = {...this, ...text.parse_grok($teardown, pattern_definitions=$patterns)} } 302021 => { this = {...this, ...text.parse_grok($teardown_icmp, pattern_definitions=$patterns)} } 106023 | 106010 | 106014 => { this = {...this, ...text.parse_grok($deny, pattern_definitions=$patterns)} } + 106017 => { this = {...this, ...text.parse_grok($land_attack, pattern_definitions=$patterns)} } 106001 => { this = {...this, ...text.parse_grok($conn_denied, pattern_definitions=$patterns)} } 106006 | 106007 => { this = {...this, ...text.parse_grok($deny_from, pattern_definitions=$patterns)} } 106100 => { this = {...this, ...text.parse_grok($acl, pattern_definitions=$patterns)} } + 106102 | 106103 => { this = {...this, ...text.parse_grok($acl_user, pattern_definitions=$patterns)} } 313004 => { this = {...this, ...text.parse_grok($denied_icmp, pattern_definitions=$patterns)} } 313008 => { this = {...this, ...text.parse_grok($denied_icmp6, pattern_definitions=$patterns)} } + 313009 => { this = {...this, ...text.parse_grok($denied_invalid_icmp, pattern_definitions=$patterns)} } 419002 => { this = {...this, ...text.parse_grok($duplicate_syn, pattern_definitions=$patterns)} } 710003 | 710005 => { this = {...this, ...text.parse_grok($denied_box, pattern_definitions=$patterns)} } 722051 => { this = {...this, ...text.parse_grok($vpn_assigned, pattern_definitions=$patterns)} } diff --git a/cisco/tests/asa/ocsf/access_control.txt b/cisco/tests/asa/ocsf/access_control.txt index e5132493..4aa78f75 100644 --- a/cisco/tests/asa/ocsf/access_control.txt +++ b/cisco/tests/asa/ocsf/access_control.txt @@ -43,6 +43,7 @@ interface_name: "inside", ip: 10.1.1.26, }, + status_detail: "no matching session", time: 2025-06-18T11:38:11Z, type_name: "Network Activity: Traffic", type_uid: 400106, @@ -50,7 +51,58 @@ facility: 20, content: "%ASA-3-313004: Denied ICMP type=0, from laddr 10.1.1.26 on interface inside to 10.1.1.27: no matching session", icmp_type: 0, - reason: "no matching session", + }, +} +{ + action: "Denied", + action_id: 2, + activity_id: 6, + activity_name: "Traffic", + category_name: "Network Activity", + category_uid: 4, + class_name: "Network Activity", + class_uid: 4001, + connection_info: { + protocol_name: "ipv6-icmp", + protocol_num: 58, + }, + disposition: "Blocked", + disposition_id: 2, + message: "Denied IPv6-ICMP type=134, code=0 from 2001:db8::1234 on interface wan1", + metadata: { + event_code: "313008", + log_name: "cisco.asa", + loggers: [ + { + device: { + hostname: "asa-edge-01", + }, + log_format: "syslog", + }, + ], + product: { + name: "Secure Firewall ASA", + vendor_name: "Cisco", + }, + profiles: [ + "security_control", + ], + version: "1.8.0", + }, + severity: "High", + severity_id: 4, + src_endpoint: { + interface_name: "wan1", + ip: 2001:db8::1234, + }, + time: 2021-05-19T09:17:15Z, + type_name: "Network Activity: Traffic", + type_uid: 400106, + unmapped: { + facility: 20, + content: "%ASA-3-313008: Denied IPv6-ICMP type=134, code=0 from 2001:db8::1234 on interface wan1", + icmp_type: 134, + icmp_code: 0, }, } { @@ -105,6 +157,177 @@ icmp_code: 0, }, } +{ + action: "Denied", + action_id: 2, + activity_id: 6, + activity_name: "Traffic", + category_name: "Network Activity", + category_uid: 4, + class_name: "Network Activity", + class_uid: 4001, + connection_info: { + protocol_name: "icmp", + protocol_num: 1, + }, + disposition: "Blocked", + disposition_id: 2, + dst_endpoint: { + interface_name: "identity", + ip: 198.51.100.51, + port: 0, + }, + message: "Denied invalid ICMP code 9, for Inside:192.0.2.206/8795 (192.0.2.206/8795) to identity:198.51.100.51/0 (198.51.100.51/0), ICMP id 295, ICMP type 8", + metadata: { + event_code: "313009", + log_name: "cisco.asa", + loggers: [ + { + device: { + hostname: "asa-edge-02", + }, + log_format: "syslog", + }, + ], + product: { + name: "Secure Firewall ASA", + vendor_name: "Cisco", + }, + profiles: [ + "security_control", + ], + version: "1.8.0", + }, + severity: "Medium", + severity_id: 3, + src_endpoint: { + interface_name: "Inside", + ip: 192.0.2.206, + port: 8795, + }, + time: 2021-05-21T09:18:16Z, + type_name: "Network Activity: Traffic", + type_uid: 400106, + unmapped: { + facility: 20, + content: "%ASA-4-313009: Denied invalid ICMP code 9, for Inside:192.0.2.206/8795 (192.0.2.206/8795) to identity:198.51.100.51/0 (198.51.100.51/0), ICMP id 295, ICMP type 8", + icmp_code: 9, + icmp_id: 295, + icmp_type: 8, + }, +} +{ + action: "Denied", + action_id: 2, + activity_id: 6, + activity_name: "Traffic", + category_name: "Network Activity", + category_uid: 4, + class_name: "Network Activity", + class_uid: 4001, + connection_info: { + protocol_name: "ip", + protocol_num: -1, + }, + disposition: "Blocked", + disposition_id: 2, + dst_endpoint: { + ip: 192.0.2.44, + }, + message: "Deny IP due to Land Attack from 192.0.2.44 to 192.0.2.44", + metadata: { + event_code: "106017", + log_name: "cisco.asa", + loggers: [ + { + device: { + hostname: "asa-edge-01", + }, + log_format: "syslog", + }, + ], + product: { + name: "Secure Firewall ASA", + vendor_name: "Cisco", + }, + profiles: [ + "security_control", + ], + version: "1.8.0", + }, + severity: "Critical", + severity_id: 5, + src_endpoint: { + ip: 192.0.2.44, + }, + status_detail: "Land Attack", + time: 2021-05-19T09:16:14Z, + type_name: "Network Activity: Traffic", + type_uid: 400106, + unmapped: { + facility: 20, + content: "%ASA-2-106017: Deny IP due to Land Attack from 192.0.2.44 to 192.0.2.44", + }, +} +{ + action: "Denied", + action_id: 2, + activity_id: 6, + activity_name: "Traffic", + category_name: "Network Activity", + category_uid: 4, + class_name: "Network Activity", + class_uid: 4001, + connection_info: { + protocol_name: "icmp", + protocol_num: 1, + }, + disposition: "Blocked", + disposition_id: 2, + dst_endpoint: { + interface_name: "Outside", + ip: 198.51.100.10, + }, + firewall_rule: { + name: "inside_policy_in", + }, + message: "Deny icmp src Inside:192.0.2.10 dst Outside:198.51.100.10 (type 11, code 0) by access-group \"inside_policy_in\" [0x0, 0x0]", + metadata: { + event_code: "106023", + log_name: "cisco.asa", + loggers: [ + { + device: { + hostname: "asa-edge-01", + }, + log_format: "syslog", + }, + ], + product: { + name: "Secure Firewall ASA", + vendor_name: "Cisco", + }, + profiles: [ + "security_control", + ], + version: "1.8.0", + }, + severity: "Medium", + severity_id: 3, + src_endpoint: { + interface_name: "Inside", + ip: 192.0.2.10, + }, + time: 2021-05-19T09:13:11Z, + type_name: "Network Activity: Traffic", + type_uid: 400106, + unmapped: { + facility: 20, + content: "%ASA-4-106023: Deny icmp src Inside:192.0.2.10 dst Outside:198.51.100.10 (type 11, code 0) by access-group \"inside_policy_in\" [0x0, 0x0]", + icmp_type: 11, + icmp_code: 0, + }, +} { action: "Denied", action_id: 2, @@ -467,21 +690,21 @@ disposition: "Blocked", disposition_id: 2, dst_endpoint: { - interface_name: "inside", - ip: 10.1.1.5, - port: 3389, + interface_name: "outside", + ip: 198.51.100.53, + port: 53, }, firewall_rule: { - name: "outside_access_in", + name: "dmz_policy", }, - message: "Deny tcp src outside:198.51.100.7/4444 dst inside:10.1.1.5/3389 by access-group \"outside_access_in\" [0x0, 0x0]", + message: "Deny tcp src dmz:192.0.2.20/6316 dst outside:198.51.100.53/53 type 3, code 0, by access-group \"dmz_policy\" [0xa1b2c3d4, 0x0]", metadata: { event_code: "106023", log_name: "cisco.asa", loggers: [ { device: { - hostname: "asa-fw", + hostname: "asa-edge-02", }, log_format: "syslog", }, @@ -498,16 +721,18 @@ severity: "Medium", severity_id: 3, src_endpoint: { - interface_name: "outside", - ip: 198.51.100.7, - port: 4444, + interface_name: "dmz", + ip: 192.0.2.20, + port: 6316, }, - time: 2025-06-18T11:38:00Z, + time: 2021-05-20T09:14:12Z, type_name: "Network Activity: Traffic", type_uid: 400106, unmapped: { facility: 20, - content: "%ASA-4-106023: Deny tcp src outside:198.51.100.7/4444 dst inside:10.1.1.5/3389 by access-group \"outside_access_in\" [0x0, 0x0]", + content: "%ASA-4-106023: Deny tcp src dmz:192.0.2.20/6316 dst outside:198.51.100.53/53 type 3, code 0, by access-group \"dmz_policy\" [0xa1b2c3d4, 0x0]", + icmp_type: 3, + icmp_code: 0, }, } { @@ -520,20 +745,20 @@ class_name: "Network Activity", class_uid: 4001, connection_info: { - protocol_name: "udp", - protocol_num: 17, + protocol_name: "tcp", + protocol_num: 6, }, disposition: "Blocked", disposition_id: 2, dst_endpoint: { - interface_name: "outside", - ip: 10.1.1.8, - port: 514, + interface_name: "inside", + ip: 10.1.1.5, + port: 3389, }, firewall_rule: { - name: "dmz_access", + name: "outside_access_in", }, - message: "Deny udp src dmz:fw-host/514 dst outside:10.1.1.8/514 by access-group \"dmz_access\" [0x0, 0x0]", + message: "Deny tcp src outside:198.51.100.7/4444 dst inside:10.1.1.5/3389 by access-group \"outside_access_in\" [0x0, 0x0]", metadata: { event_code: "106023", log_name: "cisco.asa", @@ -557,16 +782,16 @@ severity: "Medium", severity_id: 3, src_endpoint: { - hostname: "fw-host", - interface_name: "dmz", - port: 514, + interface_name: "outside", + ip: 198.51.100.7, + port: 4444, }, - time: 2025-06-18T11:38:03Z, + time: 2025-06-18T11:38:00Z, type_name: "Network Activity: Traffic", type_uid: 400106, unmapped: { facility: 20, - content: "%ASA-4-106023: Deny udp src dmz:fw-host/514 dst outside:10.1.1.8/514 by access-group \"dmz_access\" [0x0, 0x0]", + content: "%ASA-4-106023: Deny tcp src outside:198.51.100.7/4444 dst inside:10.1.1.5/3389 by access-group \"outside_access_in\" [0x0, 0x0]", }, } { @@ -579,25 +804,27 @@ class_name: "Network Activity", class_uid: 4001, connection_info: { - direction: "Inbound", - direction_id: 1, - protocol_name: "tcp", - protocol_num: 6, + protocol_name: "udp", + protocol_num: 17, }, disposition: "Blocked", disposition_id: 2, dst_endpoint: { - ip: 10.1.1.22, - port: 6022, + interface_name: "Outside", + ip: 198.51.100.11, + port: 57621, }, - message: "Inbound TCP connection denied from 198.51.100.42/49709 to 10.1.1.22/6022 flags SYN on interface outside", + firewall_rule: { + name: "inside_policy_in", + }, + message: "Deny udp src Inside:192.0.2.11/57621(LOCAL\\svc-cache) dst Outside:198.51.100.11/57621 by access-group \"inside_policy_in\" [0x0, 0x0]", metadata: { - event_code: "106001", + event_code: "106023", log_name: "cisco.asa", loggers: [ { device: { - hostname: "asa-fw", + hostname: "asa-edge-01", }, log_format: "syslog", }, @@ -611,20 +838,19 @@ ], version: "1.8.0", }, - severity: "Critical", - severity_id: 5, + severity: "Medium", + severity_id: 3, src_endpoint: { - interface_name: "outside", - ip: 198.51.100.42, - port: 49709, + interface_name: "Inside", + ip: 192.0.2.11, + port: 57621, }, - time: 2025-06-18T11:38:05Z, + time: 2021-05-19T09:15:13Z, type_name: "Network Activity: Traffic", type_uid: 400106, unmapped: { facility: 20, - content: "%ASA-2-106001: Inbound TCP connection denied from 198.51.100.42/49709 to 10.1.1.22/6022 flags SYN on interface outside", - tcp_flags: "SYN", + content: "%ASA-4-106023: Deny udp src Inside:192.0.2.11/57621(LOCAL\\svc-cache) dst Outside:198.51.100.11/57621 by access-group \"inside_policy_in\" [0x0, 0x0]", }, } { @@ -637,16 +863,133 @@ class_name: "Network Activity", class_uid: 4001, connection_info: { - protocol_name: "tcp", - protocol_num: 6, + protocol_name: "udp", + protocol_num: 17, }, disposition: "Blocked", disposition_id: 2, dst_endpoint: { - hostname: "host.example", - interface_name: "crypto", - port: 80, - }, + interface_name: "outside", + ip: 10.1.1.8, + port: 514, + }, + firewall_rule: { + name: "dmz_access", + }, + message: "Deny udp src dmz:fw-host/514 dst outside:10.1.1.8/514 by access-group \"dmz_access\" [0x0, 0x0]", + metadata: { + event_code: "106023", + log_name: "cisco.asa", + loggers: [ + { + device: { + hostname: "asa-fw", + }, + log_format: "syslog", + }, + ], + product: { + name: "Secure Firewall ASA", + vendor_name: "Cisco", + }, + profiles: [ + "security_control", + ], + version: "1.8.0", + }, + severity: "Medium", + severity_id: 3, + src_endpoint: { + hostname: "fw-host", + interface_name: "dmz", + port: 514, + }, + time: 2025-06-18T11:38:03Z, + type_name: "Network Activity: Traffic", + type_uid: 400106, + unmapped: { + facility: 20, + content: "%ASA-4-106023: Deny udp src dmz:fw-host/514 dst outside:10.1.1.8/514 by access-group \"dmz_access\" [0x0, 0x0]", + }, +} +{ + action: "Denied", + action_id: 2, + activity_id: 6, + activity_name: "Traffic", + category_name: "Network Activity", + category_uid: 4, + class_name: "Network Activity", + class_uid: 4001, + connection_info: { + direction: "Inbound", + direction_id: 1, + protocol_name: "tcp", + protocol_num: 6, + }, + disposition: "Blocked", + disposition_id: 2, + dst_endpoint: { + ip: 10.1.1.22, + port: 6022, + }, + message: "Inbound TCP connection denied from 198.51.100.42/49709 to 10.1.1.22/6022 flags SYN on interface outside", + metadata: { + event_code: "106001", + log_name: "cisco.asa", + loggers: [ + { + device: { + hostname: "asa-fw", + }, + log_format: "syslog", + }, + ], + product: { + name: "Secure Firewall ASA", + vendor_name: "Cisco", + }, + profiles: [ + "security_control", + ], + version: "1.8.0", + }, + severity: "Critical", + severity_id: 5, + src_endpoint: { + interface_name: "outside", + ip: 198.51.100.42, + port: 49709, + }, + time: 2025-06-18T11:38:05Z, + type_name: "Network Activity: Traffic", + type_uid: 400106, + unmapped: { + facility: 20, + content: "%ASA-2-106001: Inbound TCP connection denied from 198.51.100.42/49709 to 10.1.1.22/6022 flags SYN on interface outside", + tcp_flags: "SYN", + }, +} +{ + action: "Denied", + action_id: 2, + activity_id: 6, + activity_name: "Traffic", + category_name: "Network Activity", + category_uid: 4, + class_name: "Network Activity", + class_uid: 4001, + connection_info: { + protocol_name: "tcp", + protocol_num: 6, + }, + disposition: "Blocked", + disposition_id: 2, + dst_endpoint: { + hostname: "host.example", + interface_name: "crypto", + port: 80, + }, message: "TCP access denied by ACL from 198.51.100.51/65396 to crypto:host.example/80", metadata: { event_code: "710003", @@ -856,3 +1199,322 @@ content: "%ASA-6-106100: access-list acl_in permitted udp outside/198.51.100.45(49543) -> dmz/10.1.1.25(53) hit-cnt 105 300-second interval [0x0, 0x0]", }, } +{ + action: "Allowed", + action_id: 1, + activity_id: 6, + activity_name: "Traffic", + actor: { + user: { + name: "test-user", + }, + }, + category_name: "Network Activity", + category_uid: 4, + class_name: "Network Activity", + class_uid: 4001, + connection_info: { + protocol_name: "udp", + protocol_num: 17, + }, + count: 1, + disposition: "Allowed", + disposition_id: 1, + dst_endpoint: { + interface_name: "inside", + ip: 192.0.2.40, + port: 53, + }, + firewall_rule: { + name: "client_dns", + }, + message: "access-list client_dns permitted udp for user test-user outside/198.51.100.20(49721) -> inside/192.0.2.40(53) hit-cnt 1 first hit [0x55555555, 0x66666666]", + metadata: { + event_code: "106102", + log_name: "cisco.asa", + loggers: [ + { + device: { + hostname: "asa-edge-03", + }, + log_format: "syslog", + }, + ], + product: { + name: "Secure Firewall ASA", + vendor_name: "Cisco", + }, + profiles: [ + "security_control", + "host", + ], + version: "1.8.0", + }, + severity: "High", + severity_id: 4, + src_endpoint: { + interface_name: "outside", + ip: 198.51.100.20, + port: 49721, + }, + time: 2021-05-23T09:21:19Z, + type_name: "Network Activity: Traffic", + type_uid: 400106, + unmapped: { + facility: 20, + content: "%ASA-session-3-106102: access-list client_dns permitted udp for user test-user outside/198.51.100.20(49721) -> inside/192.0.2.40(53) hit-cnt 1 first hit [0x55555555, 0x66666666]", + context: "session", + }, +} +{ + action: "Denied", + action_id: 2, + activity_id: 6, + activity_name: "Traffic", + actor: { + user: { + name: "analyst", + }, + }, + category_name: "Network Activity", + category_uid: 4, + class_name: "Network Activity", + class_uid: 4001, + connection_info: { + protocol_name: "icmp", + protocol_num: 1, + }, + count: 1, + disposition: "Blocked", + disposition_id: 2, + dst_endpoint: { + interface_name: "outside", + ip: 203.0.113.144, + port: 8080, + }, + firewall_rule: { + name: "edge_filter", + }, + message: "access-list edge_filter denied icmp for user analyst inside/192.0.2.3(64321) -> outside/203.0.113.144(8080) hit-cnt 1 first hit [0x77777777, 0x88888888]", + metadata: { + event_code: "106103", + log_name: "cisco.asa", + loggers: [ + { + device: { + hostname: "asa-edge-03", + }, + log_format: "syslog", + }, + ], + product: { + name: "Secure Firewall ASA", + vendor_name: "Cisco", + }, + profiles: [ + "security_control", + "host", + ], + version: "1.8.0", + }, + severity: "Critical", + severity_id: 5, + src_endpoint: { + interface_name: "inside", + ip: 192.0.2.3, + port: 64321, + }, + time: 2021-05-23T09:22:20Z, + type_name: "Network Activity: Traffic", + type_uid: 400106, + unmapped: { + facility: 20, + content: "%ASA-1-106103: access-list edge_filter denied icmp for user analyst inside/192.0.2.3(64321) -> outside/203.0.113.144(8080) hit-cnt 1 first hit [0x77777777, 0x88888888]", + }, +} +{ + action: "Allowed", + action_id: 1, + activity_id: 6, + activity_name: "Traffic", + category_name: "Network Activity", + category_uid: 4, + class_name: "Network Activity", + class_uid: 4001, + connection_info: { + protocol_name: "udp", + protocol_num: 17, + }, + count: 1, + disposition: "Allowed", + disposition_id: 1, + dst_endpoint: { + interface_name: "inside", + ip: 198.51.100.35, + port: 53, + }, + firewall_rule: { + name: "inbound_acl", + }, + message: "access-list inbound_acl permitted udp dmz2/192.0.2.34(56575) -> inside/198.51.100.35(53) hit-cnt 1 first hit [0x11111111, 0x22222222]", + metadata: { + event_code: "106100", + log_name: "cisco.asa", + loggers: [ + { + device: { + hostname: "asa-edge-02", + }, + log_format: "syslog", + }, + ], + product: { + name: "Secure Firewall ASA", + vendor_name: "Cisco", + }, + profiles: [ + "security_control", + ], + version: "1.8.0", + }, + severity: "Informational", + severity_id: 1, + src_endpoint: { + interface_name: "dmz2", + ip: 192.0.2.34, + port: 56575, + }, + time: 2021-05-22T09:19:17Z, + type_name: "Network Activity: Traffic", + type_uid: 400106, + unmapped: { + facility: 20, + content: "%ASA-6-106100: access-list inbound_acl permitted udp dmz2/192.0.2.34(56575) -> inside/198.51.100.35(53) hit-cnt 1 first hit [0x11111111, 0x22222222]", + }, +} +{ + action: "Allowed", + action_id: 1, + activity_id: 6, + activity_name: "Traffic", + category_name: "Network Activity", + category_uid: 4, + class_name: "Network Activity", + class_uid: 4001, + connection_info: { + protocol_name: "udp", + protocol_num: 17, + }, + count: 1, + disposition: "Allowed", + disposition_id: 1, + dst_endpoint: { + interface_name: "inside", + ip: 198.51.100.35, + port: 53, + }, + firewall_rule: { + name: "inbound_acl", + }, + message: "access-list inbound_acl permitted udp dmz2/192.0.2.34(56575)(LOCAL\\\\sample-user) -> inside/198.51.100.35(53) hit-cnt 1 first hit [0x33333333, 0x44444444]", + metadata: { + event_code: "106100", + log_name: "cisco.asa", + loggers: [ + { + device: { + hostname: "asa-edge-02", + }, + log_format: "syslog", + }, + ], + product: { + name: "Secure Firewall ASA", + vendor_name: "Cisco", + }, + profiles: [ + "security_control", + ], + version: "1.8.0", + }, + severity: "Informational", + severity_id: 1, + src_endpoint: { + interface_name: "dmz2", + ip: 192.0.2.34, + port: 56575, + }, + time: 2021-05-22T09:20:18Z, + type_name: "Network Activity: Traffic", + type_uid: 400106, + unmapped: { + facility: 20, + content: "%ASA-6-106100: access-list inbound_acl permitted udp dmz2/192.0.2.34(56575)(LOCAL\\\\sample-user) -> inside/198.51.100.35(53) hit-cnt 1 first hit [0x33333333, 0x44444444]", + }, +} +{ + action: "Denied", + action_id: 2, + activity_id: 6, + activity_name: "Traffic", + actor: { + user: { + name: "quoted-user", + }, + }, + category_name: "Network Activity", + category_uid: 4, + class_name: "Network Activity", + class_uid: 4001, + connection_info: { + protocol_name: "tcp", + protocol_num: 6, + }, + count: 1, + disposition: "Blocked", + disposition_id: 2, + dst_endpoint: { + interface_name: "inside", + ip: 198.51.100.112, + port: 443, + }, + firewall_rule: { + name: "test_acl", + }, + message: "access-list test_acl denied tcp for user 'quoted-user' outside/203.0.113.142(51950) -> inside/198.51.100.112(443) hit-cnt 1 first hit [0x99999999, 0x0]", + metadata: { + event_code: "106103", + log_name: "cisco.asa", + loggers: [ + { + device: { + hostname: "asa-edge-05", + }, + log_format: "syslog", + }, + ], + product: { + name: "Secure Firewall ASA", + vendor_name: "Cisco", + }, + profiles: [ + "security_control", + "host", + ], + version: "1.8.0", + }, + severity: "Medium", + severity_id: 3, + src_endpoint: { + interface_name: "outside", + ip: 203.0.113.142, + port: 51950, + }, + time: 2025-05-25T09:24:22Z, + type_name: "Network Activity: Traffic", + type_uid: 400106, + unmapped: { + facility: 20, + content: "%ASA-4-106103: access-list test_acl denied tcp for user 'quoted-user' outside/203.0.113.142(51950) -> inside/198.51.100.112(443) hit-cnt 1 first hit [0x99999999, 0x0]", + }, +} diff --git a/cisco/tests/asa/ocsf/base.txt b/cisco/tests/asa/ocsf/base.txt index 36414924..ddd472d4 100644 --- a/cisco/tests/asa/ocsf/base.txt +++ b/cisco/tests/asa/ocsf/base.txt @@ -33,6 +33,314 @@ content: "%ASA-4-750003: Local: 198.51.100.1:500 Remote: 203.0.113.9:4500 Username: user1 Negotiation aborted due to ERROR: error", }, } +{ + activity_id: 0, + activity_name: "Unknown", + category_name: "Uncategorized", + category_uid: 0, + class_name: "Base Event", + class_uid: 0, + message: "Local:2001:db8::6:500 Remote:2001:db8::100:50329 Username:Unknown IKEv2 Negotiation aborted due to ERROR: Auth exchange failed", + metadata: { + event_code: "750003", + log_name: "cisco.asa", + loggers: [ + { + device: { + hostname: "asa-vpn-01", + }, + log_format: "syslog", + }, + ], + product: { + name: "Secure Firewall ASA", + vendor_name: "Cisco", + }, + version: "1.8.0", + }, + severity: "Low", + severity_id: 2, + time: 2025-08-06T12:02:04Z, + type_name: "Base Event: Unknown", + type_uid: 0, + unmapped: { + facility: 20, + content: "%ASA-5-750003: Local:2001:db8::6:500 Remote:2001:db8::100:50329 Username:Unknown IKEv2 Negotiation aborted due to ERROR: Auth exchange failed", + }, +} +{ + activity_id: 0, + activity_name: "Unknown", + category_name: "Uncategorized", + category_uid: 0, + class_name: "Base Event", + class_uid: 0, + message: "Local:2001:db8::6:500 Remote:2001:db8::100:50329 Username:Unknown IKEv2 Received a IKE_INIT_SA request", + metadata: { + event_code: "750002", + log_name: "cisco.asa", + loggers: [ + { + device: { + hostname: "asa-vpn-01", + }, + log_format: "syslog", + }, + ], + product: { + name: "Secure Firewall ASA", + vendor_name: "Cisco", + }, + version: "1.8.0", + }, + severity: "Low", + severity_id: 2, + time: 2025-08-06T12:02:03Z, + type_name: "Base Event: Unknown", + type_uid: 0, + unmapped: { + facility: 20, + content: "%ASA-5-750002: Local:2001:db8::6:500 Remote:2001:db8::100:50329 Username:Unknown IKEv2 Received a IKE_INIT_SA request", + }, +} +{ + activity_id: 0, + activity_name: "Unknown", + category_name: "Uncategorized", + category_uid: 0, + class_name: "Base Event", + class_uid: 0, + message: "Local:2001:db8::7:500 Remote:vpn-d.example.test:50329 Username:Unknown IKEv2 Negotiation aborted due to ERROR: Auth exchange failed", + metadata: { + event_code: "750003", + log_name: "cisco.asa", + loggers: [ + { + device: { + hostname: "asa-vpn-04", + }, + log_format: "syslog", + }, + ], + product: { + name: "Secure Firewall ASA", + vendor_name: "Cisco", + }, + version: "1.8.0", + }, + severity: "Low", + severity_id: 2, + time: 2025-08-06T12:02:10Z, + type_name: "Base Event: Unknown", + type_uid: 0, + unmapped: { + facility: 20, + content: "%ASA-5-750003: Local:2001:db8::7:500 Remote:vpn-d.example.test:50329 Username:Unknown IKEv2 Negotiation aborted due to ERROR: Auth exchange failed", + }, +} +{ + activity_id: 0, + activity_name: "Unknown", + category_name: "Uncategorized", + category_uid: 0, + class_name: "Base Event", + class_uid: 0, + message: "Local:2001:db8::7:500 Remote:vpn-d.example.test:50329 Username:Unknown IKEv2 Received a IKE_INIT_SA request", + metadata: { + event_code: "750002", + log_name: "cisco.asa", + loggers: [ + { + device: { + hostname: "asa-vpn-04", + }, + log_format: "syslog", + }, + ], + product: { + name: "Secure Firewall ASA", + vendor_name: "Cisco", + }, + version: "1.8.0", + }, + severity: "Low", + severity_id: 2, + time: 2025-08-06T12:02:09Z, + type_name: "Base Event: Unknown", + type_uid: 0, + unmapped: { + facility: 20, + content: "%ASA-5-750002: Local:2001:db8::7:500 Remote:vpn-d.example.test:50329 Username:Unknown IKEv2 Received a IKE_INIT_SA request", + }, +} +{ + activity_id: 0, + activity_name: "Unknown", + category_name: "Uncategorized", + category_uid: 0, + class_name: "Base Event", + class_uid: 0, + message: "Local:vpn-a.example.test:500 Remote:vpn-b.example.test:50329 Username:Unknown IKEv2 Negotiation aborted due to ERROR: Auth exchange failed", + metadata: { + event_code: "750003", + log_name: "cisco.asa", + loggers: [ + { + device: { + hostname: "asa-vpn-02", + }, + log_format: "syslog", + }, + ], + product: { + name: "Secure Firewall ASA", + vendor_name: "Cisco", + }, + version: "1.8.0", + }, + severity: "Low", + severity_id: 2, + time: 2025-08-06T12:02:06Z, + type_name: "Base Event: Unknown", + type_uid: 0, + unmapped: { + facility: 20, + content: "%ASA-5-750003: Local:vpn-a.example.test:500 Remote:vpn-b.example.test:50329 Username:Unknown IKEv2 Negotiation aborted due to ERROR: Auth exchange failed", + }, +} +{ + activity_id: 0, + activity_name: "Unknown", + category_name: "Uncategorized", + category_uid: 0, + class_name: "Base Event", + class_uid: 0, + message: "Local:vpn-a.example.test:500 Remote:vpn-b.example.test:50329 Username:Unknown IKEv2 Received a IKE_INIT_SA request", + metadata: { + event_code: "750002", + log_name: "cisco.asa", + loggers: [ + { + device: { + hostname: "asa-vpn-02", + }, + log_format: "syslog", + }, + ], + product: { + name: "Secure Firewall ASA", + vendor_name: "Cisco", + }, + version: "1.8.0", + }, + severity: "Low", + severity_id: 2, + time: 2025-08-06T12:02:05Z, + type_name: "Base Event: Unknown", + type_uid: 0, + unmapped: { + facility: 20, + content: "%ASA-5-750002: Local:vpn-a.example.test:500 Remote:vpn-b.example.test:50329 Username:Unknown IKEv2 Received a IKE_INIT_SA request", + }, +} +{ + activity_id: 0, + activity_name: "Unknown", + category_name: "Uncategorized", + category_uid: 0, + class_name: "Base Event", + class_uid: 0, + message: "Local:vpn-c.example.test:500 Remote:2001:db8::101:50329 Username:Unknown IKEv2 Negotiation aborted due to ERROR: Auth exchange failed", + metadata: { + event_code: "750003", + log_name: "cisco.asa", + loggers: [ + { + device: { + hostname: "asa-vpn-03", + }, + log_format: "syslog", + }, + ], + product: { + name: "Secure Firewall ASA", + vendor_name: "Cisco", + }, + version: "1.8.0", + }, + severity: "Low", + severity_id: 2, + time: 2025-08-06T12:02:08Z, + type_name: "Base Event: Unknown", + type_uid: 0, + unmapped: { + facility: 20, + content: "%ASA-5-750003: Local:vpn-c.example.test:500 Remote:2001:db8::101:50329 Username:Unknown IKEv2 Negotiation aborted due to ERROR: Auth exchange failed", + }, +} +{ + activity_id: 0, + activity_name: "Unknown", + category_name: "Uncategorized", + category_uid: 0, + class_name: "Base Event", + class_uid: 0, + message: "Local:vpn-c.example.test:500 Remote:2001:db8::101:50329 Username:Unknown IKEv2 Received a IKE_INIT_SA request", + metadata: { + event_code: "750002", + log_name: "cisco.asa", + loggers: [ + { + device: { + hostname: "asa-vpn-03", + }, + log_format: "syslog", + }, + ], + product: { + name: "Secure Firewall ASA", + vendor_name: "Cisco", + }, + version: "1.8.0", + }, + severity: "Low", + severity_id: 2, + time: 2025-08-06T12:02:07Z, + type_name: "Base Event: Unknown", + type_uid: 0, + unmapped: { + facility: 20, + content: "%ASA-5-750002: Local:vpn-c.example.test:500 Remote:2001:db8::101:50329 Username:Unknown IKEv2 Received a IKE_INIT_SA request", + }, +} +{ + activity_id: 0, + activity_name: "Unknown", + category_name: "Uncategorized", + category_uid: 0, + class_name: "Base Event", + class_uid: 0, + message: "SFR requested device to bypass further packet redirection and process TCP flow from sourceZone:203.0.113.144/8888 to destinationZone:192.0.2.222/12345 locally", + metadata: { + event_code: "434004", + log_name: "cisco.asa", + product: { + name: "Secure Firewall ASA", + vendor_name: "Cisco", + }, + version: "1.8.0", + }, + severity: "Low", + severity_id: 2, + time: 2021-05-24T09:23:21Z, + type_name: "Base Event: Unknown", + type_uid: 0, + unmapped: { + facility: 20, + app_name: "asa-sfr-01", + content: "%ASA-5-434004: SFR requested device to bypass further packet redirection and process TCP flow from sourceZone:203.0.113.144/8888 to destinationZone:192.0.2.222/12345 locally", + }, +} { activity_id: 0, activity_name: "Unknown", diff --git a/cisco/tests/asa/ocsf/built.txt b/cisco/tests/asa/ocsf/built.txt index 58d25ea6..0a4d0c3b 100644 --- a/cisco/tests/asa/ocsf/built.txt +++ b/cisco/tests/asa/ocsf/built.txt @@ -120,6 +120,177 @@ content: "%ASA-6-302015: Built inbound UDP connection 1005 for outside:198.51.100.5/53 (198.51.100.5/53) to inside:10.1.1.3/51000 (10.1.1.3/51000)", }, } +{ + activity_id: 1, + activity_name: "Open", + category_name: "Network Activity", + category_uid: 4, + class_name: "Network Activity", + class_uid: 4001, + connection_info: { + direction: "Inbound", + direction_id: 1, + protocol_name: "udp", + protocol_num: 17, + uid: "77", + }, + disposition: "Allowed", + disposition_id: 1, + dst_endpoint: { + interface_name: "inside", + ip: 198.51.100.112, + port: 9803, + }, + message: "Built inbound UDP connection 77 for outside:203.0.113.142/3424 (203.0.113.142/3424)(LOCAL\\vpn-a, 123) to inside:198.51.100.112/9803 (198.51.100.112/9803) (vpn-b)", + metadata: { + event_code: "302015", + log_name: "cisco.asa", + loggers: [ + { + device: { + hostname: "asa-edge-04", + }, + log_format: "syslog", + }, + ], + product: { + name: "Secure Firewall ASA", + vendor_name: "Cisco", + }, + profiles: [ + "security_control", + ], + version: "1.8.0", + }, + severity: "Informational", + severity_id: 1, + src_endpoint: { + interface_name: "outside", + ip: 203.0.113.142, + port: 3424, + }, + time: 2022-06-22T12:01:01Z, + type_name: "Network Activity: Open", + type_uid: 400101, + unmapped: { + facility: 20, + content: "%ASA-6-302015: Built inbound UDP connection 77 for outside:203.0.113.142/3424 (203.0.113.142/3424)(LOCAL\\vpn-a, 123) to inside:198.51.100.112/9803 (198.51.100.112/9803) (vpn-b)", + }, +} +{ + activity_id: 1, + activity_name: "Open", + category_name: "Network Activity", + category_uid: 4, + class_name: "Network Activity", + class_uid: 4001, + connection_info: { + direction: "Inbound", + direction_id: 1, + protocol_name: "udp", + protocol_num: 17, + uid: "78", + }, + disposition: "Allowed", + disposition_id: 1, + dst_endpoint: { + interface_name: "inside", + ip: 198.51.100.113, + port: 9804, + }, + message: "Built inbound UDP connection 78 for outside:203.0.113.143/3425 (203.0.113.143/3425)(LOCAL\\vpn-c) to inside:198.51.100.113/9804 (198.51.100.113/9804) (vpn-d)", + metadata: { + event_code: "302015", + log_name: "cisco.asa", + loggers: [ + { + device: { + hostname: "asa-edge-04", + }, + log_format: "syslog", + }, + ], + product: { + name: "Secure Firewall ASA", + vendor_name: "Cisco", + }, + profiles: [ + "security_control", + ], + version: "1.8.0", + }, + severity: "Informational", + severity_id: 1, + src_endpoint: { + interface_name: "outside", + ip: 203.0.113.143, + port: 3425, + }, + time: 2022-06-22T12:01:02Z, + type_name: "Network Activity: Open", + type_uid: 400101, + unmapped: { + facility: 20, + content: "%ASA-6-302015: Built inbound UDP connection 78 for outside:203.0.113.143/3425 (203.0.113.143/3425)(LOCAL\\vpn-c) to inside:198.51.100.113/9804 (198.51.100.113/9804) (vpn-d)", + }, +} +{ + activity_id: 1, + activity_name: "Open", + category_name: "Network Activity", + category_uid: 4, + class_name: "Network Activity", + class_uid: 4001, + connection_info: { + direction: "Inbound", + direction_id: 1, + protocol_name: "udp", + protocol_num: 17, + uid: "79", + }, + disposition: "Allowed", + disposition_id: 1, + dst_endpoint: { + interface_name: "inside", + ip: 198.51.100.114, + port: 9805, + }, + message: "Built inbound UDP connection 79 for outside:203.0.113.144/3426 (203.0.113.144/3426)(LOCAL\\vpn-e, 456) to inside:198.51.100.114/9805 (198.51.100.114/9805)(LOCAL\\vpn-f, 789) (vpn-g)", + metadata: { + event_code: "302015", + log_name: "cisco.asa", + loggers: [ + { + device: { + hostname: "asa-edge-04", + }, + log_format: "syslog", + }, + ], + product: { + name: "Secure Firewall ASA", + vendor_name: "Cisco", + }, + profiles: [ + "security_control", + ], + version: "1.8.0", + }, + severity: "Informational", + severity_id: 1, + src_endpoint: { + interface_name: "outside", + ip: 203.0.113.144, + port: 3426, + }, + time: 2022-06-22T12:01:03Z, + type_name: "Network Activity: Open", + type_uid: 400101, + unmapped: { + facility: 20, + content: "%ASA-6-302015: Built inbound UDP connection 79 for outside:203.0.113.144/3426 (203.0.113.144/3426)(LOCAL\\vpn-e, 456) to inside:198.51.100.114/9805 (198.51.100.114/9805)(LOCAL\\vpn-f, 789) (vpn-g)", + }, +} { activity_id: 1, activity_name: "Open", diff --git a/cisco/tests/asa/ocsf/inputs/access_control.txt b/cisco/tests/asa/ocsf/inputs/access_control.txt index 25d1d650..7ebf4a97 100644 --- a/cisco/tests/asa/ocsf/inputs/access_control.txt +++ b/cisco/tests/asa/ocsf/inputs/access_control.txt @@ -13,3 +13,14 @@ <163>Jun 18 2025 11:38:12 asa-fw : %ASA-3-313008: Denied IPv6-ICMP type=136, code=0 from fe80::21a:2bff:fe3c:4d5e on interface inside <163>Jun 18 2025 11:38:14 asa-fw : %ASA-3-710003: TCP access denied by ACL from 198.51.100.51/65396 to crypto:host.example/80 <163>Jun 18 2025 11:38:15 asa-fw : %ASA-3-710005: UDP request discarded from 198.51.100.52/60389 to outside:10.1.1.31/44861 +<166>May 22 2021 09:19:17 asa-edge-02 : %ASA-6-106100: access-list inbound_acl permitted udp dmz2/192.0.2.34(56575) -> inside/198.51.100.35(53) hit-cnt 1 first hit [0x11111111, 0x22222222] +<166>May 22 2021 09:20:18 asa-edge-02 : %ASA-6-106100: access-list inbound_acl permitted udp dmz2/192.0.2.34(56575)(LOCAL\\sample-user) -> inside/198.51.100.35(53) hit-cnt 1 first hit [0x33333333, 0x44444444] +<163>May 23 2021 09:21:19 asa-edge-03 : %ASA-session-3-106102: access-list client_dns permitted udp for user test-user outside/198.51.100.20(49721) -> inside/192.0.2.40(53) hit-cnt 1 first hit [0x55555555, 0x66666666] +<161>May 23 2021 09:22:20 asa-edge-03 : %ASA-1-106103: access-list edge_filter denied icmp for user analyst inside/192.0.2.3(64321) -> outside/203.0.113.144(8080) hit-cnt 1 first hit [0x77777777, 0x88888888] +<164>May 25 2025 09:24:22 asa-edge-05 : %ASA-4-106103: access-list test_acl denied tcp for user 'quoted-user' outside/203.0.113.142(51950) -> inside/198.51.100.112(443) hit-cnt 1 first hit [0x99999999, 0x0] +<164>May 19 2021 09:13:11 asa-edge-01 : %ASA-4-106023: Deny icmp src Inside:192.0.2.10 dst Outside:198.51.100.10 (type 11, code 0) by access-group "inside_policy_in" [0x0, 0x0] +<164>May 20 2021 09:14:12 asa-edge-02 : %ASA-4-106023: Deny tcp src dmz:192.0.2.20/6316 dst outside:198.51.100.53/53 type 3, code 0, by access-group "dmz_policy" [0xa1b2c3d4, 0x0] +<164>May 19 2021 09:15:13 asa-edge-01 : %ASA-4-106023: Deny udp src Inside:192.0.2.11/57621(LOCAL\svc-cache) dst Outside:198.51.100.11/57621 by access-group "inside_policy_in" [0x0, 0x0] +<162>May 19 2021 09:16:14 asa-edge-01 : %ASA-2-106017: Deny IP due to Land Attack from 192.0.2.44 to 192.0.2.44 +<163>May 19 2021 09:17:15 asa-edge-01 : %ASA-3-313008: Denied IPv6-ICMP type=134, code=0 from 2001:db8::1234 on interface wan1 +<164>May 21 2021 09:18:16 asa-edge-02 : %ASA-4-313009: Denied invalid ICMP code 9, for Inside:192.0.2.206/8795 (192.0.2.206/8795) to identity:198.51.100.51/0 (198.51.100.51/0), ICMP id 295, ICMP type 8 diff --git a/cisco/tests/asa/ocsf/inputs/base.txt b/cisco/tests/asa/ocsf/inputs/base.txt index e6ab25f8..5d327e59 100644 --- a/cisco/tests/asa/ocsf/inputs/base.txt +++ b/cisco/tests/asa/ocsf/inputs/base.txt @@ -1,2 +1,11 @@ <165>Jun 18 2025 11:38:10 asa-fw : %ASA-5-111008: User 'enable_15' executed the 'configure terminal' command. <164>Jun 18 2025 11:40:00 asa-fw : %ASA-4-750003: Local: 198.51.100.1:500 Remote: 203.0.113.9:4500 Username: user1 Negotiation aborted due to ERROR: error +<165>May 24 2021 09:23:21 asa-sfr-01: %ASA-5-434004: SFR requested device to bypass further packet redirection and process TCP flow from sourceZone:203.0.113.144/8888 to destinationZone:192.0.2.222/12345 locally +<165>Aug 06 2025 12:02:03 asa-vpn-01 : %ASA-5-750002: Local:2001:db8::6:500 Remote:2001:db8::100:50329 Username:Unknown IKEv2 Received a IKE_INIT_SA request +<165>Aug 06 2025 12:02:04 asa-vpn-01 : %ASA-5-750003: Local:2001:db8::6:500 Remote:2001:db8::100:50329 Username:Unknown IKEv2 Negotiation aborted due to ERROR: Auth exchange failed +<165>Aug 06 2025 12:02:05 asa-vpn-02 : %ASA-5-750002: Local:vpn-a.example.test:500 Remote:vpn-b.example.test:50329 Username:Unknown IKEv2 Received a IKE_INIT_SA request +<165>Aug 06 2025 12:02:06 asa-vpn-02 : %ASA-5-750003: Local:vpn-a.example.test:500 Remote:vpn-b.example.test:50329 Username:Unknown IKEv2 Negotiation aborted due to ERROR: Auth exchange failed +<165>Aug 06 2025 12:02:07 asa-vpn-03 : %ASA-5-750002: Local:vpn-c.example.test:500 Remote:2001:db8::101:50329 Username:Unknown IKEv2 Received a IKE_INIT_SA request +<165>Aug 06 2025 12:02:08 asa-vpn-03 : %ASA-5-750003: Local:vpn-c.example.test:500 Remote:2001:db8::101:50329 Username:Unknown IKEv2 Negotiation aborted due to ERROR: Auth exchange failed +<165>Aug 06 2025 12:02:09 asa-vpn-04 : %ASA-5-750002: Local:2001:db8::7:500 Remote:vpn-d.example.test:50329 Username:Unknown IKEv2 Received a IKE_INIT_SA request +<165>Aug 06 2025 12:02:10 asa-vpn-04 : %ASA-5-750003: Local:2001:db8::7:500 Remote:vpn-d.example.test:50329 Username:Unknown IKEv2 Negotiation aborted due to ERROR: Auth exchange failed diff --git a/cisco/tests/asa/ocsf/inputs/built.txt b/cisco/tests/asa/ocsf/inputs/built.txt index 89044bf0..73057dc3 100644 --- a/cisco/tests/asa/ocsf/inputs/built.txt +++ b/cisco/tests/asa/ocsf/inputs/built.txt @@ -2,3 +2,6 @@ <166>Jun 18 2025 11:37:48 asa-fw : %ASA-6-302015: Built inbound UDP connection 1005 for outside:198.51.100.5/53 (198.51.100.5/53) to inside:10.1.1.3/51000 (10.1.1.3/51000) <166>2018-06-27T12:17:46Z asa : %ASA-6-302013: Built outbound TCP connection 100 for outside:198.51.100.60/443 (198.51.100.60/443) to inside:10.1.1.40/52000 (10.1.1.40/52000) <166>Jun 18 2025 11:37:48 asa-fw : %ASA-6-302013: Built inbound TCP connection 3332836331 for inside:10.1.1.9/50640 (198.51.100.20/50640) to umbrella:host.example/443 (UMBRELLA-DOMAIN-BLOCK-HIT/443) 0 24 +<166>Jun 22 2022 12:01:01 asa-edge-04 : %ASA-6-302015: Built inbound UDP connection 77 for outside:203.0.113.142/3424 (203.0.113.142/3424)(LOCAL\vpn-a, 123) to inside:198.51.100.112/9803 (198.51.100.112/9803) (vpn-b) +<166>Jun 22 2022 12:01:02 asa-edge-04 : %ASA-6-302015: Built inbound UDP connection 78 for outside:203.0.113.143/3425 (203.0.113.143/3425)(LOCAL\vpn-c) to inside:198.51.100.113/9804 (198.51.100.113/9804) (vpn-d) +<166>Jun 22 2022 12:01:03 asa-edge-04 : %ASA-6-302015: Built inbound UDP connection 79 for outside:203.0.113.144/3426 (203.0.113.144/3426)(LOCAL\vpn-e, 456) to inside:198.51.100.114/9805 (198.51.100.114/9805)(LOCAL\vpn-f, 789) (vpn-g) diff --git a/cisco/tests/asa/ocsf/inputs/teardown.txt b/cisco/tests/asa/ocsf/inputs/teardown.txt index 1ca99947..b731c29d 100644 --- a/cisco/tests/asa/ocsf/inputs/teardown.txt +++ b/cisco/tests/asa/ocsf/inputs/teardown.txt @@ -1,3 +1,4 @@ <166>Jun 18 2025 11:37:50 asa-fw : %ASA-6-302014: Teardown TCP connection 9 for outside:192.0.2.2/80 to inside:10.1.1.2/4924 duration 0:00:03 bytes 2048 TCP FINs <166>Jun 18 2025 11:37:55 asa-fw : %ASA-6-302016: Teardown UDP connection 1005 for outside:198.51.100.5/53 to inside:10.1.1.3/51000 duration 0:00:05 bytes 312 <166>Jun 18 2025 11:38:16 asa-fw : %ASA-6-302021: Teardown ICMP connection for faddr 10.1.1.32/45078 gaddr 192.168.0.69/0 laddr 192.168.0.69/0 type 8 code 0 Internal-Data0/-1:RX[-1] +<166>May 19 2021 09:12:10 asa-edge-01 : %ASA-6-302016: Teardown UDP connection 220001337 for Outside:198.51.100.23/53723(LOCAL\svc-cache) to Inside:192.0.2.53/53 duration 0:00:01 bytes 256 (timeout) diff --git a/cisco/tests/asa/ocsf/teardown.txt b/cisco/tests/asa/ocsf/teardown.txt index 2af8fae0..a0405654 100644 --- a/cisco/tests/asa/ocsf/teardown.txt +++ b/cisco/tests/asa/ocsf/teardown.txt @@ -170,3 +170,63 @@ duration: "0:00:05", }, } +{ + activity_id: 2, + activity_name: "Close", + category_name: "Network Activity", + category_uid: 4, + class_name: "Network Activity", + class_uid: 4001, + connection_info: { + protocol_name: "udp", + protocol_num: 17, + uid: "220001337", + }, + disposition: "Allowed", + disposition_id: 1, + dst_endpoint: { + interface_name: "Inside", + ip: 192.0.2.53, + port: 53, + }, + message: "Teardown UDP connection 220001337 for Outside:198.51.100.23/53723(LOCAL\\svc-cache) to Inside:192.0.2.53/53 duration 0:00:01 bytes 256 (timeout)", + metadata: { + event_code: "302016", + log_name: "cisco.asa", + loggers: [ + { + device: { + hostname: "asa-edge-01", + }, + log_format: "syslog", + }, + ], + product: { + name: "Secure Firewall ASA", + vendor_name: "Cisco", + }, + profiles: [ + "security_control", + ], + version: "1.8.0", + }, + severity: "Informational", + severity_id: 1, + src_endpoint: { + interface_name: "Outside", + ip: 198.51.100.23, + port: 53723, + }, + status_detail: "(timeout)", + time: 2021-05-19T09:12:10Z, + traffic: { + bytes: 256, + }, + type_name: "Network Activity: Close", + type_uid: 400102, + unmapped: { + facility: 20, + content: "%ASA-6-302016: Teardown UDP connection 220001337 for Outside:198.51.100.23/53723(LOCAL\\svc-cache) to Inside:192.0.2.53/53 duration 0:00:01 bytes 256 (timeout)", + duration: "0:00:01", + }, +} From d29834b3a7e0471bd02347dc2522973f65b10d45 Mon Sep 17 00:00:00 2001 From: zedoraps Date: Mon, 22 Jun 2026 19:21:06 +0200 Subject: [PATCH 20/20] Use accept_tcp for ASA syslog Update the Cisco ASA TCP syslog example to use the current listening operator name. Assisted-by: GPT-5 (Codex) --- cisco/examples/asa-from-syslog-tcp.tql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cisco/examples/asa-from-syslog-tcp.tql b/cisco/examples/asa-from-syslog-tcp.tql index 2566a646..27160273 100644 --- a/cisco/examples/asa-from-syslog-tcp.tql +++ b/cisco/examples/asa-from-syslog-tcp.tql @@ -6,7 +6,7 @@ description: | them to the `cisco` topic. --- -from_tcp "0.0.0.0:514" { +accept_tcp "0.0.0.0:514" { read_syslog } cisco::asa::parse