| Search Site |
| Search Rules |
| Account |
| not registered? |
| can't login? |
| user preferences |
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Subsections
2.1 PreprocessorsPreprocessors were introduced in version 1.5 of Snort. They allow the functionality of Snort to be extended by allowing users and programmers to drop modular plugins into Snort fairly easily. Preprocessor code is run before the detection engine is called, but after the packet has been decoded. The packet can be modified or analyzed in an out-of-band manner using this mechanism. Preprocessors are loaded and configured using the preprocessor keyword. The format of the preprocessor directive in the Snort rules file is:
preprocessor <name>: <options>
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Note: Frag2 is deprecated in Snort 2.4.0 and later in favor of Frag3. See Section 2.1.2 for more information about Frag3. |
The Frag3 preprocessor is a target-based IP defragmentation module for Snort. Frag3 is intended as a replacement for the frag2 defragmentation module and was designed with the following goals:
The frag2 preprocessor used splay trees extensively for managing the data structures associated with defragmenting packets. Splay trees are excellent data structures to use when you have some assurance of locality of reference for the data that you are handling but in high speed, heavily fragmented environments the nature of the splay trees worked against the system and actually hindered performance. Frag3 uses the sfxhash data structure and linked lists for data handling internally which allows it to have much more predictable and deterministic performance in any environment which should aid us in managing heavily fragmented environments.
Target-based analysis is a relatively new concept in network-based intrusion detection. The idea of a target-based system is to model the actual targets on the network instead of merely modeling the protocols and looking for attacks within them. When IP stacks are written for different operating systems, they are usually implemented by people who read the RFCs and then their interpretation of what the RFC outlines into code. Unfortunately, there are ambiguities in the way that the RFCs define some of the edge conditions that may occurr and when this happens differnt people implement certain aspects of their IP stacks differently. For an IDS this is a big problem.
In an environment where the attacker can determine what style of IP defragmentation being used on a particular target, the attacker can try to fragment packets such that the target will put them back together in a specific manner while any passive systems trying to model the host traffic have to guess which way the target OS is going to handle the overlaps and retransmits. As I like to say, if the attacker has more information about the targets on a network than the IDS does, it is possible to evade the IDS. This is where the idea for ``target-based IDS'' came from. For more detail on this issue and how it affects IDSes, check out the famous Ptacek & Newsham paper at http://www.snort.org/docs/idspaper/.
The basic idea behind target-based IDS is that we tell the IDS information about hosts on the network so that it can avoid Ptacek & Newsham style evasion attacks based on information about how an individual target IP stack operates. Vern Paxson and Umesh Shankar did a great paper on this very topic in 2003 that detailed mapping the hosts on a network and determining how their various IP stack implementations handled the types of problems seen in IP defragmentation and TCP stream reassembly. Check it out at http://www.icir.org/vern/papers/activemap-oak03.pdf.
We can also present the IDS with topology information to avoid TTL-based evasions and a variety of other issues, but that's a topic for another day. Once we have this information we can start to really change the game for these complex modeling problems.
Frag3 was implemented to showcase and prototype a target-based module within Snort to test this idea.
Frag3 configuration is somewhat more complex than frag2. There are at least two preprocessor directives required to activate frag3, a global configuration directive and an engine instantiation. There can be an arbitrary number of engines defined at startup with their own configuration, but only one global configuration.
Global configuration
Engine Configuration
The Paxson Active Mapping paper introduced the terminology frag3 is using to describe policy types. The known mappings are as follows. Anyone who develops more mappings and would like to add to this list please feel free to send us an email!
| Platform | Type |
|---|---|
| AIX 2 | BSD |
| AIX 4.3 8.9.3 | BSD |
| Cisco IOS | Last |
| FreeBSD | BSD |
| HP JetDirect (printer) | BSD-right |
| HP-UX B.10.20 | BSD |
| HP-UX 11.00 | First |
| IRIX 4.0.5F | BSD |
| IRIX 6.2 | BSD |
| IRIX 6.3 | BSD |
| IRIX64 6.4 | BSD |
| Linux 2.2.10 | linux |
| Linux 2.2.14-5.0 | linux |
| Linux 2.2.16-3 | linux |
| Linux 2.2.19-6.2.10smp | linux |
| Linux 2.4.7-10 | linux |
| Linux 2.4.9-31SGI 1.0.2smp | linux |
| Linux 2.4 (RedHat 7.1-7.3) | linux |
| MacOS (version unknown) | First |
| NCD Thin Clients | BSD |
| OpenBSD (version unknown) | linux |
| OpenBSD (version unknown) | linux |
| OpenVMS 7.1 | BSD |
| OS/2 (version unknown) | BSD |
| OSF1 V3.0 | BSD |
| OSF1 V3.2 | BSD |
| OSF1 V4.0,5.0,5.1 | BSD |
| SunOS 4.1.4 | BSD |
| SunOS 5.5.1,5.6,5.7,5.8 | First |
| Tru64 Unix V5.0A,V5.1 | BSD |
| Vax/VMS | BSD |
| Windows (95/98/NT4/W2K/XP) | First |
Note in the advanced example (Figure 2.5), there are three engines specified running with linux, first and last policies assigned. The first two engines are bound to specific IP address ranges and the last one applies to all other traffic, packets that don't fall within the address requirements of the first two engines automatically fall through to the third one.
Frag3 is capable of detecting eight different types of anomalies. Its event output is packet-based so it will work with all output modes of Snort. Read the documentation in the doc/signatures directory with filenames that begin with ``123-'' for information on the different event types.
The Stream4 module provides TCP stream reassembly and stateful analysis capabilities to Snort. Robust stream reassembly capabilities allow Snort to ignore "stateless" attacks (which include the types of attacks that Stick and Snot produce). Stream4 also gives large scale users the ability to track many simultaneous TCP streams. Stream4 is set to handle 8192 simultaneous TCP connections in its default configuration, however, it scales to handle over 100,000 simultaneous connections.
Stream4 contains two configurable modules, the Stream4 preprocessor and the associated Stream4 reassemble plugin. The stream4_reassemble options are listed below.
| Note: Additional options can be used if Snort is running in inline mode. See Section 1.5.2 for more information. |
preprocessor stream4: [noinspect], [asynchronous_link], [keepstats [<machine|binary>]], \
[detect_scans], [log_flushed_streams], [detect_state_problems], \
[disable_evasion_alerts], [timeout <seconds>], [memcap <bytes>], \
[max_sessions <num sessions>], [cache_clean_percent <% of sessions>], \
[cache_clean_sessions <num of sessions>], [ttl_limit <count>], \
[self_preservation_threshold], [self_preservation_period], \
[suspend_threshold], [suspend_period], [enforce_state], \
[state_protection], [server_inspect_limit <bytes>]
| Option | Description |
|---|---|
| asynchronous_link | Use state transitions based only on one-sided conversation (no tracking of ack/sequence numbers). |
| cache_clean_percent | Purge this percent of least-recently used sessions from the session cache (overrides cache_clean_sessions). |
| cache_clean_sessions | Purge this number of least-recently used sessions from the session cache. |
| detect_scans | Turns on alerts for portscan events. |
| detect_state_problems | Turns on alerts for stream events of note, such as evasive RST packets, data on the SYN packet, and out of window sequence numbers. |
| enforce_state | Enforces statefulness so that sessions aren't picked up mid-stream. |
| keepstats | Records session summary information in |
| log_flushed_streams | Log the packets that are part of reassembled stream. |
| disable_evasion_alerts | Turns off alerts for events such as TCP overlap. |
| timeout <seconds> | Amount of time to keep an inactive stream in the state table; sessions that are flushed will automatically be picked up again if more activity is seen. The default value is 30 seconds. |
| memcap <bytes> | Number of bytes used to store packets for reassembly. |
| max_sessions | Maximum number of simultaneous sessions. |
| noinspect | Disables stateful inspection. |
| ttl_limit | Sets the delta value that will set off an evasion alert. |
| self_preservation_threshold | Limit on number of sessions before entering self-preservation mode (only reassemble data on the default ports). |
| self_preservation_period | Length of time (seconds) to remain in self-preservation mode. |
| suspend_threshold | Limit on number of sessions before entering suspend mode (no reassembly). |
| suspend_period | Length of time (seconds) to remain in suspend mode. |
| server_inspect_limit | Restrict inspection of server traffic to this many bytes until another client request is seen (ie: client packet with data). |
| state_protection | Protect self against DoS attacks. |
preprocessor stream4_reassemble: [clientonly], [serveronly], [both], [noalerts], \
[favor_old], [favor_new], [flush_on_alert], \
[overlap_limit], [ports <portlist>]
| Option | Description |
|---|---|
| clientonly | Provides reassembly for the client side of a connection only. |
| serveronly | Provides reassembly for the server side of a connection only. |
| both | Reassemble for client and server sides of connection. |
| noalerts | Won't alert on events that may be insertion or evasion attacks. |
| favor_old | Favor old segments based on sequence number over a new segments. |
| favor_new | Favor new segments based on sequence number over a old segments. |
| flush_on_alert | Flush a stream when an individual packet causes an alert. |
| flush_behavior <number> | Use specified flush behavior. Number greater than 0 means use old static flush points. Number equal to 0 means use new larger flush points. Number less than 0 means use random flush points defined by flush_base, flush_seed, and flush_range. |
| flush_base <number> | Lowest allowed random flushpoint. The default value is 512 bytes. Only used if flush_behavior is less than 0. |
| flush_range <number> | Space within random flushpoints are generated. The default value is 1213. Only used if flush_behavior is less than 0. |
| flush_seed <number> | Random seed for flushpoints. The default value is computed from Snort PID + time. Only used if flush_behavior is less than 0. |
| overlap_limit | Alert when the number of overlapping data bytes reaches a threshold. |
| ports <portlist> | Provides reassembly for a whitespace-separated list of ports. By default, reassembly is performed for ports 21, 23, 25, 42, 53, 80, 110, 111, 135, 136, 137, 139, 143, 445, 513, 1443, 1521, and 3306. To perform reassembly for all ports, use all as the port list. |
| flush_data_diff_size <number> | minumum size of a packet to zero out the empty space in a rebuilt packet. |
| zero_flushed_packets_limit | Zero out any space that is not filled in when flushing a rebuilt packet. |
Just setting the Stream4 and Stream4_reassemble directives without arguments in the snort.conf file will set them up in their default configurations shown in Table 2.2 and Table 2.3.
Stream4 introduces a new command line switch: -z. On TCP traffic, if the -z switch is specified, Snort will only alert on streams that have been established via a three way handshake or streams where cooperative bidirectional activity has been observed (i.e., where some traffic went one way and something other than a RST or FIN was seen going back to the originator). With -z turned on, Snort completely ignores TCP-based Stick/Snot attacks.
| Note: As of Snort v2.1.1, -z has been superseded by the flow: established rule option. Please see section 3.6.9 for more information. |
| Option | Default |
|---|---|
| session timeout (timeout) | 30 seconds |
| session memory cap (memcap) | 8388608 bytes |
| stateful inspection (noinspect) | active (noinspect disabled) |
| stream stats (keepstats) | inactive |
| state problem alerts (detect_state_problems) | inactive (detect_state_problems disabled) |
| evasion alerts (disable_evasion_alerts) | inactive (disable_evasion_alerts enabled) |
| asynchronous link (asynchronous_link) | inactive |
| log flushed streams (log_flushed_streams) | inactive |
| max sessions (max_sessions) | 8192 |
| session cache purge (cache_clean_sessions) | 5 |
| session cache purge percent (cache_clean_percent) | inactive |
| self preservation threshold (self_preservation_threshold) | 50 sessions/sec |
| self preservation period (self_preservation_period) | 90 seconds |
| suspend threshold (suspend_threshold) | 200 sessions/sec |
| suspend period (suspend_period) | 30 seconds |
| state protection (state_protection) | inactive |
| server inspect limit (server_inspect_limit) | -1 (inactive) |
| Option | Default |
|---|---|
| reassemble client (clientonly) | active |
| reassemble server (serveronly) | inactive |
| reassemble both (both) | inactive |
| reassemble ports (ports) | 21 23 25 42 53 80 110 111 135 136 137 139 143 445 513 1433 1521 3306 |
| reassembly alerts (noalerts) | active (noalerts disabled) |
| favor old packet (favor_old) | active |
| favor new packet (favor_new) | inactive |
| flush on alert (flush_on_alert) | inactive |
| overlap limit (overlap_limit) | -1 (inactive) |
The Flow tracking module is meant to start unifying the state keeping mechanisms of Snort into a single place. As of Snort 2.1.0, only a portscan detector is implemented, but in the long term, many of the stateful subsystems of Snort will be migrated over to becoming flow plugins. With the introduction of flow, this effectively makes the conversation preprocessor obsolete.
An IPv4 flow is unique when the IP protocol (ip_proto), source IP (sip), source port (sport), destination IP (dip), and destination port (dport) are the same. The dport and sport are 0 unless the protocol is TCP or UDP.
preprocessor flow: [memcap <bytes>], [rows <count>], \
[stats_interval <seconds>], [hash <1|2>]
|
preprocessor flow: stats_interval 0 hash 2
| Note: The "Portscan" preprocessor was deprecated in Snort 2.2, in favor of Flow Portscan, which was deprecated in Snort 2.3, in favor of sfPortscan. |
| Note: The Flow-Portscan preprocessor was deprecated in Snort 2.3, in favor of sfPortscan. |
The sfPortscan module, developed by Sourcefire, is designed to detect the first phase in a network attack: Reconnaissance. In the Reconnaissance phase, an attacker determines what types of network protocols or services a host supports. This is the traditional place where a portscan takes place. This phase assumes the attacking host has no prior knowledge of what protocols or services are supported by the target, otherwise this phase would not be necessary.
As the attacker has no beforehand knowledge of its intended target, most queries sent by the attacker will be negative (meaning that the service ports are closed). In the nature of legitimate network communications, negative responses from hosts are rare, and rarer still are multiple negative responses within a given amount of time. Our primary objective in detecting portscans is to detect and track these negative responses.
One of the most common portscanning tools in use today is Nmap. Nmap encompasses many, if not all, of the current portscanning techniques. sfPortscan was designed to be able to detect the different types of scans Nmap can produce.
sfPortscan will currently alert for the following types of Nmap scans:
These alerts are for one
one portscans, which are the traditional
types of scans; one host scans multiple ports on another host. Most of
the port queries will be negative, since most hosts have relatively
few services available.
sfPortscan also alerts for the following types of decoy portscans:
Decoy portscans are much like the Nmap portscans described above, only the attacker has spoofed source address inter-mixed with the real scanning address. This tactic helps hide the true identity of the attacker.
sfPortscan alerts for the following types of distributed portscans:
These are many
one portscans. Distributed portscans occur when
multiple hosts query one host for open services. This is used to evade
an IDS and obfuscate command and control hosts.
| Note: Negative queries will be distributed among scanning hosts, so we track this type of scan through the scanned host. |
sfPortscan alerts for the following types of portsweeps:
These alerts are for one
many portsweeps. One host scans a single port
on multiple hosts. This usually occurs when a new exploit comes out and the
attacker is looking for a specific service.
| Note: The characteristics of a portsweep scan may not result in many negative responses. For example, if an attacker portsweeps a web farm for port 80, we will most likely not see many negative responses. |
sfPortscan alerts on the following filtered portscans and portsweeps:
``Filtered'' alerts indicate that there were no network errors (ICMP unreachables or TCP RSTs) or responses on closed ports have been suppressed. It's also a good indicator of whether the alert is just a very active legitimate host. Active hosts, such as NATs, can trigger these alerts because they can send out many connection attempts within a very small amount of time. A filtered alert may go off before responses from the remote hosts are received.
sfPortscan only generates one alert for each host pair in question during the time window (more on windows below). On TCP scan alerts, sfPortscan will also display any open ports that were scanned. On TCP sweep alerts however, sfPortscan will only track open ports after the alert has been triggered. Open port events are not individual alerts, but tags based off the orginal scan alert.
You may want to use the following line in your snort.conf to disable evasion alerts within stream4 because some scan packets can cause these alerts to be generated:
preprocessor stream4: disable_evasion_alerts
Use of the Flow preprocessor is required for sfPortscan. Flow gives portscan direction in the case of connectionless protocols like ICMP and UDP. You should enable the Flow preprocessor in your snort.conf by using the following:
preprocessor flow: stats_interval 0 hash 2
The parameters you can use to configure the portscan module are:
Available options:
Available options:
Available options:
Defines what IPs or networks to watch. IPs or networks not falling into this range are ignored.
Ignores the source of scan alerts.
Ignores the destination of scan alerts
This option will output portscan events to the file specified. If <file> does not contain a leading slash, this file will be placed in the Snort config dir.
preprocessor sfportscan: proto <protocols> \ scan_type <portscan|portsweep|decoy_portscan|distributed_portscan|all>\ sense_level <low|medium|high> watch_ip <IP or IP/CIDR> ignore_scanners <IP list>\ ignore_scanned <IP list> logfile <path and filename>
Unified Output
In order to get all the portscan information logged with the alert, snort generates a pseudo-packet and uses the payload portion to store the additional portscan information of priority count, connection count, IP count, port count, IP range, and port range. The characteristics of the packet are:
Src/Dst MAC Addr == MACDAD IP Protocol == 255 IP TTL == 0
Other than that, the packet looks like the IP portion of the packet that caused the portscan alert to be generated. This includes any IP options, etc. The payload and payload size of the packet is equal to the length of the additional portscan information that is logged. The size tends to be around 100 - 200 bytes.
Open port alerts differ from the other portscan alerts, because open port alerts utilize the tagged packet output system. This means that if an output system that doesn't print tagged packets is used, then the user won't see open port alerts. The open port information is stored in the IP payload and contains the port that is open.
The sfPortscan alert output was designed to work with unified packet logging, so it is possible to extend favorite snort GUIs to display portscan alerts and the additional information in the IP payload using the above packet characteristics.
Log File Output
Logfile output is displayed in the following format, and explained further below:
Time: 09/08-15:07:31.603880 event_id: 2 192.168.169.3 -> 192.168.169.5 (portscan) TCP Filtered Portscan Priority Count: 0 Connection Count: 200 IP Count: 2 Scanner IP Range: 192.168.169.3:192.168.169.4 Port/Proto Count: 200 Port/Proto Range: 20:47557
If there are open ports on the target, an additional tagged packet(s) will be appended:
Time: 09/08-15:07:31.603881 event_ref: 2 192.168.169.3 -> 192.168.169.5 (portscan) Open Port Open Port: 38458
These fields are used to link an alert with the corresponding Open Port tagged packet
Priority Count keeps track of bad responses (resets, unreachables). The higher the Priority Count, the more bad responses have been received.
Connection Count lists how many connections are active on the hosts (src or dst). This is accurate for connection-based protocols, and is more of an estimate for others. Whether or not a portscan was filtered is determined here. High connection count and low priority count would indicate filtered (no response received from target).
IP Count keeps track of the last IP to contact a host, and increments the count if the next IP is different. For one-to-one scans, this is a low number. For active hosts this number will be high regardless, and one-to-one scans may appear as a distributed scan.
This field changes depending on the type of alert. Portsweeps (one-to-many) scans display the scanned IP range; Portscans (one-to-one) display the scanner IP.
Port Count keeps track of the last port contacted and increments this number when that changes. We use this count (along with IP Count) to determine the difference between one-to-one portscans and one-to-one decoys.
The most important aspect in detecting portscans is tuning the detection engine for your network(s). Here are some tuning tips:
It's important to correctly set these options. The watch_ip option is easy to understand. The analyst should set this option to the list of Cidr blocks and IPs that they want to watch. If no watch_ip is defined, sfPortscan will watch all network traffic.
The ignore_scanners and ignore_scanned options come into play in weeding out legitimate hosts that are very active on your network. Some of the most common examples are NAT IPs, DNS cache servers, syslog servers, and nfs servers. sfPortscan may not generate false positives for these types of hosts, but be aware when first tuning sfPortscan for these IPs. Depending on the type of alert that the host generates, the analyst will know which to ignore it as. If the host is generating portsweep events, then add it to the ignore_scanners option. If the host is generating portscan alerts (and is the host that is being scanned), add it to the ignore_scanned option.
When determining false positives, the alert type is very important. Most of the false positives that sfPortscan may generate are of the filtered scan alert type. So be much more suspicious of filtered portscans. Many times this just indicates that a host was very active during the time period in question. If the host continually generates these types of alerts, add it to the ignore_scanners list or use a lower sensitivity level.
The portscan alert details are vital in determining the scope of a portscan and also the confidence of the portscan. In the future, we hope to automate much of this analysis in assigning a scope level and confidence level, but for now the user must manually do this. The easiest way to determine false positives is through simple ratio estimations. The following is a list of ratios to estimate and the associated values that indicate a legimite scan and not a false positive.
Connection Count / IP Count: This ratio indicates an estimated average of connections per IP. For portscans, this ratio should be high, the higher the better. For portsweeps, this ratio should be low.
Port Count / IP Count: This ratio indicates an estimated average of ports connected to per IP. For portscans, this ratio should be high and indicates that the scanned host's ports were connected to by fewer IPs. For portsweeps, this ratio should be low, indicating that the scanning host connected to few ports but on many hosts.
Connection Count / Port Count: This ratio indicates an estimated average of connections per port. For portscans, this ratio should be low. This indicates that each connection was to a different port. For portsweeps, this ratio should be high. This indicates that there were many connections to the same port.
The reason that Priority Count is not included, is because the priority count is included in the connection count and the above comparisons take that into consideration. The Priority Count play an important role in tuning because the higher the priority count the more likely it is a real portscan or portsweep (unless the host is firewalled).
If none of these other tuning techniques work or the analyst doesn't have the time for tuning, lower the sensitivity level. You get the best protection the higher the sensitivity level, but it's also important that the portscan detection engine generates alerts that the analyst will find informative. The low sensitivity level only generates alerts based on error responses. These responses indicate a portscan and the alerts generated by the low sensitivity level are highly accurate and require the least tuning. The low sensitivity level does not catch filtered scans, since these are more prone to false positives.
The telnet_decode preprocessor allows Snort to normalize Telnet control protocol characters from the session data. In Snort 1.9.0 and above, it accepts a list of ports to run on as arguments. Also in 1.9.0, it normalizes into a separate data buffer from the packet itself so that the raw data may be logged or examined with the rawbytes content modifier3.5.3.
By default, telnet_decode runs against traffic on ports 21, 23, 25, and 119.
preprocessor telnet_decode: <ports>
The rpc_decode preprocessor normalizes RPC multiple fragmented records into a single un-fragmented record. It does this by normalizing the packet into the packet buffer. If stream4 is enabled, it will only process client-side traffic. By default, it runs against traffic on ports 111 and 32771.
| Option | Description |
|---|---|
| alert_fragments | Alert on any fragmented RPC record. |
| no_alert_multiple_requests | Don't alert when there are multiple records in one packet. |
| no_alert_large_fragments | Don't alert when the sum of fragmented records exceeds one packet. |
| no_alert_incomplete | Don't alert when a single fragment record exceeds the size of one packet. |
preprocessor rpc_decode: <ports> [ alert_fragments ] \ [no_alert_multiple_requests] [no_alert_large_fragments] \ [no_alert_incomplete]
This preprocessor measures Snort's real-time and theoretical maximum performance. Whenever this preprocessor is turned on, it should have an output mode enabled, either ``console'' which prints statistics to the console window or ``file'' with a file name, where statistics get printed to the specified file name. By default, Snort's real-time statistics are processed. This includes:
The following options can be used with the Performance Monitor:
preprocessor perfmonitor: time 30 events flow file stats.profile max \
console pktcnt 10000
preprocessor perfmonitor: time 300 file /var/tmp/snortstat pktcnt 10000
HTTPInspect is a generic HTTP decoder for user applications. Given a data buffer, HTTPInspect will decode the buffer, find HTTP fields, and normalize the fields. HTTPInspect works on both client requests and server responses.
The current version of HTTPInspect only handles stateless processing. This means that HTTPInspect looks for HTTP fields on a packet-by-packet basis, and will be fooled if packets are not reassembled. This works fine when there is another module handling the reassembly, but there are limitations in analyzing the protocol. Future versions will have a stateful processing mode which will hook into various reassembly modules.
HTTPInspect has a very ``rich'' user configuration. Users can configure individual HTTP servers with a variety of options, which should allow the user to emulate any type of web server. Within HTTPInspect, there are two areas of configuration: global and server.
The global configuration deals with configuration options that determine the global functioning of HTTPInspect. The following example gives the generic global configuration format:
preprocessor http_inspect: global \
iis_unicode_map <map_filename> \
codemap <integer> \
[detect_anomalous_servers] \
[proxy_alert]
You can only have a single global configuration, you'll get an error if you try otherwise.
This is the global iis_unicode_map file. The iis_unicode_map is a required configuration parameter. The map file can reside in the same directory as snort.conf or specified via a fully-qualified path to the map file.
The iis_unicode_map file is a Unicode codepoint map which tells HTTPInspect which codepage to use when decoding Unicode characters. For US servers, the codemap is usually 1252.
A Microsoft US Unicode codepoint map is provided in the snort source etc directory by default. It is called unicode.map and should be used if no other codepoint map is available. A tool is supplied with Snort to generate custom Unicode maps-ms_unicode_generator.c, which is available at http://www.snort.org/dl/contrib/.
| Note: Remember that this configuration is for the global IIS Unicode map--individual servers can reference their own IIS Unicode map. |
This global configuration option enables generic HTTP server traffic inspection on non-HTTP configured ports, and alerts if HTTP traffic is seen. Don't turn this on if you don't have a default server configuration that encompasses all of the HTTP server ports that your users might access. In the future, we want to limit this to specific networks so it's more useful, but for right now, this inspects all network traffic.
This enables global alerting on HTTP server proxy usage. By configuring HTTPInspect servers and enabling allow_proxy_use, you will only receive proxy use alerts for web users that aren't using the configured proxies or are using a rogue proxy server.
Please note that if users aren't required to configure web proxy use, then you may get a lot of proxy alerts. So, please only use this feature with traditional proxy environments. Blind firewall proxies don't count.
preprocessor http_inspect: global iis_unicode_map unicode.map 1252
This configuration supplies the default server configuration for any server that is not individually configured. Most of your web servers will most likely end up using the default configuration.
preprocessor http_inspect_server: server default profile all ports { 80 }
preprocessor http_inspect_server: server 10.1.1.1 profile all ports { 80 }
Important: Some configuration options have an argument of `yes' or `no'. This argument specifies whether the user wants the configuration option to generate an httpinspect alert or not. the `yes/no' argument does not specify whether the configuration option itself is on or off, only the alerting functionality. in other words, whether set to `yes' or 'no', HTTP normalization will still occur, and rules based off HTTP traffic will still trigger.
Users can configure HTTPInspect by using pre-defined HTTP server profiles. Profiles allow the user to easily configure the preprocessor for a certain type of server, but are not required for proper operation.
There are three profiles available: all, apache, and iis.
The ``all'' profile is meant to normalize the URI using most of the common tricks available. We alert on the more serious forms of evasions. This is a great profile for detecting all types of attacks, regardless of the HTTP server. ``profile all'' sets the configuration options described in Table 2.6.
| Option | Setting |
|---|---|
| flow_depth | 300 |
| chunk encoding | alert on chunks larger than 500000 bytes |
| iis_unicode_map | codepoint map in the global configuration |
| ascii decoding | on, alert off |
| multiple slash | on, alert off |
| directory normalization | on, alert off |
| apache whitespace | on, alert off |
| double decoding | on, alert on |
| %u decoding | on, alert on |
| bare byte decoding | on, alert on |
| iis unicode codepoints | on, alert on |
| iis backslash | on, alert off |
| iis delimiter | on, alert off |
| webroot | on, alert on |
| non_strict URL parsing | on |
| tab_uri_delimiter | is set |
The ``apache'' profile is used for Apache web servers. This differs from the ``iis'' profile by only accepting UTF-8 standard Unicode encoding and not accepting backslashes as legitimate slashes, like IIS does. Apache also accepts tabs as whitespace. ``profile apache'' sets the configuration options described in Table 2.7.
| Option | Setting |
|---|---|
| flow_depth | 300 |
| chunk encoding | alert on chunks larger than 500000 bytes |
| ascii decoding | on, alert off |
| multiple slash | on, alert off |
| directory normalization | on, alert off |
| webroot | on, alert on |
| apache whitespace | on, alert on |
| utf_8 encoding | on, alert off |
| non_strict url parsing | on |
| tab_uri_delimiter | is set |
The ``iis'' profile mimics IIS servers. So that means we use IIS Unicode codemaps for each server, %u encoding, bare-byte encoding, double decoding, backslashes, etc. ``profile iis'' sets the configuration options described in Table 2.8.
| Option | Setting |
|---|---|
| flow_depth | 300 |
| chunk encoding | alert on chunks larger than 500000 bytes |
| iis_unicode_map | codepoint map in the global configuration |
| ascii decoding | on, alert off |
| multiple slash | on, alert off |
| directory normalization | on, alert off |
| webroot | on, alert on |
| double decoding | on, alert on |
| %u decoding | on, alert on |
| bare byte decoding | on, alert on |
| iis unicode codepoints | on, alert on |
| iis backslash | on, alert off |
| iis delimiter | on, alert on |
| apache whitespace | on, alert on |
| non_strict URL parsing | on |
The default options used by HTTP Inspect do not use a profile and are described in Table 2.9.
| Option | Setting |
|---|---|
| port | 80 |
| flow_depth | 300 |
| chunk encoding | alert on chunks larger than 500000 bytes |
| ascii decoding | on, alert off |
| utf_8 encoding | on, alert off |
| multiple slash | on, alert off |
| directory normalization | on, alert off |
| webroot | on, alert on |
| iis backslash | on, alert off |
| apache whitespace | on, alert off |
| iis delimiter | on, alert off |
| non_strict URL parsing | on |
preprocessor http_inspect_server: server 1.1.1.1 profile all ports { 80 3128 }
ports
port
port
This is how the user configures which ports to decode on the HTTP server. Encrypted traffic (SSL) cannot be decoded, so adding port 443 will only yield encoding false positives.
iis_unicode_map
map_filename
codemap
integer
The IIS Unicode map is generated by the program ms_unicode_generator.c. This program is located on the Snort.org web site at http://www.snort.org/dl/contrib/ directory. Executing this program generates a Unicode map for the system that it was run on. So, to get the specific Unicode mappings for an IIS web server, you run this program on that server and use that Unicode map in this configuration.
When using this option, the user needs to specify the file that contains the IIS Unicode map and also specify the Unicode map to use. For US servers, this is usually 1252. But the ms_unicode_generator program tells you which codemap to use for you server, it's the ANSI code page. You can select the correct code page by looking at the available code pages that the ms_unicode_generator outputs.
flow_depth
integer
This specifies the amount of server response payload to inspect. This option significantly increases IDS performance because we are ignoring a large part of the network traffic (HTTP server response payloads). A small percentage of Snort rules are targeted at this traffic and a small flow_depth value may cause false negatives in some of these rules. Most of these rules target either the HTTP header, or the content that is likely to be in the first hundred or so bytes of non-header data. Headers are usually under 300 bytes long, but your mileage may vary.
This value can be set from -1 to 1460. A value of -1 causes Snort to ignore all server side traffic for ports defined in ports. Inversely, a value of 0 causes Snort to inspect all HTTP server payloads defined in ports (note that this will likely slow down IDS performance). Values above 0 tell Snort the number of bytes to inspect in the first packet of the server response.
ascii
yes
no
The ascii decode option tells us whether to decode encoded ASCII chars, a.k.a %2f = /, %2e = ., etc. It is normal to see ASCII encoding usage in URLs, so it is recommended that you disable HTTPInspect alerting for this option.
utf_8
yes
no
The utf-8 decode option tells HTTPInspect to decode standard UTF-8 Unicode sequences that are in the URI. This abides by the Unicode standard and only uses % encoding. Apache uses this standard, so for any Apache servers, make sure you have this option turned on. As for alerting, you may be interested in knowing when you have a UTF-8 encoded URI, but this will be prone to false positives as legitimate web clients use this type of encoding. When utf_8 is enabled, ASCII decoding is also enabled to enforce correct functioning.
u_encode
yes
no
This option emulates the IIS %u encoding scheme. How the %u encoding scheme works is as follows: the encoding scheme is started by a %u followed by 4 characters, like %uxxxx. The xxxx is a hex-encoded value that correlates to an IIS Unicode codepoint. This value can most definitely be ASCII. An ASCII character is encoded like %u002f = /, %u002e = ., etc. If no iis_unicode_map is specified before or after this option, the default codemap is used.
You should alert on %u encodings, because we are not aware of any legitimate clients that use this encoding. So it is most likely someone trying to be covert.
bare_byte
yes
no
Bare byte encoding is an IIS trick that uses non-ASCII characters as valid values when decoding UTF-8 values. This is not in the HTTP standard, as all non-ASCII values have to be encoded with a %. Bare byte encoding allows the user to emulate an IIS server and interpret non-standard encodings correctly.
The alert on this decoding should be enabled, because there are no legitimate clients that encode UTF-8 this way since it is non-standard.
base36
yes
no
This is an option to decode base36 encoded chars. This option is based off of info from http://www.yk.rim.or.jp/ shikap/patch/spp_http_decode.patch.
If %u encoding is enabled, this option will not work. You have to use the base36 option with the utf_8 option. Don't use the %u option, because base36 won't work. When base36 is enabled, ASCII encoding is also enabled to enforce correct behavior.
iis_unicode
yes
no
The iis_unicode option turns on the Unicode codepoint mapping. If there is no iis_unicode_map option specified with the server config, iis_unicode uses the default codemap. The iis_unicode option handles the mapping of non-ASCII codepoints that the IIS server accepts and decodes normal UTF-8 request.
You should alert on the iis_unicode option, because it is seen mainly in attacks and evasion attempts. When iis_unicode is enabled, ASCII and UTF-8 decoding are also enabled to enforce correct decoding. To alert on UTF-8 decoding, you must enable also enable utf_8 yes.
double_decode
yes
no
The double_decode option is once again IIS-specific and emulates IIS
functionality. How this works is that IIS does two passes through the request
URI, doing decodes in each one. In the first pass, it seems that all types of
iis encoding is done: utf-8 unicode, ascii, bare byte, and %u. In the second
pass, the following encodings are done: ascii, bare byte, and %u. We leave out
utf-8 because I think how this works is that the % encoded utf-8 is decoded to
the Unicode byte in the first pass, and then UTF-8 is decoded in the second stage.
Anyway, this is really complex and adds tons of different encodings for one
character. When double_decode is enabled, so ASCII is also enabled to enforce correct decoding.
non_rfc_char
byte
byte ...
This option lets users receive an alert if certain non-RFC chars are used in a request URI. For instance, a user may not want to see null bytes in the request URI and we can alert on that. Please use this option with care, because you could configure it to say, alert on all `/' or something like that. It's flexible, so be careful.
multi_slash
yes
no
This option normalizes multiple slashes in a row, so something like: ``foo/////////bar'' get normalized to ``foo/bar.''
If you want an alert when multiple slashes are seen, then configure with a yes, otherwise, use no.
iis_backslash
yes
no
Normalizes backslashes to slashes. This is again an IIS emulation. So a
request URI of ``/foo
bar'' gets normalized to ``/foo/bar.''
directory
yes
no
This option normalizes directory traversals and self-referential directories.
The directory:
/foo/fake\_dir/../bargets normalized to:
/foo/bar
The directory:
/foo/./bargets normalized to:
/foo/bar
If you want to configure an alert, specify ``yes'', otherwise, specify ``no.'' This alert may give false positives, since some web sites refer to files using directory traversals.
apache_whitespace
yes
no
This option deals with the non-RFC standard of using tab for a space delimiter. Apache uses this, so if the emulated web server is Apache, enable this option. Alerts on this option may be interesting, but may also be false positive prone.
iis_delimiter
yes
no
This started out being IIS-specific, but Apache takes this non-standard delimiter was well. Since this is common, we always take this as standard since the most popular web servers accept it. But you can still get an alert on this option.
chunk_length
non-zero positive integer
This option is an anomaly detector for abnormally large chunk sizes. This picks up the Apache chunk encoding exploits, and may also alert on HTTP tunneling that uses chunk encoding.
no_pipeline_req
This option turns HTTP pipeline decoding off, and is a performance enhancement if needed. By default, pipeline requests are inspected for attacks, but when this option is enabled, pipeline requests are not decoded and analyzed per HTTP protocol field. It is only inspected with the generic pattern matching.
non_strict
This option turns on non-strict URI parsing for the broken way in which Apache
servers will decode a URI. Only use this option on servers that will accept
URIs like this: "get /index.html alsjdfk alsj lj aj la jsj s
n". The
non_strict option assumes the URI is between the first and second space even if
there is no valid HTTP identifier after the second space.
allow_proxy_use
By specifying this keyword, the user is allowing proxy use on this server. This means that no alert will be generated if the proxy_alert global keyword has been used. If the proxy_alert keyword is not enabled, then this option does nothing. The allow_proxy_use keyword is just a way to suppress unauthorized proxy use for an authorized server.
no_alerts
This option turns off all alerts that are generated by the HTTPInspect preprocessor module. This has no effect on HTTP rules in the ruleset. No argument is specified.
oversize_dir_length
non-zero positive integer
This option takes a non-zero positive integer as an argument. The argument specifies the max char directory length for URL directory. If a url directory is larger than this argument size, an alert is generated. A good argument value is 300 characters. This should limit the alerts to IDS evasion type attacks, like whisker -i 4.
inspect_uri_only
This is a performance optimization. When enabled, only the URI portion of HTTP requests will be inspected for attacks. As this field usually contains 90-95% of the web attacks, you'll catch most of the attacks. So if you need extra performance, enable this optimization. It's important to note that if this option is used without any uricontent rules, then no inspection will take place. This is obvious since the URI is only inspected with uricontent rules, and if there are none available, then there is nothing to inspect.
For example, if we have the following rule set:
alert tcp any any -> any 80 ( msg:"content"; content: "foo"; )
and the we inspect the following URI:
get /foo.htm http/1.0\r\n\r\n
No alert will be generated when `inspect_uri_only' is enabled. The `inspect_uri_only' configuration turns off all forms of detection except uricontent inspection.
webroot
yes
no
This option generates an alert when a directory traversal traverses past the web server root directory. This generates much fewer false positives than the directory option, because it doesn't alert on directory traversals that stay within the web server directory structure. It only alerts when the directory traversals go past the web server root directory, which is associated with certain web attacks.
tab_uri_delimiter
This option turns on the use of the tab character (0x09) as a delimiter for a URI. Apache accepts tab as a delimiter, IIS does not. For IIS, a tab in the URI should be treated as any other character. Whether this option is on or not, a tab is treated as whitespace if a space character (0x20) precedes it. No argument is specified.
preprocessor http_inspect_server: server 10.1.1.1 \
ports { 80 3128 8080 } \
flow_depth 0 \
ascii no \
double_decode yes \
non_rfc_char { 0x00 } \
chunk_length 500000 \
non_strict \
no_alerts
preprocessor http_inspect_server: server default \
ports { 80 3128 } \
non_strict \
non_rfc_char { 0x00 } \
flow_depth 300 \
apache_whitespace yes \
directory no \
iis_backslash no \
u_encode yes \
ascii no \
chunk_length 500000 \
bare_byte yes \
double_decode yes \
iis_unicode yes \
iis_delimiter yes \
multi_slash no
preprocessor http_inspect_server: server default \
profile all \
ports { 80 8080 }
The asn.1 detection plugin decodes a packet or a portion of a packet, and looks for various malicious encodings.
The general configuration of the asn.1 rule option is as follows:
asn1: [keyword [argument]], . . .
Multiple keywords can be used in an 'asn1' option and the implied logic is boolean OR. So if any of the arguments evaluate as true, the whole option evaluates as true.
The ASN.1 keywords provide programmatic detection capabilities as well as some more dynamic type detection. Most of the keywords don't have arguments as the detection is looking for non-configurable information. If a keyword does have an argument, the keyword is followed by a comma and the argument is the next word. If a keyword has multiple arguments, then a comman separates each.
The bitstring_overflow option detects invalid bitstring encodings that are known to be remotely exploitable.
The double_overflow detects a double ASCII encoding that is larger than a standard buffer. This is known to be an exploitable function in Microsoft, but it is unknown at this time which services may be exploitable.
This detection keyword compares ASN.1 type lengths with the supplied argument. The syntax looks like, ``oversize_length 500''. This means that if an ASN.1 type is greater than 500, then this keyword is evaluated as true. This keyword must have one argument which specifies the length to compare against.
This is the absolute offset from the beginning of the packet. For example, if you wanted to decode snmp packets, you would say ``absolute_offset, 0''. absolute_offset has one argument--the offset value. Offset may be positive or negative.
This is the relative offset from the last content match or byte_test/jump.
relative_offset has one argument--the offset number. So if you
wanted to start decoding and ASN.1 sequence right after the content ``foo'',
you would specify 'content:"foo"; asn1: bitstring_overflow, relative_offset, 0'. Offset values may be positive or negative.
The following rules use ASN.1 decoding options:
alert udp any any -> any 161 (msg:"Oversize SNMP Length"; \
asn1: oversize_length, 10000, absolute_offset, 0;)
alert tcp any any -> any 80 (msg:"ASN1 Relative Foo"; content:"foo"; \
asn1: bitstring_overflow, print, relative_offset, 0;)
This mini-preprocessor is designed to detect the X-Link2State ( www.microsoft.com/technet/security/bulletin/MS05-021.mspx) vulnerability in Microsoft Exchange Server.
| Note: The X-Link2State functionality will be rolled up into an SMTP preprocessor in the Snort v2.5 timeframe. |
preprocessor xlink2state: ports { <port> [<port> <...>] } [drop]
preprocessor xlink2state: ports { 25 691 }
| site feedback | Terms of Use | Privacy Policy | forum archives ©2008 Snort and Sourcefire are registered trademarks of Sourcefire, Inc. All rights reserved. |