Conversation
Filter version 3.1.0: - Add a third header pattern for the real '<PRI>%FTD-<level>-<id>: <text>' shape; it runs only when the two existing header patterns set nothing. - Split the key-value text of 430001, 430002, 430003 and 430007 into log.<Key> (go-sdk v1.1.36 keeps underscores, so DNS_TTL is stored as log.DNS_TTL). Map only SrcIP, DstIP, SrcPort, DstPort and Protocol to origin.ip, target.ip, origin.port, target.port and protocol, each from the first copy of its key. Read UserAgent whole. Do not split a text that holds a second %FTD- header (two messages joined by the collector). - Rewrite the 98 direct log.* comparisons with equals, greaterOrEqual and lessOrEqual, and replace the undeclared lgreaterOrEqual. - Write the 16 log.* geolocation results to log.<field>Geolocation. - Apply the six LINA step fixes shared with the Cisco ASA filter: 302013 direction, 302304 protocol, 305011/305012 action, 302017 users, the 106102/106103 add order (values unchanged) and the 113009/113011 guard. Rules version v1.0.1: - Intrusion rule: read message 430001 and the device's own Priority and Classification; drop the event-type, impact and syslog-level branches. - Non-standard-port rule: read ApplicationProtocol and InitiatorPackets, require a destination port and a destination outside the private ranges; the history search is unchanged. Names, impact, grouping and MITRE labels are unchanged. The malware, indicator-of-compromise and threat-intelligence rules are unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
plugins/alerts/testdata/cisco-firepower holds 58 fabricated raw lines (documentation addresses, example names, a made-up device UUID), the fields and alerts recorded from EventProcessor 8a3ade7 (go-sdk v1.1.36), the shared grok definitions, fabricated geolocation data and replay.py, which runs the lines through the playground and checks every event and alert. The non-standard-port rule is staged there as a condition-only test copy because no OpenSearch runs; its history search is not executed. cisco_firepower_filter_test.go checks the helper where clauses (truth tables, no error without a log object), the geolocation destinations, a model of the engine's step plugins against the recorded fields (header, key-value split with underscore names, joined messages, unparsed IDs, the shared LINA fixes and the typo fix), the new and guarded step conditions, the rule contract, both changed rule conditions as go-sdk predicates (positives and near misses) and the history placeholders. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Records the evidence basis (genuine device records reviewed privately, the empty Firepower index, Cisco documentation unavailable), each change and its proof, the rules' assumptions about Cisco's meaning, expected volumes, the deferred items, the routing note and the known limits. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ed image Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The EventProcessor 8a3ade7 grok plugin trims the remaining text before
each pattern and counts an empty match as no match, and then the whole
step writes nothing. Three patterns in filters/cisco/firepower.yml match empty
text at the start:
- 302003/302004, first variant: '(to\s)?' is empty on every 302003 line,
so a 302003 line whose local side is a host name was parsed by neither
variant. The optional "to" is now read with the local address, and a
trim step removes it.
- 302022/302024/302026: the two steps for a mapped address without a
port read it with '{{.data}}', which on its own always matches empty
text, so they never wrote. They now read '[^/()]+', which only fits
when no port follows.
Filter version 3.1.1. Five fabricated lines are added to
testdata/cisco-firepower (302003 with an address and with a host name, 302004
with "to", 302022 with a mapped port, 302024 without one). Their expected
fields were recorded from the 8a3ade7 playground after the declared checks
(F-G1, F-G2). TestCiscoFirepowerGrokPatternsNeverMatchEmpty tries every
expanded pattern alone on texts that start with each printable character.
The model test and the new test both fail on 3.1.0 and pass on 3.1.1.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Adds the version 3.1.1 section: what the grok plugin does with an empty match, the three LINA steps and their fix, and the checks on EventProcessor 8a3ade7. replay.py gives 63 events and the same 10 alerts, none of the 148 private lines is one of these messages, the go-sdk v1.1.36 rule replay passes 21 of 21 checks, and the full suite has 51 passing and 11 skipped tests. The fixture and test counts elsewhere in the audit are updated. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The Firepower filter extracts nothing from real Firepower Threat Defense syslog, so none of the five Firepower rules can fire.
This draft does three things:
Built and tested on the latest versions: v11
d2479c1a, go-sdk v1.1.36, and EventProcessor8a3ade7. That engine revision is the same source as today'seventprocessor:v11.2.14image and itseventprocessor/base:1.1.7.Predecessor: #2600 (closed, historical context only).
Evidence (read-only, described without identifying data)
<PRI>%FTD-<sev>-<id>:with no timestamp and no device name. The payload isKey: Value, Key: Valuewith 58 distinct keys.Filter (
filters/cisco/firepower.yml, 3.0.3 → 3.1.1)log.*with go-sdk v1.1.36 names (underscores kept, e.g.log.DNS_TTL; spaces removed, e.g.log.PrefilterPolicy).origin.ip,target.ip,origin.port,target.port(numeric) andprotocol.log.*comparisons become go-sdk helpers. The raw form fails to compile when nologobject exists and adds an error per step.lgreaterOrEqualbecomesgreaterOrEqual/lessOrEqual. Before, that step's condition failed on every event.log.<field>Geolocationinstead of replacing the address;towas its own pattern,(to\s)?, which matched empty text on every 302003 line. A 302003 line whose local side is a host name was parsed by no step. Thetois now read with the address and trimmed off.{{.data}}, which on its own always matches empty text, so they never wrote. They now read[^/()]+, which only fits when no port follows.Rules
intrusion_prevention_high_priority_events.yml):Priority= 1, or one of fourClassificationdescriptions.log.eventType/lowercase names never existed in syslog, andlog.severityis the syslog level ("1" on every record).c2_nonstandard_port.yml):log.ApplicationProtocolandgreaterThan("log.InitiatorPackets", 0). The oldequals(..., true)could never match a string.Validation
8a3ade7: five new fabricated lines show both defects with version 3.1.0 (the 302003 host-name line kept only its result; the 302024 line had no mapped address) and the fix with 3.1.1; the other three lines are identical. Committedreplay.py: 63 events (58 plus the five new ones), 0 errors, every field as recorded, the same 10 alerts, no circuit breaker, no history search. None of the 148 private lines is one of these messages. go-sdk v1.1.36 rule replay over the 63 committed events: 21/21 checks.plugins/alertssuite passes (v1.1.36): 51 pass, 11 skip (other technologies' private-evidence tests), 0 fail. Seven of the eight new Firepower tests fail against the original files. The newest one tries every grok pattern alone on texts that start with each printable character and fails when one matches empty text at the start; it and the model test (now with the five new lines) also fail on version 3.1.0.Deferred
These need Cisco documentation or an owner decision:
For the owner, not a filter change
On one instance the Firepower device logs arrive on the Cisco Switch input, so they never reach this filter. Point that device at the Firepower input. About 1.25% of those records are two syslog messages glued together by the collector.
Limits
log.*fields is untested.See
filters/audits/cisco-firepower.md.🤖 Generated with Claude Code