2008-02-01
Abstract
Recently, a threat has appeared which obtains a file’s physical disk location information with the aid of the Windows system APIs, then proceeds to infect the corresponding system file. Ha Young Yang describes exactly how physical disk information is being used to disable Windows file protection.
Copyright © 2008 Virus Bulletin
Microsoft has released various file system APIs for Windows for the purposes of defragmentation and recovery. Unfortunately, it is possible for these APIs to be exploited for malicious purposes. Recently, a threat has appeared which obtains a file’s physical disk location information with the aid of these file system APIs. First the malware calculates the physical disk location of its target file and then it modifies the file. The modification of normal system files not only disables Windows file protection (WFP), but also causes problems for anti-virus programs in restoring the modified system files.
The piece of malware (named Win_Trojan/Rosys.49152 by AhnLab) was programmed in assembly language and infects the Userinit.exe file, which specifies which programs Windows runs when a user logs on, running logon scripts, re-establishing network connections and starting Explorer.exe.
The malicious program first calculates the physical disk location of the file and then overwrites the code with its own from the beginning to 0x1000. As a result of this overwriting operation, the system file is modified and the Windows system is no longer able to protect the file properly. Trojan downloader ability contained in the code written to the file means that, when booted, the system can be connected to specific websites to download malicious files.
Despite being infected, the system can continue to function normally because the modified trojan downloader has the ability to run the Explorer.exe file.
The virus has a driver file, pcihdd.sys, which stores a set of data, encrypted with a four-byte XOR key value, to be used in overwriting. When the virus calls a specific function in the pcihdd.sys file, it starts to decrypt the data and infects Userinit.exe by using an appropriate decoding buffer.
The virus works on NTFS, FAT16 and FAT32 file systems. Although it has a perfect algorithm to calculate the Userinit.exe disk location, it does not work on certain systems due to a bug which leaves the ‘Carry’ value out at the point of arithmetic calculation. To calculate the physical disk location of the file, the virus makes use of LCN (Logical Cluster Number) information obtained from the RETRIEVAL_POINTERS_BUFFER structure, master boot records (MBR) and boot sector.
Three types of information from the MBR are used to calculate the physical disk location: the boot indicator, system ID (volume type) and relative sectors.
Through the boot indicator the virus checks whether the system is Active Partition (0x80) or Logical Partition (0x0). It only infects Active Partition systems. Through the system ID value the virus also checks the type of file system, such as NTFS, FAT16 or FAT32. Relative sectors represent the total offsets from the beginning of a disk to the beginning of a volume or partition as the number of sectors.
Four types of information from the boot sector are used to calculate the physical disk location:
Reserved sectors
Number of FATs
Sectors per FAT
Sectors per cluster
The number of FATs and sectors per FAT are used only on FAT file systems.
The ‘DeviceIoControl’ request causes a mapping to be performed between the file address space and the volume address space. A cluster is the smallest allocation unit that the file system will use when allocating physical storage for a file. The VCN (virtual cluster number) provides ordering information about the file from ‘0’ to ‘N’ expressed in units of cluster, and the LCN (logical cluster number) provides ordering information about the volume from the beginning to the end expressed in units of cluster. Each VCN value is mapped to the corresponding LCN value, which is subsequently translated into the physical byte offset of a volume.
Figure 1 illustrates the three levels of translation, from file byte offsets to virtual cluster block and then to volume logical cluster block.
To calculate the disk location the virus performs a ‘DeviceIoControl’ request, as shown below, and applies ‘FSCTL_GET_RETRIEVAL_ POINTERS’ to the control codes and the handle of Userinit.exe:
BOOL DeviceIoControl( (HANDLE)hDevice, FSCTL_GET_RETRIEVAL_POINTERS, (LPVOID)lpInBuffer, (DWORD)nInBufferSize, (LPVOID)lpOutBuffer, (DWORD)nOutBufferSize, (LPDWORD)lpBytesReturned, (LPOVERLAPPED)lpOverlapped );
As a result of this request, the virus obtains structure values including LCN and VCN as shown below:
typedef struct RETRIEVAL_POINTERS_BUFFER{ (DWORD)ExtentCount; LARGE_INTEGER StartingVcn; struct { LARGE_INTEGER NextVcn; LARGE_INTEGER Lcn; } Extents[1]; }RETRIEVAL_POINTERS_BUFFER, *PRETRIEVAL_POINTER_BUFFER;
The following calculation algorithms are applied to obtain the disk location information for each file system. The location information expressed in units of cluster is translated to the byte offset value prior to being used.
NTFS
X = relative sectors + reserved sectors
Y = LCN * (sectors per cluster)
Disk offset = (X + Y) * SECTOR_SIZE
FAT16, FAT32
X = relative sectors + reserved sectors
Y = LCN * (sectors per cluster)
K = (number of FATs) * (sectors per FAT)
Disk offset = (X + Y + K) * SECTOR_SIZE
Figure 2 shows the structure information on RETRIEVAL_POINTERS_BUFFER obtained by the ‘DeviceIoControl’ request. It can be determined that the LCN value of Userinit.exe, applied to calculate the real disk location information, is 0x80B7B.
By applying both the calculation algorithm and the LCN information, the disk location information of the real ‘Userinit.exe’ is calculated as follows in a FAT32 environment:
X = 0x3F + 0x26 (=0x65)
Y = 0x80B7B * 0x20 (=0x1016F60)
K = 0x02 * 0x270D (=0x4E1A)
Disk offset = 0x101BDDF * 0x200(sector size)
The disk offset value obtained through the final calculation is 0x2037BBE00. The virus reads a data block of size 0x200 by applying both the disk handle value obtained from ‘\\.\PhysicalDrive0’ and the byte offset value, 0x2037BBE00. It also performs a verification process in which the disk data is compared with the Userinit.exe file data, byte by byte.
When the verification process has been completed successfully, the virus starts to overwrite its code on the corresponding disk location. The data in the pcihdd.sys file, which is encrypted with a four-byte XOR key value (0x3F702D98), is used in this overwriting process. Figure 3 and Figure 4 show the data before and after decryption respectively.
The websites connected to by the action of the overwritten code in Userinit.exe change with every mutation. The following are the sites known to date:
http://yu.8s7.net/cert.cer
http://3.joppnqq.com/test.cer
http://1.jopmm99.com/test.cer
The calculation algorithm applied in the virus is designed to run on FAT16, FAT32 and NTFS environments. But, as mentioned, the virus may not work on certain systems as a result of not considering the ‘Carry’ value at the point of arithmetic calculation. ‘Carry’ is generated at the final calculation step of 0x101BDDF * 0x200, when the sector size is multiplied.
The extract shown below shows real codes used in the virus. Bugs are generated at 'IMUL EAX, EAX, 200' codes. To correct the problem, the ‘ADC EDX, 0’ command should have been added at the end of the arithmetic calculation. In view of the fact that ‘Carry’ is considered in earlier calculation steps, its absence from the final calculation step could be interpreted as a mistake in programming.
// Final arithmetic calculation IMUL EAX, EAX, 200 // Move from the beginning of a disk to 0x2037BBE00 MOV DWORD PTR [EBP-540], EDX MOV DWORD PTR [EBP-544], EAX PUSH 0 LEA EAX, DWORD PTR [EBP-540] PUSH EAX PUSH DWORD PTR [EBP-544] PUSH DWORD PTR [EBP-530] CALL <JMP.&kernel32.SetFilePointer> // Read at 0x2037BBE00 offset PUSH 0 LEA EAX, DWORD PTR [EBP-18] PUSH EAX PUSH 200 LEA EAX, DWORD PTR [EBP-52C] PUSH EAX PUSH DWORD PTR [EBP-530] CALL <JMP.&kernel32.ReadFile> // Compare “Userinit.exe” file with a data LEA EDI, DWORD PTR [EBP-52C] LEA ESI, DWORD PTR [EBP-32C] MOV ECX, 200 REPE CMPS BYTE PTR [EDI], BYTE PTR[ESI]
There are many forms of this virus infecting Windows system files. Recently, a variety of techniques have been introduced to disable WFP (Ex. Patching sfc.dll, sfc_os.dll, Modifying Registry), but the virus described here is the first that we know of that modifies Windows system files by calculating the physical disk location of a file. It is quite possible that this will become a prevailing WFP-disabling technique in future.
The virus described here has tried to infect only the Userinit.exe file. It is hard to detect the infection of this file because Userinit.exe is executed upon booting and terminated simultaneously with the end of booting. Appropriate measures should be taken to deal with malicious programs of this type, which are becoming more sophisticated.