Suricata Flowbits



  • Dear pfSense community,

    I have a question regarding the flowbits functionality of suricata.

    My goal is to whitelist traffic on some port, let's say port 15000. When a "start" packet arrives, which includes magic bytes in the payload (for example "00 01 02 03"), the following packets of the same stream should also be allowed to pass, without the magic bytes. Are the following rules correct?:

    pass tcp any any -> somenetwork/24 15000 (msg:"pass magic bytes"; content:"|00 01 02 03|"; flowbits:set,fb1;)
    pass tcp any any -> somenetwork/24 15000 (msg:"allow following"; flowbits:isset,fb1;)
    drop ip any any <> any any (msg:"default deny"; )

    I am having problems, because the packets are not segmented using TCP segmentation, but some proprietary solution on payload basis. Therefore, all my packets get dropped, which do not include the magic bytes.
    And how do I unset the flowbit fb1 after the stream has finished? The length of the stream  is only given in the payload of the "start" packet. Any ideas on how to correctly filter/pass such packets?

    Thanks in advance



  • If the packets are not segmented by the TCP stack, then Suricata might be having trouble detecting your "magic bytes" in order to set the flowbit.  If the flowbit is not triggered, then obviously your second rule fails to trigger and the traffic is dropped.

    I'm not very experienced with flowbits as I've never written any custom rules.

    This seems like a strange way to whitelist, though.  Why not simply examine SRC or DST addresses to whitelist, or are you trying to create some sort of malware that can let itself in the front door by exploiting some obscure rule?

    Bill



  • The strange thing is, that packets with magic bytes are passed through, but all following packets of the TCP stream are dropped. If the magic bytes are not detected, those packets would also have been dropped.

    I am trying to block port scans even from trusted clients, thats why I am setting up those rules.



  • @knownPlayer:

    The strange thing is, that packets with magic bytes are passed through, but all following packets of the TCP stream are dropped. If the magic bytes are not detected, those packets would also have been dropped.

    I am trying to block port scans even from trusted clients, thats why I am setting up those rules.

    Why would the magic byte packets necessarily be dropped?  Are there other rules that you know for sure would drop them?

    Bill



  • Okay, I managed to get port 15000 to work. Now I added another port to my rule:

    pass tcp any any -> somenetwork/24 [15000,15001] (msg:"pass magic bytes"; content:"|00 01 02 03|";)

    Then I created identical traffic for both ports (magic bytes included), but only packets with port 15001 are passed and packets with destination port 15000 are dropped via default rule.

    Why does this happen, any ideas?



  • @knownPlayer:

    Okay, I managed to get port 15000 to work. Now I added another port to my rule:

    pass tcp any any -> somenetwork/24 [15000,15001] (msg:"pass magic bytes"; content:"|00 01 02 03|";)

    Then I created identical traffic for both ports (magic bytes included), but only packets with port 15001 are passed and packets with destination port 15000 are dropped via default rule.

    Why does this happen, any ideas?

    What default rule are you talking about in this sentence?

    …packets with destination port 15000 are dropped via default rule.

    There is no "default rule" in Suricata.  Only the firewall has a default rule, and when using inline IPS mode the firewall rules and Suricata have no relationship.  Assuming Suricata is on your WAN, here is the flow path for an inbound packet –-

    WAN NIC –->  Suricata Engine –-> pf (packet filter firewall) –-> your LAN or other final destination network

    So first Suricata either allows the traffic to pass or it drops the packet completely and the packet never goes to the pf firewall.  Suricata will only drop a packet if a specific DROP rule is triggered, otherwise it will pass it.  PASS rules simply shortcut any further inspection after the PASS logic test.  So with your rule, if the inbound ports match (either 15000 or 15001) and the payload contains your magic bytes, then the packet is passed on to the pf firewall for more rules testing.  It is not evaluated by any other Suricata rules, though.  That is the point of a PASS rule.  It tells Suricata to not look at that packet any further.

    Now the packet matching the PASS rule in Suricata is handed off to the pf (packet filter) firewall.  It will evaluate all traffic against your firewall rules.  If you have a firewall rule that says allow traffic from any IP address to port 15001, then the packet passes.  If the packet has any other destination port (say 15000 from your example), then the pf firewall will block it unless you have a firewall rule that allows it.  But that block or pass has nothing to do with what Suricata did with the traffic.  The way Suricata comes into the picture is to either pass the traffic on to the pf firewall for further processing, or it drops the packet and never forwards it to the firewall if the packet triggers a Suricata DROP rule.

    I went down this rabbit trail because your use of "default rule" makes me think you are conflating the relationship of Suricata Inline IPS mode and the firewall thinking they work in concert.  They are instead, completely ignorant of each other and have no idea what each other did to the packet.

    Bill



  • With the default rule I mean my drop any rule from my first post. Sorry if I wasn't being clear.

    drop ip any any <> any any (msg:"default deny"; )

    Since I am experimenting with implementing a whitelist in Suricata, I allowed all traffic on all interfaces in my pfSense. This way I can focus on Suricata first.
    My test setup seems to be working now, though I don't know exactly why.  Might have been a system restart…

    Thank you for your help Bill.



  • @knownPlayer:

    With the default rule I mean my drop any rule from my first post. Sorry if I wasn't being clear.

    drop ip any any <> any any (msg:"default deny"; )

    Since I am experimenting with implementing a whitelist in Suricata, I allowed all traffic on all interfaces in my pfSense. This way I can focus on Suricata first.
    My test setup seems to be working now, though I don't know exactly why.  Might have been a system restart…

    Thank you for your help Bill.

    Oh … OK.  When I type replies the start of the thread is buried down on the bottom of the screen and I frequently forget what has been said before... :).  I thought maybe you were talking about the firewall's default deny rule since I had forgotten about the earlier discussion.

    Bill


Log in to reply