The Evolution of 32-Bit Windows Viruses
Windows 2000 Magazine Online
Features / Peter Szor, Eugene Kaspersky / July 1, 2000

The world of computer antivirus research has changed drastically since the introduction of Windows 95. One reason for this change is that certain DOS-based viruses that used stealth techniques and undocumented DOS features became incompatible with Win95. As a result, virus writers took on the challenge of investigating the new OS and began creating new Win95-compatible DOS-executable viruses and boot viruses.

In March 1999, only 100 or so 32-bit Windows virus variants existed. Today, this number has grown to more than 600. Most of these variants are known as zoo viruses because they're contained in virus collections only and generally don't cause problems for end users. Most of the older 32-bit Windows viruses attacked only Win95. A year ago, fewer than 20 percent of all 32-bit Windows viruses were capable of replicating on Windows NT. Today, however, half of all 32-bit Windows viruses are true Win32 viruses, meaning they can replicate on NT and Windows 9x systems. Some of these viruses are already compatible with Windows 2000. Only about 25 percent of old Win32 viruses (i.e., written before Win2K) do not replicate on the release version of Win2K because of some slight incompatibility issues.

To protect yourself from viruses, it helps to understand where they came from, what forms they take, and how they can damage your systems. Armed with this information, you will stand a better chance of protecting yourself.

Early Years

The first Win95 virus, Win95/Boza, appeared in 1995 and was written by a member of the Australian VLAD virus writing group. Although it took time for others to understand the insides of the Win95 architecture, several new Win95 viruses began appearing in 1997. Some of these viruses were in the wild, meaning that they caused a significant outbreak in several end-user environments. At the end of 1997, Jacky/29A introduced Win32/Cabanas.A, the first Win32 (NT-compatible) virus.

Win32/Cabanas.A is compatible with Win2K, NT, Win9x, and Win32s (an extension for 16-bit Windows to run 32-bit applications). As a result, Win32/Cabanas.A turned Microsoft's Win32-compatibility dream into a nightmare. With the shift away from DOS, Win32 viruses will eventually replace DOS-based viruses almost completely, and the DOS-based viruses will slowly die out.

The first major outbreak of a 32-bit virus began with the Win95/Anxiety family in late 1997. The virus patched its short code (i.e., modifying the Virtual Machine Manager’s—VMM’s—code in memory, not in the actual files) directly into Win95's VMM. On Win9x systems, the memory area where the system kernel and other Virtual Device Drivers (VxDs) load remains unprotected against memory writes, which makes these systems very vulnerable to attack. As a result, a user-mode application that runs in Ring3 can easily modify system-level code that runs in Ring0. Because Win2K and NT don't support VxDs, the Win95/Anxiety virus could not spread to systems running these OSs. Regardless, Win95/Anxiety caused major problems on home user and business desktop systems.

For emerging viruses, the major hurdle with Win32 platforms has been the common binary file format, or Portable Executable (PE) format. On Win2K, NT, Win9x, and Windows CE, most system executable files (e.g., .exe, .src, .dll, .ocx) and third-party applications share the same 32-bit file format—one that is very similar to the UNIX COFF format. This common file format makes creating viruses that are compatible with all Win32 systems relatively easy for virus writers.

Weaknesses of Early 32-bit Windows Viruses

The 29A virus writer group has released a lot of 32-bit viruses, but not all of them have been foolproof. One of these, Win95/Marburg, gathered worldwide attention when several magazines accidentally shipped the virus on their cover CD-ROMs. This commercial outbreak of the Win95/Marburg virus was mostly NT-compatible, but it didn't correctly infect PE files. The virus had a flaw that was very similar to the bugs that plagued early Win95 viruses such as Win95/Boza. Specifically, the image size in the PE header described a file length that differed from the file size after the infection. Win2K's and NT's loaders are more careful than Win9x's loader when it comes to PE files. Both Win2K and NT check for possible file corruption before executing the file and display an error message if the file is corrupt.

Win95/Boza had other problems that caused the virus to fail, even on systems running different releases of Win9x. These problems occurred because the virus writers were using hard-coded addresses to APIs to more easily reach a particular system function. However, API addresses often vary from one OS system release to the next.

Win95/Marburg, like Win32/Cabanas.A, used a trick that has become today’s new standard in virus development. These viruses have a function that locates the address of each API they need to call under all Win32 systems. Viruses that append themselves to PE files can't call APIs easily because the viruses don't typically have their own imports, and the system DLLs export all system functions. Programmers use the API by static linking, which builds a proper import address table, or by calling the GetProcAddress() API to dynamically obtain the address of a particular API. An application that uses GetProcAddress() API typically needs to have a static import to call this API. The static import for the GetProcAddress() API is located in the application’s import address table, so the application is safe to call any APIs that are exported by name.

Virus writers had to implement a function that is similar in its implementation to GetProcAddress(). With this function a virus can easily append its own code to the host programs. Development of this function increased the chances that new viruses would be much more compatible with Win2K and NT. Taken a step further, 32-bit viruses that use standard Win32 APIs, implement the above functionality, and infect the PE file properly are Win2K and NT compatible.

Damaging the Hardware Under Windows 9x

Virus attacks took a big step in 1998 when the infamous Win95 virus, Win95/CIH, became the first virus to damage system hardware—specifically, the flash BIOS. CIH, like Win95/Anxiety, implements a PE infection mechanism based on VxD calls. Because the virus executes its damage routine in Ring0 (system level), you can't prevent the damage caused by the port commands (e.g., IN, OUT). Such dangerous viruses don't yet exist for Win2K and NT, but they are possible. To execute port commands, a virus has to be running in kernel mode under Win2K or NT. As a result, because most virus writers lack the knowledge to create the necessary drivers, many will have a hard time creating this type of virus. However, one virus already exists (WNT/Infis.4608) that is a native NT driver, and an update exists for Win2K (W2K/Infis.4608).

Infecting Kernel32.dll

Virus writers have written several Win32 viruses that attack kernel32.dll, which most PE applications load and use to access the most important Win32 API set, such as file functions. These viruses work by patching the export address of one exported API (e.g., GetFileAttributesA) to point into the virus code that the virus has appended to the end of the DLL image. Because 32-bit DLLs use the PE file format, virus writers can easily infect this type of file. The Win95/Lorez virus was the first virus of this kind.

These viruses can easily be per-process resident (i.e., the viruses run actively as part of a process or several processes). As a result, each process that uses kernel32.dll, which is any process that uses the basic Win32 file functions and directory functions, links to the virus code. The infected DLL attaches to every program that has kernel32.dll imports. Whenever the application calls the API with the attached virus code, the virus code gets control in the address spaces of the infected application.

Every system DLL contains a precalculated checksum that the linker places in the DLL's PE header. Unlike Win95, NT recalculates this checksum before it loads DLLs and drivers. If the calculated checksum doesn't match the checksum in the DLL's header, the system loader stops with an error message at the blue screen during system boot. However, this extra step doesn't mean that a virus writer can't implement such a virus for NT.

The Win32/Heretic virus was the first of its kind to implement proper kernel32.dll infection. As a result, the virus ran on NT. The Win32/Kriz virus also used this method to make its way into the wild. Win32/Kriz uses the CIH damage routine, but the damage routine doesn't work under NT because the virus runs in Ring3 (user mode).

Infected DLLs can be problematic to clean from the system because applications map these files from the disk to memory, and you can't modify these files once they load. Whereas you can boot an infected Win9x machine from a clean system diskette, it's much more complicated when you're using Win2K and NT with NTFS. In these situations, you need to use utilities such as NTFSDOS that can boot the system for write access. (Win2K's Recovery Console provides similar benefits, but only NTFSDOS supports NT. In addition, the NTFSDOS software can help you recover data from important system areas or files corrupted as a result of virus infection.) Fortunately, Windows’ System File Checker (SFC) feature will fix the modified system components automatically. To use SFC, type

>     sfc.exe

from the command prompt. SFC is not a virus security feature, but it helps reduce the risk of spreading viruses under Win2K.

The First Successful Win32 Worm

Virus writers released the first known Win32 worm (a special sub-class of viruses that primarily spread over networks) in January 1999. Known as Win32/SKA.A, or Happy99 worm, the worm originated on the Win95 platform. The worm also ran on older versions of NT under special circumstances where the worm could patch wsock32.dll.

The thousands of Win32/SKA.A reports that hailed from around the globe speak to the power of this threat. The worm disguises itself as an email attachment called happy99.exe. This file is the actual worm code, and it propagates by locating valid email addresses. The French virus writer known as Spanska came up with a simple solution. The worm modifies wsock32.dll and patches itself into this file so that two APIs—Connect() and Send()—can hook into the worm’s code. Thus, Win32/SKA.A can see all the network activities on the current machine. So, when someone posts an email message to another user or to a news server, the worm sends a copy of its email message with an attachment of its code.

Although the worm appeared more than a year ago, it continues to spread. These types of chain-letter worms are very successful because people usually trust messages they receive from their friends and associates. Although Win32/SKA.A came out long before the Melissa macro virus, many corporations didn't understand the worm's message in time and didn't institute strict policies that could have minimized the chance of other worm-related outbreaks later on.

Keep in mind that 32-bit worms are much more successful than viruses that spread relatively slowly. A worm can infect 1000s of machines around the globe in 1 day. Win32/SKA.A spreads more slowly than the more recent Melissa or LoveLetter because the worm sends itself only whenever a user sends an email message from the infected system. Newer viruses query the address book to get thousands of email addresses and spam themselves to as many locations as possible.

Worms with Dangerous Payloads

Virus writers took the idea behind Win32/SKA.A and implemented it in many Win32 worms. Win32/PrettyPark.A, which first appeared in France, and Win32/ExploreZip.A, which came from Israel, were probably the two most important because they were wide spread.

Win32/ExploreZip.A, which hit large American and Japanese companies, contained a very dangerous payload that truncated documents such as .doc and .xls files. Without proper backups, many companies lost thousands of files. PrettyPark let the virus writer use it as a back door to the infected system via remote commands.

Other Win32 Viruses Affecting Win2K and NT

Two other important viruses, Win32/Bolzano and Win32/FunLove, began appearing at the end of 1999. The Win32/Bolzano virus got a lot of attention because it was difficult to detect and attacked NT's file security. The Win32/FunLove virus, which was based on Win32/Bolzano, implemented an attack on Win2K. Both viruses have a short patch routine that patches ntoskrnl.exe, which contains the NT Executive, and Ntldr, which is a hidden system file in the root directory that loads NT on Intel platforms. Ntldr checks the checksum of ntoskrnl.exe during the boot period and refuses to load the kernel if the file has been altered. To modify ntoskrnl.exe, these viruses patch the Ntldr code at the place where Ntldr checks the checksum, forcing the system to skip the consistency check of the kernel file. Unfortunately, nothing in the OS checks Ntldr's consistency. Both Win32/Bolzano and Win32/FunLove patch the SeAccessCheck() kernel function in ntoskrnl.exe so that following the next boot, SeAccessCheck() will return incorrect information that indicates everybody has rights to any particular file. Obviously, someone who has the rights to modify ntoskrnl.exe must execute these viruses. Although this might sound like a significant limitation for these viruses, the viruses can always wait until a person with appropriate rights logs on to the machine. Therefore, administrators have to be careful not to execute applications without first checking the files’ contents and origin.

Fortunately, Win2K’s SFC feature will take care of the ntoskrnl.exe modifications. Systems administrators need to check the system logs for SFC messages. SFC will not display any error messages as long as an original clean copy of a system file or application is available in the SFC cache directories. If SFC does not find the original system file on the hard disk, it will display an error message and request that the original Win2K CD-ROM replace the files. Even then, SFC won’t display the changed application name. However, the system log will contain information about the changes and replacements.

Kernel-Mode Driver Viruses

Currently, only one kernel-mode driver virus exists for NT. A regular append-type virus, WNT/Infis.4608 adds 4608 bytes to the end of PE applications that run in user mode. The virus modifies the entry point so that it points to the start of the virus code. The infected applications will act as droppers of the driver component (i.e., when you execute an infected application, the virus tries to install the virus driver to the system). The virus does not use subsystem functions; instead, it uses hard-coded IDs to call native APIs. The virus can monitor all file access and infect PE applications on the fly. Once an administrator installs the virus, it can infect anything it wants. Fortunately, the virus code breaks on some NT 4.x service packs and doesn't work on Win2K or earlier NT versions. WNT/Infis.4608 is only an experimental virus (i.e., it contains fatal bugs that cause infected systems to crash before it can do the intended damage), and as such, it’s not stable enough to survive in the wild.

Complex Win32 Viruses

Several Win32 viruses exist that use polymorphic engines to make detection of virus code more difficult. Some viruses implement polymorphic engines that can change the virus code from byte to byte in different generations. Thus, you can't use a constant search string to detect the virus code unless you use some other special antivirus modules such as code emulation.

An alternative approach to polymorphic viruses is writing metamorphic viruses. These viruses consist of small modules that viruses can place in a virtually endless order using various sets of instruction sequences that differ in code but have the same result when executed.

Another element adding to the complexity of Win32 viruses is that several of these viruses consist of 10, 20, or even 100KB-long assembly code that is often encrypted multiple times. This approach provides a daily headache to antivirus researchers. Although antivirus researchers can analyze and fix macro viruses relatively quickly, most Win32 viruses are very complex, and finding a solution for a complex Win32 virus is more difficult.

Be Prepared

At least one-third of new 32-bit Windows viruses written this year propagate via email. These creations present the biggest risk for corporate users. Systems administrators have to understand this risk and educate their users to pay attention to email attachments. Not only can documents be dangerous by hiding a short macro, but executable code attachments can open access to all available resources and do anything that the user’s rights allow. With the rise in Win32 viruses, you need to be prepared and understand the security features of your Win2K and NT systems. When used properly, several built-in security features can save you time, resources, and money.