Bug #1754
closedInconsistent behavior with 'only_stream' flow keyword
Description
In testing some Suricata rules with RDP pcap, I seem to have uncovered inconsistent behavior with the 'only_stream' flow keyword. My original testing was with rules invoking luajit scripts, but the behavior occurs even without luajit scripts, so I have removed them from these rules for simplicity:
Say I want to alert on all streams flowing to port 3389. This rule will not fire. I believe this to be a bug.
alert tcp any any -> any 3389 (msg:"RDP connection request"; flow:to_server, established, only_stream; sid:15; rev:1;) $ tail -1 /var/log/suricata/suricata-stats.log | jq .stats.detect { "alert": 0, "alert_delta": 0 }
However, if I change 'only_stream' to 'no_stream' to alert on every packet flowing to port 3389, this rule does fire. And it fires A LOT.
alert tcp any any -> any 3389 (msg:"RDP connection request"; flow:to_server, established, no_stream; sid:15; rev:1;) $ tail -1 /var/log/suricata/suricata-stats.log | jq .stats.detect { "alert": 3333875, "alert_delta": 1380607 }
But finally, if I switch back to 'only_stream', but tighten the rule to add a content field that checks the first byte of the payload, the rule fires.
alert tcp any any -> any 3389 (msg:"RDP connection request"; flow:to_server, established, only_stream; content:"|03|"; offset:0; depth:1; sid:15; rev:1;) $ tail -1 /var/log/suricata/suricata-stats.log | jq .stats.detect { "alert": 363, "alert_delta": 363 }
I could possibly submit pcap privately (pending approval), but I imagine that this bug wouldn't be hard to reproduce for other traffic.