Friday, January 11, 2013

Writing IPS rules Fortinet Style

In this blog, we will explore the writing of  IPS rules for mitigation. With this series of firewall, you have the ability to write very simple to complex rules. I do believe the system runs a snort equivalent sensor, but I'm not 100% sure about this and this only my gut feeling. So if you have a SNORT background, this firewall works very similar with snort.

The firewall has the ability to deploy DoS anomalies and IPS signatures to alert, pass or drop  any simple L3/4 to L7 attacks to some degree. It's  not the best at covering all levels of attacks, but it does work to some  degree of accuracy , &  if the attack is not of a pure L3  brute flood it should be effective.

When deploying  IPS signatures, fortinet has produce a custom signature syntax guide. This guide is posted  on their kb website. ( )  It provides you the fields that's allowed and the expected input for that syntax.

here's a simple basic HTTP rule;

config ips custom
    edit "badrefer01"
        set signature "F-SBID( --name \"badrefer\"; --attack_id 3710;  --default_action drop; --content  GET; --content Referer: http\\://; )"

The rule has almost all of the characteristics of a snort rule minus direction and ports. The direction and port is pulled from the  fwpolicy that's deployed and the ips sensor configuration , but you can also add directionality and port within the rule also;

e.g IPS sensor

The Sensor is bound to the fwpolicy and is applied for traffic matching that policy & if it has a IPS sensor enabled. The "action" taken  will be pulled from the rules within the signature and the sensor;

rule setting;

So be aware of the actions that can be set. The action upon a match, will be executed by that rule and if the cmds  log and log-packets options are set, then the resulting violation and packet will be logged.

Now let's look at a rule being applied within that sensor;

 fgt3040-fw01 # show ips sensor  default
config ips sensor
    edit "default"
        set comment "prevent critical attacks"
            config entries
                edit 1
                    set severity high critical
                edit 2
                    set action block
                    set log-packet enable
                        set rule 3710 1064 1065 1066 1068  

So we have  5 customer rules-id 3710,1064-068 being applied, the action will be to block and log-packet. So let's look at a blocked messages;

And here's a drill down on a log-packet details;

So the firewall is a simple IPS/DoS device but with the function builted in. Unlike the cisco ASA, the unit does not need any licenses or module card ( AIP ) installed in order to provide IPS functions.

The custom rules written for the IPS sensors are not to be confused with the can'd Fortinet Guard rules. These are  pre-canned av/signature rules that are download and updated automatically if you have a subscription services. You can execute a cmd  get system status  to determine what version of can'd signatures are installed.  And the name looks something like the following;

IPS-DB: 3.00150(2012-02-15 23:15)

Okay so let's look at our syntax options I will go over the most common ones used;

  • protocol ip|tcp|udp
  • name "insert the name for the rule"
  • content "insert content"
  • no_case
  • pcre
  • ip_flag
  • src_addr
  • dst_addr
  • ip_proto
  • icmp_code/type
Now the above are just a few and did you notice some  similarities to SNORT?

Okay here's a rule using just L3 address and HTTP content;

edit "kentest"
        set signature "F-SBID( --attack_id 1067;  --name \"myaddress\"; --default_action drop; --content  GET; --protocol tcp;  --dst_port 80; --src_addr; )"

and a icmp protocol rule;

edit "icmp_drop"
        set signature "F-SBID( --attack_id 2349;  --name \"drop icmp rfc1918 space\"; --default_action drop;  --protocol icmp;  --icmp_type 3; --icmp_code 4;  --src_addr [ ,,]; )"

And just  as in SNORT, if you  writing a ICMP protocol rule than you will use icmp fields in that rules.  Some fields can be used in all rules such as data sizes;
edit "icmp_drop_bigpackets"
     set signature "F-SBID( --attack_id 2355;  --name \"drop icmp big payloads\"; --default_action drop; --protocol icmp;  --icmp_type 8; --data_size  >400; )"

How about a SYN packet with payload;

edit "SYN_WITHpayload"
     set signature "F-SBID( --attack_id 666;  --name \"drop syn with payloads\"; --default_action drop; --protocol tcp; --tcp_flags S;  --data_size >0; )"

How about  TCP source port  being zero'd

edit "sport_zero"
     set signature "F-SBID( --attack_id 7010;  --name \"drop zero source port\"; --default_action drop; --protocol tcp; --src_port 0;  )"

Or the opposite   TCP dst  port being zero'd

edit "dport_zero"
     set signature "F-SBID( --attack_id 7021;  --name \"drop zero destination port\"; --default_action drop; --protocol tcp; --dst_port 0;  )"

If you can do it in SNORT, you probably can do it in  Fortinet Land.  When crafting  SNORT sid  numbers, you typical will be restrict to the follow range 1000-9999

if you tried to match the std SNORT communities ranges, you might  be warned with the following errors;  "drop large icmp echo_request: custom signature id must be between 1000 and 9999"

 I hope  you find this post usefull.

Ken Felix
Freelance Network & Security Engineer
kfelix at hyperfeed dot com


  1. This comment has been removed by the author.

  2. I found the solution..
    We use "--patern".

    1. Yes, and the pattern must be enclosed in double quotes (") and
      followed by a semicolon (;).


  3. This comment has been removed by the author.