I wanted to draft a response to a post made to the snort-users group. My goal was to compare rules for detecting network activity occurring on non HTTP_PORTS that use the 'flow' option available in Snort with two alternate rules that do not use the 'flow' option. Before writing this article, I was almost certain Rule B would be my first choice, to be followed by Rule C, however, by the time I had finished the first draft, I could see that Rule A (which is is most preferred ( as long as I can specify a source or destination address for either EXTERNAL_NET or HTTP_SERVERS. )
Rule comparison tests
I created three test rules for this comparison. Rules A and B do not use 'flow'. Rule C does use 'flow'. Of the two that do not use flow, Rule A negates HTTP_PORTS from being the destination port in matching packets, whereas Rule B negates HTTP_PORTS from being the source port AND/OR the destination port in matching packets. I ran snort-2.4.3 and snort-2.7.0 against the same pre-captured data. Both versions of snort returned the same results exhibiting the same behavior.
Basic snort configuration
var EXTERNAL_NET any
var HTTP_SERVERS any
var HTTP_PORTS [ 80 ]
alert tcp $EXTERNAL_NET any -> $HTTP_SERVERS !$HTTP_PORTS (msg:"LOCAL NONHTTP nonflow test Rule A"; sid: 2000001; )alert tcp $EXTERNAL_NET !$HTTP_PORTS -> $HTTP_SERVERS HTTP_PORTS (msg:"LOCAL NONHTTP nonflow test Rule B"; sid: 2000002; )
alert tcp $EXTERNAL_NET any -> $HTTP_SERVERS !$HTTP_PORTS (msg:"LOCAL NONHTTP flow test Rule C"; flow:to_server,established; sid: 2000003; )
How does each work ?
Rule A successfully ignores HTTP_PORTS packets sent from the apparent client, but this rule matches on all return packets when we define both $EXTERNAL_NET and $HTTP_SERVERS to match 'any' host address. This latter behavior is what we definitely want to avoid.
Rule B successfully ignores HTTP_PORTS traffic, including return packets and all traffic originating from HTTP_PORTS
Rule C successfully ignores HTTP_PORTS traffic, including return traffic but only for established TCP connections. In cases where a connection is never established, network host scans (i.e. of random TCP ports) would not trigger this alert .
Which is "better" to implement: A, B or C ?
Rule A provides alerts when packets arrive on non-HTTP_PORTS but requires specifying a source or target host network to enforce packet direction and prevent related return packets from triggering on this rule.
Rule B provides alerts when packets arrive on non-HTTP_PORTS. This rule does nothing to notify you of packets that contain HTTP_PORTS as a source or estination port. Consider this rule to be 'blind' to TCP traffic involving HTTP_PORTS.
Rule C provides alerts only when access is made to normal, responsive TCP servers listening on non-HTTP_PORTS.
Why my preferred choices are A, B, and C; respectively
Rule A - When you can specify either a source or destination network to imply packet direction, this rule provides the most visibility of network activity occuring on non-HTTP_PORTS.
Rule B - If you cannot specify a source or destination network for this particular rule, this method might be the next best choice.
Problem #1: You will need to create second rule to catch the traffic this rule will miss; specifically traffic originating from HTTP_PORTS to any other port. This other rule will need to specify either a source or destination network to indicate which hosts should not be sending packets from HTTP_PORTS. (Only servers should send packets from HTTP_PORTS, whereas clients generally shouldn't.)
alert tcp $EXTERNAL_NET $HTTP_PORTS -> $REALHTTP_SERVERS !$HTTP_PORTS (msg:"LOCAL NONHTTP nonflow test Rule B fixup"; sid: 2000004; )
Problem #2: Caution: The above rule ignores packets originating from
$HTTP_PORTS going to $HTTP_PORTS. If you do not trust these connections, the
following rule would resolve this problem.alert tcp $EXTERNAL_NET $HTTP_PORTS -> $REALHTTP_SERVERS any (msg:"LOCAL NONHTTP nonflow test Rule B fixup version 2 "; sid: 2000004; )
Rule C - This works well if I have a smart network firewall or a proxy server that effectively filters abnormal TCP traffic (i.e. half-open connections and stealth scans, or custom/backdoor-type communications using faux-RFC compliant TCP protocol headers that may not qualify the 'flow' as being 'established'.)
Problem #1 You need a backup plan to catch the stealth activity that this rule may miss.
Final thoughts
In this article I was most interested in detecting all non-HTTP_PORTS traffic. I chose Rule A for this because it provides the best detection capability for the traffic I am seeking to detect. Having to define either a source or destination network to make the rule work properly is worth the detection capability gained over the other rules tested with or without flow.
If I wanted to perform passive server availibility monitoring or if I wanted to monitor the integrity of HTTP server responses in all normal traffic, the use of 'flow' (as demonstrated in Rule C ) would be a good starting point for this.