Daniel Roelker droelker@sourcefire.com Marc Norton mnorton@sourcefire.com Jeremy Hewlett jh@sourcefire.com
Documentation last updated 2004-09-08
– Overview –
This module 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 services 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.
The following are a list of the types of Nmap scans sfPortscan will currently alert for.
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.
Decoy portscans are much like the 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.
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.
Caveat: Negative queries will be distributed among scanning hosts, so we track this type of scan through the scanned host.
The alerts are for one-many portsweeps. One host scans a single port on multiple hosts. Usually occurs when a new exploit comes out and the attacker is looking for a specific service.
Caveat: 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.
IP Filtered Portscan
IP Filtered Decoy Portscan
ICMP Filtered Portsweep
“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 on 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 original scan alert.
– Configuration –
Use of the “stream5” preprocessor is required for sfPortscan. Stream gives portscan direction in the case of connectionless protocols like UDP.
preprocessor stream5_global: track_udp yes preprocessor stream5_udp:
The parameters you can use to configure the portscan module are:
proto {
scan_type {
sense_level {
“Low” alerts are only generated on error packets sent from the target host, and because of the nature of error responses, this setting should see very few false positives. However, this setting will never trigger a Filtered Scan alert because of a lack of error responses. This setting is based on a static time window of 60 seconds, afterwhich this window is reset.
“Medium” alerts track Connection Counts, and so will generate Filtered Scan alerts. This setting may false positive on active hosts (NATs, proxies, DNS caches, etc), so the user may need to deploy the use of Ignore directives to properly tune this directive.
“High” alerts continuously track hosts on a network using a time window to evaluate portscan statistics for that host. A “High” setting will catch some slow scans because of the continuous monitoring, but is very sensitive to active hosts. This most definitely will require the user to tune sfPortscan.
watch_ip { <ip1 | ip2/cidr[ [port1 | port2-port3]]> } |
Defines which IPs, networks, and specific ports on those hosts to watch. The list is a comma separated list of IP addresses, IP address using CIDR notation. Optionally, ports are specified after the IP address/CIDR using a space and can be either a single port or a range denoted by a dash. IPs or networks not falling into this range are ignored if this option is used.
ignore_scanners { <ip1 | ip2/cidr[ [port1 | port2-port3]]> } |
Ignores the source of scan alerts. The parameter is the same format as that of watch_ip.
ignore_scanned { <ip1 | ip2/cidr[ [port1 | port2-port3]]> } |
Ignores the destination of scan alerts. The parameter is the same format as that of watch_ip.
memcap { positive integer } The maximum number of bytes to allocate for portscan detection. The higher this number the more nodes that can be tracked.
disabled
This optional keyword is allowed with any policy to avoid packet processing.
This option disables the preprocessor. When the preprocessor is disabled
only the memcap option is applied when specified with the configuration.
The other options are parsed but not used. Any valid configuration may have
“disabled” added to it.
include_midstream This option will include sessions picked up in midstream by Stream4 or Stream5. This can lead to false alerts, especially under heavy load with dropped packets; which is why the option is off by default.
Example configuration:
preprocessor flow: stats_interval 0 hash 2 preprocessor sfportscan: proto { all } \ scan_type { all } \ sense_level { low }
– Alert Output –
(unified)
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.
(logfile)
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
Event_id/Event_ref
These fields are used to link an alert with the corresponding Open Port tagged packet
Priority Count
Priority Count keeps track of bad responses (resets, unreachables). The higher the Priority Count, the more bad responses have been received.
Connection Count
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
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.
Scanned/Scanner IP Range
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
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.
– Tuning sfPortscan –
The most important aspect in detecting portscans is tuning the detection engine for your network(s). Here are some tuning tips:
Use the watch_ip, ignore_scanners, and ignore_scanned options.
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.
Filtered scan alerts are much more prone to false positives.
When deteriming 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.
Make use of the Priority Count, Connection Count, IP Count, Port Count, IP range, and Port range to determine false positives.
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 legitimate 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 all else fails, lower the sensitivity level.
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.
SFPortscan uses generator ID 122 and can generate the following alerts:
SID Description — ———– 1 TCP Portscan 2 TCP Decoy Portscan 3 TCP Portsweep 4 TCP Distributed Portscan 5 TCP Filtered Portscan 6 TCP Filtered Decoy Portscan 7 TCP Filtered Portsweep 8 TCP Filtered Distributed Portscan 9 IP Protocol Scan 10 IP Decoy Protocol Scan 11 IP Protocol Sweep 12 IP Distributed Protocol Scan 13 IP Filtered Protocol Scan 14 IP Filtered Decoy Protocol Scan 15 IP Filtered Protocol Sweep 16 IP Filtered Distributed Protocol Scan 17 UDP Portscan 18 UDP Decoy Portscan 19 UDP Portsweep 20 UDP Distributed Portscan 21 UDP Filtered Portscan 22 UDP Filtered Decoy Portscan 23 UDP Filtered Portsweep 24 UDP Filtered Distributed Portscan 25 ICMP Sweep 26 ICMP Filtered Sweep 27 Open Port