The SQL Slammer wormaka Sapphire or SQL Hellwas only 376 bytes when it appeared on January 25, 2003. Yet Slammer, deemed the fastest computer worm in history, raced around the Internet infecting 90 percent of vulnerable computers within 10 minutes (according to several sources, including Microsoft). Slammer doubled its number of victims every 8.5 seconds; the extremely damaging CodeRed worm took about 37 minutes to do the same. Slammer was scanning approximately 55 million systems per second within 3 minutes of its release. By 10:00 a.m. on January 26, several ATMs were unable to process transactions, many Internet links were overwhelmed with traffic, several root DNS servers were unavailable because of the degradation of bandwidth on certain links, and approximately 120,000 computers were infected. The worm's scanning activity finally slowed, mainly because the increasing amount of traffic it generated restricted the available bandwidth. Eventually ISPs started blocking the type of traffic that the worm generated, further slowing Slammer's scanning and repopulation activities.
Many people might have heard of the Slammer worm, but few people fully understand the root of the attack. Familiarizing yourself with Slammer's methods can help you evaluate the risk to your environment and prepare for future attacks by similar worms.
The Root of the Problem
Systems running the following are vulnerable to Slammer's type of attack:
- Microsoft SQL Server 2000 Service Pack 2 (SP2), SP1, release to manufacturing (RTM), or SQL Server 2000 Evaluation Edition
- Microsoft SQL Server Desktop Engine (MSDE) 2000 SP2, SP1, or RTM
- any application that installs MSDE 2000 SP2, SP1, or RTM without the necessary hotfixes: MS02-061 (Elevation of Privilege in SQL Server Web Tasks), MS02-056 (Cumulative Patch for SQL Server), MS02-043 (Cumulative Patch for SQL Server), and MS02-039 (Buffer Overruns in SQL Server 2000 Resolution Service Could Enable Code Execution)
MSDE provides a code base for programmers so that they don't need to manually write base code for their products. One reason that so many systems are vulnerable to worms such as Slammer is that many IT departments don't know which applications were built using MSDE and thus which systems need to be patched.
To communicate with SQL Server, client systems can use one of two interprocess-communications methods: sockets on TCP port 1434, or named pipes over a NetBIOS session on TCP ports 139 or 445. Sockets, which are interfaces through which applications can communicate using the TCP/IP stack, use a combination of IP addresses and port numbers. Named pipes, which are actually shared memory segments that applications and NetBIOS use for process communications, don't use port numbers but require processes to exchange specially formatted requests.
Clients don't usually know which method of communication a SQL Server system is configured to use, so they probe the server to determine how future communications should take place. The client software sends a message to the SQL Server Resolution Service operating on the server's UDP port 1434. Microsoft SQL Monitor listens on this port and responds to incoming client requests, indicating which communications method to use. When the server receives this type of request, it accepts all the data in the request packet, and the SQL Monitor thread opens the registry and reads the value set for the HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\AAAA\MSSQLServer\CurrentVersion registry subkey (for SQL Server 2000 systems).
When SQL Monitor makes the call to open the registry, it puts the client's data on a stack. Most applications consist of subroutines that perform specific functions. When an application calls a subroutine, the application arranges the data that the subroutine needs in a structure referred to as a stack. As Figure 1 shows, the application puts a return pointerwhich contains the memory address of the point in the application to which to return after the subroutine completes executionon the stack, then adds the necessary variables in allocated buffers on top of the pointer. The subroutine first extracts data from the buffer on the top of the stacklast in, first outand performs the necessary computations, then continues to extract data until it reaches the return pointer, which directs the subroutine to return control to the application.
The crux of the problem is that vulnerable systems don't carry out proper bounds checking and will accept a request message that's larger than the buffer space allotted for the client data. That data then can overwrite the memory segment along with other memory segmentsincluding the return pointer. As Figure 2 shows, skillfully written buffer overflows input enough data to overwrite the buffers, add malicious commands, and overwrite the return pointer with a pointer that leads to the malicious commands rather than to the requesting application. If the overrun application is executing in a privileged mode, the malicious commands will also execute in that security context, letting the attacker create extensive damage.
Slammer creates a buffer overflow when SQL Monitor initiates a request to communicate with the registry, thus letting the worm execute its malicious commands in a privileged state. The infected system becomes a zombie that the worm uses to find and attack other systems. The worm makes a call to the Windows API GetTickCount function and uses the result as a seed value to generate random IP addresses, then opens a socket on the infected system and continually scans those IP addresses in an attempt to identify and infect other vulnerable systems.
One reason the original Slammer attacks occurred so quickly is that the worm uses UDP instead of TCP, so Slammer didn't need to establish a full TCP connection with each vulnerable system. The only limitation to the scanning activity and continual infection rate was the zombie's bandwidth connection to the Internet and internal servers. An infected SQL Server system could complete between 4000 and 30,000 scans per second, depending on its available bandwidth. Also, a connectionless protocol such as UDP doesn't require a three-way handshake, making it easier for the worm to bypass firewalls and spoof a UDP packet's source address and port.
After Slammer successfully completes a buffer overflow, the worm launches the second piece of its attackgenerating a damaging storm of UDP packets between servers over the Internet, thus creating a Denial of Service (DoS) attack. SQL Server 2000 lets several instances of SQL Server run on the same physical machine. Different instances work as individual logical servers. The SQL Server system uses a keep-alive mechanism to determine which instances are active and which are inactive. When an instance receives a packet with the value of 0x0A on UDP port 1434, it generates and returns to the sender a keep-alive packet with the same value. If the first packet has been spoofed to appear to come from another SQL Server system's UDP port 1434, both servers will continually send packets with the value of 0x0A to each other, generating a packet storm that continues until one of the servers is brought offline or rebooted. (The Slammer worm was developed simply to replicate rather than to install backdoors, modify files, or retain access to compromised systems. Slammer doesn't install itself on a system's hard disk but lives only in memory. Rebooting an infected system flushes the memory and removes the worm, but unless further actions are taken, the system can be reinfected quickly.)