14.8. Worm Behavior Patterns on the Network
This section discusses a few interesting network captures of computer worms as they propagate from one computer to another. Detailed examination of such captures is useful in seeing how typical exploitation can be experienced on the wire when the network traffic is examined with a packet sniffer, such as tcpdump11. Always use such tools with the network administrator's permission because you might accidentally capture sensitive data from the network.
14.8.1. Capturing the Blaster Worm
Figure 14.3. A network capture of a W32/Blaster worm infection with Ethereal.
I really like to use Ethereal, a popular sniffer and network traffic analyzer tool to browse network captures. I suggest that you use the exploit analysis of Blaster in Chapter 10 and match it with the behavior pattern of the worm in this network capture. In this particular example, the IP address 192.168.0.1 belongs to the attacker system, which is already compromised by Blaster. The IP address 192.168.0.3 (also on a local test network) is currently under attack by Blaster.
Notice the 1314 > 4444 TCP port communication between the attacker and the target (frame 42 in Figure 14.3). The attacker machine is communicating with the shellcode running on the newly compromised system on 192.168.0.3. Shortly after this (frame 48), you can see a TFTP read request for a file called msblast.exe.
This is the TFTP request that the Blaster attacker system sends to the newly compromised host, which already runs a command prompt on 4444/tcp. Notice that 192.168.0.3 runs the TFTP command and downloads from 192.168.0.1, where the Blaster attacker system waits with a "TFTP server" thread of the worm to fulfill this request. You can follow as the TFTP request is processed and the main worm body travels over the wire to the newly compromised system. Of course, all this might be less exciting to see when it happens on your own network. In this example, the two machines reside on a test network used for natural infections. (Chapter 15 explains more about natural infection strategies and analysis techniques and introduces a few more network captures of worm attacks.)
Next, in frame 82 of Figure 14.3, you can see that the attacker system again communicates with its shell on the newly compromised host and sends a "start msblast.exe" command (see the packet dump in the lower panel of Ethereal).
At that point, the worm starts to run on the newly attacked system. You also can see that action because 192.168.0.3 suddenly starts to send broadcast ARP requests such as "Who has 192.168.0.2? Tell 192.168.0.3," "Who has 192.168.0.4? Tell 192.168.0.3," and so on, as it scans the network for other machines. This behavior pattern is very typical of computer worms.
You can easily target Blaster with a NIDS system. One possibility is to check for exploit code in the first few packets, which allows you to log attacker systems on your network quickly. Another possibility is simply to look for the string "start msblast.exe," to see when a new system gets compromised. When you see this request, you will know that your systems are still not patched with the new security updates required to eliminate the vulnerability exploited by the worm.
14.8.2. Capturing the Linux/Slapper Worm
As Chapter 10 discusses in detail, the Slapper worm exploited an OpenSSL vulnerability on Apache Web servers that involved exploitation on the heap. It is important to understand the specifics of heap exploitation to be able to build host-based intrusion prevention techniques similar to those discussed in Chapter 13, "Worm-Blocking Techniques and Host-Based Intrusion Prevention." On the other hand, from the point of view of network-level defense, there are other interesting questions that you might ask. In particular, the worm exploits OpenSSL, so it is interesting to double-check whether or not the worm is encrypted on the wire. In some of the existing computer security literature, the Slapper worm is already discussed as a worm that "cannot be effectively detected with NIDS because someone would need to compromise the security provided by SSL." As I will demonstrate next, however, this statement is false.
Figure 14.4 is a capture of the Linux/Slapper worm where the IP address 184.108.40.206 is compromised by Slapper and attacks 220.127.116.11. Of course, all of this happens on our lab network, just like any other captures, so the IP address does not have to do anything with real-world targets.
Figure 14.4. A network capture of the Linux/Slapper worm infection with Ethereal.
You can see the double-take action of the two "Client Hello" messages; Slapper exploits the target twice. When the worm exploits the target the first time, the target leaks valuable information, which is used in the second exploit phase to gain proper control of the target.
Ethereal also expects that the wire contains encrypted data in frame 53, shown in Figure 14.4. Normally, this would be the case, and Ethereal would be right. However, the worm exploits the target before the encryption is established on the wire. You can see in the lower Ethereal window that some of the worm's commands are passing in the payload as plain text instead of cipher text. This is a clear indication that there is no encryption established between the two systems.
You can see that the first command is rm (remove), followed by a cat command, which creates Slapper's UU-encoded source file on the target. The propagation of the worm is visible in plain text over the wire, so there should be no problem detecting the worm using standard NIDS.
A Snort NIDS signature to detect Linux/Slapper could be the following:
alert tcp any any -> any 443 (msg:"Linux/Slapper Worm Propagation"; content:"36 35 35 20 2E 62 75 67 74 72 61 2e 63";)
This alert is generated when the string 655 .bugtraq.c is detected in a packet transmitted on port 443/tcp, which should not be the case. An SSL connection would always transmit cipher text in normal circumstances, and the filename is unique.
Note, however, that the filename might be the first thing that someone would change in a new variant of a worm, so a more appropriate NIDS signature could also investigate the key argument length field and check whether that value is larger than eight, which is the maximum allowed (as discussed in Chapter 10). I define this type of detection as a generic intrusion signature. Figure 14.5 shows a network capture of Linux/Slapper with a large key argument length field set to 64.
Figure 14.5. A Client Master Key message with a key_arg length set to 64.
The detection of the overly large key_arg length makes it possible to alert on related exploit codes generically without dealing with the specifics of each individual attack.
In the real world, it is important to identify an attack more precisely. You really want to know whether the NIDS alert is related to a Slapper worm or is coming from an individual attacker. Therefore, modern NIDS systems include two-phase detection: One phase detects attacks generically and quickly, and a second detection, triggered by the first, further identifies the attack. Because NIDS engines are hard-pressed to work fast (otherwise they start to drop packets), it is vital to implement more exact detections only after a quick filter, which is the first detection.
Such logic can help to deal with polymorphic attacks that give shellcode polymorphic abilities. Examples of such attacks are ADM_Mutate, libSchellCode, S-poly, and JempiScodes13.
14.8.3. Capturing the W32/Sasser.D Worm
The W32/Sasser.D worm was released by a German virus writer and was interesting because it targeted a Microsoft LSASS vulnerability. In Figure 14.6, you can see the worm send its code from the already compromised 10.10.10.34 attacker system to the currently exploited system on 10.10.10.36.
Figure 14.6. A network capture of the W32/Sasser.D worm.
So what is the interesting part of this attack? It appears that the first byte of the executable worm body is sent alone and shows as Len=1 in frame 90 of Figure 14.6. In the lower pane of Ethereal, you can see an M character as the payload of the packet. This is the first byte of the PE file of the worm body that starts with the MZ header. The following part of the worm executable header will start with Z in frame 91, in which a payload with a Len=1460 bytes is sent, typical on Ethernet networks.
Indeed, the worm sends itself byte by byte on the network, but without specifying an immediate sending, the IP stack will be reassembled locally, and usually a complete payload will be sent to the target. There is no guarantee, however, that the reassembling will always happen, and this can split the worm body along short packet boundaries.
Although Sasser does not attack NIDS directly, it demonstrates that worms can indeed split their exploit code to a byte-per-payload style of transfer if they specifically ask to do so. Not all NIDS have proper packet reassembling abilities, as mentioned earlier. As a result, the IDS signature of the attack might not match because the signature is split on the wire into several packets, each with a payload a few bytes long.
As an example, the CodeRed worm is normally sent in the form shown in Figure 14.7A, but a trickier variant of the worm could send its code with randomly split payload sizes, as shown in Figure 14.7B, challenging IDS implementations that do not have traffic reassembling.
Both of these methods could work correctly. Depending on the packet reassembling and signature engine abilities of a NIDS, however, the signature of the worm might not be matched correctly. This example illustrates why packet reassembling is such an important module for a properly developed IDS.
Figure 14.7. The exploit code of the CodeRed worm in complete and split forms.
14.8.4. Capturing the Ping Requests of the W32/Welchia Worm
The sad reality is that many network administrators who have corporate permission to run sniffer tools often do not really know how to use such tools to look for worm infections. As a result, they do not perform this kind of logging routinely. Such logging techniques can be useful in preparing for a worm attack in advance or in helping to eliminate an already existing in-house infection. In this section, I illustrate the use of the tcpdump tool, which is included by default in many UNIX distributions. It has become the Swiss-army knife of intrusion detection; as you will see, it is also an effective honeypot tool.
In the capture shown in Figure 14.8, you can see the Welchia worm ping the destination address 169.254.189.84 from the 169.254.56.166 address. Before Welchia attempts to exploit a new target, it wants to get a positive answer to an ICMP echo request.
Figure 14.8. The ping request of the W32/Welchia worm.
Notice the content of the ICMP echo request data in the lower pane of Ethereal. The worm uses a 0xAA filler byte to preinitialize the data structure for the ping request, instead of using zero bytes. This allows you to trace the worm's ping request with a network-capturing sniffer tool, such as tcpdump or windump (which relies on winpcap14).
If you want to track Welchia infections based on the special ping request data, use the following command15:
tcpdump -qn icmp and ip = 0xaa
You can do the same on a Windows machine (using windump):
windump -qn icmp and ip = 0xaa
This command instructs the sniffer to log ICMP traffic but reduces the scope of logging to special ICMP echo requests, which have a 0xAA filler byte at position 40 inside their request. Similar tools, such as ngrep, also can be used to perform even more complicated string matching using regular expressions.
14.8.5. Detecting W32/Slammer and Related Exploits
The W32/Slammer worm targets vulnerable Microsoft SQL servers on port 1434/udp. The only thing the worm requires is to send a datagram to the actual port. Vulnerable installations of Microsoft SQL Server will execute the worm when processing the UDP request.
Figure 14.9 shows a snippet of the Slammer worm. As discussed in Chapter 10, the exploit code built into Slammer requires a special ID in front of the worm's code. This special byte, 0x04, would be normally followed by a short string, but there is no bound checking in the code, and the stack is overflowed when a large string is received. Notice the number of filler (0x01) bytes in the worm, which shift a return address value to the proper spot.
Figure 14.9. A snippet of a Slammer worm dump loaded to HIEW.
I will use this dump to demonstrate exploit detection using NIDS software. Normally, you could use a worm-specific signature to detect this attack, and it is certainly a good idea to refine your detection and have a clue whether the actual exploit you have detected is related to Slammer. So here is the Symantec ManHunt Hybrid signature, which pretty much follows the format of a Snort signature in this example:
alert udp any any -> any 1434 (msg:"W32/Slammer Worm Propagation"; content:"|68 2E 64 6C 6C 68 65 6C 33 32 68 6B 65 72 6E|"; content:"|04|"; offset:0; depth:1;)
We generate an alert whenever any traffic targets any IP address with a 1434/udp port. We alert with the message "W32/Slammer Worm Propagation" whenever we find the h.dllhel32hkern string anywhere in the datagram. We also have 0x04 as the first byte of the packet to double-check that we are dealing with the exploit. This signature will detect Slammer effectively, however. If you want to prepare a generic detection to detect the exploit code, you could use the following signature to do so:
alert udp any any -> any 1434 (msg:"MS02-039 exploitation detected"; content:"|04|"; offset:0; depth:1; dsize>60)
This alert is very similar to the first one. In fact, it matches the first byte of the datagram, just as the worm-specific signature does. I do not use the previous sequence of bytes, but the dsize command instead, to check whether the datagram is longer than 60 bytes. In this way, we know that a vulnerable SQL Server would be under attack since a 128-byte buffer is overflowed. There are two constant strings used by SQL Server to build a Registry key when the server receives this request (as discussed in Chapter 10), hence a dsize larger than 60 will always result in an overflow conditionand at least a DoS attack.
The 60 comes from 12840271=60 (size_of_buffer-string_size1-string_size2-terminating_zero= 60).
Of course, you could argue that such signatures are more prone to false positives, but you can also see that they are less prone to false negatives. Indeed, the remaining ambiguity is a general problem of NIDS. How could the NIDS tell whether or not the UDP port 1434 traffic is related to an SQL Server on the target system? This is why more specific IDS signatures always cause fewer false positives.
Such signatures, however, can be very helpful. Imagine if Slammer were polymorphic or even metamorphicno actual bytes of the worm would be the same in different instances of the worm body on the wire. Unless the worm exploited several vulnerabilities, it would need to present the 0x04 byte in the front of the datagram and represent itself as a long-enough string. Thus the preceding generic IDS signature would also cover the polymorphic version of the worm.
In fact, modern IDS detection languages support programmable signatures. For example, such signatures use a histogram to check quickly whether there are any zero bytes in a range of the stream. Indeed, it would be better to use such filters in the preceding signature to reduce false positives further. Slammer cannot use a zero byte anywhere in its body because the worm's body is processed as a "string." Similarly, any exploit code targeting this vulnerability would need to avoid using zeros long enough to exploit the overflow condition successfully. As a result, even a polymorphic or metamorphic worm would be detected via the "frame" conditions of the exploit.