TCP/IP Stack
Fingerprinting Principles Thomas Glaser October 25,
2000
Introduction
Reconnaissance is a practice used by skilled hackers to size up
and gather information about their target. There are several ways to
go about gathering any given piece of information regarding a target
that would yield vulnerability. One of the most important pieces of
information that a hacker could have is the flavor and version
operating system of a remote host. With information in regards to
the flavor and version of the operating system, a hacker could look
for any number of possible vulnerabilities via information on the
web that are specific to that operating system and version.
For instance, if someone were to determine that an organization’s
router to the Internet was running Cisco IOS v11.x, that person
could lookup a number of known vulnerabilities at a web site like http://www.securityfocus.com/
that are relevant to IOS v11.x. One such vulnerability that affects
IOS v11.x is a denial of service type attack if the router is
running a web server. A packet could be crafted such that it would
pass the contents: http://<router-ip>/%% to the server
port with a spoofed source address that would cause the router to
crash. Since the source address was spoofed, it would be extremely
difficult if not impossible to track down the perpetrator.
The proliferation of several new tools have been made available
on the Internet that to a high degree of accuracy can tell the
operating system of a host just by examining subtle details in the
way the TCP/IP stack was implemented within that operating system.
This method is called TCP/IP fingerprinting.
Examples of these tools include nmap and queso. This paper
examines the specific methodology used by probably the most popular
tool for TCP/IP fingerprinting, nmap.
TCP/IP Fingerprinting via NMAP
Since each developer of an operating system implements TCP/IP a
bit differently than another developer of an operating system,
different operating system’s TCP/IP stack could respond differently
given the same situation in a TCP/IP conversation.
At the time of this writing, NMAP interrogates the target
machine’s TCP/IP stack by sending it eight different packets and
observing the response. Each of the eight different packets are
specially crafted to put the target machine in a position where
there is a high probability that two things will happen:
- The target operating system’s TCP/IP stack will respond unique
in comparison to another operating system’s TCP/IP stack.
- The target operating system TCP/IP stack will respond in a
consistent manner.
Knowing how a given operating system’s TCP/IP stack would respond
in advance to each of the eight tests allows NMAP to determine with
a high degree of accuracy not only which operating system the target
is running, but also what version it is running as well.
The crafted test packets are sent one at a time by the source
machine running nmap. The tests are documented in the table
below:
Test |
Description |
TSeq |
A series of SYN packets are sent to
the target machine to see how TCP sequence numbers are
derived. |
T1 |
A SYN packet with options (WNMTE)
set is sent to an open TCP port. |
T2 |
A NULL packet with options (WNMTE)
set is sent to an open TCP port. |
T3 |
A SYN,FIN,PSH,URG packet with
options (WNMTE) set is sent to an open TCP port. |
T4 |
An ACK packet with options (WNMTE)
set is sent to an open TCP port. |
T5 |
A SYN packet with options (WNMTE)
set is sent to a closed TCP port. |
T6 |
A ACK packet with options (WNMTE)
set is sent to a closed TCP port. |
T7 |
A FIN,PSH,URG packet with options
(WNMTE) set is sent to a closed TCP port. |
PU |
A packet to a closed UDP
port. |
Several different metrics are observed for each of the first
seven tests to help determine the target operating system. They are:
- Whether or not the target host responded.
- Whether or not the target host responded with a packet that
had the "Don’t Fragment" bit set.
- The Window Size set by the target host in the response packet.
- The relationship of the acknowledgement number of the TCP
packet sent in response to NMAP’s prior TCP packet.
- Flags set in the TCP packet sent in response.
- TCP options that are in the responding packet.
The first test (Tseq) and last test (PU) uses different metrics
that will not be covered in this paper, but the same principles
apply.
All of these metrics can measure something different between
operating systems and different versions of the same operating
system given a certain test. But these metrics are consistent with
the same version of a given operating system given any of the tests
that NMAP implements.
NMAP holds all of its known operating system fingerprints in a
text file called nmap-os-fingerprints. There are a few
hundred fingerprints documented that include at least one entry for
all the popular operating systems. An entry in the file typically
looks like: Fingerprint Windows 2000
TSeq(Class=RI%gcd=<5%SI=>BBB&<FFFF)
T1(DF=Y%W=402E%ACK=S++%Flags=AS%Ops=MNWNNT)
T2(Resp=Y%DF=N%W=0%ACK=S%Flags=AR%Ops=)
T3(Resp=Y%DF=Y%W=402E%ACK=S++%Flags=AS%Ops=MNWNNT)
T4(DF=N%W=0%ACK=O%Flags=R%Ops=)
T5(DF=N%W=0%ACK=S++%Flags=AR%Ops=)
T6(DF=N%W=0%ACK=O%Flags=R%Ops=)
T7(DF=N%W=0%ACK=S++%Flags=AR%Ops=)
PU(DF=N%TOS=0%IPLEN=38%RIPTL=148%RID=E%RIPCK=E%UCK=E%ULEN=134%DAT=E)
The line that states Fingerprint Windows 2000 identifies
the operating system (and sometimes version) that owns the
fingerprint. The next line that begins with a TSeq,
identifies the method for calculating TCP sequence numbers for a
given TCP session. The lines that follow, starting with T1 through
PU, are descriptive of how that operating system fingerprinted would
respond to the given test.
The tests T1 through T7 are all TCP tests. The symbol ‘%’
delimits the metrics used in fingerprinting. The symbol ‘|’ is used
to represent "or" in a given set of answers to a metric to state
that a number of given results would satisfy the fingerprint.
The metrics are detailed in the following table:
Metric |
Valid
Values |
Description |
Resp |
Y = There was a response
N = There was no response |
Whether or not the host responded
to the test packet by sending a reply. |
DF |
Y = DF was set
N = DF was not set |
Whether or not the host responding
to the test packet sent the "Don’t Fragment" bit in
response. |
W |
Can be a two-byte integer expressed
in hexadecimal. |
Window advertisement size sent by
the host responding to the test packet. |
ACK |
0 = ack zero
S = ack sequence number
S++ = ack sequence number + 1 |
The acknowledgement sequence number
response type. |
Flags |
S = SYN
A = ACK
R = RST
F = FIN
U = URG
P = PSH |
Indicate what flags were set in the
responding packet. |
Ops |
M = MSS
E = Echoed MSS
W = Window Scale
T = Timestamp
N = No Option |
Options sent back by the host
responding to the test packet. There can be any number of
options set (including none) in any order. |
For example, let us take the first test in the previous
fingerprint example: T1(DF=Y%W=402E%ACK=S++%Flags=AS%Ops=MNWNNT)
This test states that the response packet of the target host to
NMAP sending a SYN packet with options to it had the following
characteristics:
Resp= |
Resp is not defined; which means
the metric is satisfied whether or not the target
replies |
DF=Y |
The "Don’t Fragment" bit was
set |
W=402E |
The window size was 402E |
ACK=S++ |
Acknowledgement number was one plus
the initial sequence number |
Flags=AS |
The packet had the SYN/ACK flags
set |
Ops=MNWNNT |
The packet had the following option
flags set in this order: MNWNNT |
The following is a trace (using dump) that illustrates how the
tests are implemented. There is a source machine running NMAP
(10.0.2.3) and a target machine (10.0.2.6) that we would like to
test to see if NMAP can find a TCP/IP stack fingerprint for in its
fingerprint file.
Source Test Packet
1 (NMAP) |
10:37:42.324053 10.0.2.3.34031 > 10.0.2.6.135: S
1338197984:1338197984(0) win 4096 <wscale 10,nop,mss
265,timestamp 1061109567 0,eol> (ttl 59, id 9783)
|
Target’s
Response |
10:37:42.324518 10.0.2.6.135 > 10.0.2.3.34031: S
2863638239:2863638239(0) ack 1338197985 win 16430 <mss
1460,nop,wscale 0,nop,nop,timestamp 0 0> (DF) (ttl 128, id
15245) |
The first test packet NMAP sends out is a SYN packet some TCP
options set. Looking at the above trace and going through our
metrics we can deduce the following:
- The target responded so the metric Resp=Y
- The "Don’t Fragment" bit (DF) was set in the target’s response
so the metric DF=Y
- The window size is 16430; however, in hex that is 402E. So the
metric W=402E
- The acknowledgement number equals the source sequence number
plus 1. So the metric Ack=S++
- A SYN/ACK packet was sent in response. So the metric Flags=AS
- The TCP options MNWNNT was sent in response. So the metric
Ops=MNWNNT.
The fingerprint for T1 (Test 1) would look like:
T1(DF=Y%W=402E%Ack=S++%Flags=AS%Ops=MNWNNT)
Source Test Packet
2 (NMAP) |
10:37:42.324315 10.0.2.3.34032 > 10.0.2.6.135: . win
4096 <wscale 10,nop,mss 265,timestamp 1061109567 0,eol>
(ttl 59, id 1545) |
Target’s
Response |
10:37:42.324718 10.0.2.6.135 > 10.0.2.3.34032: R
0:0(0) ack 1338197984 win 0 (ttl 128, id
15246) |
The second test packet NMAP sends out is a NULL packet some TCP
options set. Looking at the above trace and going through our
metrics we can deduce the following:
- The target responded so the metric Resp=Y
- The "Don’t Fragment" bit (DF) was not set in the target’s
response. So the metric DF=N
- The window size is 0. So the metric W=0
- The acknowledgement number equals the most recent source
sequence number. So the metric Ack=S
- An ACK and a RESET were sent in response. So the metric
Flags=AR
- There were no TCP options sent in response. So the metric
Ops=.
The fingerprint for T2 would look like: T2(Resp=Y%DF=N%W=0%ACK=S%Flags=AR%Ops=)
Source Test Packet
3 (NMAP) |
10:37:42.327823 10.0.2.3.34033 > 10.0.2.6.135: SFP
1338197984:1338197984(0) win 4096 urg 0 <wscale 10,nop,mss
265,timestamp 1061109567 0,eol> (ttl 59, id 4649)
|
Target’s
Response |
10:37:42.328265 10.0.2.6.135 > 10.0.2.3.34033: S
2863675212:2863675212(0) ack 1338197985 win 16430 <mss
1460,nop,wscale 0,nop,nop,timestamp 0 0> (DF) (ttl 128, id
15247) |
The third test packet NMAP sends out is a SYN/FIN/PSH/URG packet
some TCP options set to a known open port. The fingerprint for T3
would look like: T3(Resp=Y%DF=Y%W=402E%ACK=S++%Flags=AS%Ops=MNWNNT)
Source Test Packet
4 (NMAP) |
10:37:42.334937 10.0.2.3.34034 > 10.0.2.6.135: . ack
0 win 4096 <wscale 10,nop,mss 265,timestamp 1061109567
0,eol> (ttl 59, id 6192) |
Target’s
Response |
10:37:42.335359 10.0.2.6.135 > 10.0.2.3.34034: R
0:0(0) win 0 (ttl 128, id 15248) |
The fourth test packet NMAP sends out is an ACK packet some TCP
options set to a known open port. The fingerprint for T4 would look
like: T4(DF=N%W=0%ACK=O%Flags=R%Ops=)
Source Test Packet
5 (NMAP) |
10:37:42.340712 10.0.2.3.34035 > 10.0.2.6.32775: S
1338197984:1338197984(0) win 4096 <wscale 10,nop,mss
265,timestamp 1061109567 0,eol> (ttl 59, id
62508) |
Target’s
Response |
10:37:42.341113 10.0.2.6.32775 > 10.0.2.3.34035: R
0:0(0) ack 1338197985 win 0 (ttl 128, id
15249) |
The fifth test packet NMAP sends out is an SYN packet some TCP
options set to a known closed port. The fingerprint for T5 would
look like: T5(DF=N%W=0%ACK=S++%Flags=AR%Ops=)
Source Test Packet
6 (NMAP) |
10:37:42.343991 10.0.2.3.34036 > 10.0.2.6.32775: .
ack 0 win 4096 <wscale 10,nop,mss 265,timestamp 1061109567
0,eol> (ttl 59, id 18026) |
Target’s
Response |
10:37:42.344416 10.0.2.6.32775 > 10.0.2.3.34036: R
0:0(0) win 0 (ttl 128, id 15250) |
The sixth test packet NMAP sends out is an ACK packet some TCP
options set to a known closed port. The fingerprint for T6 would
look like: T6(DF=N%W=0%ACK=O%Flags=R%Ops=)
Source Test Packet
7 (NMAP) |
10:37:42.349443 10.0.2.3.34037 > 10.0.2.6.32775: FP
1338197984:1338197984(0) win 4096 urg 0 <wscale 10,nop,mss
265,timestamp 1061109567 0,eol> (ttl 59, id
37913) |
Target’s
Response |
10:37:42.349840 10.0.2.6.32775 > 10.0.2.3.34037: R
0:0(0) ack 1338197985 win 0 (ttl 128, id
15251) |
The seventh test packet NMAP sends out is an FIN/PSH/URG packet
some TCP options set to a known closed port. The fingerprint for T7
would look like: T7(DF=N%W=0%ACK=S++%Flags=AR%Ops=)
Adding up the results of the cumulative testing results in the
examples shows a fingerprint that matches the fingerprint shown for
Windows 2000 above.
Countermeasures to TCP/IP
Fingerprinting?
There has been a little bit of talk on the Internet regarding
possible counter measures to stack fingerprinting. The two main
solutions that come up most often:
- Use a TCP/IP filtering technique (or firewall) to keep hosts
from getting tested or responding to the tests
- Modifying the TCP/IP stack behavior via option set within the
operating system itself.
At this point properly configured TCP/IP filtering techniques
seem to provide the best protection.
Operating systems such as Microsoft Windows, Linux, and Sun
Solaris have added the ability to modify TCP behavior. Such things
as TCP options and window sizes can now be configured. The use of
these new features as countermeasures alone have drawn criticism
from those who participated in a BugTraq thread called "Preventing
Remote OS Detection":
The fact of the matter is that most of these fixes are
stopgap measures and not very extensible. The proper fix is
standards compliance and ubiquitous support. Of course the
question then becomes which standards do we adhere to, and what is
to be done if there isn't standard defined behavior for some
instance...? That's a good one. I say, close the Internet for
repairs.
http://www.securityfocus.com/archive/1/12670
"route"
Feb 22 1999
As route suggested, the true fix is "standards compliance and
ubiquitous support" that he and another colleague suggested is near
impossible:
You probably can't, at least without a significant,
tedious, and error-prone code audit. We've been doing research on
OS fingerprinting for the past few years, and there are hundreds
of different stack-specific idiosyncrasies.
http://www.securityfocus.com/archive/1/12675
Thomas H. Ptacek
Feb 22 1999
References
[1] Fyodor. "Remote OS detection via TCP/IP Stack
FingerPrinting." October 18, 1998. http://www.insecure.org/nmap/nmap-fingerprinting-article.html
[2] Various. "nmap-os-fingerprints." October 12, 2000. Included
with NMAP tool.
[3] Gilbert, Patrick. "PREVENTING REMOTE OS DETECTION." http://www.pgci.ca/fingerprint.html
(October 12, 2000)
[4] Ptacek, Thomas. "BugTraq Article: Re:
Preventing remote OS detection." February 22, 1999. http://www.securityfocus.com/archive/1/12663
(October 24, 2000)
[5] route. "BugTraq Article: Re:
Preventing remote OS detection." February 22, 1999. http://www.securityfocus.com/archive/1/12670
(October 24, 2000)
[6] Information Sciences Institute. "RFC793." September 1981. ftp://ftp.cis.ufl.edu/pub/ietf/rfc/rfc793.txt
[7] Microsoft Corporation. "Description of Windows 2000 TCP
Features." December 29, 1999. http://support.microsoft.com/support/kb/articles/Q224/8/29.ASP
(October 24, 2000)
[8] Hall, Eric. "Advanced TCP Options." February 8, 1999. http://www.networkcomputing.com/1003/1003ws1.html
<
Previous : Next
> Click
here to return to the FAQ index |