Suricata: The Snort Replacer (Part 3: Rules)

Discussion in 'Linux Security' started by Eric Hansen, Jul 30, 2013.

  1. Eric Hansen

    Eric Hansen Moderator Staff Writer

    Messages:
    124
    Likes Received:
    87
    Trophy Points:
    28
    In the previous installment, we configured Suricata and successfully tested it via a simple rule that alerts on ICMP/ping packets being detected. In this part we will cover some aspects about rules. While this will mostly be a quick and dirty overview, it should help you on your way to making Suricata more fit for your network and your personal needs.

    First lets look at the rule we created last time:
    Code:
    alert ip any any -> any any (msg:"ICMP detected"; sid:2; rev:1;)

    Rule Action

    We’ll break this down into parts:
    alert - This is the action we want to perform on the rule. suricata.yaml goes over the actions (called “Action Order”), but here’s a short description of options:
    1. pass - This can be compared to “ACCEPT” in iptables, in that if the packet matches this rule it’ll be accepted through. From my standpoint this is mostly useful if you suspect a rule is causing an issue but you don’t want to disable the rule altogether.
    2. drop - The packet doesn’t get processed any further down the chain and the sender isn’t notified. This is akin to the “DROP” target in iptables, where it will silently remove the packet from the network stack. The documents also say that an alert is generated as well. This also only works for IPS mode (which if you followed this guide, yours is in).
    3. reject - This acts the same as drop but will also notify the sender that the packet has been removed from the stack. Personally I don’t use this one unless I’m troubleshooting a rule so I at least know its hitting it, but your network might like this functionality.
    4. alert - This is the one we used in our rule, and it basically just notifies you of any packets that have matched rules. This is great for first testing out rules because the packets will still flow through the stack, but you will know its being detected, and then you can either change the action to drop/reject/pass or keep it as is.
    In the suricata.yaml file you’ll see something similar to this:
    Code:
    action-order:
    - pass
    - drop
    - reject
    - alert
    What this is stating is from top-to-bottom, which has precedence if multiple rules exist. If you have two of the same rules, for example, but one action was “pass” and the other was “alert”, then the “pass” action would be what processes the packet, ignoring the “alert” one.
    Protocol

    Next, there’s the protocol that we want our rule to keep an eye out for. Again I’ll explain the options.
    1. ip - This is the protocol that our rule will match. When ip is specified it will watch for all or any packets on the network involving the adapter. That’s why if you were to test our rule by doing anything at all to that machine, the rule would match.
    2. tcp - When you want to match a rule against TCP traffic, set the protocol to this. If reject action was set for the rule, the sender would be notified via RST flag set.
    3. udp - Similar to tcp but for UDP packets instead. Like everything else involving UDP, if reject action was set for the rule, then the sender may not be notified, since there is no checking in this protocol.
    4. icm - For ICMP packets (i.e.: ping). If reject is the action for the rule, ICMP-error is sent back as a response (as is with UDP).
    5. Suricata also allows you to specify layer 7 protocols as well which are HTTP (http), SSL and TLS (tls for both), FTP (ftp) and SMB (smb).
    Source and Destination IP and Port


    Now we start to get into the more complex stuff involving rules: source and destination information. If you want to make this easier on yourself, go back to part 2 where we specify the HOME_NET and EXTERNAL_NET to declare variables. However, you will still find this helpful as well.

    In our rule, we use any any for both source and destination IPs and ports. This is the lazy-man’s way of setting up rules and I highly suggest not doing it. You can specify multiple IPs, ports and variables in both the IP and port portions, and here’s the basic guidelines:
    1. ! - An exclamation mark specifies “not”, so “! 10.0.1.0/8” means any IP not in the 10.0.1.0 subnet.
    2. [] - This is how you specify multiple IPs and ports. They go inside the brackets and are comma-separated. You can also mix-and-match with the ! as well. For example, if you wanted the rule to match IP 192.168.0.5 but not 192.168.1.0/24, you would do “[! 192.168.1.0/24, 192.168.0.5]”. The value will be matched in the order you pass it.
    3. You can also throw in variables as well, like so: [$EXTERNAL_NET, !$HOME_NET] or if you want to exclude only two IP blocks from the rule: ![192.168.1.0/24,192.168.0.0/24] (this will match everything but IPs in the 192.168.1.0/24 and 192.168.0.0/24 ranges.
    Ports act similarly but they have one additional sign that you can use:
    1. : - Specifies a range of ports (i.e.: [80:82] will match ports 80-82). If you want a non-specific range (i.e.: only a maximum or minimum port number), you can do this: [:1024] (matches everything from 0-1024) or [1024:] (matches from 1024 to the highest [typically 65535]).
    Direction Specification

    Between the IP and ports is the direction of packet flow, in our case ->. There’s two options for this:
    1. -> - This is the most common and means only check if the source IP and port are coming in to the destination IP and port. Essentially this is Suricata’s version of the INPUT chain in iptables.
    2. <> - This will match packet flow in either direction, as if you were to add the rule to both the INPUT and OUTPUT chains in iptables. Typically not used as much but does serve some purposes.
    Rule Options

    This is the most complex part of writing your own rules and there are just way too many options to cover so I will just link you to the documents for this, but the last part is the rule options (everything you see between the ()). Since ours is extremely basic I will cover what we have in ours, then I’ll provide the links to the rest.

    Our rule options look like this:
    Code:
    msg:"ICMP detected"; sid:2; rev:1;
    These are the 3 most basic options you really need to make the rule parsable and usable in Suricata.

    1. msg - What will be prompted in our alert (unless you’re using pass as the action, set this regardless). If you remember from part 2, our alerts displayed the following text: “07/24/2013-21:38:17.547119 [**] [1:2:1] ICMP detected [**] [Classification: (null)] [Priority: 3] {ICMP} 10.0.3.1:8 -> 10.0.3.10:0” (at least mine did, yours will probably be different). Notice the “ICMP detected” part? That’s our message from the rule itself.
    2. sid - This is a unique ID for the rule. If multiple rules have the same sid Suricata will let you know, and not be nice about it. Typically you should pick a really high number (> 10,000) if you are going to write your own.
    3. rev - Revision number/ID. From my experience the program would hiccup or not load the rule properly if this wasn’t set, or handled properly (incremented by 1 every time the rule was changed). However, your mileage may vary.
    Like I said, there are so many rule options available, but they fall into 5 different categories right now: meta-settings (options not pertaining to any specifics about the packet [i.e.: msg, sid, rev]), payload (the packet data itself, such as IRC commands), HTTP (heavily used when TCP protocol is set, useful for using Suricata as a content filtering system), flow (helpful when wanting more fine-grained control over the connection’s status and such) and IP reputation (gives an idea if an IP is legit or known to be associated with malware, spam, etc...).

    As always, if you have any questions feel free to leave a comment and I’ll be glad to assist.

    Attached Files:

    • slide.jpg
      slide.jpg
      File size:
      17.7 KB
      Views:
      124,418
    Toots likes this.
  2. Rob

    Rob Administrator Staff Member

    Messages:
    575
    Likes Received:
    217
    Trophy Points:
    43
  3. robbtek

    robbtek New Member

    Messages:
    4
    Likes Received:
    0
    Trophy Points:
    1
    I want to check subnet but exclude one ip .

    I've read your documentation and in my suricata configuration I've set HOME_NET wit :

    HOME_NET: "[10.10.10.0/24, !10.10.10.247]"

    But, when I start suricata receive this error :

    12/8/2013 -- 08:56:09 - <Error> - [ERRCODE: SC_ERR_ADDRESS_ENGINE_GENERIC(89)] - failed to parse address " 10.10.10.247"
    12/8/2013 -- 08:56:09 - <Error> - [ERRCODE: SC_ERR_INVALID_YAML_CONF_ENTRY(139)] - failed to parse address var "HOME_NET" with value "[10.10.10.0/24, !10.10.10.247]". Please check it's syntax
    12/8/2013 -- 08:56:09 - <Error> - [ERRCODE: SC_ERR_INVALID_YAML_CONF_ENTRY(139)] - basic address vars test failed. Please check /etc/suricata/suricata.yaml for errors

    I've Suricata version 1.4.5 RELEASE .

    How can I exclude one ip from check, what is correct syntax .

    Thanks
  4. Eric Hansen

    Eric Hansen Moderator Staff Writer

    Messages:
    124
    Likes Received:
    87
    Trophy Points:
    28
    Thanks @Rob :D

    @robbtek I am not experiencing that issue. If you can post your full suricata.yaml file some place I can probably help more. I changed me to be the following and I had no issues:
    Code:
    HOME_NET: "[10.10.10.0/24,!10.10.10.247]"
  5. Kernl Kracker

    Kernl Kracker New Member

    Messages:
    1
    Likes Received:
    0
    Trophy Points:
    0
    It looks like a formatting error. Put a space between HOME_NET: and "[....
  6. robbtek

    robbtek New Member

    Messages:
    4
    Likes Received:
    0
    Trophy Points:
    1
    I tried with ...

    Code:
      HOME_NET: "[10.10.10.0/24, !10.10.10.247]"
    
    and ...

    Code:
      HOME_NET: "[10.10.10.0/24,!10.10.10.247]"
    
    There is a white space between HOME_NET: and "[....

    But same error
  7. Eric Hansen

    Eric Hansen Moderator Staff Writer

    Messages:
    124
    Likes Received:
    87
    Trophy Points:
    28
    Please post the suricata.yaml file on GitHub, pastebin or somewhere so I can look at the whole thing.
  8. robbtek

    robbtek New Member

    Messages:
    4
    Likes Received:
    0
    Trophy Points:
    1
    My suricata configuration file is the default installation file .
    I only change HOME_NET var (and want to exclude one ip from check)

    Thanks
  9. Eric Hansen

    Eric Hansen Moderator Staff Writer

    Messages:
    124
    Likes Received:
    87
    Trophy Points:
    28
    From the examples I've seen, its set like this:
    Code:
    [10.0.0.0/24, !10.0.0.5]
    According to the offical Redmine for Suricata's suricata.yaml (https://redmine.openinfosecfoundation.org/attachments/718/suricata.yaml#L732) its quoted. You seem to be doing both of these so I'm not sure where the issue is, as it should work (and does on my end).
  10. Memol

    Memol New Member

    Messages:
    2
    Likes Received:
    0
    Trophy Points:
    1
    Hello!
    I started a conversion but you may not have seen,I guess.
    I would be most grateful if you could help me with installing PF_Ring in Fedora for Suricata.I want to have it work with standard libpcap and PF_Ring as well.In fact I have installed Suricata and it's working properly ,now I want to have it with PF_Ring.
    Thank you in advance.
    Last edited: Sep 28, 2013
  11. Eric Hansen

    Eric Hansen Moderator Staff Writer

    Messages:
    124
    Likes Received:
    87
    Trophy Points:
    28
    Sorry currently in the middle of getting married and stuff very soon.

    As for this working with PF_Ring, I can't guarantee it. However, from what I've seen, this should compile Suricata to make it happen:
    Code:
    sudo ./configure --enable-pfring --with-libpfring-libraries=/usr/local/lib --with-libpfring-includes=/usr/local/include --with-libpcap-libraries=/usr/local/lib --with-libpcap-includes=/usr/local/include 
    Replace "/usr/local" with the correct path if need be.

    Then your modprobe file for PF_Ring should look like this:
    Code:
    options pf_ring transparent_mode=0 min_num_slots=32768 enable_tx_capture=0
    Lastly you can start Suricata like this:
    Code:
    sudo /usr/local/bin/suricata --pfring-int=eth0 --pfring-cluster-id=99 --pfring-cluster-type=cluster_flow -c /etc/suricata/suricata.yaml
    Changing the appropriate information (i.e.: eth0 to your interface).
  12. Memol

    Memol New Member

    Messages:
    2
    Likes Received:
    0
    Trophy Points:
    1
    Thank you so much. I'm sorry if I made you trouble.
    Wish you the best!
    Hope you'll live happily together for ever!:)
    Love your wife sacrificially so she blooms as God planned.Bible(26-27).
  13. aditya_prakash90

    aditya_prakash90 New Member

    Messages:
    1
    Likes Received:
    0
    Trophy Points:
    1
    hi i m new to this group and also to snort. my doubt is that when snort action is BLOCK then the signature is getting triggered in the alert file only for the first time for specific attack. for regenerating it ,i need to kill snort and run it again. but when this is in ALERT mode ,for each attack of same type the alert is getting triggered everytime .

    for example : when i m doing svmap for 1st time with BLOCK mode alert is getting triggered, again i do the same svmap the alert is not getting triggered eventhough attack is prevented from happening.
    but when in ALERT mode for each attempt of svmap(attacking tool) signature is getting triggered without running the snort again.

    so is this behaviour normal keeping snort function in mind that when in drop mode the snort blocks the attack and alert is triggered only once(that is for the 1st time) or it should triggered for each attempt.

    i will be highly obliged if somebody helps me out
    aditya prakash

Share This Page