Understanding Snort’s Decoder Module: Decoding Network Packets for Intrusion Detection

0x00 A Simple Rule: Decoder Module

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

  • alert: indicates that an alert will be triggered if this rule is activated
  • tcp: protocol type
  • IP address: source/destination IP address
  • any/80: port number
  • ->: direction operator, with <> being bidirectional.
  • msg: prints a message in the alert and packet log
  • sid: Snort rule ID…

The meaning of this rule is easily understood at first glance. Snort uses rules to match packets for real-time traffic analysis and network packet logging in a Network Intrusion Detection/Prevention System (NIDS/NIPS).

0x01 SNORT Directory Structure – Decoder Module

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

/etc/snort
 ├── barnyard2.conf      Barnyard2 log analysis tool configuration file
 ├── snort.conf          Snort configuration file (critical)
 ├── threshold.conf      Event filtering configuration file
 ├── classification.config  Rule classification configuration file (classtype)
 ├── reference.config      External reference configuration file (reference)
 ├── gen-msg.map      Mapping of generated IDs and messages
 ├── sid-msg.map      Mapping of Snort IDs and messages
 ├── 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 (critical)
 │  ├── web-iis.rules 
 │  ├── web-php.rules
 More…
 ├── so_rules            Shared Object rule sets
 │  ├── browser-ie.rules
 │  ├── browser-other.rules    
 More…

0x02 Decoder Module snort.conf Configuration File

 This file is the core configuration file for Snort, including the following sections:
  1) Set the network variables. Configure various network addresses for easy rule usage
  2) Configure the decoder      Set the decoder
  3) Configure the base detection engine  Set the basic detection engine
  4) Configure dynamic loaded libraries   Set dynamic libraries
  5) Configure preprocessors     Set preprocessors
  6) Configure output plugins    Set output plugins
  7) Customize your rule set     Customize rule sets
  8) Customize preprocessor and decoder rule sets Set preprocessor and decoder rules
  9) Customize shared object rule set Configure shared object rule sets

0x03 SNORT Architecture: Decoder Module

Paste_Image.png

  • Packet sniffing module, primarily responsible for listening to network packets and analyzing them according to the TCP/IP protocol.
  • Preprocessor module, including 1. Packet reassembly preprocessor, which prevents attacks from being split across multiple packets to evade detection; 2. Protocol decoding preprocessor, which decodes packet protocols into a standard format before sending them to the detection module; 3. Protocol anomaly detection preprocessor.
  • Detection engine module, which matches packets with rules in a multi-dimensional linked list. If a packet content matches any rule, an alert is triggered.
  • Alert/log module. After the detection engine passes packets to the alert module, it processes them according to rule definitions (alert, log, etc.), such as logging or database entry.

Next, we’ll explore these four major modules in detail.

0x04 Decoder Module and Preprocessor Modules

4.1 Decoder Module Overview

The decoder and preprocessor modules’ functions are similar, both processing packets before the rule detection engine. The decoder module captures raw network packets from the monitored network, decodes them according to each network protocol layer from bottom to top, and saves the decoded data to corresponding data structures, which are then handed over to the preprocessor module.

Only after being processed by the preprocessor module can the decoded packets be matched by the main detection engine. Preprocessors address evasive IDS techniques. Their roles include:

1) Checking or modifying packets for suspicious behavior to ensure accurate interpretation by the detection engine. 2) Normalizing traffic for precise signature matching by the detection engine.

Known IDS evasion techniques include:

1)– Polymorphic URL encoding; 2)– Polymorphic shellcode; 3)– Session segmenting; 4)– IP fragmentation;

Snort includes three main types of preprocessors (examples):

1) Packet reassembly preprocessors:

  • frag3: IP fragmentation reassembly and attack monitoring.
  • stream: Maintains TCP stream state and reassembles sessions.

2) Protocol normalization preprocessors:

  • http_inspect: Normalizes HTTP streams.
  • rpcDecode: Normalizes RPC calls.

3) Anomaly detection preprocessors:

  • ARP spoof: Detects ARP spoofing.
  • sfPortscan: Detects port scans.

4.2 Decoder Module Configuration

Configuration involves two steps, both in the snort.conf file.

1. Configure decoder or preprocessor parameters in sections 2) and 5) of snort.conf.

2. Enable detection rules in section 8) of snort.conf.

4.2.1 Example of Configuring a Decoder

1. Configure the decoder

config disable_decode_alerts   Disable decode alerts.
config enable_decode_oversized_alerts
      Alert if a packet's (IP, UDP, TCP) length exceeds the length field.
# Stop generic decode events

Format: config decoder [option], with # for comments.

2. Enable decoder detection rules

include $PREPROC_RULE_PATH/decoder.rules

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

3. In decoder.rules, we find the rule for detecting abnormal IP lengths.

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

4.2.2 Example of Configuring http_inspect Preprocessor

1. Below is the default configuration for http_inspect

preprocessor http_inspect: global iis_unicode_map unicode.map 1252 compress_depth 65535 decompress_depth 65535
#unicode.map is the decode file for the http_inspect Unicode decoder.
preprocessor http_inspect_server: server default \
http_methods { GET POST PUT SEARCH MKCOL ...} \
    ...  
    enable_cookie        # Extract HTTP request or response cookies into cache for rule matching.
    normalize javascript # Decode JavaScript in tags.
    ...

2. Enable preprocessor rules

#include $PREPROC_RULE_PATH/preprocessor.rules

Below is a decoding rule:

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

Notice this rule differs from the earlier ones, as it lacks source/destination IPs, ports, etc. It indicates this rule is triggered automatically by the decoder without user intervention. Generally, we do not need to modify decoder or preprocessor rules; simply add, configure, or remove plugins via snort.conf.

0x05 Detection Engine Module

Rule structure: alert tcp 202.110.8.1 any -> 122.111.90.8 80 (msg:”Web Access”; sid:1) |—||—||—||—||—||—||—||—||—||– Rule Header –||—||—||—||—||—||—||—||–||—||—||—||- Rule Options –||—||—||—||-|

5.1 Rule Header

Actions:

Snort includes five action types: alert, log, pass, activate, and dynamic.

   1)Alert: Triggers an alert and logs the packet.
  2)Log:   Logs the packet.
  3)Pass:  Ignores the packet.
  4)Activate: Alerts and activates another dynamic rule.
  5)Dynamic: Remains idle until activated by an activate rule and then acts as a log rule.

Protocol:

Snort can analyze four protocols: TCP, UDP, ICMP, and IP. In the future, it may support more, such as ARP, IGRP, GRE, OSPF, RIP, and IPX.

IP Address:

1) Addresses can be specific IPs or CIDR blocks. You may also define IP address lists, which are IPs or CIDR blocks separated by commas and enclosed in square brackets [,]. 2) The negation operator is !. 3) The keyword “any” can be used to define any address.

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 -> specifies the flow direction of the rule. The left side of the direction operator is considered the source, and the right side is the destination. The bidirectional operator is <>.

Port Number:

1) Port numbers can be represented in several ways, including any port, static port definition, range, and through the use of negation operators.
2) Static port definition represents a single port number, such as 111 representing portmapper, 23 representing telnet, 80 representing HTTP, and so on.
3) Port ranges are indicated using the range operator “:”. For example, 80: , :1024, 80:1024

5.2 Rule Options

Rule options are divided into four main categories:

1) General rule option
2) Payload detection rule option
3) Non-Payload detection rule option
4) Post detection rule option

5.2.1 General Rule Option

sid

 snort id, this keyword is used to identify the uniqueness of snort rules (more details will be provided later). The range of sid is allocated as follows:
  • <100 reserved for future use
  • 100-100,000 included in the snort release package
  • >1000,000 used for local rules

msg

 Identifies a message, however, the msg in the rule does not work, the relationship between sid and msg can be found 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 the sid with the msg, otherwise, the alerts will show the issue demonstrated in the first image.

Decoder Module

This file is used to map the sid with the msg for custom rules and customize alert messages in snort’s own rules. The above Snort Alert[1:1000015:0] corresponds to Snort alert[gid:sid:rev]. This indicates that a rule requires these three elements to be unique, so it is inappropriate to say that only sid uniquely identifies a rule.

gid

 generator id, this is used to indicate which part of snort triggered the rule, such as the decoder, preprocessor, or snort's own rules. Check /usr/local/share/doc/snort/generators file (not a configuration file):

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

The gid for decoder and preprocessor is not listed entirely. It shows that Snort Rule Engine gid is 1, custom and snort’s own rules (rules in /etc/snort/rules directory) have gid default to 1. However, decoders and preprocessors also have sids. For example:

In /etc/snort/rules/protocol-icmp.rules:

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;)

gid is default to 1

In /etc/snort/preproc_rules/decoder.rules:

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

As shown, the rules have the same sid but are distinguished by gid.

gen-msg.map

This file functions similarly to sid-msg.map and logically should include sid-msg.map (sid-msg.map assumes default gid to be 1)

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 # example
...

Take the second rule in gid as an example, if this rule gets triggered, it will alert snort_decoder: WARNING: too many IPv6 extension headers rather than DECODE_IP6_EXCESS_EXT_HDR. Therefore, the msg in the rule only serves as an identifier, the alert msg must be looked up in sid-msg.map and gen-msg.map.

rev

This keyword is used to identify the version of rule modifications and must be used with sid and gid to uniquely identify a rule. This concludes the introduction of the three elements: gid, sid, and rev.

reference

External attack references allow rules to include identifiers from external attack identification systems. This plugin currently supports specific systems and these plugins are used by output plugins to provide extra information links about the alert.

Decoder Module

reference.config

Format: config reference: system URL

Example: config reference: cve http://cve.mitre.org/cgi-bin/cvename.cgi?name= defines URLs for external security sites. For example, if the rule defines reference: cve,1001, it appends 1001 to the end of the URL, http://cve.mitre.org/cgi-bin/cvename.cgi?name=1001, clicking [cve] in the alert will redirect to the corresponding site. Note: reference must also correlate with sid in sid-msg.map otherwise it will not work, similar to msg.

classtype

Rule classification identifier. This keyword categorizes alerts into different attack classes. Using this keyword and priority, users can assign priority levels to each type in the rule class.

priority

Sets the priority level for classtype. Classtype and priority should be used together, and classification.config links them.

classification.config

Format: config classification: shortname, short description, priority

Example: config classification: attempted-admin, Attempted Administrator Privilege Gain, 1 The entries in this file are the default values, and the priority keyword can override the priority level in the rule. 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 rule, generally in key-value pairs.

General rule options only label, classify, etc., a rule but do not actually perform filtering or detection.

5.2.2 Payload Detection Rule Options

content

Content is one of Snort’s key keywords. It specifies the pattern to search for in the payload of packets. The content data can include mixed text and binary data. Binary data is usually enclosed in the pipe symbol “|” and represented as bytecode, that is, the hexadecimal form of binary data.

 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            content string case insensitive
rawbytes         directly match raw packet data
Depth              match depth
Offset             start matching offset
Distance          distance between two content matches
Within            maximum distance between two content matches  
http_cookie       match cookie
http_raw_cookie   match unnormalized cookie
http_header       match header
http_raw_header   match unnormalized header
http_method       match method
http_url          match url
http_raw_url      match unnormalized url
http_stat_code    match status code in match
http_stat_msg     match status information
http_encode       match encoding format

The HTTP modifier that starts with “http” needs to be used together with the previously introduced preprocessor, http_inspect.

pcre

Allows users to employ 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 of regular expressions, refer to snort_manual.

protected_content

Encrypts the content in the rule using a hash algorithm to protect the confidentiality of the rule. protected_content:[!]"", length:orig_len[, hash:md5|sha256|sha512];

rawbytes

Ignores the operations of decoders and preprocessors, directly matching the raw network packets.

Only some common payload detection rule options are listed above. Refer to snort_manual for more keywords.

5.2.3 Non-Payload Detection Rule Option

Fragoffset                IP Offset
Ttl                       IP Time to Live
Tos                       IP Type of Service
Id                        IP Identification
Ipopts                    IP Options
Fragbits                  IP Flags
Dsize                     Packet Payload Size
Flags                     TCP Flags
Seq                       TCP Sequence
Ack                       TCP Acknowledgment
Window                    TCP Window
Icmp_id                   ICMP ID

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

5.2.4 Post-Detection Rule Option

Logto                     Log Output Path
Session                   Extract User Data from TCP Session
Resp                      Terminate Malicious Requests by Sending a Response
React                     Not Only Log the Specific Packet Triggering the Rule
Tag                       Not Only Log the Specific Packet Triggering the Rule
Activates                 activate action
Activates_by              dynamic action
Count                     Number of Packets Matchable After dynamic Rule is Triggered
Replace                   Replace Content
Detection-filter          Detection Filter

5.3 Detection Engine Module Configuration

1. Write rules in the *.rules files under /etc/rules directory. 2. snort.conf 7) includes corresponding rules.

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

0x06 Snort Alert/Log Module

6.1 Output Module Configuration

snort.conf 6): Configure output plugins to 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 purpose of barnyard2 is to store the unified2 formatted data into the database. Set it to be associated with snort logs. config waldo_file: /var/log/snort/barnyard.waldo Set the database output database: log, mysql, user=snort password=123456 dbname=snort host=localhost

6.2 Database

ER Diagram

Decoder Module

schema

Decoder Module

vseq: Database Schema ID
ctime: Database Creation Time

The information table, not related to other database contents

sensor

Decoder Module

sid: Sensor ID
hostname: User Name Associated with the Sensor
Interface: Network Interface Corresponding to the Sensor
filter: Filter Rules for Corresponding Sensor
detail: Represents Sensor Monitoring Mode, Level of Detail for Recording Mode
encoding: Form in which Data is Stored
last_cid: Last Value of Alarm Captured by Sensor for Each sid

detail

Decoder Module

0 - fast detection
1 - full detection

Detection level of the sensor.

encoding

Decoder Module

0 - Hex
1 - base64
2 - ascii

Form in which data exists in the packet.

event

Decoder Module

sid: sensor id
cid: event id   Events ID. sid and cid together as the primary key, where cid is sorted based on sid. Each sid corresponds to its cid sequence.
signature: Corresponding to sig_id in the signature table, indicating which type of rules this alert event belongs to.
timestamp: System time when the alert event occurred.

The most core table, each alert data will be stored in the event table, an event data represents a packet.

signature

Decoder Module

sig_id: Represents the total number of alert types. This is the primary key for the alert types. Uniquely identifies a rule.
sig_name: Alert Name. Corresponds to the Msg in each alert statement.
sig_class_id: Corresponds to sig_class_id in the sig_class table. Represents the major class information of the alert type.
sig_priority: Alert priority
sig_rev: Version number
sig_sid: snort id   
sig_gid: generate id 

A table storing snort rules, we can see sig_sid, sig_gid, sig_rev correspond to sid, gid, rev in the rules. Note the distinction between the snort ID in the rules and the sensor ID in the database.

sig_reference

Decoder Module

sig_id: Corresponding alert type
ref_id: Corresponding primary key in the reference table
ref_seq: Reference sequence number

Provides reference information for alert types in the signature table. Connects the signature with the reference table.

reference

Decoder Module

Ref_id: Primary key
Ref_system_id: Corresponding reference system table
Ref_tag: Parameters following rules like cve, bugtraq

reference_system

Decoder Module

ref_system_id: Primary key
ref_system_name: Reference system name, such as cve, url, etc.

sig_class

Decoder Module

sig_class_id: Class ID
sig_class_name: Class Name

Classification information for signature alert types.

iphdr

Decoder Module

tcphdr

Decoder Module

udphdr

Decoder Module

icmphdr

Decoder Module

data

Decoder Module

data_payload: Packet Payload

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

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

opt

Decoder Module

IP and OPT options.

References:

Reposted from: https://www.cnblogs.com/HacTF/p/7992787.html