Apologies for the delayed response! I was reflecting on ET’s QA process with @trobinson667 and how it led to us to releasing…
- “2046294 - ET MALWARE Mystic Stealer C2 Client Hello Packet” as active
- “2046295 - ET MALWARE Mystic Stealer C2 Session Key Response Packet” as disabled/deactivated.
@trobinson667 shared some great insight that I’d like to share here now.
Before I get started, I want to mentioned I made a mistake. In my previous comment, I said
If we omit needed flowbit, the rule alerts a lot and there is an oppurtunity to improve rule performance by adding more content.
During QA, our process did not omit the flowbit mystic_stealer_conn_init when testing “2046295 - ET MALWARE Mystic Stealer C2 Session Key Response Packet”. Apologies for the confusion my comment caused.
OK, now onto discussing ET QA’s process and why 2046295 was noted as having high check activity by Suricata!
===
TLDR: 2046295 - ET MALWARE Mystic Stealer C2 Session Key Response Packet does not have defined content. As you mentioned and as I understand now, this rule does not have good choices for content as the response packet is gibberish. We can not tighten the rule further.
Suricata will always process/check a rule in the following order: content, flowbits, then other rule options. Given this order, Suricata will not use defined flowbits to ignore rules when checking traffic.
If you would like to ensure Suricata does not check a rule against traffic, please define a fast_pattern content that is unique.
Keep in mind that Suricata will only run a check for a given rule if
1) the selected fast_pattern content appears in the analyzed traffic
2) no content is selected (oh no! This is bad!)
===
The ET QA process uses Suricata Engine’s Rule Profiling stats to determine if a rule is performant, 11.9. Rule Profiling — Suricata 8.0.0-dev documentation. Let’sfocus on the importance of checks and matches and how 2046295 - ET MALWARE Mystic Stealer C2 Session Key Response Packet was considered frequently checked.
A Suricata rule consists of three parts, (6.1. Rules Format — Suricata 6.0.0 documentation):
- The action, that determines what happens when the signature matches
- The header, defining the protocol, IP addresses, ports and direction of the rule.
- The rule options, defining the specifics of the rule
As Suricata runs, it will take a ruleset and split the rules into buckets. These buckets are defined by header criteria like tcp $EXTERNAL_NET any -> $HOME_NET any
.
Suppose there is traffic that satisfies a bucket’s header criteria, tcp $EXTERNAL_NET any -> $HOME_NET any
. Then, Suricata will evaluate that bucket by iterating through each rule’s determined fast_pattern content THEN its other rule options.
What is a fast_pattern? It is a prefilter keyword placed after a rule’s content. This prefilter keyword only placed after one content value; its placement is explicitly user-defined or implicitly Suricata-defined. If you’d like to learn more about fast_patterns, see : 6.9.1.1. Suricata Fast Pattern Determination Explained — Suricata 6.0.0 documentation.
What are rule options? They are other parts of a rule such as other content or keywords like dsize and flowbits.
Without getting into too much detail, if a rule’s fast_pattern DOES NOT exists in traffic, then the rule is ignored and not checked. However, if the fast_pattern exists or NO CONTENT IS DEFINED AT ALL, then that rule will be checked so its entirety is evaluated for a possible match (e.g. alert) against traffic.
Again, a rule is first checked then it is evaluated completely to determine if there is a match.
Let’s review the provided rules.
Bucket 1: tcp $HOME_NET any -> $EXTERNAL_NET any
(msg:"ET MALWARE Mystic Stealer C2 Client Hello Packet"; flow:established,to_server;
content:"|b5 19 6f 94|"; fast_pattern;
dsize:4;
flowbits:set, mystic_stealer_conn_init;
flowbits:noalert;)
This rule will be checked only if content:“|b5 19 6f 94|”; exists. This rule will be considered a match if dsize:4; is satisfied. After the match occurs, set the flowbit and suppressed the alert.
Bucket 2: tcp $EXTERNAL_NET any -> $HOME_NET any
(msg:"ET MALWARE Mystic Stealer C2 Session Key Response Packet"; flow:established,to_client;
flowbits:isset, mystic_stealer_conn_init;
dsize:256;)
This rule does not have defined content, thus no fast_pattern. It will get checked every time Bucket 2’s header crieria is satified against traffic!
However there’s a flowbit present. Does it prevent the checks? No, "in Suricata, flowbits:isset is checked after the fast pattern match but before other content matches. ", 6.35. Differences From Snort — Suricata 6.0.0 documentation
Let’s reword that…
If a rule has flowbits, the flowbits will not be checked first. The determined fast_pattern content will be used, then the flowbits and other rule options (like dsize)
This high check activity is why the rule was released as deactivated.
Instead of treating these rules as a pair, they were released as independent rules. The Mystic Stealer C2 Client Hello Packet rule was performant in QA and so the flowbits:noalert was removed. The flowbit mystic_stealer_conn_init still exists both rules so that anyone that activates" Mystic Stealer C2 Session Key Response Packet" may use both rules.
Let us know if you have any more questions! Answering your question also helped me further understand when flowbits are parsed in Suricata amongst other rule options.
***Additional Notes:
I would like to point out an interesting note about the flow keyword. “The flow keyword can be used to match on direction of the flow”, 6.10. Flow Keywords — Suricata 6.0.0 documentation. And so, this keyword would be considered in a bucket’s header data criteria too.