|
9th USENIX Security Symposium Paper 2000   
[Technical Index]
Defeating TCP/IP Stack Fingerprinting
Department of Electrical Engineering and Computer Science University of Michigan 1301 Beal Ave. Ann Arbor, Mich. 48109-2122 {mcsmart,rmalan,farnam}@eecs.umich.edu
Abstract
This paper describes the design and implementation of a TCP/IP stack
fingerprint scrubber.
The fingerprint scrubber is a new tool to restrict a remote user's ability
to determine
the operating system of another host on the network.
Allowing entire subnetworks to be remotely scanned and characterized
opens up security vulnerabilities.
Specifically, operating system exploits can be efficiently run
against a pre-scanned network
because exploits will usually only work against a specific operating system
or software running on that platform.
The fingerprint scrubber works at both the
network and transport layers to convert ambiguous traffic from a
heterogeneous group of hosts into sanitized packets that do not
reveal clues about the hosts' operating systems. This paper evaluates the
performance of a fingerprint scrubber implemented in the FreeBSD kernel
and looks at the limitations of this approach.
1. DescriptionTCP/IP stack fingerprinting is the process of determining the identity of a remote host's operating system by analyzing packets from that host. Freely available tools (such as nmap [3] and queso [15]) exist to scan TCP/IP stacks efficiently by quickly matching query results against a database of known operating systems. The reason this is called ``fingerprinting'' is therefore obvious; this process is similar to identifying an unknown person by taking his or her unique fingerprints and finding a match in a database of known fingerprints. The difference is that in real fingerprinting, law enforcement agencies use fingerprinting to track down suspected criminals; in computer networking potential attackers can use fingerprinting to quickly create a list of targets.We argue that fingerprinting tools can be used to aid unscrupulous users in their attempts to break into or disrupt computer systems. A user can build up a profile of IP addresses and corresponding operating systems for later attacks. Nmap can scan a subnetwork of 254 hosts in only a few seconds, or it can be set up to scan very slowly, i.e. over days. These reports can be compiled over weeks or months and cover large portions of a network. When someone discovers a new exploit for a specific operating system, it is simple for an attacker to generate a script to run the exploit against each corresponding host matching that operating system. An example might be an exploit that installs code on a machine to take part in a distributed denial of service attack. Fingerprinting scans can also potentially use non-trivial amounts of network resources including bandwidth and processing time by intrusion detection systems and routers. Fingerprinting provides fine-grained determination of an operating system. For example, nmap has knowledge of 21 different versions of Linux. Other methods of determining an operating system are generally coarse-grained because they use application-level methods. An example is the banner message a user receives when he or she uses telnet to connect to a machine. Many systems freely advertise their operating system in this way. This paper does not deal with blocking application-level fingerprinting because it must be dealt with on an application by application basis. Almost every system connected to the Internet is vulnerable to fingerprinting. The major operating systems are not the only TCP/IP stacks identified by fingerprinting tools. Routers, switches, hubs, bridges, embedded systems, printers, firewalls, web cameras, and even game consoles are identifiable. Many of these systems, like routers, are important parts of the Internet infrastructure, and compromising infrastructure is a more serious problem than compromising end hosts. Therefore a general mechanism to protect any system is needed. Some people may consider stack fingerprinting a nuisance rather than a security attack. As with most tools, fingerprinting has both good and bad uses. Network administrators should be able to fingerprint machines under their control to find known vulnerabilities. Stack fingerprinting is not necessarily illegal or an indication of malicious behavior, but we believe the number of scans will grow in frequency as more people access the Internet and discover easy to use tools such as nmap. As such, network administrators may not be willing to spend time or money tracking down what they consider petty abuses each time they occur. Instead they may choose to reserve their resources for full-blown intrusions. Also, there may be networks that no single authority has administrative control over, such as a university residence hall. A tool that detects fingerprinting scans but turns them away would allow administrators to track attempts while keeping them from penetrating into local networks. This paper presents the design and implementation of a tool to defeat TCP/IP stack fingerprinting. We call this new tool a fingerprint scrubber. The fingerprint scrubber is transparently interposed between the Internet and the network under protection. The intended use of the scrubber is for it to be placed in front of a set of end hosts or a set of network infrastructure components. The goal of the tool is to block the majority of stack fingerprinting techniques in a general, fast, scalable, and transparent manner. We describe an experimental evaluation of the tool and show that our implementation blocks known fingerprint scan attempts and is prepared to block future scans. We also show that our fingerprint scrubber can match the performance of a plain IP forwarding gateway on the same hardware and is an order of magnitude more scalable than a transport-level firewall. The remaining sections are organized as follows. We describe TCP/IP stack fingerprinting in more detail in Section 2. In Section 3 we describe the design and implementation of our fingerprint scrubber. In Section 4 we evaluate the validity and performance of the scrubber. In Section 5 we cover related work and in Section 6 we cover future directions. Finally, in Section 7 we summarize our work.
|
(a)TCP Sequence Prediction: Class=truly random Difficulty=9999999 (Good luck!) Remote operating system guess: Linux 2.0.35-37 (b) TCP Sequence Prediction: Class=trivial time dependency Difficulty=1 (Trivial joke) Remote operating system guess: Xerox DocuPrint N40 |
While nmap contains a lot of functionality and does a good job of performing fine-grained fingerprinting, it does not implement all of the techniques that could be used. Various timing-related scans could be performed. For example, determining whether a host implements TCP Tahoe or TCP Reno by imitating packet loss and watching recovery behavior. We discuss this threat and potential solutions in Section 3.2.4. Also, a persistent person could also use methods such as social engineering or application-level techniques to determine a host's operating system. Such techniques are outside the scope of this work. However, there will still be a need to block TCP/IP fingerprinting scans even if an application-level fingerprinting tool is developed. Currently, TCP/IP fingerprinting is the fastest and easiest method for identifying remote hosts' operating systems, and introducing techniques that target applications will not make it obsolete.
We intend for the fingerprint scrubber to be placed in front of a set of systems with only one connection to a larger network. We expect that a fingerprint scrubber would be most appropriately implemented in a gateway machine from a LAN of heterogeneous systems (i.e. Windows, Solaris, MacOS, printers, switches) to a larger corporate or campus network. A logical place for such a system would be as part of an existing firewall. Another use would be to put a scrubber in front of the control connections of routers. The network under protection must be restricted to having one connection to the outside world because all packets traveling to and from a host must travel through the scrubber.
Because the scrubber affects only traffic moving through it, an administrator on the trusted side of the network will still be able to scan the network. Alternatively, an IP access list or some other authentication mechanism could be added to the fingerprint scrubber to allow authorized hosts to bypass scrubbing.
The fingerprint scrubber operates at the IP and TCP layers to cover a wide range of known and potential fingerprinting scans. We could have simply implemented a few of the techniques discussed in the following sections to defeat nmap. However, the goal of this work is to stay ahead of those developing fingerprinting tools. By making the scrubber operate at a generic level for both IP and TCP, we feel we have raised the bar sufficiently high.
The fingerprint scrubber is based off the protocol scrubber by Malan, et al. [7]. The protocol scrubber operates at the IP and TCP layers of the protocol stack. It is a set of kernel modifications to allow fast TCP flow reassembly to avoid TCP insertion and deletion attacks as described by Ptacek and Newsham [13]. The protocol scrubber follows TCP state transitions by maintaining a small amount of state for each connection, but it leaves the bulk of the TCP processing and state maintenance to the end hosts. This allows a tradeoff between the performance of a stateless solution with the control of a full transport-layer proxy. The protocol scrubber is implemented under FreeBSD, and we continued under FreeBSD 2.2.8 for our development.
Figure 2 shows the data flow through the kernel for the fingerprint scrubber. Packets come in from either the trusted or untrusted interface through an Ethernet driver. Incoming IP packets are handed to ip_input through a software interrupt, just as would be done normally. A filter in ip_input determines if the packet should be forwarded to the TCP scrubbing code. If not, then it follows the normal IP forwarding path to ip_output. If it is, then isg_input (ISG stands for Internet Scrubbing Gateway) performs IP fragment reassembly if necessary and passes the packet to isg_tcpin. Inside isg_tcpin the scrubber keeps track of the TCP connection's state. The packet is passed to isg_forward to perform TCP-level processing. Finally, isg_output modifies the next-hop link level address and isg_output or ip_output hands the packet straight to the correct device driver interface for the trusted or untrusted link.
We must also make sure that differences in the packets sent by the trusted hosts to the untrusted hosts don't reveal clues. These checks and modifications are done in isg_forward for TCP modifications, isg_output for IP modifications to TCP segments, and ip_output for IP modifications to non-TCP packets.
The fingerprint scrubber uses the code in Figure 3 to normalize IP type-of-service and fragment bits in the header. This occurs for all ICMP, IGMP, UDP, TCP, and other packets for protocols built on top of IP. Uncommon and generally unused combinations of TOS bits are removed. In the case that these bits need to be used (i.e. an experimental modification to IP) this functionality could be removed. Most TCP/IP implementations we have tested ignore the reserved fragment bit and reset it to 0 if it is set, but we wanted to be safe so we mask it out explicitly. The don't fragment bit is reset if the MTU of the next link is large enough for the packet. This check is not shown in the figure.
Modifying the don't fragment bit could break MTU discovery through the scrubber. One could argue that the reason you would put the fingerprint scrubber in place is to hide information about the systems behind it. This might include topology and bandwidth information. However, such a modification is controversial. We leave the decision on whether or not to clear the don't fragment bit up to the end user by allowing the option to be turned off.
/* * Normalize IP type-of-service flags */ switch (ip->ip_tos) { case IPTOS_LOWDELAY: case IPTOS_THROUGHPUT: case IPTOS_RELIABILITY: case IPTOS_MINCOST: case IPTOS_LOWDELAY|IPTOS_THROUGHPUT: break; default: ip->ip_tos = 0; } /* * Mask out reserved fragment flag. * The MTU of the next downstream link * is large enough for the packet so * clear the don't fragment flag. */ ip->ip_off &= ~(IP_RF|IP_DF); |
The fragment reassembly code is a slightly modified version of the standard implementation in the FreeBSD 2.2.8 kernel. It keeps fragments on a set of doubly linked lists. It first calculates a hash to determine which list the fragment maps to. A linear search is done over this list to find the IP datagram the fragment goes with and its place within the datagram. Old data in the fragment queue is always chosen over new data.
ICMP error messages are meant to include at least the IP header plus 8 bytes of data from the packet that caused the error. According to RFC 1812 [1], as many bytes as possible, up to a total ICMP packet length of 576 bytes, are allowed. However, nmap takes advantage of the fact that certain operating systems quote different amounts of data. To counter this we force all ICMP error messages coming from the trusted side to have data payloads of only 8 bytes by truncating larger data payloads. Alternatively, we could look inside of ICMP error messages to determine if IP tunneling is being used. If so, then we would allow more than 8 bytes.
, as many bytes as possible, up to a total ICMP packet length of 576 bytes, are allowed. However, nmap takes advantage of the fact that certain operating systems quote different amounts of data. To counter this we force all ICMP error messages coming from the trusted side to have data payloads of only 8 bytes by truncating larger data payloads. Alternatively, we could look inside of ICMP error messages to determine if IP tunneling is being used. If so, then we would allow more than 8 bytes.
A large amount of information can be gleaned from TCP options. We did not want to disallow certain options because some of them aid in the performance of TCP (i.e. SACK) yet are not widely deployed. Therefore we restricted our modifications to reordering the options within the TCP header. We simply provide a canonical ordering of the TCP options known to us. Unknown options are included after all known options. The handling of unknown options and ordering can be configured by the end user.
We also defeat attempts at predicting TCP sequence numbers by modifying the normal sequence number of new TCP connections. The fingerprint scrubber stores a random number when a new connection is initiated. Each TCP segment for the connection traveling from the trusted interface to the untrusted interface has its sequence number incremented by this value. Each segment for the connection traveling in the opposite direction has its acknowledgment number decremented by this value.
It would be very difficult to create a generic method for defeating timing-related scans, especially unknown scans. One approach would be to add a small, random amount of delay to packets going out the untrusted interface. The scrubber could even forward packets out-of-order. However this approach would introduce an increased amount of queuing delay and probably degrade performance. In addition, these measures are not guaranteed to block scans. For example, even with small amounts of random delay, it would be relatively easy to determine if a TCP stack implements TCP Tahoe or TCP Reno based on simulated losses because a packet retransmitted after an RTO has a much larger delay than one retransmitted because of fast retransmit.
We implemented protection against one possible timing-related scan. Some operating systems implement ICMP rate limiting, but they do so at different rates, and some don't do any rate limiting. We added a parameter for ICMP rate limiting to the fingerprint scrubber to defeat such a scan. The scrubber records a timestamp when an ICMP message travels from the trusted interface to the untrusted interface. The timestamps are kept in a small hash table referenced by the combination of the source and destination IP addresses. Before an ICMP message is forwarded to the outgoing, untrusted interface, it is checked against the cached timestamp. The packet is dropped if a certain amount of time has not passed since the previous ICMP message was sent to that destination from the source specified in the cache.
Figure 4 shows the fingerprint scrubber rate limiting ICMP echo requests and replies. In this instance, an untrusted host is sending ICMP echo requests once every 20 milliseconds using the -f flag with ping (flooding). The scrubber allows the requests through unmodified since we are not trying to hide the identity of the untrusted host from the trusted host. As the ICMP echo replies come back, however, the fingerprint scrubber makes sure that only those replies that come at least 50 ms apart are forwarded. Since the requests are coming 20 ms apart, for every three requests one reply will make it through the scrubber. Therefore the untrusted host receives a reply once every 60 ms.
We chose 50 ms for convenience because ping -f generates a stream of ICMP echo requests 20 ms apart, and we wanted the rate limiting to be noticeable. The exact value for a production system would have to be determined by an administrator or based upon previous ICMP flood attack thresholds. The goal was to homogenize the rate of ICMP traffic traveling from the untrusted interface to the trusted interface because operating systems rate limit their ICMP messages at different rates. Another method for confusing a fingerprinter would be to add small, random delays to each ICMP message. Such an approach would require keeping less state. We can add delay to ICMP replies, as opposed to TCP segments, because they won't affect network performance.
The scrubber and end hosts each had 500 MHz Pentium III CPUs and 256 megabytes of main memory. The end hosts each had one 3Com 3c905B Fast Etherlink XL 10/100BaseTX Ethernet card (xl device driver). The gateway had two Intel EtherExpress Pro 10/100B Ethernet cards (fxp device driver). The network was configured to have all traffic from 10.0.0/24 go to 10.1.0/24 through the gateway machine. Figure 5 shows how the three machines were connected as well as the trusted and untrusted domains.
Nmap was consistently able to determine all of the host operating systems without the fingerprint scrubber interposed. However, it was completely unable to make even a close guess with the fingerprint scrubber interposed. In fact, it wasn't able to distinguish much about the hosts at all. For example, without the scrubber nmap was able to accurately identify a FreeBSD 2.2.8 system in our lab. With the scrubber nmap guessed 14 different operating systems from three vendors. Each guess was wrong. Figure 6 shows a condensed result of the guesses nmap made against FreeBSD before and after interposing the scrubber.
The two main components that aid in blocking nmap are the enforcement of a three-way handshake for TCP and the reordering of TCP options. Many of nmap's scans work by sending probes without the SYN flag set so they are discarded right away. Similarly, operating systems vary greatly in the order that they return TCP options. Therefore nmap suffers from a large loss in available information.
We intend this tool to be general enough to block potential or new scans also. We believe that the inclusion of IP header flag normalization and IP fragment reassembly aid in that goal even though we do not know of any existing tool that exploits such differences.
(a)Remote operating system guess: FreeBSD 2.2.1 - 3.2 (b) Remote OS guesses: AIX 4.0 - 4.1, AIX 4.02.0001.0000, AIX 4.1, AIX 4.1.5.0, AIX 4.2, AIX 4.3.2.0 on an IBM RS/*, Raptor Firewall 6 on Solaris 2.6, Solaris 2.5, 2.5.1, Solaris 2.6 - 2.7, Solaris 2.6 - 2.7 X86, Solaris 2.6 - 2.7 with tcp_strong_iss=0, Solaris 2.6 - 2.7 with tcp_strong_iss=2, Sun Solaris 8 early acces beta (5.8) Beta_Refresh February 2000 |
We measured both the throughput from the trusted side out to the untrusted side and from the untrusted side into the trusted side. This was to take into account our asymmetric filtering of the traffic. We ran experiments for TCP traffic to show the affect of a bulk TCP transfer and for UDP to exercise the fragment reassembly code. We used three kernels on the gateway machine to test different functionality of the fingerprint scrubber. The IP forwarding kernel is the unmodified FreeBSD kernel, which we use as our baseline for comparison. The fingerprint scrubbing kernel includes the TCP options reordering, IP header flag normalization, ICMP modifications, and TCP sequence number modification but not IP fragment reassembly. The last kernel is the full fingerprint scrubber with fragment reassembly code turned on. We also compared the fingerprint scrubber to a full application-level proxy. The TIS Firewall Toolkit's plug-gw proxy is an example of a firewall component that operates at the user-level to do transport-layer proxying [18]. When a new TCP connection is made to the proxy, plug-gw creates a second connection from the proxy to the server. The proxy's only job is to read and copy data from one connection to the other. A more fully featured firewall will process the copied headers and data, which adds additional latency and requires more state. Therefore the performance of plug-gw represents a minimum amount of work a firewall built from application-level proxies must perform. We modified the original plug-gw code so that it did no logging and no DNS resolutions, which resulted in a large performance increase. The proxy's kernel was also modified so that a large number of processes could be accommodated. A custom user-space proxy optimized for speed would certainly do better (the plug-gw proxy forks a child for each incoming connection). However, the multiple data copies and context switching will always resign any user-space implementation to significantly worse performance than in-kernel approaches[8; 17].
Table 1 shows the TCP bulk transfer results for an untrusted host connecting to a trusted host. Table 2 shows the results for a trusted host connecting to an untrusted host. The first result is that both directions show the same throughput. The second, and more important result, is that even when all of the fingerprint scrubber's functionality is enabled we are seeing a throughput almost exactly that of the plain IP forwarding. The bandwidth of the link is obviously the critical factor for all of the throughput experiments, therefore we would like to run these experiments again on a faster network in the future.
We ran the UDP experiment with the IP forwarding kernel and the fingerprint scrubbing kernel with IP fragment reassembly. Again, we measured both the untrusted to trusted direction and vice versa. To measure the affects of fragmentation, we ran the test at varying sizes up to the MTU of the Ethernet link and above. Note that 1472 bytes is the maximum UDP data payload that can be transmitted since the UDP plus IP headers add an additional 28 bytes to get up to the 1500 byte MTU of the link. The 2048 byte test corresponds to two fragments and the 8192 byte test corresponds to five fragments.
Table 3 shows the UDP transfer results for an untrusted host connecting to a trusted host. Table 4 shows the results for a trusted host connecting to an untrusted host. Once again both directions show the same throughput. We also see that the throughput of the fingerprint scrubber with IP fragment reassembly is almost exactly that of the plain IP forwarding. This is even true in the case of the 8192 byte test where the fragments must be reassembled at the gateway and then re-fragmented before being sent out.
We also ran an experiment to measure the scalability of the fingerprint scrubber. That is, how many concurrent TCP connections can our fingerprint scrubbing gateway support? We set up three machines as web servers to act as sinks for HTTP requests. On three other machines we ran increasing numbers of clients repeatedly requesting the same 1 KB file from the web servers. The choice of 1 KB allows us to keep the web servers' CPUs from being the limiting factor. Instead, the bandwidth of the link is again the bottleneck. The clients were connected with a 100 Mbps hub and the servers were connected with a 100 Mbps switch. The number of connections per second being made through the fingerprint scrubber was measured on the hub.
Figure 7 shows the number of sustained connections per second measured for plain IP forwarding, TCP/IP fingerprint scrubbing, fingerprint scrubbing with IP fragment reassembly, and the plug-gw application-level proxy. The error bars represent the standard deviation for each second. The results of the experiment are that the fingerprint scrubber scales comparably to the unmodified IP forwarder and performs much better than the transport proxy. The fingerprint scrubber achieves a rate of about 2,700 connections per second, which may be enough for most LANs. In comparison, the plug-gw proxy only achieves a rate of about 300 connections per second, which is an order of magnitude worse than the scrubber. The abysmal performance of the application-level proxy can be explained by the number of interrupts, data copies, and context switches incurred by such a user-level process. For each TCP connection, the proxy has to keep track of two complete TCP state machines and copy data up from the kernel then back down. The system running plug-gw was CPU bound for all but a few concurrent clients.
Achieving full line-speed in the fingerprint scrubber for higher bandwidth links would probably require dedicated hardware. A platform such as Intel's Internet Exchange Architecture (IXA) [14; 5] could help. The small size of the TCP state table we use in the fingerprint scrubber would be amenable to such a system.
could help. The small size of the TCP state table we use in the fingerprint scrubber would be amenable to such a system.
Various tools are available to secure a single machine against nmap's operating system fingerprinting. The TCP/IP traffic logger iplog [10] can detect an nmap fingerprint scan and send out a packet designed to confuse the results. Other tools and operating system modifications simply use state inherently kept in the TCP implementation to drop certain scan types. However, none of these tools can be used to protect an entire network of heterogeneous systems. In addition, these methods will not work for networks that are not under single administrative control, unlike the fingerprint scrubber.
Vern Paxson presents a tool to analyze a TCP implementation's behavior called tcpanaly [12]. It works offline on tcpdump traces to try to distinguish if a certain traffic pattern is consistent with an implementation. In this way, it is doing a sort of TCP fingerprinting. However, tcpanaly suffers from a lot of uncertainty that makes it unfeasible as a fingerprinting tool. It also keeps explicit knowledge of several TCP/IP implementations. In contrast, our fingerprint scrubber has no knowledge of other implementations. The main contribution tcpanaly makes is not in fingerprinting but in analyzing the correctness of a TCP implementation and aiding in determining if an implementation has faults.
Malan, et al. [7] have presented the idea of not only transport-level scrubbing, but also application-level scrubbing. Obviously more specialization would need to be done. The main focus is on HTTP traffic to protect web servers. The idea could be extended to protect infrastructure components such as routers by scrubbing RIP, OSPF, and BGP.
have presented the idea of not only transport-level scrubbing, but also application-level scrubbing. Obviously more specialization would need to be done. The main focus is on HTTP traffic to protect web servers. The idea could be extended to protect infrastructure components such as routers by scrubbing RIP, OSPF, and BGP.
Because of the close relationship between firewalls and fingerprint scrubbers, we would like to combine the two technologies. We would use the scrubber as a substrate and add features, such as authentication, required by a fully functional firewall. We believe such a system would combine the additional security benefits of a modern firewall with the performance characteristics and benefits of the fingerprint scrubber.
We would also like to examine how IP security [6] affects TCP/IP stack fingerprinting and operating system discovery. If a host implementing IPsec doesn't allow unknown hosts to establish connections, then those hosts will not be able to discern the host's operating system because all packets will be dropped. If a host does allow unknown hosts to connect in tunnel mode, however, then a fingerprint scrubber will be ineffective. The scrubber will be unable to examine and modify the encrypted and encapsulated IP and TCP headers. However, allowing any host to make a secure connection to an IPsec-enabled host is not the standard procedure unless it is a public server. Another portion of IPsec that could be exploited is the key exchange protocols, such as ISAKMP/IKE [9; 4]. If different systems have slight differences in their implementations, a scanner might be able to discern the host's operating system.
Another thing we would like to try is to have the fingerprint scrubber spoof an operating system's fingerprint instead of anonymizing it. For example, it might be interesting to have all of the computers on your network appear to be running the secure operating system OpenBSD. This is harder to do than simply removing ambiguities because you have to introduce artifacts in enough places to make the deception plausible.
As network infrastructure components increase in speed, tools such as the fingerprint scrubber must scale to meet the demand. To try to achieve line-speed, we would like to implement core components of the fingerprint scrubber in hardware. An example would be to build the minimal TCP state machine we use into a platform such as Intel's Internet Exchange Architecture (IXA) [14; 5].
The fingerprint scrubber successfully and completely blocks known scans by removing many clues from the IP and TCP layers. Because of its general design, it should also be effective against any evolutionary enhancements to fingerprint scanners. It can protect an entire network against scans designed to profile vulnerable systems. Such scans are often the first step in an attack to gain control of exploitable computers. Once compromised these systems could be used as part of a distributed denial of service attack. By blocking the first step, the fingerprint scrubber increases the security of a heterogeneous network.
This paper was originally published in the
Proceedings of the 9th USENIX Security Symposium,
August 14-17, 2000, Denver, Colorado, USA
Last changed: 29 Jan. 2002 ml |
|