sfPortscan
----------
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.

* TCP Portscan
* UDP Portscan
* IP Portscan

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.

* TCP Decoy Portscan
* UDP Decoy Portscan
* IP Decoy Portscan

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.

* TCP Distributed Portscan
* UDP Distributed Portscan
* IP Distributed Portscan

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.

* TCP Portsweep
* UDP Portsweep
* IP Portsweep
* ICMP Portsweep

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.

* TCP Filtered Portscan
* UDP Filtered Portscan
* IP Filtered Portscan

* TCP Filtered Decoy Portscan
* UDP Filtered Decoy Portscan
* IP Filtered Decoy Portscan

* TCP Filtered Portsweep
* UDP Filtered Portsweep
* IP Filtered Portsweep
* ICMP Filtered Portsweep

* TCP Filtered Distributed Portscan
* UDP Filtered Distributed Portscan
* IP Filtered Distributed Portscan

"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 { <proto> }
  Available options:
	tcp 
	udp 
	icmp 
	ip 
	all 

* scan_type { <scan_type> } 
  Available options: 
	portscan 
	portsweep 
	decoy_portscan 
	distributed_portscan 
	all

* sense_level { <level> }
  Available options:
	low
	medium 
	high

  "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 seperated 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.

* logfile { <file> } 
  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.

* 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.

* detect_ack_scans
  This option will include sessions picked up in midstream by the stream
  module, which is necessary to detect ACK scans.  However, 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

  1. Event_id/Event_ref

     These fields are used to link an alert with the corresponding 
     Open Port tagged packet

  2. Priority Count

     Priority Count keeps track of bad responses (resets,
     unreachables). The higher the Priority Count, the more bad
     responses have been received.

  3. 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).

  4. 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.

  5. 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. 

  6. 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:

  1. 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.
  
  2. 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.
     
  3. 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 legitmate 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).
     
  4. 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.
     

Alerts
======

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

