Strange Case of W32.Xpaj.B: Patient Zero
A number of days ago, we observed a new variant of the W32.Xpaj.B virus and we blogged all of the initial details about its new features and how the outbreak sample is the patient zero of the infection. We have now done more analysis and the conclusion is in: there is no outbreak and W32.Xpaj.B is not coming back, at least for now.
From the analysis we uncovered the following:
- Samples infected by patient zero do not have the capability to infect other samples
- A 64-bit kernel mode payload injects a Dynamic-Link Library (DLL) into the target processes, but the DLL is empty
- Infected samples do not carry a copy of the virus body from patient zero, but they are infected with a substantially smaller version of the virus
All of these facts seem to suggest that this patient zero was meant to be just a test sample; the virus is not attempting to run any meaningful payload functionality and the self-replication feature is not present. This is also confirmed by our telemetry data. If we take a look at the number of master boot record (MBR) infections observed in the wild (note that MBR infections are only from the new variant of W32.Xpaj.B, not from the old one), we can count less than 50 at the moment, which is surprisingly low.
This sample was simply not meant to be released to the public for a pandemic infection. My guess is that it might have been pushed out to some specific target just for a small test on the field, or that it was somehow leaked from its writers.
Patient zero infects the MBR and copies its payloads at the end of the disk. When the compromised computer is booted, the MBR will cause the payloads to be extracted and loaded.
Figure 1. Payloads installed to disk
The payloads are:
- 64-bit user mode DLL: It is the DLL injected into targeted processes on 64-bit Windows
- 32-bit user mode virus body: Samples infected (32-bit .exe files and DLLs only) will carry this viral body, not the one from “patient zero”
- 64-bit kernel mode payload: Code that runs in 64-bit kernel mode
- 32-bit kernel mode payload: Code that runs in 32-bit kernel mode
As stated in my last blog entry, the virus will not infect kernel mode drivers; the kernel mode payload is only loaded through the MBR.
Reduced viral body payload
During our tests, a simple problem showed up: the infected samples, when run, were not infecting other samples. In other words, the only way to replicate infections was to run patient zero and generate a first generation of infected files. None of these files, when run, were infecting anything; therefore we were not able to produce a second generation of infections.
I decided then to dig deeper into the problem and I found that there is quite a difference between the viral body found in patient zero and the viral body found in the first generation of infected samples—the size! The viral body from patient zero is about 170 KB, while the one from infected sample is about 50 KB—a big difference!
The viral body from infected samples comes from the compressed payloads that are stored at the end of the physical disk during infection from “patient zero”. I analyzed this attenuated version of the virus and I found it lacking the code to perform infection of other samples. It also lacks the code to infect the MBR and it does not carry the compressed payloads.
So what does it do? Well, it seems that all it does is this:
- Read and write encrypted data to a randomly named file in %Windir%
- Handle encrypted network communication towards the command-and-control (C&C) server
It is possible that the virus may receive an update of itself but, at the moment, the C&C server is not alive (so we cannot confirm this).
Kernel mode payload
Part of the kernel mode functionality has been already described in my previous blog entry and in other articles, however, after more analysis; I have found some interesting details. Some Application Programming Interfaces (APIs) and symbols are present, but not called or used in the current payload. This suggests they may be included in future versions of the virus. A couple of interesting ones:
- KeServiceDescriptorTable: Possibly used for installing kernel mode function hooks, or maybe to end security products by removing their own function hooks.
- IoCreateDriver: Can be used to load any driver. Maybe the authors want the possibility to load other drivers for particular tasks when needed.
We can also find KeGetCurrentIrql, which is not really interesting on its own, but the code seems to be using it in a particular way:
Figure 2. KeGetCurrentIrql is loaded dynamically, based on which PE module it is in
The code retrieves the API and saves information about which module it is in. This happens because in Windows versions up to XP the API was located in hal.dll, while from Windows Vista and later, it is located in ntoskrnl.exe. So, this tells us the malware authors are testing this thing in Windows Vista and Windows 7, maybe even in Windows 8 as well, who knows!
Finally, some of the kernel mode code that used to be in the viral body itself (in the old version) has been moved to the kernel mode payload in the new version. Yet, there is still kernel mode code in the viral body of patient zero, so it may look like the authors of the virus are abandoning the idea of infecting drivers, and moving the intended kernel mode functionality into a dedicated payload.
This is probably also dictated by the fact that the virus can only infect 32-bit .exe files and DLLs: if the author wants his code to be run in kernel mode then he has to add the functionality to infect 64-bit Portable Executable (PE) files as well, and must also support drivers. Basically, one single virus body should be able to run both in 32 and 64-bit, and both in user mode and kernel mode. This is clearly overkill in terms of writing and maintaining such a malware. Instead, the malware authors have used dedicated payloads, thereby adding modularity to the code, which allows faster development.
64-Bit DLL payload
As discussed above, the 64-bit DLL that is supposed to be injected in some targeted process is basically empty. You can see it in this image:
Figure 3. Dummy 64-bit payload DLL
There is no real code, only some test strings. Also, the format of the DLL PE and the string from the data section would suggest that this DLL was written directly in assembly language rather than compiled from a C/C++ compiler.
In conclusion, there is still no outbreak, but this patient zero clearly shows a dangerous evolution of the threat. There is no way to tell when (or even if) we are going to see this new variant released, but my guess is that it won’t happen too long from now. Thanks to this sample we have been vaccinated—we have been able to perform a pre-emptive analysis and we are one step ahead—but rest assured, we will keep monitoring this threat and we will be ready for it when it spreads in the wild.