Feature #8766
Updated by Jeff Lucovsky 16 days ago
Rule writers have While implementing bsize-as-depth (#4226, PRs #15596 / #15674), @catenacyber suggested that an explicit keyword would be friendlier for rule authors than reasoning about bsize / startswith / endswith to count indicate "this content is the bytes and write content:"..."; bsize:10;, or write content:"..."; startswith; endswith;, to express entire buffer." Proposal Add an "exact" keyword: a no-argument content that's modifier that pins the whole buffer. Neither says what buffer length to the writer means, and length of the bsize number has to be kept in step with preceding content. It is shorthand for bsize:<content-length> -- the content by hand. Philippe suggested a keyword for it while reviewing #4226. spans the whole buffer. Behavior * "exact" follows a content and takes no argument. * It adds a bsize equal is equivalent to bsize:<len> where len is the content's content length, so this rule: it reuses the existing bsize machinery: the length validation, the depth optimization, and -- for a lone content -- the startswith/endswith anchoring and MPM length prefilter. No new inspection path is added. * Because the length is derived, the rule stays correct if the content later changes; there is no literal length to keep in sync. * It is rejected when there is no preceding content, or when that content carries a relative modifier (distance/within), a negation, or a non-zero offset -- cases where "spans the whole buffer" no longer holds. Note that offset:0 is allowed. <pre> Example: alert dns any any -> any any (msg:"exact"; dns.query; \ content:"google.com"; exact; sid:1;) </pre> matches only when dns.query is "google.com", exactly "google.com" -- the same as content:"google.com"; bsize:10;. engine-analysis The analyzer now suggests "exact" when a single content has is pinned to be the only keyword in the whole buffer before "exact", and it can only carry nocase, a plain fast_pattern and offset:0, whether those come before or after "exact". Anything else gets the rule rejected: a negation, distance, within, depth, startswith, endswith, a non-zero offset, fast_pattern:only or a chopped fast_pattern. So does a rule that could never match, like one with another bsize that rules out startswith/endswith, replacing the content's length, or earlier bsize:<len> suggestion. Relationship to #4226 #4226 already handles the inference side: an isdataat that wants data past the content. It works on app-layer and packet buffers such as dns.query or tcp.hdr, but not on the raw payload, where dsize does the job, or on base64_data, where exact bsize does. "exact" works by adding equal to a bsize, so anything that improves bsize improves "exact" too. Once #4226 lone content's length is in, the rule is only evaluated when the buffer is exactly the content. applied as startswith/endswith automatically. engine-analysis will also suggest "exact" for a single content that has both startswith and endswith, where "exact" would work, and suggest a single bsize range when a buffer has both a lower and an upper bsize.