Remove old, unmaintained p0f support.

Addresses GH-417
This commit is contained in:
Johanna Amann 2019-06-19 09:29:32 -07:00
parent 8f668ce82c
commit 632e83de57
12 changed files with 7 additions and 1978 deletions

5
NEWS
View file

@ -429,6 +429,11 @@ Removed Functionality
- Removed the BroControl ``update`` command, which was deprecated in Bro 2.6. - Removed the BroControl ``update`` command, which was deprecated in Bro 2.6.
- Removed p0f (passive OS fingerprinting) support. The version of p0f shipped with zeek was
ancient, probably did not give any reliable support anymore and did not offer a clear upgrade
path. The ``OS_version_found`` event as well as the ``generate_OS_version_event`` configuration
option were removed.
Deprecated Functionality Deprecated Functionality
------------------------ ------------------------

View file

@ -1844,9 +1844,6 @@ function add_signature_file(sold: string, snew: string): string
## since that can search paths relative to the current script. ## since that can search paths relative to the current script.
global signature_files = "" &add_func = add_signature_file; global signature_files = "" &add_func = add_signature_file;
## ``p0f`` fingerprint file to use. Will be searched relative to ``ZEEKPATH``.
const passive_fingerprint_file = "base/misc/p0f.fp" &redef;
## Definition of "secondary filters". A secondary filter is a BPF filter given ## Definition of "secondary filters". A secondary filter is a BPF filter given
## as index in this table. For each such filter, the corresponding event is ## as index in this table. For each such filter, the corresponding event is
## raised for all matching packets. ## raised for all matching packets.
@ -3991,30 +3988,6 @@ type software: record {
version: software_version; version: software_version;
}; };
## Quality of passive fingerprinting matches.
##
## .. zeek:see:: OS_version
type OS_version_inference: enum {
direct_inference, ##< TODO.
generic_inference, ##< TODO.
fuzzy_inference, ##< TODO.
};
## Passive fingerprinting match.
##
## .. zeek:see:: OS_version_found
type OS_version: record {
genre: string; ##< Linux, Windows, AIX, ...
detail: string; ##< Kernel version or such.
dist: count; ##< How far is the host away from the sensor (TTL)?.
match_type: OS_version_inference; ##< Quality of the match.
};
## Defines for which subnets we should do passive fingerprinting.
##
## .. zeek:see:: OS_version_found
global generate_OS_version_event: set[subnet] &redef;
# Type used to report load samples via :zeek:see:`load_sample`. For now, it's a # Type used to report load samples via :zeek:see:`load_sample`. For now, it's a
# set of names (event names, source file names, and perhaps ``<source file, line # set of names (event names, source file names, and perhaps ``<source file, line
# number>``), which were seen during the sample. # number>``), which were seen during the sample.

View file

@ -1,834 +0,0 @@
#
# p0f - SYN fingerprints
# ----------------------
#
# .-------------------------------------------------------------------------.
# | The purpose of this file is to cover signatures for incoming TCP/IP |
# | connections (SYN packets). This is the default mode of operation for |
# | p0f. This is also the biggest and most up-to-date set of signatures |
# | shipped with this project. The file also contains a detailed discussion |
# | of all metrics examined by p0f, and some practical notes on how to |
# | add new signatures. |
# `-------------------------------------------------------------------------'
#
# (C) Copyright 2000-2006 by Michal Zalewski <lcamtuf@coredump.cx>
#
# Each line in this file specifies a single fingerprint. Please read the
# information below carefully before attempting to append any signatures
# reported by p0f as UNKNOWN to this file to avoid mistakes. Note that
# this file is compatible only with the default operation mode, and not
# with -R or -A options (SYN+ACK and RST+ modes).
#
# We use the following set metrics for fingerprinting:
#
# - Window size (WSS) - a highly OS dependent setting used for TCP/IP
# performance control (max. amount of data to be sent without ACK).
# Some systems use a fixed value for initial packets. On other
# systems, it is a multiple of MSS or MTU (MSS+40). In some rare
# cases, the value is just arbitrary.
#
# NEW SIGNATURE: if p0f reported a special value of 'Snn', the number
# appears to be a multiple of MSS (MSS*nn); a special value of 'Tnn'
# means it is a multiple of MTU ((MSS+40)*nn). Unless you notice the
# value of nn is not fixed (unlikely), just copy the Snn or Tnn token
# literally. If you know this device has a simple stack and a fixed
# MTU, you can however multiply S value by MSS, or T value by MSS+40,
# and put it instead of Snn or Tnn. One system may exhibit several T
# or S values. In some situations, this might be a source of some
# additional information about the setup if you have some time to dig
# thru the kernel sources; in some other cases, like Windows, there seem
# to be a multitude of variants and WSS selection algorithms, but it's
# rather difficult to find a pattern without having the source.
#
# If WSS looks like a regular fixed value (for example is a power of two),
# or if you can confirm the value is fixed by looking at several
# fingerprints, please quote it literaly. If there's no apparent pattern
# in WSS chosen, you should consider wildcarding this value - but this
# should be the last option.
#
# NOTE: Some NAT devices, such as Linux iptables with --set-mss, will
# modify MSS, but not WSS. As a result, MSS is changed to reflect
# the MTU of the NAT device, but WSS remains a multiple of the original
# MSS. Fortunately for us, the source device would almost always be
# hooked up to Ethernet. P0f handles it automatically for the original
# MSS of 1460, by adding "NAT!" tag to the result.
#
# In certain configurations, Linux erratically (?) uses MTU from another
# interface on the default gw interface. This only happens on systems with
# two network interfaces. Thus, some Linux systems that do not go thru NAT,
# but have multiple interfaces instead, will be also tagged this way.
#
# P0f recognizes and automatically wildcards WSS of 12345, as generated
# by sendack and sendsyn utilities shipped with the program, when
# reporting a new signature. See test/sendack.c and test/sendsyn.c for more
# information about this.
#
# - Overall packet size - a function of all IP and TCP options and bugs.
# While this is partly redundant in the real world, we record this value
# to capture rare cases when there are IP options (which we do not currently
# examine) or packet data past the headers. Both situations are rare.
#
# Packet size MAY be wildcarded, but the meaning of the wildcard is
# very special, and means the packet must be larger than PACKET_BIG
# (defined in config.h as 100). This is usually not necessary, except
# for some really broken implementations in RST+ mode. For more information,
# see p0fr.fp. P0f automatically wildcards big packets when reporting
# new signatures.
#
# NEW SIGNATURE: Copy this value literally.
#
# - Initial TTL - We check the actual TTL of a received packet. It can't
# be higher than the initial TTL, and also shouldn't be dramatically
# lower (maximum distance is defined in config.h as 40 hops).
#
# NEW SIGNATURE: *Never* copy TTL from a p0f-reported signature literally.
# You need to determine the initial TTL. The best way to do it is to
# check the documentation for a remote system, or check its settings.
# A fairly good method is to simply round the observed TTL up to
# 32, 64, 128, or 255, but it should be noted that some obscure devices
# might not use round TTLs (in particular, some shoddy appliances and
# IRIX and Tru64 are known to use "original" initial TTL settings). If not
# sure, use traceroute or mtr to see how far you are from the host.
#
# Note that -F option overrides this check if no signature can be found.
#
# - Don't fragment flag (DF) - some modern OSes set this to implement PMTU
# discovery. Others do not bother.
#
# NEW SIGNATURE: Copy this value literally. Note: this setting is
# sometimes cleared by firewalls and/or certain connectivity clients.
# Try to find out what's the actual state for a given OS if you see both,
# and add the right one. P0f will automatically detect a case when a
# firewall removed the DF flag and will append "(firewall!)" suffix to
# the signature, so if the DF version is the right one, don't add no-DF
# variant, unless it has a different meaning.
#
# - Maximum segment size (MSS) - this setting is usually link-dependent. P0f
# uses it to determine link type of the remote host.
#
# NEW SIGNATURE: Always wildcard this value, except for rare cases when
# you have an appliance with a fixed value, know the system supports only
# a very limited number of network interface types, or know the system
# is using a value it pulled out of nowhere. I use specific unique MSS
# to tell Google crawlbots from the rest of Linux population, for example.
#
# If a specific MSS/MTU is unique to a certain link type, be sure to
# add it to mtu.h instead of creating several variants of each signature.
#
# - Window scaling (WSCALE) - this feature is used to scale WSS.
# It extends the size of a TCP/IP window to 32 bits, of sorts. Some modern
# systems implement this feature.
#
# NEW SIGNATURE: Observe several signatures. Initial WSCALE is often set
# to zero or other low value. There's usually no need to wildcard this
# parameter.
#
# - Timestamp - some systems that implement timestamps set them to
# zero in the initial SYN. This case is detected and handled appropriately.
#
# NEW SIGNATURE: Copy T or T0 option literally.
#
# - Selective ACK permitted - a flag set by systems that implement
# selective ACK functionality,
#
# NEW SIGNATURE: copy S option literally.
#
# - NOP option - its presence, count and sequence is a useful OS-dependent
# characteristic,
#
# NEW SIGNATURE: copy N options literally.
#
# - Other and unrecognized options (TTCP-related and such) - implemented by
# some eccentric or very buggy TCP/IP stacks ;-),
#
# NEW SIGNATURE: copy ? options literally.
#
# - EOL option. Contrary to the popular belief, the presence of EOL
# option is actually quite rare, most systems just NOP-pad to the
# packet boundary.
#
# NEW SIGNATURE: copy E option literally.
#
# - The sequence of TCP all options mentioned above - this is very
# specific to the implementation,
#
# NEW SIGNATURE: Copy the sequence literally.
#
# - Quirks. Some buggy stacks set certain values that should be zeroed in a
# TCP packet to non-zero values. This has no effect as of today, but is
# a valuable source of information. Some systems actually seem to leak
# memory there. Other systems just exhibit harmful but very specific
# behavior. This section captures all unusual yes-no properties not
# related to the main and expected header layout. We detect the following:
#
# - Data past the headers. Neither SYN nor SYN+ACK packets are supposed
# to carry any payload. If they do, we should take notice. The actual
# payload is not examined, but will be displayed if use the -X option.
# Note that payload is not unusual in RST+ mode (see p0fr.fp), very
# rare otherwise.
#
# - Options past EOL. Some systems have some trailing data past EOL
# in the options section of TCP/IP headers. P0f does not examine this
# data as of today, simply detects its presence. If there is a
# confirmed sizable population of systems that have data past EOL, it
# might be a good idea to look at it. Until then, you have to recompile
# p0f with DEBUG_EXTRAS set or use -x to display this data,
#
# - Zero IP ID. This again is a (mostly) harmless setting to use a fixed
# IP ID for packets with DF set. Some systems reportedly use zero ID,
# most OSes do not. There is a very slight probability of a false
# positive when IP ID is "naturally" chosen to be zero on a system
# that otherwise does set proper values, but the probability is
# neglible (if it becomes a problem, recompile p0f with IGNORE_ZEROID
# set in the sources).
#
# - IP options specified. Usually, packets do not have any IP options
# set, but there can be some. Until there is a confirmed sizable
# population of systems that do have IP options in a packet, p0f
# does not examine those in detail, but it might change (use
# DEBUG_EXTRAS or -x to display IP options if any found),
#
# - URG pointer value. SYN packets do not have URG flag set, so the
# value in URG pointer in TCP header is ignored. Most systems set it
# to zero, but some OSes (some versions of Windows, for example) do
# not zero this field or even simply leak memory; the actual value is
# not examined, because most cases seem to be just random garbage
# (you can use DEBUG_EXTRAS or -x to report this information though);
# see doc/win-memleak.txt for more information,
#
# - "Unused" field value. This should be always zero, but some systems
# forget to clear it. This might result in some funny issues in the
# future. P0f checks for non-zero value (and will display it if
# DEBUG_EXTRAS is set, or you can use -x),
#
# - ACK number non-zero. ACK value in SYN packets with no ACK flag
# is disregarded and is usually set to zero (just like with URG
# pointer), but some systems forget to do it. The exact value is
# not examined (but will be displayed with DEBUG_EXTRAS, or you can
# use -x). Note that this is not an anomaly in SYN+ACK and RST+ modes,
#
# - Non-zero second timestamp. The initial SYN packet should have the
# second timestamp always zeroed. SYN+ACK and RST+ may "legally" have
# this quirk though,
#
# - Unusual flags. If, in addition to SYN (or SYN+ACK), there are some
# auxilinary flags that do not modify the very meaning of a packet,
# p0f records this (this can be URG, PUSH, or something else).
#
# Note: ECN flags (ECE and CWR) are ignored and denoted in a separate
# way. ECN is never by default, because some systems can't handle it,
# and it probably does not make much sense to include it in signatures
# right now.
#
# - TCP option segment parsing problems. If p0f fails to decode options
# because of a badly broken packet, it records this fact.
#
# There are several other quirks valid only in RST+ mode, see p0fr.fp for
# more information. Those quirks are unheard of in SYN and SYN+ACK
# modes.
#
# NEW SIGNATURE: Copy "quirks" section literally.
#
# We DO NOT use ToS for fingerprinting. While the original TCP/IP
# fingerprinting research believed this value would be useful for this
# purpose, it is not. The setting is way too often tweaked by network
# devices.
#
# To wildcard MSS, WSS or WSCALE, replace it with '*'. You can also use a
# modulo operator to match any values that divide by nnn - '%nnn' (and,
# as stated above, WSS also supports special values Snn and Tnn).
#
# Fingerprint entry format:
#
# wwww:ttt:D:ss:OOO...:QQ:OS:Details
#
# wwww - window size (can be * or %nnn or Sxx or Txx)
# "Snn" (multiple of MSS) and "Tnn" (multiple of MTU) are allowed.
# ttt - initial TTL
# D - don't fragment bit (0 - not set, 1 - set)
# ss - overall SYN packet size (* has a special meaning)
# OOO - option value and order specification (see below)
# QQ - quirks list (see below)
# OS - OS genre (Linux, Solaris, Windows)
# details - OS description (2.0.27 on x86, etc)
#
# If OS genre starts with '*', p0f will not show distance, link type
# and timestamp data. It is useful for userland TCP/IP stacks of
# network scanners and so on, where many settings are randomized or
# bogus.
#
# If OS genre starts with @, it denotes an approximate hit for a group
# of operating systems (signature reporting still enabled in this case).
# Use this feature at the end of this file to catch cases for which
# you don't have a precise match, but can tell it's Windows or FreeBSD
# or whatnot by looking at, say, flag layout alone.
#
# If OS genre starts with - (which can prefix @ or *), the entry is
# not considered to be a real operating system (but userland stack
# instead). It is important to mark all scanners and so on with -,
# so that they are not used for masquerade detection (also add this
# prefix for signatures of application-induced behavior, such as
# increased window size with Opera browser).
#
# Option block description is a list of comma or space separated
# options in the order they appear in the packet:
#
# N - NOP option
# E - EOL option
# Wnnn - window scaling option, value nnn (or * or %nnn)
# Mnnn - maximum segment size option, value nnn (or * or %nnn)
# S - selective ACK OK
# T - timestamp
# T0 - timestamp with zero value
# ?n - unrecognized option number n.
#
# P0f can sometimes report ?nn among the options. This means it couldn't
# recognize this option (option number nn). It's either a bug in p0f, or
# a faulty TCP/IP stack, or, if the number is listed here:
#
# http://www.iana.org/assignments/tcp-parameters
#
# ...the stack might be simply quite exotic.
#
# To denote no TCP options, use a single '.'.
#
# Quirks section is usually an empty list ('.') of oddities or bugs of this
# particular stack. List items are not separated in any way. Possible values:
#
# P - options past EOL,
# Z - zero IP ID,
# I - IP options specified,
# U - urg pointer non-zero,
# X - unused (x2) field non-zero,
# A - ACK number non-zero,
# T - non-zero second timestamp,
# F - unusual flags (PUSH, URG, etc),
# D - data payload,
# ! - broken options segment.
#
# WARNING WARNING WARNING
# -----------------------
#
# Do not add a system X as OS Y just because NMAP says so. It is often
# the case that X is a NAT firewall. While nmap is talking to the
# device itself, p0f is fingerprinting the guy behind the firewall
# instead.
#
# When in doubt, use common sense, don't add something that looks like
# a completely different system as Linux or FreeBSD or LinkSys router.
# Check DNS name, establish a connection to the remote host and look
# at SYN+ACK (p0f -A -S should do) - does it look similar?
#
# Some users tweak their TCP/IP settings - enable or disable RFC1323,
# RFC1644 or RFC2018 support, disable PMTU discovery, change MTU, initial
# TTL and so on. Always compare a new rule to other fingerprints for
# this system, and verify the system isn't "customized". It is OK to
# add signature variants caused by commonly used software (PFs, security
# packages, etc), but it makes no sense to try to add every single
# possible /proc/sys/net/ipv4/* tweak on Linux or so.
#
# KEEP IN MIND: Some packet firewalls configured to normalize outgoing
# traffic (OpenBSD pf with "scrub" enabled, for example) will, well,
# normalize packets. Signatures will not correspond to the originating
# system (and probably not quite to the firewall either).
#
# NOTE: Try to keep this file in some reasonable order, from most to
# least likely systems. This will speed up operation. Also keep most
# generic and broad rules near ehe end.
#
# Still decided to add signature? Let us know - mail a copy of your discovery
# to lcamtuf@coredump.cx. You can help make p0f better, and I can help you
# make your signature more accurate.
#
##########################
# Standard OS signatures #
##########################
# ----------------- AIX ---------------------
# AIX is first because its signatures are close to NetBSD, MacOS X and
# Linux 2.0, but it uses a fairly rare MSSes, at least sometimes...
# This is a shoddy hack, though.
45046:64:0:44:M*:.:AIX:4.3
16384:64:0:44:M512:.:AIX:4.3.2 and earlier
16384:64:0:60:M512,N,W%2,N,N,T:.:AIX:4.3.3-5.2 (1)
32768:64:0:60:M512,N,W%2,N,N,T:.:AIX:4.3.3-5.2 (2)
65535:64:0:60:M512,N,W%2,N,N,T:.:AIX:4.3.3-5.2 (3)
65535:64:0:64:M*,N,W1,N,N,T,N,N,S:.:AIX:5.3 ML1
# ----------------- Linux -------------------
S1:64:0:44:M*:A:Linux:1.2.x
512:64:0:44:M*:.:Linux:2.0.3x (1)
16384:64:0:44:M*:.:Linux:2.0.3x (2)
# Endian snafu! Nelson says "ha-ha":
2:64:0:44:M*:.:Linux:2.0.3x (MkLinux) on Mac (1)
64:64:0:44:M*:.:Linux:2.0.3x (MkLinux) on Mac (2)
S4:64:1:60:M1360,S,T,N,W0:.:Linux:2.4 (Google crawlbot)
S4:64:1:60:M1430,S,T,N,W0:.:Linux:2.4-2.6 (Google crawlbot)
S2:64:1:60:M*,S,T,N,W0:.:Linux:2.4 (large MTU?)
S3:64:1:60:M*,S,T,N,W0:.:Linux:2.4 (newer)
S4:64:1:60:M*,S,T,N,W0:.:Linux:2.4-2.6
S3:64:1:60:M*,S,T,N,W1:.:Linux:2.6, seldom 2.4 (older, 1)
S4:64:1:60:M*,S,T,N,W1:.:Linux:2.6, seldom 2.4 (older, 2)
S3:64:1:60:M*,S,T,N,W2:.:Linux:2.6, seldom 2.4 (older, 3)
S4:64:1:60:M*,S,T,N,W2:.:Linux:2.6, seldom 2.4 (older, 4)
T4:64:1:60:M*,S,T,N,W2:.:Linux:2.6 (older, 5)
S4:64:1:60:M*,S,T,N,W5:.:Linux:2.6 (newer, 1)
S4:64:1:60:M*,S,T,N,W6:.:Linux:2.6 (newer, 2)
S4:64:1:60:M*,S,T,N,W7:.:Linux:2.6 (newer, 3)
T4:64:1:60:M*,S,T,N,W7:.:Linux:2.6 (newer, 4)
S20:64:1:60:M*,S,T,N,W0:.:Linux:2.2 (1)
S22:64:1:60:M*,S,T,N,W0:.:Linux:2.2 (2)
S11:64:1:60:M*,S,T,N,W0:.:Linux:2.2 (3)
# Popular cluster config scripts disable timestamps and
# selective ACK:
S4:64:1:48:M1460,N,W0:.:Linux:2.4 in cluster
# This happens only over loopback, but let's make folks happy:
32767:64:1:60:M16396,S,T,N,W0:.:Linux:2.4 (loopback)
32767:64:1:60:M16396,S,T,N,W2:.:Linux:2.6 (newer, loopback)
S8:64:1:60:M3884,S,T,N,W0:.:Linux:2.2 (loopback)
# Opera visitors:
16384:64:1:60:M*,S,T,N,W0:.:-Linux:2.2 (Opera?)
32767:64:1:60:M*,S,T,N,W0:.:-Linux:2.4 (Opera?)
# Some fairly common mods & oddities:
S22:64:1:52:M*,N,N,S,N,W0:.:Linux:2.2 (tstamp-)
S4:64:1:52:M*,N,N,S,N,W0:.:Linux:2.4 (tstamp-)
S4:64:1:52:M*,N,N,S,N,W2:.:Linux:2.6 (tstamp-)
S4:64:1:44:M*:.:Linux:2.6? (barebone, rare!)
T4:64:1:60:M1412,S,T,N,W0:.:Linux:2.4 (rare!)
# ----------------- FreeBSD -----------------
16384:64:1:44:M*:.:FreeBSD:2.0-4.2
16384:64:1:60:M*,N,W0,N,N,T:.:FreeBSD:4.4 (1)
1024:64:1:60:M*,N,W0,N,N,T:.:FreeBSD:4.4 (2)
57344:64:1:44:M*:.:FreeBSD:4.6-4.8 (RFC1323-)
57344:64:1:60:M*,N,W0,N,N,T:.:FreeBSD:4.6-4.9
32768:64:1:60:M*,N,W0,N,N,T:.:FreeBSD:4.8-5.1 (or MacOS X 10.2-10.3)
65535:64:1:60:M*,N,W0,N,N,T:.:FreeBSD:4.7-5.2 (or MacOS X 10.2-10.4) (1)
65535:64:1:60:M*,N,W1,N,N,T:.:FreeBSD:4.7-5.2 (or MacOS X 10.2-10.4) (2)
65535:64:1:60:M*,N,W0,N,N,T:Z:FreeBSD:5.1 (1)
65535:64:1:60:M*,N,W1,N,N,T:Z:FreeBSD:5.1 (2)
65535:64:1:60:M*,N,W2,N,N,T:Z:FreeBSD:5.1 (3)
65535:64:1:64:M*,N,N,S,N,W1,N,N,T:.:FreeBSD:5.3-5.4
65535:64:1:64:M*,N,W1,N,N,T,S,E:P:FreeBSD:6.x (1)
65535:64:1:64:M*,N,W0,N,N,T,S,E:P:FreeBSD:6.x (2)
65535:64:1:44:M*:Z:FreeBSD:5.2 (RFC1323-)
# 16384:64:1:60:M*,N,N,N,N,N,N,T:.:FreeBSD:4.4 (tstamp-)
# ----------------- NetBSD ------------------
16384:64:0:60:M*,N,W0,N,N,T:.:NetBSD:1.3
65535:64:0:60:M*,N,W0,N,N,T0:.:-NetBSD:1.6 (Opera)
16384:64:1:60:M*,N,W0,N,N,T0:.:NetBSD:1.6
65535:64:1:60:M*,N,W1,N,N,T0:.:NetBSD:1.6W-current (DF)
65535:64:1:60:M*,N,W0,N,N,T0:.:NetBSD:1.6X (DF)
32768:64:1:60:M*,N,W0,N,N,T0:.:NetBSD:1.6Z or 2.0 (DF)
32768:64:1:64:M1416,N,W0,S,N,N,N,N,T0:.:NetBSD:2.0G (DF)
32768:64:1:64:M*,N,W0,S,N,N,N,N,T0:.:NetBSD:3.0 (DF)
# ----------------- OpenBSD -----------------
16384:64:1:64:M*,N,N,S,N,W0,N,N,T:.:OpenBSD:3.0-3.9
57344:64:1:64:M*,N,N,S,N,W0,N,N,T:.:OpenBSD:3.3-3.4
16384:64:0:64:M*,N,N,S,N,W0,N,N,T:.:OpenBSD:3.0-3.4 (scrub)
65535:64:1:64:M*,N,N,S,N,W0,N,N,T:.:-OpenBSD:3.0-3.4 (Opera?)
32768:64:1:64:M*,N,N,S,N,W0,N,N,T:.:OpenBSD:3.7
# ----------------- Solaris -----------------
S17:64:1:64:N,W3,N,N,T0,N,N,S,M*:.:Solaris:8 (RFC1323 on)
S17:64:1:48:N,N,S,M*:.:Solaris:8 (1)
S17:255:1:44:M*:.:Solaris:2.5-7 (1)
# Sometimes, just sometimes, Solaris feels like coming up with
# rather arbitrary MSS values ;-)
S6:255:1:44:M*:.:Solaris:2.5-7 (2)
S23:64:1:48:N,N,S,M*:.:Solaris:8 (2)
S34:64:1:48:M*,N,N,S:.:Solaris:9
S34:64:1:48:M*,N,N,N,N:.:Solaris:9 (no sack)
S44:255:1:44:M*:.:Solaris:7
4096:64:0:44:M1460:.:SunOS:4.1.x
S34:64:1:52:M*,N,W0,N,N,S:.:Solaris:10 (beta)
32850:64:1:64:M*,N,N,T,N,W1,N,N,S:.:Solaris:10 (1203?)
32850:64:1:64:M*,N,W1,N,N,T,N,N,S:.:Solaris:9.1
# ----------------- IRIX --------------------
49152:60:0:44:M*:.:IRIX:6.2-6.4
61440:60:0:44:M*:.:IRIX:6.2-6.5
49152:60:0:52:M*,N,W2,N,N,S:.:IRIX:6.5 (RFC1323+) (1)
49152:60:0:52:M*,N,W3,N,N,S:.:IRIX:6.5 (RFC1323+) (2)
61440:60:0:48:M*,N,N,S:.:IRIX:6.5.12-6.5.21 (1)
49152:60:0:48:M*,N,N,S:.:IRIX:6.5.12-6.5.21 (2)
49152:60:0:64:M*,N,W2,N,N,T,N,N,S:.:IRIX:6.5 IP27
# ----------------- Tru64 -------------------
# Tru64 and OpenVMS share the same stack on occassions.
# Relax.
32768:60:1:48:M*,N,W0:.:Tru64:4.0 (or OS/2 Warp 4)
32768:60:0:48:M*,N,W0:.:Tru64:5.0 (or OpenVMS 7.x on Compaq 5.0 stack)
8192:60:0:44:M1460:.:Tru64:5.1 (no RFC1323) (or QNX 6)
61440:60:0:48:M*,N,W0:.:Tru64:v5.1a JP4 (or OpenVMS 7.x on Compaq 5.x stack)
# ----------------- OpenVMS -----------------
6144:64:1:60:M*,N,W0,N,N,T:.:OpenVMS:7.2 (Multinet 4.3-4.4 stack)
# ----------------- MacOS -------------------
S2:255:1:48:M*,W0,E:.:MacOS:8.6 classic
16616:255:1:48:M*,W0,E:.:MacOS:7.3-8.6 (OTTCP)
16616:255:1:48:M*,N,N,N,E:.:MacOS:8.1-8.6 (OTTCP)
32768:255:1:48:M*,W0,N:.:MacOS:9.0-9.2
32768:255:1:48:M1380,N,N,N,N:.:MacOS:9.1 (OT 2.7.4) (1)
65535:255:1:48:M*,N,N,N,N:.:MacOS:9.1 (OT 2.7.4) (2)
# ----------------- Windows -----------------
# Windows TCP/IP stack is a mess. For most recent XP, 2000 and
# even 98, the pathlevel, not the actual OS version, is more
# relevant to the signature. They share the same code, so it would
# seem. Luckily for us, almost all Windows 9x boxes have an
# awkward MSS of 536, which I use to tell one from another
# in most difficult cases.
8192:32:1:44:M*:.:Windows:3.11 (Tucows)
S44:64:1:64:M*,N,W0,N,N,T0,N,N,S:.:Windows:95
8192:128:1:64:M*,N,W0,N,N,T0,N,N,S:.:Windows:95b
# There were so many tweaking tools and so many stack versions for
# Windows 98 it is no longer possible to tell them from each other
# without some very serious research. Until then, there's an insane
# number of signatures, for your amusement:
S44:32:1:48:M*,N,N,S:.:Windows:98 (low TTL) (1)
8192:32:1:48:M*,N,N,S:.:Windows:98 (low TTL) (2)
%8192:64:1:48:M536,N,N,S:.:Windows:98 (13)
%8192:128:1:48:M536,N,N,S:.:Windows:98 (15)
S4:64:1:48:M*,N,N,S:.:Windows:98 (1)
S6:64:1:48:M*,N,N,S:.:Windows:98 (2)
S12:64:1:48:M*,N,N,S:.:Windows:98 (3
T30:64:1:64:M1460,N,W0,N,N,T0,N,N,S:.:Windows:98 (16)
32767:64:1:48:M*,N,N,S:.:Windows:98 (4)
37300:64:1:48:M*,N,N,S:.:Windows:98 (5)
46080:64:1:52:M*,N,W3,N,N,S:.:Windows:98 (RFC1323+)
65535:64:1:44:M*:.:Windows:98 (no sack)
S16:128:1:48:M*,N,N,S:.:Windows:98 (6)
S16:128:1:64:M*,N,W0,N,N,T0,N,N,S:.:Windows:98 (7)
S26:128:1:48:M*,N,N,S:.:Windows:98 (8)
T30:128:1:48:M*,N,N,S:.:Windows:98 (9)
32767:128:1:52:M*,N,W0,N,N,S:.:Windows:98 (10)
60352:128:1:48:M*,N,N,S:.:Windows:98 (11)
60352:128:1:64:M*,N,W2,N,N,T0,N,N,S:.:Windows:98 (12)
# What's with 1414 on NT?
T31:128:1:44:M1414:.:Windows:NT 4.0 SP6a (1)
64512:128:1:44:M1414:.:Windows:NT 4.0 SP6a (2)
8192:128:1:44:M*:.:Windows:NT 4.0 (older)
# Windows XP and 2000. Most of the signatures that were
# either dubious or non-specific (no service pack data)
# were deleted and replaced with generics at the end.
65535:128:1:48:M*,N,N,S:.:Windows:2000 SP4, XP SP1+
%8192:128:1:48:M*,N,N,S:.:Windows:2000 SP2+, XP SP1+ (seldom 98)
S20:128:1:48:M*,N,N,S:.:Windows:SP3
S45:128:1:48:M*,N,N,S:.:Windows:2000 SP4, XP SP1+ (2)
40320:128:1:48:M*,N,N,S:.:Windows:2000 SP4
S6:128:1:48:M*,N,N,S:.:Windows:XP, 2000 SP2+
S12:128:1:48:M*,N,N,S:.:Windows:XP SP1+ (1)
S44:128:1:48:M*,N,N,S:.:Windows:XP SP1+, 2000 SP3
64512:128:1:48:M*,N,N,S:.:Windows:XP SP1+, 2000 SP3 (2)
32767:128:1:48:M*,N,N,S:.:Windows:XP SP1+, 2000 SP4 (3)
# Windows 2003 & Vista
8192:128:1:52:M*,W8,N,N,N,S:.:Windows:Vista (beta)
32768:32:1:52:M1460,N,W0,N,N,S:.:Windows:2003 AS
65535:64:1:52:M1460,N,W2,N,N,S:.:Windows:2003 (1)
65535:64:1:48:M1460,N,N,S:.:Windows:2003 (2)
# Odds, ends, mods:
S52:128:1:48:M1260,N,N,S:.:Windows:XP/2000 via Cisco
65520:128:1:48:M*,N,N,S:.:Windows:XP bare-bone
16384:128:1:52:M536,N,W0,N,N,S:.:Windows:2000 w/ZoneAlarm?
2048:255:0:40:.:.:Windows:.NET Enterprise Server
44620:64:0:48:M*,N,N,S:.:Windows:ME no SP (?)
S6:255:1:48:M536,N,N,S:.:Windows:95 winsock 2
32000:128:0:48:M*,N,N,S:.:Windows:XP w/Winroute?
16384:64:1:48:M1452,N,N,S:.:Windows:XP w/Sygate? (1)
17256:64:1:48:M1460,N,N,S:.:Windows:XP w/Sygate? (2)
# No need to be more specific, it passes:
*:128:1:48:M*,N,N,S:U:-Windows:XP/2000 while downloading (leak!)
# ----------------- HP/UX -------------------
32768:64:1:44:M*:.:HP-UX:B.10.20
32768:64:1:48:M*,W0,N:.:HP-UX:11.00-11.11
# Whoa. Hardcore WSS.
0:64:0:48:M*,W0,N:.:HP-UX:B.11.00 A (RFC1323+)
# ----------------- RiscOS ------------------
16384:64:1:68:M1460,N,W0,N,N,T,N,N,?12:.:RISC OS:3.70-4.36 (inet 5.04)
12288:32:0:44:M536:.:RISC OS:3.70 inet 4.10
4096:64:1:56:M1460,N,N,T:T:RISC OS:3.70 freenet 2.00
# ----------------- BSD/OS ------------------
8192:64:1:60:M1460,N,W0,N,N,T:.:BSD/OS:3.1-4.3 (or MacOS X 10.2)
# ---------------- NetwonOS -----------------
4096:64:0:44:M1420:.:NewtonOS:2.1
# ---------------- NeXTSTEP -----------------
S8:64:0:44:M512:.:NeXTSTEP:3.3 (1)
S4:64:0:44:M1024:.:NeXTSTEP:3.3 (2)
# ------------------ BeOS -------------------
1024:255:0:48:M*,N,W0:.:BeOS:5.0-5.1
12288:255:0:44:M*:.:BeOS:5.0.x
# ------------------ OS/400 -----------------
8192:64:1:60:M1440,N,W0,N,N,T:.:OS/400:V4R4/R5
8192:64:0:44:M536:.:OS/400:V4R3/M0
4096:64:1:60:M1440,N,W0,N,N,T:.:OS/400:V4R5 + CF67032
28672:64:0:44:M1460:A:OS/390:?
# ------------------ ULTRIX -----------------
16384:64:0:40:.:.:ULTRIX:4.5
# ------------------- QNX -------------------
S16:64:0:44:M512:.:QNX:demodisk
16384:64:0:60:M1460,N,W0,N,N,T0:.:QNX:6.x
# ------------------ Novell -----------------
16384:128:1:44:M1460:.:Novell:NetWare 5.0
6144:128:1:44:M1460:.:Novell:IntranetWare 4.11
6144:128:1:44:M1368:.:Novell:BorderManager ?
# According to rfp:
6144:128:1:52:M*,W0,N,S,N,N:.:Novell:Netware 6 SP3
# -------------- SCO UnixWare ---------------
S3:64:1:60:M1460,N,W0,N,N,T:.:SCO:UnixWare 7.1
S17:64:1:60:M*,N,W0,N,N,T:.:SCO:UnixWare 7.1.x
S23:64:1:44:M1380:.:SCO:OpenServer 5.0
# ------------------- DOS -------------------
2048:255:0:44:M536:.:DOS:Arachne via WATTCP/1.05
T2:255:0:44:M984:.:DOS:Arachne via WATTCP/1.05 (eepro)
16383:64:0:44:M536:.:DOS:Unknown via WATTCP (epppd)
# ------------------ OS/2 -------------------
S56:64:0:44:M512:.:OS/2:4
28672:64:0:44:M1460:.:OS/2:Warp 4.0
# ----------------- TOPS-20 -----------------
# Another hardcore MSS, one of the ACK leakers hunted down.
0:64:0:44:M1460:A:TOPS-20:version 7
# ------------------ AMIGA ------------------
S32:64:1:56:M*,N,N,S,N,N,?12:.:AMIGA:3.9 BB2 with Miami stack
# ------------------ Minix ------------------
# Not quite sure.
# 8192:210:0:44:M1460:X:@Minix:?
# ------------------ Plan9 ------------------
65535:255:0:48:M1460,W0,N:.:Plan9:edition 4
# ----------------- AMIGAOS -----------------
16384:64:1:48:M1560,N,N,S:.:AMIGAOS:3.9 BB2 MiamiDX
# ----------------- FreeMiNT ----------------
S44:255:0:44:M536:.:FreeMiNT:1 patch 16A (Atari)
###########################################
# Appliance / embedded / other signatures #
###########################################
# ---------- Firewalls / routers ------------
S12:64:1:44:M1460:.:@Checkpoint:(unknown 1)
S12:64:1:48:N,N,S,M1460:.:@Checkpoint:(unknown 2)
4096:32:0:44:M1460:.:ExtremeWare:4.x
S32:64:0:68:M512,N,W0,N,N,T,N,N,?12:.:Nokia:IPSO w/Checkpoint NG FP3
S16:64:0:68:M1024,N,W0,N,N,T,N,N,?12:.:Nokia:IPSO 3.7 build 026
S4:64:1:60:W0,N,S,T,M1460:.:FortiNet:FortiGate 50
8192:64:1:44:M1460:.:@Eagle:Secure Gateway
# ------- Switches and other stuff ----------
4128:255:0:44:M*:Z:Cisco:7200, Catalyst 3500, etc
S8:255:0:44:M*:.:Cisco:12008
S4:255:0:44:M536:Z:Cisco:IOS 11.0
60352:128:1:64:M1460,N,W2,N,N,T,N,N,S:.:Alteon:ACEswitch
64512:128:1:44:M1370:.:Nortel:Contivity Client
# ---------- Caches and whatnots ------------
8190:255:0:44:M1428:.:Google:Wireless Transcoder (1)
8190:255:0:44:M1460:.:Google:Wireless Transcoder (2)
8192:64:1:64:M1460,N,N,S,N,W0,N,N,T:.:NetCache:5.2
16384:64:1:64:M1460,N,N,S,N,W0,N:.:NetCache:5.3
65535:64:1:64:M1460,N,N,S,N,W*,N,N,T:.:NetCache:5.3-5.5 (or FreeBSD 5.4)
20480:64:1:64:M1460,N,N,S,N,W0,N,N,T:.:NetCache:4.1
S44:64:1:64:M1460,N,N,S,N,W0,N,N,T:.:NetCache:5.5
32850:64:1:64:N,W1,N,N,T,N,N,S,M*:.:NetCache:Data OnTap 5.x
65535:64:0:60:M1460,N,W0,N,N,T:.:CacheFlow:CacheOS 4.1
8192:64:0:60:M1380,N,N,N,N,N,N,T:.:CacheFlow:CacheOS 1.1
S4:64:0:48:M1460,N,N,S:.:Cisco:Content Engine
27085:128:0:40:.:.:Dell:PowerApp cache (Linux-based)
65535:255:1:48:N,W1,M1460:.:Inktomi:crawler
S1:255:1:60:M1460,S,T,N,W0:.:LookSmart:ZyBorg
16384:255:0:40:.:.:Proxyblocker:(what's this?)
65535:255:0:48:M*,N,N,S:.:Redline: T|X 2200
# ----------- Embedded systems --------------
S9:255:0:44:M536:.:PalmOS:Tungsten T3/C
S5:255:0:44:M536:.:PalmOS:3/4
S4:255:0:44:M536:.:PalmOS:3.5
2948:255:0:44:M536:.:PalmOS:3.5.3 (Handera)
S29:255:0:44:M536:.:PalmOS:5.0
16384:255:0:44:M1398:.:PalmOS:5.2 (Clie)
S14:255:0:44:M1350:.:PalmOS:5.2.1 (Treo)
16384:255:0:44:M1400:.:PalmOS:5.2 (Sony)
S23:64:1:64:N,W1,N,N,T,N,N,S,M1460:.:SymbianOS:7
8192:255:0:44:M1460:.:SymbianOS:6048 (Nokia 7650?)
8192:255:0:44:M536:.:SymbianOS:(Nokia 9210?)
S22:64:1:56:M1460,T,S:.:SymbianOS:? (SE P800?)
S36:64:1:56:M1360,T,S:.:SymbianOS:60xx (Nokia 6600?)
S36:64:1:60:M1360,T,S,W0,E:.:SymbianOS:60xx
32768:32:1:44:M1460:.:Windows:CE 3
# Perhaps S4?
5840:64:1:60:M1452,S,T,N,W1:.:Zaurus:3.10
32768:128:1:64:M1460,N,W0,N,N,T0,N,N,S:.:PocketPC:2002
S1:255:0:44:M346:.:Contiki:1.1-rc0
4096:128:0:44:M1460:.:Sega:Dreamcast Dreamkey 3.0
T5:64:0:44:M536:.:Sega:Dreamcast HKT-3020 (browser disc 51027)
S22:64:1:44:M1460:.:Sony:Playstation 2 (SOCOM?)
S12:64:0:44:M1452:.:AXIS:Printer Server 5600 v5.64
3100:32:1:44:M1460:.:Windows:CE 2.0
####################
# Fancy signatures #
####################
1024:64:0:40:.:.:-*NMAP:syn scan (1)
2048:64:0:40:.:.:-*NMAP:syn scan (2)
3072:64:0:40:.:.:-*NMAP:syn scan (3)
4096:64:0:40:.:.:-*NMAP:syn scan (4)
1024:64:0:40:.:A:-*NMAP:TCP sweep probe (1)
2048:64:0:40:.:A:-*NMAP:TCP sweep probe (2)
3072:64:0:40:.:A:-*NMAP:TCP sweep probe (3)
4096:64:0:40:.:A:-*NMAP:TCP sweep probe (4)
1024:64:0:60:W10,N,M265,T,E:P:-*NMAP:OS detection probe (1)
2048:64:0:60:W10,N,M265,T,E:P:-*NMAP:OS detection probe (2)
3072:64:0:60:W10,N,M265,T,E:P:-*NMAP:OS detection probe (3)
4096:64:0:60:W10,N,M265,T,E:P:-*NMAP:OS detection probe (4)
1024:64:0:60:W10,N,M265,T,E:PF:-*NMAP:OS detection probe w/flags (1)
2048:64:0:60:W10,N,M265,T,E:PF:-*NMAP:OS detection probe w/flags (2)
3072:64:0:60:W10,N,M265,T,E:PF:-*NMAP:OS detection probe w/flags (3)
4096:64:0:60:W10,N,M265,T,E:PF:-*NMAP:OS detection probe w/flags (4)
32767:64:0:40:.:.:-*NAST:syn scan
12345:255:0:40:.:A:-p0f:sendsyn utility
# UFO - see tmp/*:
56922:128:0:40:.:A:-@Mysterious:port scanner (?)
5792:64:1:60:M1460,S,T,N,W0:T:-@Mysterious:NAT device (2nd tstamp)
S12:128:1:48:M1460,E:P:@Mysterious:Chello proxy (?)
S23:64:1:64:N,W1,N,N,T,N,N,S,M1380:.:@Mysterious:GPRS gateway (?)
#####################################
# Generic signatures - just in case #
#####################################
*:128:1:52:M*,N,W0,N,N,S:.:@Windows:XP/2000 (RFC1323+, w, tstamp-)
*:128:1:52:M*,N,W*,N,N,S:.:@Windows:XP/2000 (RFC1323+, w+, tstamp-)
*:128:1:52:M*,N,N,T0,N,N,S:.:@Windows:XP/2000 (RFC1323+, w-, tstamp+)
*:128:1:64:M*,N,W0,N,N,T0,N,N,S:.:@Windows:XP/2000 (RFC1323+, w, tstamp+)
*:128:1:64:M*,N,W*,N,N,T0,N,N,S:.:@Windows:XP/2000 (RFC1323+, w+, tstamp+)
*:128:1:48:M536,N,N,S:.:@Windows:98
*:128:1:48:M*,N,N,S:.:@Windows:XP/2000

View file

@ -285,7 +285,6 @@ set(bro_SRCS
NetVar.cc NetVar.cc
Obj.cc Obj.cc
OpaqueVal.cc OpaqueVal.cc
OSFinger.cc
PacketFilter.cc PacketFilter.cc
Pipe.cc Pipe.cc
PolicyFile.cc PolicyFile.cc

View file

@ -140,9 +140,6 @@ RecordType* backdoor_endp_stats;
RecordType* software; RecordType* software;
RecordType* software_version; RecordType* software_version;
RecordType* OS_version;
EnumType* OS_version_inference;
TableVal* generate_OS_version_event;
double table_expire_interval; double table_expire_interval;
double table_expire_delay; double table_expire_delay;
@ -425,10 +422,6 @@ void init_net_var()
software = internal_type("software")->AsRecordType(); software = internal_type("software")->AsRecordType();
software_version = internal_type("software_version")->AsRecordType(); software_version = internal_type("software_version")->AsRecordType();
OS_version = internal_type("OS_version")->AsRecordType();
OS_version_inference = internal_type("OS_version_inference")->AsEnumType();
generate_OS_version_event =
opt_internal_table("generate_OS_version_event");
packet_type = internal_type("packet")->AsRecordType(); packet_type = internal_type("packet")->AsRecordType();

View file

@ -143,9 +143,6 @@ extern RecordType* backdoor_endp_stats;
extern RecordType* software; extern RecordType* software;
extern RecordType* software_version; extern RecordType* software_version;
extern RecordType* OS_version;
extern EnumType* OS_version_inference;
extern TableVal* generate_OS_version_event;
extern double table_expire_interval; extern double table_expire_interval;
extern double table_expire_delay; extern double table_expire_delay;

View file

@ -1,689 +0,0 @@
/*
Taken with permission from:
p0f - passive OS fingerprinting (GNU LESSER GENERAL PUBLIC LICENSE)
-------------------------------------------------------------------
"If you sit down at a poker game and don't see a sucker,
get up. You're the sucker."
(C) Copyright 2000-2003 by Michal Zalewski <lcamtuf@coredump.cx>
*/
// To make it easier to upgrade this file to newer releases of p0f,
// it remains in the coding style used by p0f rather than Bro.
#include "OSFinger.h"
#include "net_util.h"
#include "util.h"
#include "Var.h"
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
void int_delete_func(void* v)
{
delete (int*) v;
}
// Initializes data structures for fingerprinting in the given mode.
OSFingerprint::OSFingerprint(FingerprintMode arg_mode)
{
err = 0;
mode = arg_mode;
sigcnt=gencnt=0;
problems=0;
char* fname;
memset(sig, 0, sizeof(struct fp_entry)*MAXSIGS);
memset(bh, 0, sizeof(struct fp_entry*)*OSHSIZE);
os_matches.SetDeleteFunc(int_delete_func);
if (mode == SYN_FINGERPRINT_MODE)
{
fname = copy_string(internal_val("passive_fingerprint_file")->AsString()->CheckString());
load_config(fname);
delete [] fname;
}
else if (mode == SYN_ACK_FINGERPRINT_MODE)
{//not yet supported
load_config("p0fsynack.sig");
}
else if (mode == RST_FINGERPRINT_MODE)
{//not yet supported
load_config("p0frst.sig");
}
else
{
Error("OS fingerprinting: unknown mode!");
}
}
bool OSFingerprint::CacheMatch(const IPAddr& addr, int id)
{
HashKey* key = addr.GetHashKey();
int* pid = new int;
*pid=id;
int* prev = os_matches.Insert(key, pid);
bool ret = (prev ? *prev != id : 1);
if (prev)
delete prev;
delete key;
return ret;
}
// Determines whether the signature file had any collisions.
void OSFingerprint::collide(uint32 id)
{
uint32 i,j;
uint32 cur;
if (sig[id].ttl % 32 && sig[id].ttl != 255 && sig[id].ttl % 30)
{
problems=1;
reporter->Warning("OS fingerprinting: [!] Unusual TTL (%d) for signature '%s %s' (line %d).",
sig[id].ttl,sig[id].os,sig[id].desc,sig[id].line);
}
for (i=0;i<id;i++)
{
if (!strcmp(sig[i].os,sig[id].os) &&
!strcmp(sig[i].desc,sig[id].desc)) {
problems=1;
reporter->Warning("OS fingerprinting: [!] Duplicate signature name: '%s %s' (line %d and %d).",
sig[i].os,sig[i].desc,sig[i].line,sig[id].line);
}
/* If TTLs are sufficiently away from each other, the risk of
a collision is lower. */
if (abs((int)sig[id].ttl - (int)sig[i].ttl) > 25) continue;
if (sig[id].df ^ sig[i].df) continue;
if (sig[id].zero_stamp ^ sig[i].zero_stamp) continue;
/* Zero means >= PACKET_BIG */
if (sig[id].size) { if (sig[id].size ^ sig[i].size) continue; }
else if (sig[i].size < PACKET_BIG) continue;
if (sig[id].optcnt ^ sig[i].optcnt) continue;
if (sig[id].quirks ^ sig[i].quirks) continue;
switch (sig[id].wsize_mod) {
case 0: /* Current: const */
cur=sig[id].wsize;
do_const:
switch (sig[i].wsize_mod) {
case 0: /* Previous is also const */
/* A problem if values match */
if (cur ^ sig[i].wsize) continue;
break;
case MOD_CONST: /* Current: const, prev: modulo (or *) */
/* A problem if current value is a multiple of that modulo */
if (cur % sig[i].wsize) continue;
break;
case MOD_MSS: /* Current: const, prev: mod MSS */
if (sig[i].mss_mod || sig[i].wsize *
(sig[i].mss ? sig[i].mss : 1460 ) != (int) cur)
continue;
break;
case MOD_MTU: /* Current: const, prev: mod MTU */
if (sig[i].mss_mod || sig[i].wsize * (
(sig[i].mss ? sig[i].mss : 1460 )+40) != (int) cur)
continue;
break;
}
break;
case 1: /* Current signature is modulo something */
/* A problem only if this modulo is a multiple of the
previous modulo */
if (sig[i].wsize_mod != MOD_CONST) continue;
if (sig[id].wsize % sig[i].wsize) continue;
break;
case MOD_MSS: /* Current is modulo MSS */
/* There's likely a problem only if the previous one is close
to '*'; we do not check known MTUs, because this particular
signature can be made with some uncommon MTUs in mind. The
problem would also appear if current signature has a fixed
MSS. */
if (sig[i].wsize_mod != MOD_CONST || sig[i].wsize >= 8) {
if (!sig[id].mss_mod) {
cur = (sig[id].mss ? sig[id].mss : 1460 ) * sig[id].wsize;
goto do_const;
}
continue;
}
break;
case MOD_MTU: /* Current is modulo MTU */
if (sig[i].wsize_mod != MOD_CONST || sig[i].wsize <= 8) {
if (!sig[id].mss_mod) {
cur = ( (sig[id].mss ? sig[id].mss : 1460 ) +40) * sig[id].wsize;
goto do_const;
}
continue;
}
break;
}
/* Same for wsc */
switch (sig[id].wsc_mod) {
case 0: /* Current: const */
cur=sig[id].wsc;
switch (sig[i].wsc_mod) {
case 0: /* Previous is also const */
/* A problem if values match */
if (cur ^ sig[i].wsc) continue;
break;
case 1: /* Current: const, prev: modulo (or *) */
/* A problem if current value is a multiple of that modulo */
if (cur % sig[i].wsc) continue;
break;
}
break;
case MOD_CONST: /* Current signature is modulo something */
/* A problem only if this modulo is a multiple of the
previous modulo */
if (!sig[i].wsc_mod) continue;
if (sig[id].wsc % sig[i].wsc) continue;
break;
}
/* Same for mss */
switch (sig[id].mss_mod) {
case 0: /* Current: const */
cur=sig[id].mss;
switch (sig[i].mss_mod) {
case 0: /* Previous is also const */
/* A problem if values match */
if (cur ^ sig[i].mss) continue;
break;
case 1: /* Current: const, prev: modulo (or *) */
/* A problem if current value is a multiple of that modulo */
if (cur % sig[i].mss) continue;
break;
}
break;
case MOD_CONST: /* Current signature is modulo something */
/* A problem only if this modulo is a multiple of the
previous modulo */
if (!sig[i].mss_mod) continue;
if ((sig[id].mss ? sig[id].mss : 1460 ) %
(sig[i].mss ? sig[i].mss : 1460 )) continue;
break;
}
/* Now check option sequence */
for (j=0;j<sig[id].optcnt;j++)
if (sig[id].opt[j] ^ sig[i].opt[j]) goto reloop;
problems=1;
reporter->Warning("OS fingerprinting: [!] Signature '%s %s' (line %d)\n"
" is already covered by '%s %s' (line %d).",
sig[id].os,sig[id].desc,sig[id].line,sig[i].os,sig[i].desc,
sig[i].line);
reloop:
;
}
}
// Loads a given file into to classes data structures.
void OSFingerprint::load_config(const char* file)
{
uint32 ln=0;
char buf[MAXLINE];
char* p;
FILE* c = open_file(find_file(file, bro_path(), ".osf"));
if (!c)
{
Error("Can't open OS passive fingerprinting signature file", file);
return;
}
sigcnt=0; //every time we read config we reset it to 0;
while ((p=fgets(buf,sizeof(buf),c)))
{
uint32 l;
char obuf[MAXLINE],genre[MAXLINE],desc[MAXLINE],quirks[MAXLINE];
char w[MAXLINE],sb[MAXLINE];
char* gptr = genre;
uint32 t,d,s;
struct fp_entry* e;
ln++;
/* Remove leading and trailing blanks */
while (isspace(*p)) p++;
l=strlen(p);
while (l && isspace(*(p+l-1))) *(p+(l--)-1)=0;
/* Skip empty lines and comments */
if (!l) continue;
if (*p == '#') continue;
if (sscanf(p,"%[0-9%*()ST]:%d:%d:%[0-9()*]:%[^:]:%[^ :]:%[^:]:%[^:]",
w, &t,&d,sb, obuf, quirks,genre,desc) != 8)
Error("OS fingerprinting: Syntax error in p0f signature config line %d.\n",(uint32)ln);
gptr = genre;
if (*sb != '*') s = atoi(sb); else s = 0;
reparse_ptr:
switch (*gptr)
{
case '-': sig[sigcnt].userland = 1; gptr++; goto reparse_ptr;
case '*': sig[sigcnt].no_detail = 1; gptr++; goto reparse_ptr;
case '@': sig[sigcnt].generic = 1; gptr++; gencnt++; goto reparse_ptr;
case 0: Error("OS fingerprinting: Empty OS genre in line",(uint32)ln);
}
sig[sigcnt].os = strdup(gptr);
sig[sigcnt].desc = strdup(desc);
sig[sigcnt].ttl = t;
sig[sigcnt].size = s;
sig[sigcnt].df = d;
if (w[0] == '*')
{
sig[sigcnt].wsize = 1;
sig[sigcnt].wsize_mod = MOD_CONST;
}
else if (tolower(w[0]) == 's')
{
sig[sigcnt].wsize_mod = MOD_MSS;
if (!isdigit(*(w+1)))
Error("OS fingerprinting: Bad Snn value in WSS in line",(uint32)ln);
sig[sigcnt].wsize = atoi(w+1);
}
else if (tolower(w[0]) == 't')
{
sig[sigcnt].wsize_mod = MOD_MTU;
if (!isdigit(*(w+1)))
Error("OS fingerprinting: Bad Tnn value in WSS in line",(uint32)ln);
sig[sigcnt].wsize = atoi(w+1);
}
else if (w[0] == '%')
{
if (!(sig[sigcnt].wsize = atoi(w+1)))
Error("OS fingerprinting: Null modulo for window size in config line",(uint32)ln);
sig[sigcnt].wsize_mod = MOD_CONST;
}
else
sig[sigcnt].wsize = atoi(w);
/* Now let's parse options */
p=obuf;
sig[sigcnt].zero_stamp = 1;
if (*p=='.') p++;
while (*p)
{
uint8 optcnt = sig[sigcnt].optcnt;
switch (tolower(*p))
{
case 'n': sig[sigcnt].opt[optcnt] = TCPOPT_NOP;
break;
case 'e': sig[sigcnt].opt[optcnt] = TCPOPT_EOL;
if (*(p+1))
Error("OS fingerprinting: EOL not the last option, line",(uint32)ln);
break;
case 's': sig[sigcnt].opt[optcnt] = TCPOPT_SACK_PERMITTED;
break;
case 't': sig[sigcnt].opt[optcnt] = TCPOPT_TIMESTAMP;
if (*(p+1)!='0')
{
sig[sigcnt].zero_stamp=0;
if (isdigit(*(p+1)))
Error("OS fingerprinting: Bogus Tstamp specification in line",(uint32)ln);
}
break;
case 'w': sig[sigcnt].opt[optcnt] = TCPOPT_WINDOW;
if (p[1] == '*')
{
sig[sigcnt].wsc = 1;
sig[sigcnt].wsc_mod = MOD_CONST;
}
else if (p[1] == '%')
{
if (!(sig[sigcnt].wsc = atoi(p+2)))
Error("OS fingerprinting: Null modulo for wscale in config line",(uint32)ln);
sig[sigcnt].wsc_mod = MOD_CONST;
}
else if (!isdigit(*(p+1)))
Error("OS fingerprinting: Incorrect W value in line",(uint32)ln);
else sig[sigcnt].wsc = atoi(p+1);
break;
case 'm': sig[sigcnt].opt[optcnt] = TCPOPT_MAXSEG;
if (p[1] == '*')
{
sig[sigcnt].mss = 1;
sig[sigcnt].mss_mod = MOD_CONST;
}
else if (p[1] == '%')
{
if (!(sig[sigcnt].mss = atoi(p+2)))
Error("OS fingerprinting: Null modulo for MSS in config line",(uint32)ln);
sig[sigcnt].mss_mod = MOD_CONST;
}
else if (!isdigit(*(p+1)))
Error("OS fingerprinting: Incorrect M value in line",(uint32)ln);
else sig[sigcnt].mss = atoi(p+1);
break;
/* Yuck! */
case '?': if (!isdigit(*(p+1)))
Error("OS fingerprinting: Bogus ?nn value in line",(uint32)ln);
else sig[sigcnt].opt[optcnt] = atoi(p+1);
break;
default: Error("OS fingerprinting: Unknown TCP option in config line",(uint32)ln);
}
if (++sig[sigcnt].optcnt >= MAXOPT)
Error("OS fingerprinting: Too many TCP options specified in config line",(uint32)ln);
/* Skip separators */
do { p++; } while (*p && !isalpha(*p) && *p != '?');
}
sig[sigcnt].line = ln;
p = quirks;
while (*p)
switch (toupper(*(p++)))
{
case 'E':
Error("OS fingerprinting: Quirk 'E' is obsolete. Remove it, append E to the options. Line",(uint32)ln);
break;
case 'K':
if ( mode != RST_FINGERPRINT_MODE )
Error("OS fingerprinting: Quirk 'K' is valid only in RST+ (-R) mode (wrong config file?). Line",(uint32)ln);
sig[sigcnt].quirks |= QUIRK_RSTACK;
break;
case 'Q': sig[sigcnt].quirks |= QUIRK_SEQEQ; break;
case '0': sig[sigcnt].quirks |= QUIRK_SEQ0; break;
case 'P': sig[sigcnt].quirks |= QUIRK_PAST; break;
case 'Z': sig[sigcnt].quirks |= QUIRK_ZEROID; break;
case 'I': sig[sigcnt].quirks |= QUIRK_IPOPT; break;
case 'U': sig[sigcnt].quirks |= QUIRK_URG; break;
case 'X': sig[sigcnt].quirks |= QUIRK_X2; break;
case 'A': sig[sigcnt].quirks |= QUIRK_ACK; break;
case 'T': sig[sigcnt].quirks |= QUIRK_T2; break;
case 'F': sig[sigcnt].quirks |= QUIRK_FLAGS; break;
case 'D': sig[sigcnt].quirks |= QUIRK_DATA; break;
case '!': sig[sigcnt].quirks |= QUIRK_BROKEN; break;
case '.': break;
default: Error("OS fingerprinting: Bad quirk in line",(uint32)ln);
}
e = bh[SIGHASH(s,sig[sigcnt].optcnt,sig[sigcnt].quirks,d)];
if (!e)
{
bh[SIGHASH(s,sig[sigcnt].optcnt,sig[sigcnt].quirks,d)] = &sig[sigcnt];
}
else
{
while (e->next) e = e->next;
e->next = &sig[sigcnt];
}
collide(sigcnt);
if (++sigcnt >= MAXSIGS)
Error("OS fingerprinting: Maximum signature count exceeded.\n");
}
fclose(c);
if (!sigcnt)
Error("OS fingerprinting: no signatures loaded from config file.");
}
// Does the actual match between the packet and the signature database.
// Modifies retval and contains OS Type and other useful information.
// Returns config-file line of the matching signature as id.
int OSFingerprint::FindMatch(struct os_type* retval, uint16 tot,uint8 df,
uint8 ttl,uint16 wss,uint8 ocnt,uint8* op,
uint16 mss,uint8 wsc,uint32 tstamp,
uint32 quirks,uint8 ecn) const
{
uint32 j; //used for counter in loops
struct fp_entry* p;
uint8 orig_df = df;
struct fp_entry* fuzzy = 0;
uint8 fuzzy_now = 0;
int id = 0; //return value: 0 indicates no match.
retval->os="UNKNOWN";
retval->desc=NULL;
retval->gadgets=0;
retval->match=0;
retval->uptime=0;
re_lookup:
p = bh[SIGHASH(tot,ocnt,quirks,df)];
while (p)
{
/* Cheap and specific checks first... */
/* psize set to zero means >= PACKET_BIG */
if (p->size) { if (tot ^ p->size) { p = p->next; continue; } }
else if (tot < PACKET_BIG) { p = p->next; continue; }
if (ocnt ^ p->optcnt) { p = p->next; continue; }
if (p->zero_stamp ^ (!tstamp)) { p = p->next; continue; }
if (p->df ^ df) { p = p->next; continue; }
if (p->quirks ^ quirks) { p = p->next; continue; }
/* Check MSS and WSCALE... */
if (!p->mss_mod) {
if (mss ^ p->mss) { p = p->next; continue; }
} else if (mss % p->mss) { p = p->next; continue; }
if (!p->wsc_mod) {
if (wsc ^ p->wsc) { p = p->next; continue; }
} else if (wsc % p->wsc) { p = p->next; continue; }
/* Then proceed with the most complex WSS check... */
switch (p->wsize_mod)
{
case 0:
if (wss ^ p->wsize) { p = p->next; continue; }
break;
case MOD_CONST:
if (wss % p->wsize) { p = p->next; continue; }
break;
case MOD_MSS:
if (mss && !(wss % mss))
{
if ((wss / mss) ^ p->wsize) { p = p->next; continue; }
}
else if (!(wss % 1460))
{
if ((wss / 1460) ^ p->wsize) { p = p->next; continue; }
}
else { p = p->next; continue; }
break;
case MOD_MTU:
if (mss && !(wss % (mss+40)))
{
if ((wss / (mss+40)) ^ p->wsize) { p = p->next; continue; }
}
else if (!(wss % 1500))
{
if ((wss / 1500) ^ p->wsize) { p = p->next; continue; }
}
else { p = p->next; continue; }
break;
}
/* Numbers agree. Let's check options */
for (j=0;j<ocnt;j++)
if (p->opt[j] ^ op[j]) goto continue_search;
/* Check TTLs last because we might want to go fuzzy. */
if (p->ttl < ttl)
{
if ( mode != RST_FINGERPRINT_MODE )fuzzy = p;
p = p->next;
continue;
}
/* Naah... can't happen ;-) */
if (!p->no_detail)
if (p->ttl - ttl > MAXDIST)
{
if (mode != RST_FINGERPRINT_MODE ) fuzzy = p;
p = p->next;
continue;
}
continue_fuzzy:
/* Match! */
id = p->line;
if (mss & wss)
{
if (p->wsize_mod == MOD_MSS)
{
if ((wss % mss) && !(wss % 1460)) retval->gadgets|=GADGETNAT;
}
else if (p->wsize_mod == MOD_MTU)
{
if ((wss % (mss+40)) && !(wss % 1500)) retval->gadgets|=GADGETNAT2;
}
}
retval->os=p->os;
retval->desc=p->desc;
retval->dist=p->ttl-ttl;
if (ecn) retval->gadgets|=GADGETECN;
if (orig_df ^ df) retval->gadgets|=GADGETFIREWALL;
if (p->generic) retval->match=MATCHGENERIC;
if (fuzzy_now) retval->match=MATCHFUZZY;
if (!p->no_detail && tstamp)
{
retval->uptime=tstamp/360000;
retval->gadgets|=GADGETUPTIME;
}
return id;
continue_search:
p = p->next;
}
if (!df) { df = 1; goto re_lookup; } //not found with df=0 do df=1
if (fuzzy)
{
df = orig_df;
fuzzy_now = 1;
p = fuzzy;
fuzzy = 0;
goto continue_fuzzy;
}
if (mss & wss)
{
if ((wss % mss) && !(wss % 1460)) retval->gadgets|=GADGETNAT;
else if ((wss % (mss+40)) && !(wss % 1500)) retval->gadgets|=GADGETNAT2;
}
if (ecn) retval->gadgets|=GADGETECN;
if (tstamp)
{
retval->uptime=tstamp/360000;
retval->gadgets|=GADGETUPTIME;
}
return id;
}

View file

@ -1,161 +0,0 @@
// Taken with permission from:
//
// p0f - passive OS fingerprinting (GNU LESSER GENERAL PUBLIC LICENSE)
// -------------------------------------------------------------------
//
// "If you sit down at a poker game and don't see a sucker,
// get up. You're the sucker."
//
// (C) Copyright 2000-2003 by Michal Zalewski <lcamtuf@coredump.cx>
#ifndef osfinger_h
#define osfinger_h
#include "util.h"
#include "Dict.h"
#include "Reporter.h"
#include "IPAddr.h"
// Size limit for size wildcards.
#define PACKET_BIG 100
// Maximum number of signatures allowed in the config file.
#define MAXSIGS 1024
// Max signature line length.
#define MAXLINE 1024
// Maximum distance from a host to be taken seriously. Between 35 and 64
// is sane. Making it too high might result in some (very rare) false
// positives, too low will result in needless UNKNOWNs.
#define MAXDIST 40
// Maximum number of TCP options. A TCP packet can have at most 64 bytes
// of header, 20 of which are non-options. Thus, if a single option
// consumes 1 bytes (the minimum, there can only be 44 bytes of options.
// We err on the safe side.
#define MAXOPT 64
declare(PDict,int);
struct os_type {
const char* os;
char* desc;
uint8 dist;
uint16 gadgets;
uint16 match;
uint32 uptime;
};
struct fp_entry {
struct fp_entry* next;
char* os; // OS genre
char* desc; // OS description
uint8 no_detail; // disable guesstimates
uint8 generic; // generic hit
uint8 userland; // userland stack
uint16 wsize; // window size
uint8 wsize_mod; // MOD_* for wsize
uint8 ttl; // TTL
uint8 df; // don't fragment bit
uint8 zero_stamp; // timestamp option but zero value?
uint16 size; // packet size
uint8 optcnt; // option count
uint8 opt[MAXOPT]; // TCPOPT_*
uint16 wsc; // window scaling option
uint16 mss; // MSS option
uint8 wsc_mod; // modulo for WSCALE (NONE or CONST)
uint8 mss_mod; // modulo for MSS (NONE or CONST)
uint32 quirks; // packet quirks and bugs
uint32 line; // config file line
};
struct mtu_def {
uint16 mtu;
char* dev;
};
enum FingerprintMode {
SYN_FINGERPRINT_MODE, SYN_ACK_FINGERPRINT_MODE, RST_FINGERPRINT_MODE,
};
class OSFingerprint {
public:
explicit OSFingerprint(FingerprintMode mode);
~OSFingerprint() {}
bool Error() const { return err; }
int FindMatch(struct os_type* retval, uint16 tot, uint8 DF_flag,
uint8 TTL, uint16 WSS, uint8 ocnt, uint8* op, uint16 MSS,
uint8 win_scale, uint32 tstamp, uint32 quirks, uint8 ECN) const;
bool CacheMatch(const IPAddr& addr, int id);
void load_config(const char* file);
protected:
void collide(uint32 id);
void Error(const char* msg)
{
reporter->Error("%s", msg);
err = true;
}
void Error(const char* msg, int n)
{
reporter->Error(msg, n);
err = true;
}
void Error(const char* msg, const char* s)
{
reporter->Error(msg, s);
err = true;
}
private:
bool err; // if true, a fatal error has occurred
unsigned int mode;
uint32 sigcnt, gencnt;
uint8 problems;
struct fp_entry sig[MAXSIGS];
/* By hash */
#define OSHSIZE 16
struct fp_entry* bh[OSHSIZE];
PDict(int) os_matches;
};
#define SIGHASH(tsize, optcnt, q, df) \
((uint8(((tsize) << 1) ^ ((optcnt) << 1) ^ (df) ^ (q) )) & 0x0f)
#define MOD_NONE 0
#define MOD_CONST 1
#define MOD_MSS 2
#define MOD_MTU 3
#define QUIRK_PAST 0x1 /* P */
#define QUIRK_ZEROID 0x2 /* Z */
#define QUIRK_IPOPT 0x4 /* I */
#define QUIRK_URG 0x8 /* U */
#define QUIRK_X2 0x10 /* X */
#define QUIRK_ACK 0x20 /* A */
#define QUIRK_T2 0x40 /* T */
#define QUIRK_FLAGS 0x80 /* F */
#define QUIRK_DATA 0x100 /* D */
#define QUIRK_BROKEN 0x200 /* ! */
#define QUIRK_RSTACK 0x400 /* K */
#define QUIRK_SEQEQ 0x800 /* Q */
#define QUIRK_SEQ0 0x1000 /* 0 */
#define GADGETNAT 0x1
#define GADGETNAT2 0x2
#define GADGETFIREWALL 0x4
#define GADGETECN 0x8
#define GADGETUPTIME 0x10
#define MATCHGENERIC 0x1
#define MATCHFUZZY 0x2
#endif

View file

@ -14,7 +14,6 @@
#include "NetVar.h" #include "NetVar.h"
#include "Sessions.h" #include "Sessions.h"
#include "Reporter.h" #include "Reporter.h"
#include "OSFinger.h"
#include "analyzer/protocol/icmp/ICMP.h" #include "analyzer/protocol/icmp/ICMP.h"
#include "analyzer/protocol/udp/UDP.h" #include "analyzer/protocol/udp/UDP.h"
@ -130,15 +129,6 @@ NetSessions::NetSessions()
dump_this_packet = 0; dump_this_packet = 0;
num_packets_processed = 0; num_packets_processed = 0;
if ( OS_version_found )
{
SYN_OS_Fingerprinter = new OSFingerprint(SYN_FINGERPRINT_MODE);
if ( SYN_OS_Fingerprinter->Error() )
exit(1);
}
else
SYN_OS_Fingerprinter = 0;
if ( pkt_profile_mode && pkt_profile_freq > 0 && pkt_profile_file ) if ( pkt_profile_mode && pkt_profile_freq > 0 && pkt_profile_file )
pkt_profiler = new PacketProfiler(pkt_profile_mode, pkt_profiler = new PacketProfiler(pkt_profile_mode,
pkt_profile_freq, pkt_profile_file->AsFile()); pkt_profile_freq, pkt_profile_file->AsFile());
@ -155,7 +145,6 @@ NetSessions::~NetSessions()
{ {
delete ch; delete ch;
delete packet_filter; delete packet_filter;
delete SYN_OS_Fingerprinter;
delete pkt_profiler; delete pkt_profiler;
Unref(arp_analyzer); Unref(arp_analyzer);
delete discarder; delete discarder;
@ -987,24 +976,6 @@ FragReassembler* NetSessions::NextFragment(double t, const IP_Hdr* ip,
return f; return f;
} }
int NetSessions::Get_OS_From_SYN(struct os_type* retval,
uint16 tot, uint8 DF_flag, uint8 TTL, uint16 WSS,
uint8 ocnt, uint8* op, uint16 MSS, uint8 win_scale,
uint32 tstamp, /* uint8 TOS, */ uint32 quirks,
uint8 ECN) const
{
return SYN_OS_Fingerprinter ?
SYN_OS_Fingerprinter->FindMatch(retval, tot, DF_flag, TTL,
WSS, ocnt, op, MSS, win_scale, tstamp,
quirks, ECN) : 0;
}
bool NetSessions::CompareWithPreviousOSMatch(const IPAddr& addr, int id) const
{
return SYN_OS_Fingerprinter ?
SYN_OS_Fingerprinter->CacheMatch(addr, id) : 0;
}
Connection* NetSessions::FindConnection(Val* v) Connection* NetSessions::FindConnection(Val* v)
{ {
BroType* vt = v->Type(); BroType* vt = v->Type();

View file

@ -17,7 +17,6 @@
class EncapsulationStack; class EncapsulationStack;
class Connection; class Connection;
class OSFingerprint;
class ConnCompressor; class ConnCompressor;
struct ConnID; struct ConnID;
@ -77,14 +76,6 @@ public:
FragReassembler* NextFragment(double t, const IP_Hdr* ip, FragReassembler* NextFragment(double t, const IP_Hdr* ip,
const u_char* pkt); const u_char* pkt);
int Get_OS_From_SYN(struct os_type* retval,
uint16 tot, uint8 DF_flag, uint8 TTL, uint16 WSS,
uint8 ocnt, uint8* op, uint16 MSS, uint8 win_scale,
uint32 tstamp, /* uint8 TOS, */ uint32 quirks,
uint8 ECN) const;
bool CompareWithPreviousOSMatch(const IPAddr& addr, int id) const;
// Looks up the connection referred to by the given Val, // Looks up the connection referred to by the given Val,
// which should be a conn_id record. Returns nil if there's // which should be a conn_id record. Returns nil if there's
// no such connection or the Val is ill-formed. // no such connection or the Val is ill-formed.
@ -240,7 +231,6 @@ protected:
analyzer::stepping_stone::SteppingStoneManager* stp_manager; analyzer::stepping_stone::SteppingStoneManager* stp_manager;
Discarder* discarder; Discarder* discarder;
PacketFilter* packet_filter; PacketFilter* packet_filter;
OSFingerprint* SYN_OS_Fingerprinter;
int build_backdoor_analyzer; int build_backdoor_analyzer;
int dump_this_packet; // if true, current packet should be recorded int dump_this_packet; // if true, current packet should be recorded
uint64 num_packets_processed; uint64 num_packets_processed;

View file

@ -4,7 +4,6 @@
#include "NetVar.h" #include "NetVar.h"
#include "File.h" #include "File.h"
#include "OSFinger.h"
#include "Event.h" #include "Event.h"
#include "analyzer/protocol/pia/PIA.h" #include "analyzer/protocol/pia/PIA.h"
@ -115,201 +114,6 @@ static RecordVal* build_syn_packet_val(int is_orig, const IP_Hdr* ip,
return v; return v;
} }
static RecordVal* build_os_val(int is_orig, const IP_Hdr* ip,
const struct tcphdr* tcp, uint32 tcp_hdr_len)
{
if ( ! is_orig )
// Later we might use SYN-ACK fingerprinting here.
return 0;
// Passive OS fingerprinting wants to know a lot about IP and TCP
// options: how many options there are, and in which order.
int winscale = 0;
int MSS = 0;
int optcount = 0;
uint32 quirks = 0;
uint32 tstamp = 0;
uint8 op[MAXOPT];
if ( ip->HdrLen() > 20 )
quirks |= QUIRK_IPOPT;
if ( ip->ID() == 0 )
quirks |= QUIRK_ZEROID;
if ( tcp->th_seq == 0 )
quirks |= QUIRK_SEQ0;
if ( tcp->th_seq == tcp->th_ack )
quirks |= QUIRK_SEQEQ;
if ( tcp->th_flags & ~(TH_SYN|TH_ACK|TH_RST|TH_ECE|TH_CWR) )
quirks |= QUIRK_FLAGS;
if ( ip->TotalLen() - ip->HdrLen() - tcp_hdr_len > 0 )
quirks |= QUIRK_DATA; // SYN with data
if ( tcp->th_ack )
quirks |= QUIRK_ACK;
if ( tcp->th_urp )
quirks |= QUIRK_URG;
if ( tcp->th_x2 )
quirks |= QUIRK_X2;
// Parse TCP options.
u_char* options = (u_char*) tcp + sizeof(struct tcphdr);
u_char* opt_end = (u_char*) tcp + tcp_hdr_len;
while ( options < opt_end )
{
unsigned int opt = options[0];
if ( opt == TCPOPT_EOL )
{
op[optcount++] = TCPOPT_EOL;
if ( ++options < opt_end )
quirks |= QUIRK_PAST;
// All done - could flag if more junk left over ....
break;
}
if ( opt == TCPOPT_NOP )
{
op[optcount++] = TCPOPT_NOP;
++options;
continue;
}
if ( options + 1 >= opt_end )
{
// We've run off the end, no room for the length.
quirks |= QUIRK_BROKEN;
break;
}
unsigned int opt_len = options[1];
if ( options + opt_len > opt_end )
{
// No room for rest of the options.
quirks |= QUIRK_BROKEN;
break;
}
if ( opt_len == 0 )
// Trashed length field.
break;
switch ( opt ) {
case TCPOPT_SACK_PERMITTED:
// SACKOK LEN
op[optcount] = TCPOPT_SACK_PERMITTED;
break;
case TCPOPT_MAXSEG:
// MSS LEN D0 D1
if ( opt_len < 4 )
break; // bad length
op[optcount] = TCPOPT_MAXSEG;
MSS = (options[2] << 8) | options[3];
break;
case TCPOPT_WINDOW:
// WSCALE LEN D0
if ( opt_len < 3 )
break; // bad length
op[optcount] = TCPOPT_WINDOW;
winscale = options[2];
break;
case TCPOPT_TIMESTAMP:
// TSTAMP LEN T0 T1 T2 T3 A0 A1 A2 A3
if ( opt_len < 10 )
break; // bad length
op[optcount] = TCPOPT_TIMESTAMP;
tstamp = ntohl(extract_uint32(options + 2));
if ( extract_uint32(options + 6) )
quirks |= QUIRK_T2;
break;
default: // just skip over
op[optcount]=opt;
break;
}
if ( optcount < MAXOPT - 1 )
++optcount;
else
quirks |= QUIRK_BROKEN;
options += opt_len;
}
struct os_type os_from_print;
int id = sessions->Get_OS_From_SYN(&os_from_print,
uint16(ip->TotalLen()),
uint8(ip->DF()), uint8(ip->TTL()),
uint16(ntohs(tcp->th_win)),
uint8(optcount), op,
uint16(MSS), uint8(winscale),
tstamp, quirks,
uint8(tcp->th_flags & (TH_ECE|TH_CWR)));
if ( sessions->CompareWithPreviousOSMatch(ip->SrcAddr(), id) )
{
RecordVal* os = new RecordVal(OS_version);
os->Assign(0, new StringVal(os_from_print.os));
if ( os_from_print.desc )
os->Assign(1, new StringVal(os_from_print.desc));
else
os->Assign(1, val_mgr->GetEmptyString());
os->Assign(2, val_mgr->GetCount(os_from_print.dist));
os->Assign(3, OS_version_inference->GetVal(os_from_print.match));
return os;
}
return 0;
}
static void passive_fingerprint(TCP_Analyzer* tcp, bool is_orig,
const IP_Hdr* ip, const struct tcphdr* tp,
uint32 tcp_hdr_len)
{
// is_orig will be removed once we can do SYN-ACK fingerprinting
if ( OS_version_found && is_orig )
{
const IPAddr& orig_addr = tcp->Conn()->OrigAddr();
AddrVal* src_addr_val = new AddrVal(orig_addr);
if ( generate_OS_version_event->Size() == 0 ||
generate_OS_version_event->Lookup(src_addr_val) )
{
RecordVal* OS_val = build_os_val(is_orig, ip, tp, tcp_hdr_len);
if ( OS_val )
{ // found new OS version
tcp->ConnectionEventFast(OS_version_found, {
tcp->BuildConnVal(),
src_addr_val->Ref(),
OS_val,
});
}
}
Unref(src_addr_val);
}
}
TCP_Analyzer::TCP_Analyzer(Connection* conn) TCP_Analyzer::TCP_Analyzer(Connection* conn)
: TransportLayerAnalyzer("TCP", conn) : TransportLayerAnalyzer("TCP", conn)
@ -1286,8 +1090,6 @@ void TCP_Analyzer::DeliverPacket(int len, const u_char* data, bool is_orig,
}); });
} }
passive_fingerprint(this, is_orig, ip, tp, tcp_hdr_len);
Unref(SYN_vals); Unref(SYN_vals);
} }

View file

@ -545,7 +545,7 @@ event signature_match%(state: signature_state, msg: string, data: string%);
## descr: The raw (unparsed) software identification string as extracted from ## descr: The raw (unparsed) software identification string as extracted from
## the protocol. ## the protocol.
## ##
## .. zeek:see:: software_parse_error software_unparsed_version_found OS_version_found ## .. zeek:see:: software_parse_error software_unparsed_version_found
event software_version_found%(c: connection, host: addr, event software_version_found%(c: connection, host: addr,
s: software, descr: string%); s: software, descr: string%);
@ -564,7 +564,6 @@ event software_version_found%(c: connection, host: addr,
## the protocol. ## the protocol.
## ##
## .. zeek:see:: software_version_found software_unparsed_version_found ## .. zeek:see:: software_version_found software_unparsed_version_found
## OS_version_found
event software_parse_error%(c: connection, host: addr, descr: string%); event software_parse_error%(c: connection, host: addr, descr: string%);
## Generated when a protocol analyzer finds an identification of a software ## Generated when a protocol analyzer finds an identification of a software
@ -581,25 +580,9 @@ event software_parse_error%(c: connection, host: addr, descr: string%);
## ##
## str: The software identification string as extracted from the protocol. ## str: The software identification string as extracted from the protocol.
## ##
## .. zeek:see:: software_parse_error software_version_found OS_version_found ## .. zeek:see:: software_parse_error software_version_found
event software_unparsed_version_found%(c: connection, host: addr, str: string%); event software_unparsed_version_found%(c: connection, host: addr, str: string%);
## Generated when an operating system has been fingerprinted. Zeek uses `p0f
## <http://lcamtuf.coredump.cx/p0f.shtml>`__ to fingerprint endpoints passively,
## and it raises this event for each system identified. The p0f fingerprints are
## defined by :zeek:id:`passive_fingerprint_file`.
##
## c: The connection.
##
## host: The host running the reported OS.
##
## OS: The OS version string.
##
## .. zeek:see:: passive_fingerprint_file software_parse_error
## software_version_found software_unparsed_version_found
## generate_OS_version_event
event OS_version_found%(c: connection, host: addr, OS: OS_version%);
## Generated each time Zeek's internal profiling log is updated. The file is ## Generated each time Zeek's internal profiling log is updated. The file is
## defined by :zeek:id:`profiling_file`, and its update frequency by ## defined by :zeek:id:`profiling_file`, and its update frequency by
## :zeek:id:`profiling_interval` and :zeek:id:`expensive_profiling_multiple`. ## :zeek:id:`profiling_interval` and :zeek:id:`expensive_profiling_multiple`.