13
THE RISE OF MBR RANSOMWARE

Image

So far, the examples of malware described in this book all belong to a particular class: computer trojans with rootkit or bootkit functionality whose intention is to persist on victims’ systems long enough to perform various malicious activities—committing browser click fraud, sending spam, opening a backdoor, or creating an HTTP proxy, to name just a few. These trojans use bootkit persistence methods to persevere on infected computers and rootkit functionality to remain undetected.

In this chapter, we’ll take a look at ransomware, a family of malware with a very different modus operandi. As the name suggests, the main purpose of ransomware is to lock users out of their data or computer system entirely and demand a ransom to restore access.

In most known cases, ransomware uses encryption to deprive users of their data. Once the malware is executed, it attempts to encrypt everything of value to a user—documents, photos, emails, and so on—and then demands the user pay a ransom to get the encryption key to decrypt their data.

Most ransomware targets user files stored in the computer filesystem, though these methods don’t implement any advanced rootkit or bootkit functionality and thus aren’t relevant for this book. However, some ransomware families instead encrypt sectors of the hard drive to block user access to the system, using bootkit functionality to do so.

In this chapter, we’ll focus on the latter category: ransomware that targets computer hard drives and deprives victims not only of files but also of access to the entire computer system. This type of ransomware encrypts certain areas of the hard drive and installs a malicious bootloader onto the MBR. Instead of booting the operating system, the bootloader performs low-level encryption of the hard drive’s content and displays a message to a victim demanding a ransom. In particular, we’ll focus on two families that have received a lot of media attention: Petya and Satana.

A Brief History of Modern Ransomware

The first traces of ransomware-like malware were apparent in the computer virus AIDS, first discovered in the wild in 1989. AIDS used methods similar to those of modern ransomware to infect old MS-DOS COM executables by overwriting the beginning of files with malicious code in a way that made it impossible to recover them. AIDS, however, didn’t demand that victims pay a ransom to restore access to the infected programs—it simply obliterated the information without the option of retrieval.

The first known malware to demand a ransom was the GpCode trojan, which first appeared in 2004. It was famous for using a 660-bit RSA encryption algorithm to lock user files. Advances in integer factorization made it nearly feasible to factor 600-bit integers in 2004 (a cash prize was awarded in 2005 for the successful factoring of RSA-640, a 640-bit number). Subsequent modifications were upgraded with 1,024-bit RSA encryption, which improved the malware’s resilience against brute-force attacks. GpCode was spread via an email attachment purporting to be a job application. Once it was executed on the victim systems, it proceeded to encrypt user files and display the ransom message.

Despite these early appearances, ransomware wasn’t a widespread threat until 2012, but it has remained prevalent ever since. One factor that likely played an important role in its growth was the rise in popularity of anonymized online services, such as Bitcoin payment systems and Tor. Ransomware developers could take advantage of such systems to collect ransom payments without being tracked by law enforcement organizations. This cybercrime business proved to be extremely profitable, resulting in varied development and wide distribution of ransomware.

The ransomware that kicked off the surge in 2012 was Reveton, which disguised itself as a message from a law enforcement organization tailored to a user’s location. For instance, victims in the United States were shown a message purporting to be from the FBI. The victims were accused of illegal activities, such as using copyrighted content without permission or viewing and distributing pornography, and instructed to pay a fine to services such as Ukash, Paysafe, or MoneyPak.

Shortly after, more threats with similar functionality appeared in the wild. CryptoLocker, discovered in 2013, was the leading ransomware threat at that time. It used 2,048-bit RSA encryption and was mainly spread via compromised websites and email attachments. One of the interesting features of CryptoLocker was that its victims had to pay the ransom in the form of Bitcoin or prepaid cash vouchers. Using Bitcoin added another level of anonymity to the threat and made it extremely difficult to track the attackers.

Another remarkable piece of ransomware is CTB-Locker, which appeared in 2014. CTB stands for Curve/TOR/Bitcoin, indicating the core technologies employed by the threat. CTB-Locker used the Elliptic Curve Cryptography (ECC) encryption algorithm and was the first known ransomware to use the TOR protocol to conceal C&C servers.

The cybercrime business remains extremely profitable to this day, and ransomware continues to evolve, with many modifications regularly emerging. The ransomware families discussed here constitute only a small fraction of all the known threats in this class.

Ransomware with Bootkit Functionality

In 2016, two new families of ransomware were discovered: Petya and Satana. Instead of encrypting user files in the filesystem, Petya and Satana encrypted parts of the hard drive to make the OS unbootable and displayed a message to victims demanding payment to restore the encrypted sectors. The easiest way to implement an interface to display a ransom message is to leverage MBR-based bootkit infection techniques.

Petya locked users out of their systems by encrypting the contents of the master file table (MFT) on the hard drive. The MFT is an essential, special data structure in the NTFS volume that contains information on all the files stored within it, like their location on the volume, their filenames, and other attributes. It is primarily used as an index for finding the locations of files on the hard drive. By encrypting the MFT, Petya ensured that files could not be located and that victims weren’t able to access files on the volume or even boot their system.

Petya was mainly distributed as a link in an email purporting to open a job application. The infected link actually pointed to the malicious ZIP archive containing the Petya dropper. The malware even used the legitimate service Dropbox to host the ZIP archives.

Discovered shortly after Petya, Satana also deprived victims of access to their systems by encrypting the MBR of the hard drive. Though its MBR infection capabilities weren’t as sophisticated as Petya’s—and even contained a few bugs—they were interesting enough that Satana deserves a little discussion.

The Ransomware Modus Operandi

Before going into the technical analysis of Petya and Satana’s bootloader components, let’s take a high-level look at the way modern ransomware operates. Each family of ransomware has its own peculiarities that deviate slightly from the picture given here, but Figure 13-1 reflects the most common pattern of ransomware operation.

image

Figure 13-1: Modus operandi of modern ransomware

Shortly after being executed on the victim’s system, the ransomware generates a unique encryption key for a symmetric cipher—that is, any block or stream cipher (for example, AES, RC4, or RC5). This key, which we’ll refer to as the file encryption key (FEK), is used to encrypt user files. The malware uses a (pseudo-) random number generator to generate a unique key that cannot be guessed or predicted.

Once the file encryption key is generated, it’s transmitted to a C&C server for storage. To avoid interception by network traffic monitoring software, the malware encrypts the file encryption key with a public key embedded in the malware , frequently using RSA encryption algorithms or ECC encryption, as is the case with CTB-Locker and Petya. This private key isn’t present in the malware body and is known only to the attackers, ensuring that no one else can access the file encryption key.

Once the C&C server confirms receipt of the file encryption key, the malware proceeds to encrypt user files on the hard drive . To reduce the volume of the files it needs to encrypt, the ransomware uses an embedded list of file extensions to filter out irrelevant files (executables, system files, and so forth), and encrypts only specific user files likely to be of greatest value to the victim, such as documents, images, and photos.

After encryption, the malware destroys the file encryption key on the victim’s system , making it practically impossible for the user to recover the contents of the files without paying the ransom. At this point, the file encryption key typically exists only in the attacker’s C&C server, though in some cases an encrypted version of it is stored on the victim’s system. Even then, without knowing the private encryption key, it’s still practically impossible for the user to recover the file encryption key and restore access to the files.

Next, the malware shows the user a ransom message with instructions on how to pay the ransom. In some cases, the ransom message is embedded in the malware body, and in other cases, it retrieves a ransom page from the C&C server.

Analyzing the Petya Ransomware

In this section, we’ll focus on the technical analysis of the Petya hard drive encryption functionality. Petya arrives on the victim’s computer in the form of the malicious dropper, which, once executed, unpacks the payload containing the main ransomware functionality implemented as a DLL file.

Acquiring Administrator Privileges

While most ransomware doesn’t require administrator privileges, Petya does in order to be able to write data directly onto the hard drive of the victim’s system. Without this privilege, Petya wouldn’t be able to modify the contents of the MBR and install the malicious bootloader. The dropper executable file contains a manifest specifying that the executable can be launched only with administrator privileges. Listing 13-1 shows an excerpt from the dropper’s manifest.

<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
 <security>
  <requestedPrivileges>
  <requestedExecutionLevel level="requireAdministrator" uiAccess="false"/>
  </requestedPrivileges>
 </security>
</trustInfo>

Listing 13-1: An excerpt from the Petya dropper’s manifest

The security section contains the parameter requestedExecutionLevel, set to requireAdministrator . When a user attempts to execute the dropper, the OS loader checks the user’s current execution level. If it is lower than Administrator, the OS displays a dialog asking whether the user wants to run the program with elevated privileges (if the user’s account has administrative privileges) or prompts for the administrator’s credentials (if the user account doesn’t have administrative privileges). If the user decides not to grant the application administrator privileges, the dropper won’t be launched and no damage will be done to the system. If the user is lured into executing the dropper with administrator privileges, the malware proceeds to infect the system.

Petya infects the system in two steps. In step 1, it gathers information on the target system, determines the type of partitioning used on the hard drive, generates its configuration information (encryption keys and ransomware message), constructs the malicious bootloader for step 2, and then infects the computer’s MBR with the malicious bootloader and initiates a system reboot.

After the reboot the malicious bootloader is executed, triggering the second step of the infection process. The malicious MBR bootloader encrypts the hard drive sectors that host the MFT and then reboots machine one more time. After the second reboot, the malicious bootloader shows the ransom message generated in step 1.

We’ll look at these steps in more detail in the following sections.

Infecting the Hard Drive (Step 1)

Petya starts its infection of the MBR by getting the name of the file that represents the physical hard drive. On Windows operating systems, you can directly access the hard drive by executing the CreateFile API and passing it the string '\.PhysicalDriveX' as a filename parameter, where X corresponds to the index of the hard drive in the system. In the case of a system with a single hard drive, the filename of the physical hard drive is '\.PhysicalDrive0'. However, if there is more than one hard drive, the malware uses the index of the drive from which the system is booted.

Petya accomplishes this by sending the special request IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS to the NTFS volume that contains the current instance of Windows, which it gets by executing the DeviceIoControl API. This request returns an array of structures that describe all the hard drives used to host the NTFS volume. More specifically, this request returns an array of NTFS volume extents. A volume extent is a contiguous run of sectors on one disk. For instance, a single NTFS volume might be hosted on two hard drives, in which case this request will return an array of two extents. The layout of the returned structures is shown in Listing 13-2.

typedef struct _DISK_EXTENT {
DWORD         DiskNumber;
LARGE_INTEGER StartingOffset;
LARGE_INTEGER ExtentLength;
} DISK_EXTENT, *PDISK_EXTENT;

Listing 13-2: The DISK_EXTENT layout

The StartingOffset field describes the position of the volume extent on the hard drive as the offset from the beginning of the hard drive in sectors, and ExtentLength provides its length. The DiskNumber parameter contains the index of the corresponding hard drive in the system, which also corresponds to the index in the filename for the hard drive. The malware uses the DiskNumber field of the very first structure in the returned array of the volume extents to construct the filename and access the hard drive.

After constructing the filename for the physical hard drive, the malware determines the partitioning scheme of the hard drive with the request IOCTL_DISK_GET_PARTITION_INFO_EX, sent to the hard drive.

Petya is capable of infecting hard drives with either MBR-based partitions or GUID Partition Table (GPT) partitions (the layout of the GPT partition is described in Chapter 14). First we’ll look at how Petya infects MBR-based hard drives, and then we’ll describe the particulars of the GPT-based disk infection.

Infecting the MBR Hard Drive

To infect an MBR partitioning scheme, Petya first reads the MBR to calculate the amount of free disk space between the beginning of the hard drive and the beginning of the very first partition. This space is used to store the malicious bootloader and its configuration information. Petya retrieves the starting sector number of the very first partition; if it starts at a sector with an index less than 60 (0x3C), it means there’s not enough space on the hard drive, so Petya stops the infection process and exits.

If the index is 60 or more, there is enough space and the malware proceeds with constructing the malicious bootloader, which consists of two components: the malicious MBR code and the second-stage bootloader. Figure 13-2 shows the layout of the first 57 sectors of the hard drive after infection.

image

Figure 13-2: Layout of the hard drive sectors with Petya infection for MBR disks

To construct the malicious MBR, Petya combines the partition table of the original MBR with the malicious MBR code, writing the result to the very first sector of the hard drive in place of the original MBR. The original MBR is XORed with a fixed byte value of 0x37, and the result is written to sector 56 .

The second-stage malicious bootloader occupies 17 contiguous sectors (0x2E00 bytes) of the disk space and is written on the hard drive in sectors 34 to 50 . The malware also obfuscates sectors 1 to 33 by XORing its contents with the fixed byte value 0x37.

The configuration data for the malicious bootloader is stored in sector 54 and is used by the bootloader in step 2 of the infection process. We’ll dive into the details of the configuration data structure in “Encrypting with the Malicious Bootloader Configuration Data” on page 215.

Petya also uses sector 55 to store a 512-byte buffer filled with 0x37 byte values, which will be used to validate the victim-provided password and unlock the hard drive, as we’ll discuss in “Displaying the Ransom Message” on page 224.

With that, the infection of the MBR is complete. Although in Figure 13-2 sector 57 is marked “Encrypted clusters counter,” this isn’t used at this stage of infection. It will be used by the malicious bootloader code in step 2 to store the number of the MFT’s encrypted clusters.

Infecting the GPT Hard Drive

The GPT hard drive infection process is similar to MBR hard drive infection, but with a few extra steps. The first additional step encrypts the backup copy of the GPT header to make system recovery more difficult. The GPT header holds information about the layout of the GPT hard drive, and this backup copy enables the system to recover the GPT header in the event that it’s corrupted or invalid.

To find the backup GPT header, Petya reads the sector at offset 1 from the hard drive that contains the GPT header, then reaches into the field that contains the offset of the backup copy.

Once it has the location, Petya obfuscates the backup GPT header, as well as the 32 sectors preceding it, by XORing them with the fixed constant 0x37, as shown in Figure 13-3 . These sectors contain the backup GPT.

image

Figure 13-3: Layout of the hard drive sectors with Petya infection for GPT disks

Since the layout of the hard drive is different for a GPT partitioning scheme than for MBR partitioning, Petya cannot simply reuse the GPT partition table as is to construct the malicious MBR (as it does in the case of the MBR hard drive). Instead, it manually constructs an entry in the partition table of the infected MBR that represents the whole hard drive.

Apart from these points, the infection of a GPT hard drive is exactly the same as that of MBR disks. However, it’s important to note that this approach won’t work on systems with UEFI boot enabled. As you’ll learn in Chapter 14, in a UEFI boot process, UEFI code (rather than the MBR code) is responsible for booting the system. If Petya is executed on a UEFI system, it will simply render the system unbootable, because the UEFI loader won’t be able to read the encrypted GPT or its backup copy to determine the location of the OS loader.

The Petya infection will work on hybrid systems that use legacy BIOS boot code and a GPT partitioning scheme—for instance, when the BIOS Compatibility Support Mode is enabled—since on such systems the MBR sector is still used to store the first-stage system bootloader code but is modified to recognize GPT partitions.

Encrypting with the Malicious Bootloader Configuration Data

We mentioned that during step 1 of the infection process, Petya writes the bootloader configuration data to sector 54 of the hard drive. The bootloader uses this data to complete the encryption of the hard drive’s sectors. Let’s look how this data is generated.

The configuration data structure is shown in Listing 13-3.

typedef struct _PETYA_CONFIGURATION_DATA {
BYTE EncryptionStatus;
BYTE SalsaKey[32];
BYTE SalsaNonce[8];
  CHAR RansomURLs[128];
  BYTE RansomCode[343];
} PETYA_CONFIGURATION_DATA, * PPETYA_CONFIGURATION_DATA;

Listing 13-3: Petya configuration data layout

The structure starts with a flag indicating whether the MFT of the hard drive is encrypted or not. During step 1 of the infection process, the malware clears this flag, since no MFT encryption takes place at this stage. This flag is set by the malicious bootloader in step 2, once it starts the MFT encryption. Following the flag are the encryption key and initialization value (IV) used for encrypting the MFT, which we’ll go over next.

Generating Cryptographic Keys

To implement cryptographic functionality, Petya uses the public library mbedtls (“embedded TLS”), intended for use in embedded solutions. This tiny library implements a wide variety of modern cryptographic algorithms for symmetric and asymmetric data encryption, hash functions, and more. Its small memory footprint is ideal for the limited resources available at the stage of the malicious bootloader where MFT encryption takes place.

One of Petya’s most interesting features is that it uses the rare Salsa20 cipher to encrypt the MFT. This cipher generates a stream of key characters that are XORed with plaintext to obtain a ciphertext, and it takes as input a 256-bit key and a 64-bit initialization value. For the public key encryption algorithm, Petya uses ECC. Figure 13-4 shows a high-level view of the process for generating cryptographic keys.

To generate the Salsa20 encryption key, the malware first generates a password—a 16-byte random string of alphanumerical characters . Petya then expands this string into a 32-byte Salsa20 key using the algorithm presented in Listing 13-4, which encrypts the content of MFT sectors on the hard drive. The malware also generates a 64-bit nonce (initialization value) for Salsa20 using a pseudorandom-number generator.

do
{
  config_data->salsa20_key[2 * i] = password[i] + 0x7A;
  config_data->salsa20_key[2 * i + 1] = 2 * password[i];
  ++i;
} while ( i < 0x10 );

Listing 13-4: Expanding the password into a Salsa20 encryption key

Next, Petya generates the key for the ransom message as a string to be displayed on the ransom page. A victim must provide this ransom key to the C&C server in order to get the password to decrypt the MFT.

Generating the Ransom Key

Only the attacker should be able to retrieve the password from the ransom key, so in order to protect it, Petya uses the ECC public key encryption scheme, which is embedded in the malware. We will refer to this public key as the C&C public key ecc_cc_public_key.

image

Figure 13-4: Generating an encryption key

First, Petya generates a temporary ECC key pair , known as an ephemeral key, on the victim’s system to establish secure communication with the C&C server: ecc_ephemeral_pub and ecc_ephemeral_priv.

Next, it generates a shared secret (that is, a shared key) using the ECC Diffie-Hellman key agreement algorithm . This algorithm allows two parties to share a secret known only to them, and any adversary eavesdropping would not be able to deduce it. On the victim’s computer, the shared secret is computed as shared_secret = ECDHE(ecc_ephemeral_priv, ecc_cc_public_key), where ECDHE is the Diffie-Hellman key agreement routine. It takes two parameters: the private ephemeral key of the victim and the public C&C key embedded in the malware. The same secret is computed by the attacker as shared_secret = ECDHE(ecc_ephemeral_pub, ecc_cc_private_key), where it takes its own private C&C key and the victim’s public ephemeral key.

Once the shared_secret is generated, the malware computes its hash value with the SHA512 hashing algorithm and uses the first 32 bytes of the hash as an AES key : aes_key = SHA512(shared_secret)[0:32].

Then it encrypts the password as follows, using the aes_key it just derived: encrypted_password = AES(aes_key XOR password). As you can see, before encrypting the password, the malware XORs the password with the AES key.

Finally, Petya encodes the ephemeral public key and the encrypted password using a base58 encoding algorithm to obtain an ASCII string that is used as the ransom key : ransom_key = base58_encode(ecc_ephemeral_pub, encrypted_password).

Verifying the Ransom Key

If the user pays the ransom, the attacker provides the password to decrypt the data, so let’s look at how the attacker validates the ransom key to recover the victim’s password.

Once the victim sends the ransom key to the attackers, Petya decodes it using a base58 decoding algorithm and obtains the victim’s public ephemeral key and encrypted password: ecc_ephemeral_pub, encrypted_password = base58_decode(ransom_key) .

The attacker then computes the shared secret using the ECDHE key agreement protocol as described in the previous section: shared_secret = ECDHE(ecc_ephemeral_pub, ecc_cc_private_key) .

With the shared secret, the attacker can derive the AES encryption key by computing the SHA512 hash of the shared secret the same way as before: aes_key = SHA512(shared_secret)[0:32] .

Once the AES key is computed, the attacker can decrypt the password and get the victim’s password as password=AES_DECRYPT(encrypted_password) XOR aes_key.

The attacker has now obtained the victim’s password from the ransom key, which no one else can do without the attacker’s private key.

Generating Ransom URLs

As the final piece of configuration information for the second stage of the bootloader, Petya generates ransom URLs to be shown in the ransom message that tells the victim how to pay the ransom and recover the system’s data. The malware randomly generates an alphanumerical victim ID, and then combines it with the malicious domain name to get URLs in the form http://<malicious_domain>/<victim_id>. Figure 13-5 shows a couple of example URLs.

image

Figure 13-5: Petya configuration data with ransom URLs

You can see that the top-level domain name is .onion, which implies that the malware uses TOR to generate the URLs.

Crashing the System

Once the malicious bootloader and its configuration data are written onto the hard drive, Petya crashes the system and forces a reboot so that it can execute the malicious bootloader and complete the infection of the system. Listing 13-5 shows how this is done.

void __cdecl RebootSystem()
{
  hProcess = GetCurrentProcess();
  if ( OpenProcessToken(hProcess, 0x28u, &TokenHandle) )
  {
    LookupPrivilegeValueA(0, "SeShutdownPrivilege", NewState.Privileges);
    NewState.PrivilegeCount = 1;
    NewState.Privileges[0].Attributes = 2;
  AdjustTokenPrivileges(TokenHandle, 0, &NewState, 0, 0, 0);
    if ( !GetLastError() )
    {
      v1 = GetModuleHandleA("NTDLL.DLL");
      NtRaiseHardError = GetProcAddress(v1, "NtRaiseHardError");
    (NtRaiseHardError)(0xC0000350, 0, 0, 0, 6, &v4);
    }
  }
}

Listing 13-5: The Petya routine to force a system restart

Petya executes the system API routine NtRaiseHardError to crash the system, which notifies the system of a serious error preventing normal operation and requiring a reboot to avoid data loss or damage.

To execute this routine, the calling process needs the privilege SeShutdownPrivilege, which is easily obtained given that Petya is launched with administrator account rights. As shown in Listing 13-5, before executing NtRaiseHardError, Petya adjusts the current privileges by calling AdjustTokenPrivileges .

Encrypting the MFT (Step 2)

Now let’s focus on the second step of the infection process. The bootloader consists of two components: a malicious MBR and the second-stage bootloader (which we’ll refer to as the malicious bootloader in this section). The only purpose of the malicious MBR code is to load the second-stage bootloader into memory and execute it, so we’ll skip an analysis of the malicious MBR. The second-stage bootloader implements the most interesting functionality of the ransomware.

Finding Available Disks

Once the bootloader receives control, it must gather information on the available disks in the system. To do so, it relies on the well-known INT 13h service, as shown in Listing 13-6.

mov     dl, [bp+disk_no]
mov     ah, 8
  int     13h

Listing 13-6: Using INT 13h to check the availability of disks in system

To check for the availability and size of the hard drives, the malware stores the index numbers in the dl register and then executes INT 13h. The disks are assigned index numbers sequentially, so Petya finds hard drives in the system by checking disk indexes from 0 through 15. Next, it moves the value 8 into the ah register , which denotes the “get current drive parameters” function of INT 13h. Then the malware executes INT 13h. After execution, if ah is set to 0, the specified disk is present in the system and the dx and cx registers contain disk size information. If the ah register isn’t equal to 0, it means that the disk with the given index doesn’t exist in the system.

Next, the malicious bootloader reads the configuration data from sector 54 and checks whether the MFT of the hard drives is encrypted by looking at the very first byte in the read buffer, which corresponds to the EncryptionStatus field in the configuration data. If the flag is clear—meaning that the contents of the MFT aren’t encrypted—the malware proceeds to encrypt the MFT of the hard drives available in the system, completing the infection process. If the MFT is already encrypted, the malicious bootloader shows the ransom message to the victim. We’ll discuss the ransom message shortly, but first, we’ll focus on how the malicious bootloader performs the encryption.

Encrypting the MFT

If the EncryptionStatus flag of the configuration data is clear (that is, set to 0), the malware reads the Salsa20 encryption key and the IV from the SalsaKey and SalsaNonce parameters, respectively, and uses them to encrypt the hard drive data. The bootloader then sets the EncryptionStatus flag and destroys SalsaKey in the section 54 configuration data to prevent decryption of the data.

Next, the bootloader reads sector 55 of the infected hard drive, which will later be used to validate the password entered by the victim. At this point, this sector occupies 0x37 bytes. Petya encrypts this sector with the Salsa20 algorithm using the key and the IV read from the configuration data, then writes the result back into sector 55.

Now the malicious bootloader is ready to encrypt the MFT of the hard drives in the system. The encryption process extends the duration of the boot process considerably, so in order to avoid arousing suspicion, Petya displays a fake chkdsk message, as shown in Figure 13-6. The system utility chkdsk is used to repair filesystems on the hard drive, and it’s not unusual to see a chkdsk message after a system crash. With the fake message on the screen, the malware runs the following algorithm for each hard drive available in the system.

image

Figure 13-6: A fake chkdsk message

First, the malware reads the MBR of the hard drive and iterates through the MBR partition table, looking for available partitions. It checks the parameter describing the type of the filesystem used in the partition and skips all the partitions with a type value other than 0x07 (indicating that the partition contains an NTFS volume), 0xEE, and 0xEF (indicating that the hard drive has a GPT layout). If the hard drive does have a GPT layout, the malicious boot code obtains the location of the partition from the GPT partition table.

Parsing the GPT Partition Table

In the case of GPT partition tables, the malware takes an additional step to find partitions on the hard drive: it reads the GPT partition table from the hard drive, starting at the third sector. Each entry in the GPT partition table is 128 bytes long and is structured as shown in Listing 13-7.

typedef struct _GPT_PARTITION_TABLE_ENTRY {
  BYTE PartitionTypeGuid[16];
  BYTE PartitionUniqueGuid[16];
  QWORD PartitionStartLba;
  QWORD PartitionLastLba;
  QWORD PartitionAttributes;
  BYTE PartitionName[72];
} GPT_PARTITION_TABLE_ENTRY, *PGPT_PARTITION_TABLE_ENTRY;

Listing 13-7: Layout of the GPT partition table entry

The very first field, PartitionTypeGuid, is an array of 16 bytes containing the identifier of the partition type, which determines what kind of data the partition is intended to store. The malicious boot code checks this field to filter out all partition entries except those with a PartitionTypeGuid field equal to {EBD0A0A2-B9E5-4433-87C0-68B6B72699C7}; this type is known as a basic data partition for the Windows operating system, used to store NTFS volumes. This is exactly what the malware is interested in.

If the malicious boot code identifies a basic data partition, it reads the PartitionStartLba and PartitionLastLba fields that contain the address of the very first and last sectors of the partition, respectively, to determine the location of the target partition on the hard drive. Once the Petya boot code has the coordinates of the partition, it proceeds to the next step.

Locating the MFT

To locate the MFT, the malware reads the VBR of the selected partitions from the hard drive (the layout of the VBR is described in detail in Chapter 5). The parameters of the filesystem are described in the BIOS parameter block (BPB), the structure of which is shown in Listing 13-8.

typedef struct _BIOS_PARAMETER_BLOCK_NTFS {
  WORD SectorSize;
BYTE SectorsPerCluster;
  WORD ReservedSectors;
  BYTE Reserved[5];
  BYTE MediaId;
  BYTE Reserved2[2];
  WORD SectorsPerTrack;
  WORD NumberOfHeads;
  DWORD HiddenSectors;
  BYTE Reserved3[8];
  QWORD NumberOfSectors;
QWORD MFTStartingCluster;
  QWORD MFTMirrorStartingCluster;
  BYTE ClusterPerFileRecord;
  BYTE Reserved4[3];
  BYTE ClusterPerIndexBuffer;
  BYTE Reserved5[3];
  QWORD NTFSSerial;
  BYTE Reserved6[4];
} BIOS_PARAMETER_BLOCK_NTFS, *PBIOS_PARAMETER_BLOCK_NTFS;

Listing 13-8: Layout of the BIOS parameter block in the VBR

The malicious boot code checks the MFTStartingCluster , which specifies the location of the MFT as an offset from the beginning of the partition in clusters. A cluster is the minimal addressable unit of storage in the filesystem. The size of the cluster may change from system to system and is specified in the SectorsPerCluster field , which is also checked by the malware. For instance, the most typical value for this field for NTFS is 8, making it 4,096 bytes given that the sector size is 512 bytes. Using these two fields, Petya computes the offset of the MFT from the beginning of the partition.

Parsing the MFT

The MFT is laid out as an array of items, each describing a particular file or directory. We won’t go into the details of the MFT format, as it is complex enough to warrant at least a chapter of its own. Instead, we’ll provide only the information necessary for understanding Petya’s malicious bootloader.

At this point, the malware has the starting address of the MFT from MFTStartingCluster, but to get the exact locations, Petya also needs to know the size of the MFT. Moreover, the MFT may not be stored as a contiguous run of sectors on the hard drive, but rather partitioned into small runs of sectors spread out over the hard drive. To get information on the exact location of the MFT, the malicious code reads and parses the special metadata file $MFT, found in the NTFS metadata files that correspond to the first 16 records of the MFT.

Each of these files contains essential information for ensuring the correct operation of the filesystem:

$MFT Self-reference to the MFT, containing information on the size and location of the MFT on the hard drive

$MFTMirr Mirror of the MFT containing copies of the first 16 records

$LogFile The logfile for the volume with the transaction data

$BadClus A list of all the corrupted clusters on the volume marked as “bad”

As you can see, the very first metadata file, $MFT, contains all the information necessary for determining the exact location of the MFT on the hard drive. The malicious code parses this file to get the location of the contiguous runs of sectors, then encrypts them using the Salsa20 cipher.

Once all the MFTs on the hard drives present in the system are encrypted, the infection process is complete, and the malware executes INT 19h to start the boot process all over again. This interrupt handler makes the BIOS boot code load the MBR of the bootable hard drive in memory and execute its code. This time, when the malicious boot code reads the configuration information from sector 54, the EncryptionStatus flag is set to 1, indicating that the MFT encryption is complete, and the malware proceeds with displaying the ransom message.

Displaying the Ransom Message

The ransom message displayed by the boot code is shown in Figure 13-7.

image

Figure 13-7: The Petya ransom message

The message informs the victim that their system has been compromised by Petya ransomware and that the hard disk is encrypted with a military-grade encryption algorithm. It then provides instructions for unlocking the data. You can see the list of URLs that Petya generated in the first step of the infection process. The pages at these URLs contain further instructions for the victim. The malware also displays the ransom code the user needs to enter to get the password for decryption.

The malware generates the Salsa20 key from the password entered on the ransom page and attempts to decrypt sector 55, used for the key verification. If the password is correct, the decryption of sector 55 results in a buffer occupying 0x37 bytes. In this case, the ransomware accepts the password, decrypts the MFTs, and restores the original MBR. If the password is incorrect, the malware shows the message "Incorrect key! Please try again."

Wrapping Up: Final Thoughts on Petya

This concludes our discussion of the Petya infection process, but we have a few final notes on interesting aspects of its approach.

First, unlike other ransomware that encrypts user files, Petya works with the hard drive in low-level mode, reading and writing raw data, and thus requires administrator privileges. However, it doesn’t exploit any local privilege escalation (LPE) vulnerabilities, instead relying on manifest information embedded in the malware, as discussed earlier in this chapter. Thus, if a user chooses not to grant the application administrator privileges, the malware won’t be launched due to the manifest requirements. And even if it were executed without administrative privileges, Petya couldn’t open the handle for the hard drive device and so couldn’t do any harm. In that case, the CreateFile routine that Petya used to obtain the handle for the hard drive would return a value of INVALID_HANDLE, resulting in an error.

To circumvent this limitation, Petya was often distributed with another ransomware: Mischa. Mischa is an ordinary ransomware that encrypts user files rather than the hard drive and doesn’t require administrator access rights to the system. If Petya failed to get administrator privileges, the malicious dropper executed Mischa instead. Discussions on Mischa are outside the scope of this chapter.

Second, as already discussed, rather than encrypting the contents of the files on the hard drive, Petya encrypts the metadata stored in the MFT so that the filesystem can’t get information on the file locations and attributes. Thus, even though the file contents aren’t encrypted, victims still cannot access their files. This means the contents of the files may potentially be recovered through data recovery tools and methods. Such tools are frequently used in forensic analysis to recover information from corrupted images.

Finally, as you may already have gleaned, Petya is quite a complex piece of malware written by skilled developers. The functionality it implements implies a deep understanding of filesystems and bootloaders. This malware marks another step in ransomware evolution.

Analyzing the Satana Ransomware

Now, let’s take a look at another example of ransomware that targets the boot process: Satana. Whereas Petya infects only the hard drive’s MBR, Satana also encrypts the victim’s files.

Moreover, the MBR isn’t Satana’s main infection vector. We’ll demonstrate that the malicious bootloader code written in place of the original MBR contains flaws and was likely under development at the time of Satana’s distribution.

In this section, we’ll focus only on the MBR infection functionality, since user-mode file encryption functionality is beyond the scope of this chapter.

The Satana Dropper

Let’s start with the Satana dropper. Once unpacked in memory, the malware copies itself into a file with a random name in the TEMP directory and executes the file. Satana requires administrator privileges to infect the MBR and, like Petya, doesn’t exploit any LPE vulnerabilities to gain elevated privileges. Instead, it checks the privilege level of its process using the setupapi!IsUserAdmin API routine, which in turn checks whether the security token of the current process is a member of the administrator group. If the dropper doesn’t have the privileges to infect the system, it executes the copy in the TEMP folder and attempts to execute the malware under the administrator account by using the ShellExecute API routine with a runas parameter, which displays a message asking the victim to grant the application administrator privileges. If the user chooses No, the malware calls ShellExecute with the same parameters over and over again until the user chooses Yes or kills the malicious process.

The MBR Infection

Once Satana gains administrator privileges, it proceeds with infecting the hard drive. Throughout the infection process, the malware extracts several components from the dropper’s image and writes them to the hard drive. Figure 13-8 shows the layout of the first sectors of a hard drive infected by Satana. In this section, we’ll describe each element of the MBR infection in detail. We assume that sector indexing starts with 0, to simplify the explanation.

image

Figure 13-8: Layout of the hard drive with Satana infection

To access the hard drive in low-level mode, the malware uses the same APIs as Petya: CreateFile, DeviceIoControl, WriteFile, and SetFilePointer. To open a handle to a file representing the hard drive, Satana uses the CreateFile routine with the string '\.PhysicalDrive0' as a FileName argument. Then the dropper executes the DeviceIoControl routine with the IOCTL_DISK_GET_DRIVE_GEOMETRY parameter to get the hard drive parameters, such as the total number of sectors and the sector size in bytes.

NOTE

The method of using '\.PhysicalDrive0' to obtain a handle to the hard drive isn’t 100 percent reliable, as it assumes that the bootable hard drive is always at index 0. Though this is the case for most systems, it is not guaranteed. In this regard, Petya is more careful, as it determines the index of the current hard drive dynamically at infection time, while Satana uses a hardcoded value.

Before proceeding with the infection of the MBR, Satana ensures there is enough free space to store the malicious bootloader components on the hard drive between the MBR and the first partition by enumerating the partitions and locating the first partition and its starting sector. If there are fewer than 15 sectors between the MBR and the first partition, Satana quits the infection process and continues with encrypting user files. Otherwise, it attempts to infect the MBR.

First, Satana is supposed to write a buffer with user font information in sectors starting at sector 7 . The buffer can take up to eight sectors of the hard drive. The information written to these sectors is intended to be used by the malicious bootloader to display the ransom message in a language other than the default (English). However, we haven’t seen it used in the Satana samples we’ve analyzed. The malware didn’t write anything at sector 7 and therefore used the default English language to display the ransom message.

Satana writes the ransom message to display to the user at boot time in sectors 2 to 5 , written in plaintext without encryption.

Then the malware reads the original MBR from the very first sector and encrypts it by XORing with a 512-byte key, generated at the stage of infection using a pseudorandom-number generator. Satana fills a buffer of 512 bytes with random data and XORs every byte of the MBR with the corresponding byte in the key buffer. Once the MBR is encrypted, the malware stores the encryption key in sector 6 and the encrypted original MBR in sector 1 of the hard drive.

Finally, the malware writes the malicious MBR to the very first sector of the hard drive . Before overwriting the MBR, Satana encrypts the infected MBR by XORing it with a randomly generated byte value and writes the key at the end of the infected MBR so that the malicious MBR code can use this key to decrypt itself at system bootup.

This step completes the MBR infection process, and Satana continues with user file encryption. To trigger the execution of the malicious MBR, Satana reboots the computer shortly after encrypting the user files.

Dropper Debug Information

Before continuing our analysis of the malicious MBR code, we’d like to mention a particularly interesting aspect of the dropper. The samples of Satana we analyzed contained a lot of verbose debug information documenting the code implemented in the dropper, similar to our findings from the Carberp trojan discussed in Chapter 11.

This presence of debug information in the dropper reinforces the notion that Satana was in development when we were analyzing it. Satana uses the OutputDebugString API to output debugging messages, which you can see in the debugger or by using other tools that intercept debug output. Listing 13-9 shows an excerpt from the malware’s debug trace intercepted with the DebugMonitor tool.

00000042 27.19946671  [2760] Engine: Try to open drive \.PHYSICALDRIVE0
00000043    27.19972229  [2760] Engine: \.PHYSICALDRIVE0 opened
00000044 27.21799088  [2760] Total sectors:83875365
00000045    27.21813583  [2760] SectorSize: 512
00000046    27.21813583  [2760] ZeroSecNum:15
00000047    27.21813583  [2760] FirstZero:2
00000048    27.21813583  [2760] LastZero:15
00000049 27.21823502  [2760] XOR key=0x91
00000050    27.21839333  [2760] Message len: 1719
00000051 27.21941948  [2760] Message written to Disk
00000052    27.22294235  [2760] Try write MBR to Disk: 0
00000053 27.22335243  [2760] Random sector written
00000054    27.22373199  [2760] DAY: 2
00000055 27.22402954  [2760] MBR written to Disk# 0

Listing 13-9: Debug output of the Satana dropper

You can see in this output that the malware tries to access '\.PhysicalDrive0' to read and write sectors from and to the hard drive. At , Satana obtains the parameters of the hard drive: size and total number of sectors. At , it writes the ransom message on the hard drive and then generates a key to encrypt the infected MBR . It stores the encryption key and then overwrites the MBR with the infected code . These messages reveal the malware’s functionality without requiring us to do hours of reverse-engineering work.

The Satana Malicious MBR

Satana’s malicious bootloader is relatively small and simple compared to Petya’s. The malicious code is contained in a single sector and implements the functionality for displaying the ransom message.

Once the system boots, the malicious MBR code decrypts itself by reading the decryption key from the end of the MBR sectors and XORing the encrypted MBR code with the key. Listing 13-10 shows the malicious MBR decryptor code.

seg000:0000    pushad
seg000:0002    cld
seg000:0003 mov     si, 7C00h
seg000:0006    mov     di, 600h
seg000:0009    mov     cx, 200h
seg000:000C rep movsb
seg000:000E    mov     bx, 7C2Ch
seg000:0011    sub     bx, 7C00h
seg000:0015    add     bx, 600h
seg000:0019    mov     cx, bx
seg000:001B decr_loop:
seg000:001B    mov     al, [bx]
seg000:001D xor     al, byte ptr ds:xor_key
seg000:0021    mov     [bx], al
seg000:0023    inc     bx
seg000:0024    cmp     bx, 7FBh
seg000:0028    jnz     short loc_1B
seg000:002A jmp     cx

Listing 13-10: Satana’s malicious MBR decryptor

First, the decryptor initializes the si, di, and cx registers to copy the encrypted MBR code to another memory location, and then it decrypts the copied code by XORing it with the byte value . Once the decryption is done, the instruction at transfers the execution flow to the decrypted code (address in cx).

If you look closely at the line copying the encrypted MBR code to another memory location, you may spot a bug: the copying is done by the rep movsb instruction , which copies the number of bytes specified by the cx register from the source buffer, whose address is stored in ds:si, to the destination buffer, whose address is specified in the es:di registers. However, the segment registers ds and es aren’t initialized in the MBR code. Instead, the malware assumes that the ds (data segment) register has exactly the same value as the cs (code segment) register (that is, that ds:si should be translated to cs:7c00h, which corresponds to the address of the MBR in memory). However, this isn’t always true: the ds register may contain a different value. If that is the case, the malware will attempt to copy the wrong bytes from the memory at the ds:si address—which is completely different from the location of the MBR. To fix the bug, the ds and es registers need to be initialized with the value of the cs register, 0x0000 (since the MBR is loaded at address 0000:7c00h, the cs register contains 0x0000).

The functionality of the decrypted code is straightforward: the malware reads the ransom message from sectors 2 to 5 into a memory buffer, and if there is a font written to sectors 7 to 15, Satana loads it using the INT 10h service. The malware then displays the ransom message using the same INT 10h service and reads input from the keyboard. Satana’s ransom message is shown in Figure 13-9.

At the bottom, the message prompts the user to enter the password to unlock the MBR. There’s a trick, though: the malware doesn’t actually unlock the MBR upon entry of the password. As you can see in the password verification routine presented in Listing 13-11, the malware doesn’t restore the original MBR.

seg000:01C2 mov     si, 2800h
seg000:01C5    mov     cx, 8
seg000:01C8 call    compute_checksum
seg000:01CB    add     al, ah
seg000:01CD cmp     al, ds:2900h
seg000:01D1 infinit_loop:
seg000:01D1 jmp     short infinit_loop

Listing 13-11: Satana password verification routine

image

Figure 13-9: Satana ransom message

The compute_checksum routine computes a checksum of the 8-byte string stored at address ds:2800h and stores the result in the ax register. Then the code compares the checksum with the value at address ds:2900h . However, regardless of the outcome of the comparison, the code loops infinitely at , meaning the execution flow doesn’t go any further from this point, even though the malicious MBR contains code for decrypting the original MBR and restoring it at the very first sector. The victim who paid the ransom to unlock their system isn’t actually able to do so without system recovery software. This is a vivid reminder that victims of ransomware shouldn’t pay the ransom, as no one can guarantee that they’ll retrieve their data.

Wrapping Up: Final Thoughts on Satana

Satana is an example of a ransomware program still catching up with modern ransomware trends. The flaws observed in the implementation and the abundance of debugging information suggest that the malware was in development when we first saw it in the wild.

Compared to Petya, Satana lacks sophistication. Despite the fact that it never restores the original MBR, its MBR infection approach isn’t as damaging as Petya’s. The only boot component affected by Satana is the MBR, making it possible for the victim to restore access to the system by repairing the MBR using the Windows installation DVD, which can recover information on the system partitions and rebuild a new MBR with a valid partition table.

Victims can also restore access to the system by reading the encrypted MBR from sector 1 of the MBR and XORing it with the encryption key stored in sector 6. This retrieves the original MBR, which should be written to the very first sector to restore access to the system. However, even if a victim manages to restore access to the system by recovering the MBR, the contents of the files encrypted by Satana will still be unavailable.

Conclusion

This chapter covers some of the major evolutions in modern ransomware. Attacks on both home users and organizations constitute a modern trend in the malware evolution, one that the antivirus industry has had to struggle to catch up with after the outbreak of trojans encrypting the contents of user files in 2012.

Although this new trend in ransomware is gaining in popularity, developing bootkit components requires different skills and knowledge than developing trojans for encrypting user files. The flaws in Satana’s bootloader component are a clear example of this gulf of skills.

As we’ve seen with other malware, this arms race between malware and security software development has forced ransomware to evolve and adopt bootkit infection techniques to stay under the radar. As more and more ransomware has emerged, many security practices have become routine, such as backing up data—one of the best protection methods against a wide variety of threats, especially ransomware.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset