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..d39adb09 --- /dev/null +++ b/cisco/changelog/unreleased/add-cisco-asa-support.md @@ -0,0 +1,43 @@ +--- +title: Add Cisco Secure Firewall ASA support +type: feature +authors: + - zedoraps +prs: + - 162 +created: 2026-06-18T00:00:00Z +--- + +The `cisco` package now parses Cisco Secure Firewall ASA syslog messages and +maps them to OCSF. + +`cisco::asa::parse` extracts the `%ASA--: ` frame +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 +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 provides. + +`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`. diff --git a/cisco/examples/asa-from-syslog-tcp.tql b/cisco/examples/asa-from-syslog-tcp.tql new file mode 100644 index 00000000..27160273 --- /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. +--- + +accept_tcp "0.0.0.0:514" { + read_syslog +} +cisco::asa::parse +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/access_control.tql b/cisco/operators/asa/ocsf/events/access_control.tql new file mode 100644 index 00000000..67da17f2 --- /dev/null +++ b/cisco/operators/asa/ocsf/events/access_control.tql @@ -0,0 +1,65 @@ +--- +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 + 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, + } +} + +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 = { + inbound: 1, + outbound: 2, + } + if $directions[$event.asa.direction]? != null { + $event.ocsf.connection_info.direction_id = $directions[$event.asa.direction] + } +} +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 +} + +// 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" { + $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/authentication.tql b/cisco/operators/asa/ocsf/events/authentication.tql new file mode 100644 index 00000000..19ed56c0 --- /dev/null +++ b/cisco/operators/asa/ocsf/events/authentication.tql @@ -0,0 +1,66 @@ +--- +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. +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 { + $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", 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? != 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 { + $event.ocsf.status_id = 0 // Unknown +} diff --git a/cisco/operators/asa/ocsf/events/built.tql b/cisco/operators/asa/ocsf/events/built.tql new file mode 100644 index 00000000..95cc09ad --- /dev/null +++ b/cisco/operators/asa/ocsf/events/built.tql @@ -0,0 +1,30 @@ +--- +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. +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. +$event.ocsf.metadata.profiles = ["security_control"] +$event.ocsf.disposition_id = 1 // Allowed 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..60cdde75 --- /dev/null +++ b/cisco/operators/asa/ocsf/events/teardown.tql @@ -0,0 +1,32 @@ +--- +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 + +// 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 +} + +// Connection decisions populate the security_control profile. +$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 new file mode 100644 index 00000000..9bac74f9 --- /dev/null +++ b/cisco/operators/asa/ocsf/map.tql @@ -0,0 +1,104 @@ +--- +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", + }, + // The event mappers that set firewall fields add the security_control profile. + 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", + }] +} + +// 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).time() + } 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) { + // 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 + } +} + +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 | 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 } +} + +// The message ID is recorded in metadata.event_code, so drop it from unmapped. +drop $event.asa.message_id? + +// 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/operators/asa/ocsf/network_endpoints.tql b/cisco/operators/asa/ocsf/network_endpoints.tql new file mode 100644 index 00000000..3f525376 --- /dev/null +++ b/cisco/operators/asa/ocsf/network_endpoints.tql @@ -0,0 +1,108 @@ +--- +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 + connection id, 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 = {} +if $event.asa.connection_id? != null { + $event.ocsf.connection_info.uid = (move $event.asa.connection_id).string() +} + +// --- 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 + } + $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? + +// --- 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 + } + $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? + +// --- 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, + "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. +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 +} 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? diff --git a/cisco/operators/asa/parse.tql b/cisco/operators/asa/parse.tql new file mode 100644 index 00000000..1440db65 --- /dev/null +++ b/cisco/operators/asa/parse.tql @@ -0,0 +1,134 @@ +--- +description: >- + Parses a Cisco Secure Firewall ASA message into a normalized ASA event. + + 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. + + 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 ASA message body (starting at `%ASA`). + type: field + default: content +--- + +// 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 = { + DIRECTION: r#"(inbound|outbound)"#, + ENDPOINT_TAG: r#"(?:\([^)]*\))*"#, + HOST: r#"[^/ ]+"#, +} +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 +// 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}\)%{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. +// 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( %{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}\)%{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 +// 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}"# + +// 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 $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 +// 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" + +// 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 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 => { 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)} } + 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)} } + 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 + } else if protocol == "protocol" and protocol_num? != null { + 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/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/access_control.txt b/cisco/tests/asa/ocsf/access_control.txt new file mode 100644 index 00000000..4aa78f75 --- /dev/null +++ b/cisco/tests/asa/ocsf/access_control.txt @@ -0,0 +1,1520 @@ +{ + 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: { + ip: 10.1.1.27, + }, + 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", + 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: "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, + unmapped: { + 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, + }, +} +{ + 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, + }, +} +{ + 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=136, code=0 from fe80::21a:2bff:fe3c:4d5e on interface inside", + 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: [ + "security_control", + ], + version: "1.8.0", + }, + severity: "High", + severity_id: 4, + src_endpoint: { + interface_name: "inside", + ip: fe80::21a:2bff:fe3c:4d5e, + }, + time: 2025-06-18T11:38:12Z, + type_name: "Network Activity: Traffic", + type_uid: 400106, + unmapped: { + facility: 20, + content: "%ASA-3-313008: Denied IPv6-ICMP type=136, code=0 from fe80::21a:2bff:fe3c:4d5e on interface inside", + 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: "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, + 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, + }, + 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", + 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: { + interface_name: "outside", + ip: 198.51.100.30, + }, + time: 2025-06-18T11:38:04Z, + type_name: "Network Activity: Traffic", + type_uid: 400106, + unmapped: { + facility: 20, + 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]", + 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", + 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: { + 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: { + facility: 20, + 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]", + 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: { + 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", + 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.43, + port: 137, + }, + time: 2025-06-18T11:38:06Z, + type_name: "Network Activity: Traffic", + type_uid: 400106, + unmapped: { + facility: 20, + content: "%ASA-2-106006: Deny inbound UDP from 198.51.100.43/137 to 10.1.1.23/137 on interface outside", + }, +} +{ + 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, + }, + 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", + 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: "dmz", + ip: 198.51.100.40, + }, + time: 2025-06-18T11:38:08Z, + type_name: "Network Activity: Traffic", + type_uid: 400106, + unmapped: { + facility: 20, + content: "%ASA-3-106014: Deny inbound icmp src dmz:198.51.100.40 dst inside:10.1.1.20 (type 8, code 0)", + 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_num: 47, + }, + disposition: "Blocked", + disposition_id: 2, + dst_endpoint: { + interface_name: "outside", + ip: 10.1.1.21, + }, + 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", + 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: "outside", + ip: 198.51.100.41, + }, + time: 2025-06-18T11:38:07Z, + type_name: "Network Activity: Traffic", + type_uid: 400106, + unmapped: { + facility: 20, + content: "%ASA-3-106010: Deny inbound protocol 47 src outside:198.51.100.41 dst outside:10.1.1.21", + }, +} +{ + 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, + }, + 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", + 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: { + interface_name: "outside", + ip: 198.51.100.9, + }, + time: 2025-06-18T11:38:02Z, + type_name: "Network Activity: Traffic", + type_uid: 400106, + unmapped: { + facility: 20, + 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]", + }, +} +{ + 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: "outside", + ip: 198.51.100.53, + port: 53, + }, + firewall_rule: { + name: "dmz_policy", + }, + 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-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: "dmz", + ip: 192.0.2.20, + port: 6316, + }, + time: 2021-05-20T09:14:12Z, + type_name: "Network Activity: Traffic", + type_uid: 400106, + unmapped: { + facility: 20, + 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, + }, +} +{ + 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", + 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: { + 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: { + 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]", + }, +} +{ + 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: 198.51.100.11, + port: 57621, + }, + 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: "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.11, + port: 57621, + }, + time: 2021-05-19T09:15:13Z, + type_name: "Network Activity: Traffic", + type_uid: 400106, + unmapped: { + facility: 20, + 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]", + }, +} +{ + 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", + 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", + 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: { + ip: 198.51.100.51, + port: 65396, + }, + time: 2025-06-18T11:38:14Z, + type_name: "Network Activity: Traffic", + type_uid: 400106, + unmapped: { + facility: 20, + content: "%ASA-3-710003: TCP access denied by ACL from 198.51.100.51/65396 to crypto:host.example/80", + }, +} +{ + 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", + 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: { + ip: 198.51.100.52, + port: 60389, + }, + time: 2025-06-18T11:38:15Z, + type_name: "Network Activity: Traffic", + type_uid: 400106, + unmapped: { + facility: 20, + content: "%ASA-3-710005: UDP request discarded from 198.51.100.52/60389 to outside:10.1.1.31/44861", + }, +} +{ + 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", + 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: { + 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: { + facility: 20, + 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]", + }, +} +{ + 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", + 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.45, + port: 49543, + }, + time: 2025-06-18T11:38:09Z, + type_name: "Network Activity: Traffic", + type_uid: 400106, + unmapped: { + facility: 20, + 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/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..db5b768e --- /dev/null +++ b/cisco/tests/asa/ocsf/authentication.txt @@ -0,0 +1,193 @@ +{ + 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, + content: "%ASA-6-722051: Group User IP <198.51.100.60> IPv4 Address <10.8.0.5> IPv6 address <::> assigned to session", + 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, + 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", + 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, + content: "%ASA-5-746013: user-identity: Delete IP-User mapping 10.1.1.40 - LOCAL\\user03 Succeeded - VPN user logout", + }, + 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, + content: "%ASA-5-746013: user-identity: Delete IP-User mapping 10.1.1.41 - LOCAL\\user04 Failed - PIP notification", + }, + user: { + domain: "LOCAL", + name: "user04", + }, +} diff --git a/cisco/tests/asa/ocsf/base.tql b/cisco/tests/asa/ocsf/base.tql new file mode 100644 index 00000000..45627114 --- /dev/null +++ b/cisco/tests/asa/ocsf/base.tql @@ -0,0 +1,9 @@ +from_file f"{env("TENZIR_INPUTS")}/base.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/base.txt b/cisco/tests/asa/ocsf/base.txt new file mode 100644 index 00000000..ddd472d4 --- /dev/null +++ b/cisco/tests/asa/ocsf/base.txt @@ -0,0 +1,378 @@ +{ + 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, + 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", + 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, + content: "%ASA-5-111008: User 'enable_15' executed the 'configure terminal' command.", + }, +} 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..0a4d0c3b --- /dev/null +++ b/cisco/tests/asa/ocsf/built.txt @@ -0,0 +1,411 @@ +{ + 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, + 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", + }, +} +{ + 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, + 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", + 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, + 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)", + }, +} +{ + 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, + 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)", + }, +} diff --git a/cisco/tests/asa/ocsf/inputs/access_control.txt b/cisco/tests/asa/ocsf/inputs/access_control.txt new file mode 100644 index 00000000..7ebf4a97 --- /dev/null +++ b/cisco/tests/asa/ocsf/inputs/access_control.txt @@ -0,0 +1,26 @@ +<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 +<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 +<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/authentication.txt b/cisco/tests/asa/ocsf/inputs/authentication.txt new file mode 100644 index 00000000..4c8cd087 --- /dev/null +++ b/cisco/tests/asa/ocsf/inputs/authentication.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/inputs/base.txt b/cisco/tests/asa/ocsf/inputs/base.txt new file mode 100644 index 00000000..5d327e59 --- /dev/null +++ b/cisco/tests/asa/ocsf/inputs/base.txt @@ -0,0 +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 new file mode 100644 index 00000000..73057dc3 --- /dev/null +++ b/cisco/tests/asa/ocsf/inputs/built.txt @@ -0,0 +1,7 @@ +<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 +<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/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/teardown.txt b/cisco/tests/asa/ocsf/inputs/teardown.txt new file mode 100644 index 00000000..b731c29d --- /dev/null +++ b/cisco/tests/asa/ocsf/inputs/teardown.txt @@ -0,0 +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/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/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..98a7953f --- /dev/null +++ b/cisco/tests/asa/ocsf/network.txt @@ -0,0 +1,49 @@ +{ + 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, + 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", + }, +} 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..a0405654 --- /dev/null +++ b/cisco/tests/asa/ocsf/teardown.txt @@ -0,0 +1,232 @@ +{ + 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: { + ip: 10.1.1.32, + }, + 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: { + ip: 192.168.0.69, + }, + time: 2025-06-18T11:38:16Z, + type_name: "Network Activity: Close", + type_uid: 400102, + unmapped: { + facility: 20, + 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]", + 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, + 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", + 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, + 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", + 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", + }, +} 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.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..6d35e745 --- /dev/null +++ b/cisco/tests/asa/parse.tql @@ -0,0 +1,5 @@ +from_file env("TENZIR_INPUT") { + read_syslog +} +cisco::asa::parse +sort message_id, text diff --git a/cisco/tests/asa/parse.txt b/cisco/tests/asa/parse.txt new file mode 100644 index 00000000..8228b2f8 --- /dev/null +++ b/cisco/tests/asa/parse.txt @@ -0,0 +1,181 @@ +{ + 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, + timestamp: "Jun 18 2025 11:38:00", + 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]", + 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", +} +{ + facility: 20, + severity: 4, + timestamp: "Jun 18 2025 11:38:03", + 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]", + 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", +} +{ + facility: 20, + severity: 5, + timestamp: "Jun 18 2025 11:38:10", + 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.", +} +{ + facility: 20, + severity: 6, + timestamp: "Jun 18 2025 11:37:48", + 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", + 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, +} +{ + 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: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, + timestamp: "Jun 18 2025 11:37:50", + 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", + 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..5f11d1c4 --- /dev/null +++ b/cisco/tests/asa/parse_content.txt @@ -0,0 +1,23 @@ +{ + facility: 20, + severity: 6, + timestamp: "Jun 18 2025 11:37:50", + 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", + 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_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"