W32.Cabanas

Risk Level 1: Very Low

Printer Friendly Page

Discovered: August 18, 1998
Updated: February 13, 2007 11:46:35 AM
Also Known As: Cabanas
Type: Virus


Win32.Cabanas is not only compatible with Windows NT, but is also a per-process memory resident, fast infecting, antidebugging, partially packed/encrypted, antiheuristic, semistealth virus. Thus the "Win32" prefix is not misleading, as the virus is able to spread in all Win32-based systems. The author of the virus was a member of the 29A group and was the same virus writer who wrote the WM.CAP.A virus. CAP.A is a virus which had an absolutely new infection mechanism and a difficult-to-understand structure. Win32.Cabanas is also a complex virus. Most of the time it is relatively easy to understand a virus by using a disassembler; some of the DOS viruses can be analyzed completely in a few hours, even if their code is longer than 4 KB.

This is not the case with Cabanas; it took days to analyze. For instance Cabanas cannot be traced at all from application-level debuggers such as TD32 (Turbo Debugger 32); it needs the power of SoftIce. This is because a typical debugger is focused on the traced program's address space and cannot go to the operating system level. Cabanas appears to have to have been very carefully written.

Running an infected Portable Executable (PE)* file

When a Win32.Cabanas-infected file is executed, the execution starts at the original host entry point. Cabanas does not touch the entry point field in the Image File Header. Instead it patches the host program at its entry point. Leapfrog, a DOS virus, was the first virus that used this method. Five bytes at the entry point are replaced with a FAR JMP to the address where the original program ended. This can be considered as an antiheuristic feature, as the host entry point value in the PE header keeps pointing inside the code section, possibly turning off some heuristic flags.

NOTE: The method that the virus uses to handles the relocations table is explained later in this document

The first JMP points to the real entry point. The first function in Cabanas unpacks and decrypts a string table which consist of Win32 KERNEL API names. The unpack mechanism is simple but effective. The word "File" is replaced and not used in the strings. The string GetProcAddress is not packed at the beginning of the string table, but the next function name is described as 'Ge','’'’+0x80h,'AttributesA' which means GetFileAttributesA when unpacked. Since Cabanas has unicode support, the next string is GetFileAttributesW, which is packed in two bytes: 80h, SizeOfPreviousUnpackedString. The other strings are packed similarly. This effectively reduces the space wasted by the API names string table.

Now the real problem is that the virus uses Structured Exception Handling (typically abbreviated to SEH) as an antidebugging trick. The goal of this function is to set a new SEH-FRAME and generate an exception. When the execution reaches the instruction that causes the exception, the control is redirected to the operating system’s exception handler (EIP will point into the kernel.) This is very annoying and needs the power of SoftIce to trace. The operating system’s exception handler set the exception type and returns to the application, because the SEH-FRAME was set. As a result, no general protection will be displayed and the SEH-FRAME will be removed.

When the unpack/decryptor function is ready, the virus calls a routine to get the original base address of Kernel32.dll. During infection time the virus searches for GetModuleHandleA and GetModuleHandleW in the import table. When it finds them its saves a pointer to the actual DWORD in the .idata list. Since the loader puts the addresses into this table before it executes the virus, Cabanas gets them easily.

If the application does not have a GetModuleHandleA or GetModuleHandleW import, the virus uses a third (undocumented) way to get the base address of Kernel32.dll by getting it from the ForwarderChain field of Kernel32 imports. This appears to be the biggest bug in the current version of the virus because this does not work under Windows NT; it only works under Windows 95. None of the infected samples that we received worked correctly if the application did not have GetModuleHandleA or GetModuleHandleW imports. (This is possible, because there are other ways to get the handle on Windows NT.)

NOTE: In Win32 environments the module handle and the base address mean the same thing.

When the virus has the base address/module handle of Kernel32.dll, it calls its own routine to get the address of GetProcAddress function.The first method is based on the search in the Import Table during infection time. The virus saves a pointer to the .idata section whenever it finds a GetProcAddress import in the host. In most cases Win32 applications import the GetProcAddress API, thus the virus should not use a secondary routine to get the same result. If the first method failed the virus calls a function which is able to search for GetProcAddress export in Kernel32 which could be called as GetProcAddress-From-ExportsTable. This function is able to search in Kernel32’s Exports table and find the address of GetProcAddress.

The opposite of importing a function is "exporting." This function is used by .exe and .dll files. A PE file stores information about its exported functions in the .edata section.

Kernel32.dll's Export table consists of an Image_Export_directory which has pointers to three different lists:
  • Function address table
  • Function name table
  • Function ordinal table

Cabanas searches for the GetProcAddress string in the function address table. When the routine finds the get GetProcAddress string, it also gets a pointer to the function ordinal table. This pointer finally retrieves the API function entry point for the function from the function address table and returns. In fact, this is almost the same algorithm that the real GetProcAddress from Kernel32.dll follows internally.

This function is one of the most important ones from the virus's point of view and is compatible with all Win32-based systems.

If the entry point of GetProcAddress was returned by the GetProcAddressFromExportsTable function, the virus saves this address and use it later on. If not, the GetProcAddressFromExportsTable function will be used several times. This function is also saved with "Structured Exception Handling" to avoid possible exceptions.

After this, the virus gets all the API addresses that it wants to use in a loop. When the addresses are available Cabanas is ready to replicate and calls its direct action infection routine.

Direct action infection

The direct action infection part is fast enough to go unnoticed, even though it goes through all the files in Windows folder, Windows System folder and in the current folder. This is because the virus works with "memory mapped" files only, a new feature implemented in Win32-based systems, which simplifies file handling and increases overall system performance. The full process does not take more then a few seconds on a 486-based system. First, the virus gets the name of Windows folder using the GetWindowsDirectoryA API, then it gets the name of Windows System folder with GetSystemDirectoryA API, and it then calls the function which searches for noninfected executable images. This function uses FindFirstFileA and FindNextFileA APIs in a loop with the *.* parameter. It searches for non-folder entries and checks the size of the files it found.

Files with a size evenly divisible by 101 are assumed to be infected. This is called the "Size Padding" technique. Some DOS viruses use it as well. Other files which are too large will not be infected. After this the virus checks the file extension, and if the file is an .exe or .scr file, the virus opens and maps the file by using CreateFileA and CreateFileMappingA functions. If the file is considered too small. it closes the file. Then it check the "MZ" marker at the beginning of the image. Next, it positions to the possible "PE" header area. It checks that the executable was made to run on 386 and faster computes, and looks for the type of the file. It cannot be a .dll, but it has to be an executable file.

Next it calculates a special checksum which uses the checksum field of PE files Optional Header and the file-stamp field of the Image File Header. If the file seems to be infected, the virus closes the file. If not, the file is chosen for infection. Cabanas then closes the file, blanks the file attribute of the file with SetFileAttributeA API, and saves the original attributes for later use. This means the virus is not stopped by the Read Only attribute. Then it reopens and maps the possible host file in write mode.

Next it searches for the GetModuleHandleA, GetModuleHandleW, and GetProcAddress API imports in the host’s import table and calculates pointers to the .idata section. Then it calls the routine that patches the virus image into the file.

This routine first checks that the .idata section has MEM_WRITE characteristics. If not it sets this flag on the section, but only if this section is not located in an executable area. This means that there are some extreme cases when this table is part of the .text (CODE) section. This prevents the virus from turning on suspicious flags on the code section, triggered by some heuristic scanner. Then it goes to the entry point of the image and replaces five bytes with a FAR JMP instruction which will point to the original end of the host. After that it checks the relocation table. This is because some relocations may overwrite the FAR JMP at the entry point. If the relocation table size is not zero the virus calls a special routine to search for such relocation entries in the .reloc area. It clears the relocation type on the relocation record if it points into the FAR JMP area; thus this relocation will not take into account by the loader. The routine also marks the relocation so that Cabanas will be able to relocate the host later on.

Then it encrypts all the information that has to be encrypted in the virus body, including the table which holds the original five bytes from the entry point and its location. This block is a parameter block which will be used by the virus to rebuild and start the host application. Next the virus calculates the special checksum for self-check purposes and saves this to the time stamp field of the header. When everything is ready, the virus calculates the new size of the file and makes this value divisible by 101. The real virus code is around 3000 bytes. The virus does not create a new section header for its code, but patches the last section header in the file (usually .reloc) to take enough space for the virus code, and it changes the characteristics to have the MEM_WRITE flag. This makes the infection less risky and less noticeable. This proves to be a clear advance with respect to previous Windows 95 viruses which added a new section header to the file. Then the virus changes the SizeOfImage field in the header to fit in the file and unmaps and closes the file by using: UnmapViewOfFile and CloseHandle APIs. Next it truncates the file at the previously calculated size and resets the original time and date stamp with SetFileTime API to the original. Finally Cabanas resets the original attribute of the file.

When all the possible files had been checked by Cabanas, the virus is ready to go resident.

Rebuild the host, Hook API functions and Go memory resident
The next phase is to rebuild the host program. The virus uses the GetCurrentProcess and WriteProcessMemory API functions to write back the five original bytes at the entry point. After this it relocates the code area, if necessary, by searching in the .reloc section for marked relocation entries. Next the virus hooks API functions and goes resident.

This is based on the manipulation of the import table. Since the host program holds the addresses of imported functions in its .idata section, all the virus has to do is to replace those addresses to point to its own API handlers.

To make those calculations, the virus opens and maps the infected program. Then it allocates memory for its per-process part. This is done by using VirtualAlloc API. The virus allocates a 12232-byte block and copies itself into this new allocated area. Then it searches for all the possible function names it wants to hook: GetProcAddress, GetFileAttributesA, GetFileAttributesW, MoveFileExA, MoveFileExW, _lopen,CopyFileA, CopyFileW, OpenFile, MoveFileA, MoveFileW, CreateProcessA, CreateProcessW, CreateFileA, CreateFileW, FindClose, FindFirstFileA, FindFirstFileW, FindNextFileA, FindNextFileW, SetFileAttrA, and SetFileAttrW. Whenever it finds one, it saves the original address to its own JMP table and replaces the .idata section’s DWORD (which holds the original address of the API) with a pointer to its own API handlers. Finally the virus closes and unmaps the host and starts the application, by jumping into the original entry point in the .text (CODE) section.

GetProcAddress is used by many programs. When the application calls GetProcAddress, the new handler first calls the original GetProcAddress to get the address of the requested API. After this it checks if the function is a Kernel32 API and it is one of the APIs that the virus wants to hook. If it is, and it is not hooked yet, the virus returns a new API address which will point into the NewJMPTable, giving the program an address to the new handler.

Stealth and fast infection
Cabanas is a semistealth virus: during FindFirstFileA, FindFirstFileW, FindNextFileA, and FindNextFileW the virus checks for already-infected programs. If the program is not infected, the virus infects it; otherwise, it hides the file size difference by returning the original size for the host program. There are no Windows scanners which have efficient self-checks before they start to scan for viruses. If the scanner checks its size by calling the above APIs, it cannot detect the file size difference itself, and it begins the scanning process if no other self-check has been used. During this time, the virus can see all the file names the application accessed and it infects every single noninfected file.

Because the Cmd.exe (Command Interpreter of Windows NT) is using the above APIs during the DIR command, every noninfected file will be infected (if Cmd.exe was infected previously by Win32.Cabanas). The virus also infects files during every other hooked API request.

Other text in the virus
Apart from the encrypted API name strings, the virus also contains the following copyright message:

(c) Win32.Cabanas v1.0 by jqwerty/29A

Recommendations

Symantec Security Response encourages all users and administrators to adhere to the following basic security "best practices":

  • Use a firewall to block all incoming connections from the Internet to services that should not be publicly available. By default, you should deny all incoming connections and only allow services you explicitly want to offer to the outside world.
  • Enforce a password policy. Complex passwords make it difficult to crack password files on compromised computers. This helps to prevent or limit damage when a computer is compromised.
  • Ensure that programs and users of the computer use the lowest level of privileges necessary to complete a task. When prompted for a root or UAC password, ensure that the program asking for administration-level access is a legitimate application.
  • Disable AutoPlay to prevent the automatic launching of executable files on network and removable drives, and disconnect the drives when not required. If write access is not required, enable read-only mode if the option is available.
  • Turn off file sharing if not needed. If file sharing is required, use ACLs and password protection to limit access. Disable anonymous access to shared folders. Grant access only to user accounts with strong passwords to folders that must be shared.
  • Turn off and remove unnecessary services. By default, many operating systems install auxiliary services that are not critical. These services are avenues of attack. If they are removed, threats have less avenues of attack.
  • If a threat exploits one or more network services, disable, or block access to, those services until a patch is applied.
  • Always keep your patch levels up-to-date, especially on computers that host public services and are accessible through the firewall, such as HTTP, FTP, mail, and DNS services.
  • Configure your email server to block or remove email that contains file attachments that are commonly used to spread threats, such as .vbs, .bat, .exe, .pif and .scr files.
  • Isolate compromised computers quickly to prevent threats from spreading further. Perform a forensic analysis and restore the computers using trusted media.
  • Train employees not to open attachments unless they are expecting them. Also, do not execute software that is downloaded from the Internet unless it has been scanned for viruses. Simply visiting a compromised Web site can cause infection if certain browser vulnerabilities are not patched.
  • If Bluetooth is not required for mobile devices, it should be turned off. If you require its use, ensure that the device's visibility is set to "Hidden" so that it cannot be scanned by other Bluetooth devices. If device pairing must be used, ensure that all devices are set to "Unauthorized", requiring authorization for each connection request. Do not accept applications that are unsigned or sent from unknown sources.
  • For further information on the terms used in this document, please refer to the Security Response glossary.

Writeup By: Douglas Knowles
Search by name
Example: W32.Beagle.AG@mm
Windows 7
Windows Vista Security