Intrusion Detection FAQ: What is Remote Identification, Next Generation (RING)?

Summary
By measuring the behavior of various operating systems' TCP retransmission timeout lengths (or RTOs), it is possible to distinguish between OSes on a network. Franck Veysset, Olivier Courtay, and Olivier Heen of the Intranode Research Team first published this concept in April, 2002, and their paper goes into appreciable detail in its discussion of this technique, the mechanisms by which TCP retransmission timers are computed, and OS fingerprinting in general.

To demonstrate this concept, the researchers simultaneously released a proof-of-concept tool which leverages this specific exposure: Remote Identification, Next Generation, or RING.

The goal of this paper is to explore RING's effectiveness as stand-alone OS fingerprinting tool, and offer suggestions of how an organization can protect themselves against RING specifically as well as future implementations of this concept.

A Note on Ethics
The Intranode paper documents the usefulness for security researchers and engineers to be able to remotely detect particular operating systems, apparently without any sort of authentication or provable authorization. The paper, while otherwise thorough, neglects to mention the obvious value these methods also have for unauthorized attackers in assessing potential targets for compromise. Perhaps this counterpoint was left out in hopes of avoiding legal or ethical responsibility for the misuse of their research -- I'm not sure what the legal climate in France is like these days (come to think of it, I'm not sure what it's like in the USA, either.)

For the purposes of this paper, I will be treating RING as purely an attacker's tool. While I agree that remote OS fingerprinting is certainly part of legitimate "white hat" security work, I believe RING and future derivatives will be used at least as often by the unscrupulous and the criminal.

Acquiring and Compiling RING
Source URIs:

http://www.tcpdump.org/release/libpcap-0.7.1.tar.gz (BSD License)
http://www.intranode.com/pdf/techno/ring-0.0.1.tar.gz (GNU Public License)
http://www.packetfactory.net/Projects/Libnet/dist/libnet.tar.gz (BSD License)
http://prdownloads.sourceforge.net/libdnet/libdnet-1.2.tar.gz (BSD License)


RING is only semi-standalone, since it also requires libnet (by Mike D. Schiffman) and libdnet (by Dug Song) for packet construction and filtering capabilities. And like most other useful Ethernet packages, it requires libpcap for packet capturing. The INSTALL instructions mention libdnet 1.2 specifically, but 1.4 seems to work fine.

RING is comes in two flavors: source for Linux 2.4, and source for everyone else. I fall into the "everyone else" category, since I'm on the Linux 2.2.17 kernel, running the Debian Potato (testing) Linux distribution.

RING is also available as an patch for nmap, and installation instructions are provided in a later nmap-hackers post. I haven't experimented with either of these versions; according to the authors, they are all functionally identical.

How it Works
RING relies on intentionally creating a half-open connections with a target. This concept is not new in and of itself; it is the basis of all "SYN Flooding" denial-of-service attacks. In a September, 1996 advisory, CERT/CC illustrated a normal TCP three-way handshake:

Figure 1.1: A typical TCP three-way handshake*


By silently dropping the target's SYN-ACK, RING never completes the handshake, and never sends the final ACK. While the goal of SYN flooding is to exhaust the target's network resources by sending many SYNs and never ACKing them, RING's goal is to measure the time between each successive SYN-ACK retransmission.

None of the RFCs regarding TCP's retransmission timeout explicitly state what it must be set at and how it increases over successive attempts**. So, each TCP stack has its own implementation. By building a fingerprint list of known timeouts associated with particular operating systems, then, it gets very easy to start guessing operating systems.

It's important to stress that this information is gathered by sending only a single, normal SYN packet. This is what makes RTO measuring stand out from other means of guessing OSes, since it is both efficient and difficult to detect. In his seminal 1999 paper, Fyodor discusses many methodologies for OS fingerprinting, but all rely on either a sequence of packets (as in TCP Initial Sequence Number sampling), or abnormally formed packets (such as the various scans involving TCP flags and options).

Testing RING's Effectiveness
I have selected a variety of targets to represent a rich (if Windows-heavy) environment, and I plan to run RING against these devices, three times each, using an empty fingerprint list. After completing this first pass, I will average and smooth out the measured RTOs, and use those values to build a new fingerprint list. Finally, I will run RING against a second, identical set of devices.

The expectation is RING will correctly identify the devices on the second pass by using the results of the first. To monitor the test and measure RING's stealth, I will be logging with the ever popular packet analyzer, tcpdump.

As a control, I will be using netcat (the "TCP/IP Swiss army knife" by Hobbit) to establish connections to the same devices on the same ports, and logging these sessions as well. The goal here is to compare normal SYN packets with RING's, and detect any indicators which could be used as an IDS signature.

Table 1.1: First pass set


Table 1.2: Second pass set


Building a Fingerprint File
I want to capture all TCP traffic to or from my laptop (IP address 10.1.54.38), and write it to tcpdump-ring.log in binary format:

$ tcpdump -i eth0 -w tcpdump-ring.log 'tcp and host 10.1.54.38'

In another command shell, I'll write the OS name to firstpass-results.log, and run RING against the target IP, 10.1.54.28, writing the results also to firstpass-results.log. I'll do this three times for each device on the list.

$ echo 'TEST SunOS 5.6' >> 1pass.log ; ./ring -d 10.1.220.31 -s 10.1.54.38 -p 23 -f /dev/null -i eth0 >> 1pass.log

Repeat this for each target. Note that RING requires a fingerprint file, but since I don't care about matching at this point, I gave it /dev/null.

At the end of the first pass, I have a results log that looks like this:
TEST SunOS 5.6
3494016 6399768 12799690 25599038
OS: Nothing Match
3495820 6399831 12799648 25599036
OS: Nothing Match
3497260 6399804 12799659 25599107
OS: Nothing Match
TEST Red Hat 7.0
3148430 6499923 12499495 24499283
OS: Nothing Match
3497575 6499676 12499318 24499545
OS: Nothing Match
3085932 6499852 12499549 24499319
[...etc...]
TEST Microsoft Windows XP Professional
3011842 6015190
OS: Nothing Match
2882513 6015162
OS: Nothing Match
2858048 6015166
OS: Nothing Match


Each set of numbers in the above is the time, in milliseconds, each subsequent SYN-ACK is received from the target. For example, my first test was against a SunOS 5.6 server, and it resent its SYN-ACK 3.49~ seconds after the first SYN-ACK, then 6.39~, 12.79~, and finally 25.59~ seconds after that. I can compare this to my tcpdump log to verify RING's times*:

Initial SYN:
12:20:54.736268 10.1.54.38.1451 > 10.1.220.31.23: S 221002:221002(0) win 1024 <mss 1460,sackOK,timestamp 79877292 0,nop,wscale 0>

First SYN-ACK response:
12:20:54.736749 10.1.220.31.23 > 10.1.54.38.1451: S 1812524980:1812524980(0) ack 221003 win 10136 <nop,nop,timestamp 246683108 79877292,nop,wscale 0,mss 1460> (DF)

Subsequent SYN-ACK responses:
12:20:58.230776 10.1.220.31.23 > 10.1.54.38.1451: S 1812524980:1812524980(0) ack 221003 win 10136 <nop,nop,timestamp 246683458 79877292,nop,wscale 0,mss 1460> (DF)
12:21:04.630542 10.1.220.31.23 10.1.54.38.1451: S 1812524980:1812524980(0) ack 221003 win 10136 <nop,nop,timestamp 246684098 79877292,nop,wscale 0,mss 1460> (DF)
12:21:17.430234 10.1.220.31.23 > 10.1.54.38.1451: S 1812524980:1812524980(0) ack 221003 win 10136 <nop,nop,timestamp 246685378 79877292,nop,wscale 0,mss 1460> (DF)
12:21:43.029274 10.1.220.31.23 > 10.1.54.38.1451: S 1812524980:1812524980(0) ack 221003 win 10136 <nop,nop,timestamp 246687938 79877292,nop,wscale 0,mss 1460> (DF)

So, after averaging and smoothing the RTO's reported by RING, I now have a working fingerprint list for a variety of devices:

Figure 1.2: RING fingerprint file


I noticed different service pack versions of the same Windows platform did not seem to affect RTO times. This discovery was quite a relief, since patch level information is invaluable to a directed attacker. On the other hand, different Windows platforms do return different RTOs. Compare this with nmap's OS fingerprinting scan results against my first Windows NT 4.0 server on port 139:

Figure 1.3: Nmap OS fingerprinting scan results:


Nmap lumps together three different Microsoft operating systems in one guess, while RING aims to be much more discriminate. Nmap also complains about having just one open source port to work with, while RING is designed to query just one port. (This is important if the user wanted to fingerprint, say, a secured webserver across the Internet, and all of its ports but 443 (https) were closed).

The Moment of Truth
Using my new fingerprint file, I ran RING against my second, identical set of target devices. Some are on the same subnets as the first set, others are not. Since RING takes care of network variance by first calculating normal round-trip times, their locations shouldn't matter.

$ echo 'RINGing 10.1.220.30 on port 23...' >> 2pass.log; ./ring -d 143.155.220.30 -s 10.1.54.38 -p 23 -f ./tod.fingerprints -i eth0 >> 2pass.log ; tail -n 4 secondpass-results.log

This was repeated for each target device, and the results are below.

RINGing 10.1.220.31...
3498885 6402668 12796759 25599115
OS:SunOS_5.6_Server
distance:37427
RINGing 10.1.251.25...
3053171 6498470 12497390 24494537
OS:Red_Hat_7.0_Server
distance:73568
RINGing 10.2.52.11...
5739047 12163749 24315294
OS:Cisco_Catalyst_2948G_Router
distance:57502
RINGing 10.2.27.15...
6175469 11998882 23999106
OS:Extreme_Networks_Summit48_Router
distance:793457
RINGing 10.2.108.15 on port 23...
5506467 23998596
OS:Dell_TrueMobile_Wireless_Access_Point
distance:102129
RINGing 10.2.11.204 on port 80...
496166 998933 1998414 3996819 7993630 15967284 19984153
OS:Lexmark_Optra_S2450_Printer
distance:90831
RINGing 10.1.216.126 on port 139...
3223184 6562341 13124753
OS:Windows_NT_4.0_Server
distance:130278
RINGing 10.1.158.67 on port 139...
2950250 6006357 12017156
OS:Windows_NT_4.0_Server
distance:1806237
RINGing 10.1.183.49 on port 139...
2970859 6034588
OS:Windows_XP_Professional
distance:195447
RINGing 10.1.80.172 on port 139...
3257860 6562329
OS:Windows_2000_Advanced_Server_SP2
distance:90189
RINGing 10.1.54.131 on port 139...
2938810 5907769
OS:Windows_XP_Professional
distance:241041

RING successfully identified the device in ten of the eleven cases. The only miss was 10.1.183.49, and even then, RING was close -- it's really Windows 2000 Advanced Server (SP1), but RING reported it as a Windows XP Professional workstation.

Looking at these results, RING has proved to be very accurate for at least these sample targets, and I have no doubt that, given enough fingerprint samples, RING can be an effective tool for remotely fingerprinting virtually any TCP device with at least one open port.

A Silver Lining: RING Isn't Very Stealthy
True, RING does send only a single SYN packet, and is neccisarilty slow enough to evade standard portscan-detecting thresholds, there is some good news for network defenders. RING has a flaw in its implementation which gives away its presence. Below is the tcpdump log of a number of RING's initial SYNs:

$ tcpdump -n -r tcpdump-ring.log 'src host 10.1.54.38 and tcp[13] & 2 != 0"

12:20:54.736268 10.1.54.38.1451 > 10.1.220.31.23: S 221002:221002(0) win 1024 <mss 1460,sackOK,timestamp 79877292 0,nop,wscale 0>
12:22:03.222172 10.1.54.38.1452 > 10.1.220.31.23: S 221002:221002(0) win 1024 <mss 1460,sackOK,timestamp 79877292 0,nop,wscale 0>
12:23:17.248246 10.1.54.38.1457 > 10.1.220.31.23: S 221002:221002(0) win 1024 <mss 1460,sackOK,timestamp 79877292 0,nop,wscale 0>
12:25:28.561043 10.1.54.38.1459 > 10.1.251.12.23: S 221002:221002(0) win 1024 <mss 1460,sackOK,timestamp 79877292 0,nop,wscale 0>
12:27:45.208158 10.1.54.38.1469 > 10.1.251.12.23: S 221002:221002(0) win 1024 <mss 1460,sackOK,timestamp 79877292 0,nop,wscale 0>
12:28:52.117392 10.1.54.38.1470 > 10.1.251.12.23: S 221002:221002(0) win 1024 <mss 1460,sackOK,timestamp 79877292 0,nop,wscale 0>
[...etc...]
13:02:00.928313 10.1.54.38.1712 > 10.1.54.199.139: S 221002:221002(0) win 1024 <mss 1460,sackOK,timestamp 79877292 0,nop,wscale 0>
13:03:05.803371 10.1.54.38.1716 > 10.1.54.199.139: S 221002:221002(0) win 1024 <mss 1460,sackOK,timestamp 79877292 0,nop,wscale 0>
13:04:11.994878 10.1.54.38.1731 > 10.1.54.199.139: S 221002:221002(0) win 1024 <mss 1460,sackOK,timestamp 79877292 0,nop,wscale 0>

I noticed immediately that the initial sequence number and the timestamp are identical for every scan. Exploiting this, I can write a pair of Snort rules to detect RING activity, like so:

Figure 1.4: Snort rules for RING


Big caveats: These rules are strictly tentative. Since I haven't compiled RING anywhere else, I can't verify that the initial sequence numbers or timestamp values don't vary from platform to platform, or even machine to machine. To be fair, the authors released RING as version 0.0.1, and merely as a proof-of-concept tool. Though I'm certainly no C debugger, I suspect that adding some randomness to fix this predictable behavior would require only trivial effort.

Impact and Countermeasures
The one type of service which is most impacted by RING and the concepts behind it is the virtual honeypot/honeynet. These systems rely on misleading attackers into believing they are attacking, say, a Windows server, when the real machine is in fact a Linux box. Reliably impersonating other OSes, in light of this exposure, will be much more difficult to pull off. Fortunately, it appears that some of the concepts presented by Rob Beck may help - specifically, using a user-space packet mangler like Netfilter/IPTables to enforce a misleading RTO on all outgoing packets.

As for everyone else, the most direct way to defend against this exposure would be for vendors to reimplement their TCP stacks and force the RTO to conform to some uniform standard. In the meantime, engineers can rearchitect their networks to place important, hardened servers behind intermediate devices -- this solution already foils Netcraft's proprietary OS fingerprinting methods, since the proxy, not the "real" server, does all the talking to the outside world.

But, these are fairly extreme and expensive countermeasures in the face of this information leakage. Obfuscating this information only fools attackers who actually care what OS is running. Most automated attacks don't look before they leap -- Nimda, for example, is perfectly happy trying IIS vulnerabilities against Apache servers. To quote Elizabeth Zwicky, "you get rid of attackers by getting rid of vulnerabilities,"* not by hiding them.

References
Beck, Rob. "Passive-Aggressive Resistance: OS Fingerprint Evasion." Linux Journal. Sep 1, 2001. URL: http://www.linuxjournal.com/article.php?sid=4750 (May 4, 2002).

Braden, R. "RFC 1122: Requirements for Internet Hosts -- Communication Layers." Oct 1989. URL: http://www.ietf.org/rfc/rfc1122.txt (May 4, 2002).

CERT Coordination Center. "CERTŪ Advisory CA-1996-21 TCP SYN Flooding and IP Spoofing Attacks." Nov 29, 2000. URL: http://www.cert.org/advisories/CA-1996-21.html (May 4, 2002).

Clark, Mark. "Virtual Honeynets." Nov 7, 2001. URL: http://online.securityfocus.com/infocus/1506 (May 3, 2002).

Courtay, Olivier. "OS fingerprinting technique." Neohapsis Archive: NMAP-hackers. Apr 18, 2002. URL: http://archives.neohapsis.com/archives/nmap/2002/0015.html (May 3, 2002).

Fyodor. "Remote OS Detection via TCP/IP Stack Fingerprinting." Apr 10, 1999. URL: http://www.insecure.org/nmap/nmap-fingerprinting-article.html (May 4, 2002).

Information Sciences Institute. "RFC 793: Transmission Control Protocol. Sep 1981. URL: http://www.ietf.org/rfc/rfc793.txt (May 4, 2002).

Hobbit. "Netcat 1.10." Mar 20, 1996. URL: http://www.atstake.com/research/tools/nc110.txt (May 4, 2002).

Netcraft. "Netcraft Frequently Asked Questions." 2000. URL: http://uptime.netcraft.com/up/accuracy.html (May 4, 2002).

Paxon and Allman. "RFC 2988: Computing TCP's Retransmission Timer." Nov 2000. URL: http://www.ietf.org/rfc/rfc2988.txt (May 4, 2002).

Roesch and Green. "Snort User's Manual Chapter 2: Writing Snort Rules." Snort User's Manual. URL: http://www.snort.org/docs/writing_rules (May 4, 2002).

Tcpdump.org (Originally: Lawrence Berkeley National Laboratory). "Tcpdump/libpcap." URL: http://www.tcpdump.org (May 4, 2002).

Veysset, Courtay, and Heen. "New Tool and Technique For Remote Operating System Fingerprinting." Intranode Research Team Articles. Apr 2002. URL: http://www.intranode.com/pdf/techno/ring-full-paper.pdf (May 4, 2002).

Zwicky, Elizabeth. "Fun with Vulnerability Scanners." Crypto-Gram Newsletter. Dec 15, 2001. (Reprinted from Dr. Dobb's Journal. Nov 2001.) URL: http://www.counterpane.com/crypto-gram-0112.html#9 (May 4, 2002).

Tod Beardsley