Comprehensive Guide to Packet Decoding in Snort: Configuration, Rules, and Modules

1 A Simple Rule

 alert tcp 202.110.8.1 any ->  122.111.90.8 80 (msg:”Web Access”; sid:1)
  • alert: indicates an alert will be triggered if this rule is matched
  • tcp: protocol type
  • IP address: source/destination IP address
  • any/80: port number
  • -> : directional operator, there is also a bidirectional operator <>
  • msg: message printed in alerts and log entries
  • sid: Snort rule id

This rule is straightforward. Snort uses rules to analyze packets in real time and log network traffic, functioning as a Network Intrusion Detection/Prevention System (NIDS/NIPS).

2 Snort Directory Structure

It’s recommended to configure Snort’s directory structure as follows:

 /etc/snort
 ├── barnyard2.conf      	#barnyard2 log analysis tool configuration file
 ├── snort.conf          	#snort configuration file (key file)
 ├── threshold.conf      	#event filtering configuration file
 ├── classification.config 	#rule classification configuration file (classtype)
 ├── reference.config      	#external reference configuration file (reference)
 ├── gen-msg.map      		#generate id and message mapping file
 ├── sid-msg.map      		#snort id and message mapping file
 ├── unicode.map      		#preprocessor http_inspect encoding translation file
 ├── preproc_rules       	#preprocessor and decoder rule sets
 │ ├── decoder.rules  
 │ ├── preprocessor.rules
 │ └── sensitive-data.rules
 ├── rules               	#Snort rule sets (key files)
 │  ├── web-iis.rules 
 │  ├── web-php.rules
 More…
 ├── so_rules            	#Share Object rule sets
 │  ├── browser-ie.rules
 │  ├── browser-other.rules    
 More…

3 Configuration File – snort.conf

This file is the core file for Snort configuration, including the following parts:

 1) Set the network variables.  					#Define network addresses for easier rule usage
2) Configure the decoder      					#Configure the decoder
3) Configure the base detection engine  		#Configure the base detection engine
4) Configure dynamic loaded libraries   		#Configure dynamic load libraries
5) Configure preprocessors     					#Configure preprocessors
6) Configure output plugins    					#Configure output plugins
7) Customize your rule set             			#Customize your rule set
8) Customize preprocessor and decoder rule set	#Customize preprocessor and decoder rule set
9) Customize shared object rule set             #Customize shared object rule set

4 Snort Architecture

Packet Sniffing and Decoding Module: Responsible for packet capturing and decoding based on TCP/IP protocols.

Preprocessor Module: 1. Packet reassembly preprocessor prevents fragmented attack info from bypassing Snort detection; 2. Protocol normalization preprocessor decodes protocols into a standard format for detection; 3. Protocol anomaly detection preprocessor.

Detection Engine Module: Matches packets against rules in three-dimensional linked lists and triggers alerts based on matches.

Alert/Logging Module: Transmits packets to the alert module for processing (database, log) as per rules.

5 Decoder and Preprocessor Modules

5.1 Module Overview

Both modules process packets before they reach the detection engine, hence they are discussed together.

The decoder module decodes raw network data packets by network protocol stack and saves the data in structures for the preprocessor to handle.

Post-decoding, packets undergo preprocessing for the detection engine to match rules. Preprocessors address IDS evading techniques:

  1. Inspect or modify suspicious packets to ensure proper interpretation by the detection engine.
  2. Traffic normalization for accurate signature matching by the detection engine.

Known IDS evasion techniques include:

  1. Polymorphic URL encoding
  2. Polymorphic shellcode
  3. Session splitting
  4. IP fragmentation

Snort includes three main types of preprocessors:

  1. Packet Reassembly Preprocessors: frag3 (IP fragmentation reassembly and attack detection), stream (TCP stream state maintenance and session reassembly)


  2. Protocol Normalization Preprocessors: http_inspect (HTTP traffic normalization), rpcDecode (RPC call normalization)


  3. Anomaly Detection Preprocessors: ARP spoof detection, sfPortscan (port scan detection)


5.2 Module Configuration

Configuration requires two steps, both in snort.conf.

  1. Configure decoder or preprocessor parameters in snort.conf.
  2. Enable detection rules in snort.conf.
5.2.1 Decoder Configuration Example
  1. Configure the decoder


     config disable_decode_alerts   			#Disable decode alerts
    config enable_decode_oversized_alerts
    # Trigger alert if packet's length exceeds protocol length fields
    # Stop generic decode events

    Format: config decoder [option], use # for comments


  2. Enable decoder detection rules


     include $PREPROC_RULE_PATH/decoder.rules

    Use include keyword in snort.conf to incorporate configuration and rule files.


  3. Decoder rule example – detect abnormal IP length in decoder.rules:


     alert ( msg:"DECODE_IPV4_DGRAM_GT_IPHDR"; sid:6; gid:116; rev:1; metadata:rule-type decode; classtype:protocol-command-decode;)

5.2.2 Preprocessor http_insepect Configuration Example
  1. Default configuration for http_inspect:


     preprocessor http_inspect: global iis_unicode_map unicode.map 1252 compress_depth 65535 decompress_depth 65535
    #unicode.map decodes unicode in http_inspect preprocessor
    preprocessor http_inspect_server: server default \
    http_methods { GET POST PUT SEARCH MKCOL ...} \
    ...
    enable_cookie #Extract cookies from HTTP requests/responses for rule matching
    normalize javascript #Decode javascript in tags...

  2. Enable preprocessor rules


     #include $PREPROC_RULE_PATH/preprocessor.rules

    Example of a decoder rule:


     alert ( msg:"DECODE_TCP_INVALID_OFFSET"; sid:46; gid:116; rev:1; metadata:rule-type decode; reference:cve,2004-0816; classtype:bad-unknown;)

The rule identified here is different from the previous one that was observed; it lacks information such as source/destination IP and port details, indicating that this rule is automatically triggered by the decoder without user intervention. Generally, we don’t need to modify the rules of decoders or preprocessors; we only need to add, configure, or delete plugins in the snort.conf file.

6 Detection Engine Module

Rule Structure:

alert tcp 202.110.8.1 any -> 122.111.90.8 80 (msg:”Web Access”; sid:1)

6.1 Rule Header

Action: In Snort, there are five types of actions: alert, log, pass, activate and dynamic.

  1. alert: Generates an alert and then logs the packet.
  2. log: Logs the packet.
  3. pass: Drops the packet.
  4. activate: Generates an alert and activates another dynamic rule.
  5. dynamic: Remains idle until activated by an activate rule, then acts as a log rule.

Protocol: Snort currently supports analysis of four protocols: TCP, UDP, ICMP, and IP. More protocols might be supported in the future, such as ARP, IGRP, GRE, OSPF, RIP, IPX, etc.

IP Address:

    1. An address consists of either a direct IP address or a CIDR block. IP address lists can also be specified, which are composed of multiple IP addresses and CIDR blocks separated by commas and enclosed in square brackets [].
    2. The negation operator is represented by !.
    3. The keyword “any” can be used to define any address.

      For example:


      alert tcp ![192.168.1.0/24,10.1.1.0/16] any -> 192.168.2.1 80 (msg:”notice!”; content|xxxx|;)

      Direction Operator: The direction operator -> indicates the direction of the flow to which the rule applies. The IP address and port number to the left of the direction operator are considered the source, while those to the right are the destination. There is also a bidirectional operator <>.


      Port Number:



      1. Port numbers can be represented in several ways, including any port, static port definitions, ranges, and using the negation operator.

      2. Static port definitions represent a single port number, such as 111 for portmapper, 23 for telnet, 80 for HTTP, etc.

      3. Port ranges are represented using the range operator “:”. For example, 80:, :1024, 80:1024.


      6.2 Rule Options


      Rule options are categorized into four types:



      1. General rule options

      2. Payload detection rule options

      3. Non-payload detection rule options

      4. Post-detection rule options


      6.2.1 General Rule Options



      • sid: Snort ID. This keyword is used to uniquely identify a Snort rule. The range of sids is allocated as follows:


        <100      # Reserved for future use
        100-1,000,000 # Included in Snort distribution
        >1,000,000 # Used for local rules



      • msg: Indicates a message. However, the msg in the rule itself is not functional; the relationship between the sid and msg is looked up in sid-msg.map.




      • sid-msg.map: Format: sid || msg


        Example: 384 || PROTOCOL-ICMP PING


        In /etc/snort/rules/protocol-icmp.rules, we find the rule:


        alert icmp $EXTERNAL_NET any -> $HOME_NET any (msg:"PROTOCOL-ICMP PING"; icode:0; itype:8; metadata:ruleset community; classtype:misc-activity; sid:384; rev:8;)

        This file maps sid to msg. Without this file, an alert would not have a corresponding message.


        This file allows customization of alert messages in conjunction with custom rules. Snort alerts follow the format Snort Alert[gid: sid: rev]. This indicates that a rule requires these three components to be uniquely identified; relying solely on sid is not sufficient.




      • gid: Generate ID. This indicates the part of Snort that triggers the rule, such as the decoder, preprocessor, or Snort’s own rules.


        You can view the /usr/local/share/doc/snort/generators file (which is not a configuration file):


        rules_subsystem       1   # Snort Rules Engine
        rpc_decode 106 # RPC Preprocessor
        stream4 111 # Stream4 Preprocessor
        ftp 125 # FTP Decoder

        Gids for decoder and preprocessor are not listed here in full, but we can see that Snort Rule Engine has a gid of 1 by default, indicating both custom rules and Snort’s own rules in /etc/snort/rules. Decoders and preprocessors also have sids. Here is an example:


        In /etc/snort/rules/protocol-icmp.rules, a rule:


        alert icmp $EXTERNAL_NET any -> $HOME_NET any (msg:"PROTOCOL-ICMP Traceroute"; icode:0; itype:30; metadata:ruleset community; classtype:misc-activity; sid:456; rev:8;)

        Default gid is 1


        In /etc/snort/preproc_rules/decoder.rules, another rule:


        alert (msg:"DECODE_IP6_EXCESS_EXT_HDR"; sid:456; gid:116; rev:1; metadata:rule-type decode; classtype:misc-activity;)

        Sid 456 exists in both rules, so gid is required for differentiation.




      • gen-msg.map: Similar to sid-msg.map, logically it includes sid-msg.map (sid-msg.map is equivalent to gid of 1 by default).


        Format: generatorid || alertid (sid) || MSG


        Example:


        1   || 1   || snort general alert
        129 || 2 || stream5: Data on SYN packet
        116 || 271 || snort_decoder: WARNING: IPv6 header claims to not be IPv6
        116 || 456 || snort_decoder: WARNING: too many IPV6 extension headers

        Using the second rule from the gid section as an example, if it is triggered, it would alert “snort_decoder: WARNING: too many IPV6 extension headers” instead of “DECODE_IP6_EXCESS_EXT_HDR”. Hence, msg in the rule only indicates, while actual alert messages are mapped using sid-msg.map and gen-msg.map.




      • rev: This keyword identifies the version of a modified rule. It must be used with sid and gid to uniquely identify a rule. Thus, the unique elements sid, gid, and rev are fully explained.




      • reference: External attack reference. This keyword allows a rule to include an external attack identification system. This plugin currently supports several specific systems, used by output plugins to provide additional information about the generated alert.




      • reference.config: Format: config reference: system URL


        Example: config reference: cve http://cve.mitre.org/cgi-bin/cvename.cgi?name= defines some security websites’ URLs. If the rule defines reference: cve,1001, it adds 1001 to the end of the URL to form http://cve.mitre.org/cgi-bin/cvename.cgi?name=1001, and clicking the reference in the alert would navigate to the specific website.


        Note: reference needs to be mapped to sid in sid-msg.map to be functional, similar to msg.




      • classtype: Classification type for rules. This keyword categorizes alerts into different attack types. Using this keyword and priority, users can assign priorities to each rule class.




      • priority: Sets the priority of the classtype. classtype and priority are used together, connected via the classification.config file.




      • classification.config: Format: config classification: shortname, short description, priority


        Example: config classification: attempted-admin, Attempted Administrator Privilege Gain, 1


        This file lists default values; the priority keyword can be used in rules to override priority.


        Example:


        alert tcp any any -> any 80 (msg:"EXPLOIT ntpdx overflow"; dsize:>128; classtype:attempted-admin; priority:10);



      • metadata




      Custom information can be added to the rules, usually in the form of key-value pairs. The general rule option only labels and categorizes a rule, without actual filtering and detection.


6.2.2 Payload Detection Rule Options

      • content content is one of Snort’s important keywords. It specifies the pattern to search for in the payload of the packet. Its option data can contain a mix of text and binary data. Binary data is usually enclosed in pipe symbols “|”, represented in bytecode, which is the hexadecimal form of the binary data.


        For example:


        alert tcp any any -> any 139 (content:"|5c 00|P|00|I|00|P|00|E|00 5c|";)
        alert tcp any any -> any 80 (content:“GET”;)

        content has many modifiers:


         nocase            Case-insensitive string match
        rawbytes Match raw packet data
        depth Match depth
        offset Starting offset for match
        distance Distance between content matches
        within Maximum distance between content matches
        http_cookie Match cookies
        http_raw_cookie Match raw (non-normalized) cookies
        http_header Match headers
        http_raw_header Match raw (non-normalized) headers
        http_method Match HTTP methods
        http_url Match URLs
        http_raw_url Match raw (non-normalized) URLs
        http_stat_code Match HTTP status codes
        http_stat_msg Match HTTP status messages
        http_encode Match encoding formats

        The http-prefixed modifiers need to be used in conjunction with the http_inspect preprocessor introduced earlier.



      • pcre Allows users to use regular expressions compatible with the PERL language.


        Format: pcre:[!]"(//|m)[ismxAEGRUBPHMCOIDKY]


        Example:


        alert tcp any any -> any 80 (content:“/foo.php?id="; pcre:"/\/foo.php?id=[0-9]{1,10}/iU";)

        For details on regular expressions, consult the snort_manual.



      • protected_content Uses hash algorithms to encrypt the content in queries, protecting the rule’s privacy.


        Format: protected_content:[!]"", length:orig_len[, hash:md5|sha256|sha512];



      • rawbytes Ignores the decoder and preprocessors’ operations, directly matching raw network packets.


The above are just some commonly used payload detection rule options. For more keywords, consult the snort_manual.

6.2.3 Non-Payload Detection Rule Options
 fragoffset          IP fragment offset
ttl                 IP Time-to-Live
tos                 IP Type of Service
id                  IP identification
ipopst              IP options
fragbits            IP fragment flags
dsize               Packet payload size
flags               TCP flags
seq                 TCP sequence number
ack                 TCP acknowledgment number
window              TCP window size
icmp_id             ICMP identification

These rule options match specific fields in the packet frame structure.

6.2.4 Post-Detection Rule Options
 logto               Log output path
session             Capture user data from TCP sessions
resp                Terminate malicious requests by sending responses
react               Not just log the specific packet triggering the rule
tag                 Not just log the specific packet triggering the rule
activates           Activate action
activates_by        Dynamic action
count               Number of packets that the dynamic rule can match once triggered
replace             Replace content
detection-filter    Detection filtering

6.3 Detection Engine Module Configuration


      1. Write rules in the *.rules files under /etc/rules directory



      2. Include the corresponding rules in snort.conf


        Example:


         include $RULE_PATH/local.rules
        #include $RULE_PATH/app-detect.rules
        #include $RULE_PATH/attack-responses.rules
        #include $RULE_PATH/backdoor.rules
        #include $RULE_PATH/bad-traffic.rules
        #include $RULE_PATH/blacklist.rules

7 Snort Alert/Log Module

7.1 Output Module Configuration

The output module configuration is in the snort.conf file under Configure output plugins. Multiple output formats are supported. The following example configures Snort to log alerts in unified2 format, and uses barnyard2 to parse unified2 files and log alerts into the database.

Set the log path:

 config logdir:/var/log/snort 

Set the output format to unified2:

 output unified2: filename snort.log, limit 128

barnyard2.conf

The barnyard2 configuration role is to log unified2 format data into the database.

Link to snort log:

 config waldo_file: /var/log/snort/barnyard.waldo 

Configure the database:

 output database: log, mysql, user=snort password=123456 dbname=snort host=localhost

7.2 Database


    • schema


       vseq: Database schema ID
      ctime: Database creation time

      Information table, not linked to other database contents.



    • sensor


       sid: Sensor ID
      hostname: User name of the sensor
      interface: Network interface of the sensor
      filter: Filtering rules for the sensor
      detail: Level of detail in sensor's monitoring mode
      encoding: Data representation format
      last_cid: Last captured alert ID for each sid


    • detail


       0 - fast: Quick detection
      1 - full: Comprehensive detection

      Detection level of the sensor.



    • encoding


       0 - Hex
      1 - base64
      2 - ASCII

      Data representation formats in the packet.



    • event


       sid: Sensor ID
      cid: Event ID - unique within sid
      signature: Corresponding signature ID in the signature table
      timestamp: System time of the alert event

      The core table, each event represents a packet.



    • signature


       sig_id: Unique rule ID
      sig_name: Alert name (message in alert statement)
      sig_class_id: Classification ID in sig_class table
      sig_priority: Alert priority
      sig_rev: Rule revision number
      sig_sid: Snort rule ID
      sig_gid: Generator ID

      Stores Snort rules, mapping sig_sid, sig_gid, and sig_rev to sid, gid, and rev in the rules.



    • sig_reference


       sig_id: Corresponding signature ID
      ref_id: Corresponding reference ID
      ref_seq: Reference sequence number

      Links signature to reference information.



    • reference


       ref_id: Main ID
      ref_system_id: Reference system ID
      ref_tag: Parameters following cve or bugtraq in rules


    • reference_system


       ref_system_id: Main ID
      ref_system_name: Name of the reference system (e.g., cve, url)


    • sig_class


       sig_class_id: Classification ID
      sig_class_name: Classification name

      Classification information for alert signatures.



    • iphdr



    • tcphdr



    • udphdr



    • icmphdr



    • data data_payload: Packet payload


      When the protocol in the rule is TCP, the data_payload contains the content following TCP


      When the protocol in the rule is ICMP, the data_payload contains the value of the data field in the ICMP header



    • opt IP and OPT options