Decrypting the Petya Ransomware

Petya is a relatively new ransomware variant that first appeared on the cyber-crime scene at the beginning of 2016.
While Petya doesn’t have an impressive infection rate like other ransomware such as CryptoWall or TeslaCrypt, it was immediately flagged as the next step in ransomware evolution.

Petya’s developers were not content with merely encrypting all the important files found on the victim’s hard-drive but also decided to hold the entire hard-drive’s content hostage by encrypting its Master-File-Table (MFT), rendering the entire file system useless until the ransom is paid.

This is what caught the attention of our research group and made us decide to dive deeper into the encryption logic implementation to get a better understanding of this new type of threat.

Our research revealed multiple flaws in the encryption algorithm implementation providing a method of restoring all data encrypted by Petya, which were further confirmed by recent posts by college researchers who arrived at the same conclusion and provided a web-service for decrypting the encrypted files.

This post provides an overview of Petya’s operations as well as a detailed explanation of its encryption flaws.


Petya can be best described as a three stage ransomware, where each stage has its own dedicated functionality:

  • Stage 0 “MBR Overwrite” – Overwrite the hard-drive’s Master Boot Record and implanting custom boot-loader.
  • Stage 1 “MFT Encryption” – Use the custom boot-loader introduced in Stage 0 to encrypt all Master-File-Table (MFT) records, which renders the file system completely unreadable.
  • Stage 2 “Ransom Demand” – Display the Petya logo and the ransom note detailing what must be done to decrypt the hard-drive.

Stage 0 – “MBR Overwrite”

After querying for the system drive name (for example “\\.\PhysicalDrive1”), the MBR is identified by directly using the DeviceIOControl code API IOCTL_DISK_GET_PARTITION_INFO_EX.
The overwriting operations are only performed for partitions returning the values PARTITION_STYLE_MBR or PARTITION_STYLE_GPT.

fig 1

Petya then generates an 8-byte Initialization Vector (IV) as well as a 16-byte random key which is further expanded to a 32-byte encryption key with this simple algorithm:

fig 2

Both these values will be used further in the encryption process performed at Stage 1.
At this point, Petya encrypts the original MBR by XORing its content with 0x37. It then saves this encrypted value to the 56th Disk Sector.
Petya continues to encrypt disk sectors 1-34 (the physical range is 0x200h-0x4400h) with the exact same method.

fig 3

Petya then implants its own bootstrap code, while keeping the original partition entries. This bootstrap code is responsible for executing the next stages. It also creates an “ONION_SECTOR” structure which is written to the 54th disk sector. This section contains the encryption key and IV generated earlier as well as other information required to identify the victim host and decrypt the drive.

fig 4

Petya also fills the 55th drive sector with the byte 0x37. This value is checked after the decryption process is complete to validate a correct decryption process.
After Stage 0 execution is over, the drive’s sector map looks like this:

fig 5

Finally, Petya forces a system reboot by using ntdll!NtRaiseHardError API, which is also where the ransomware’s first flaw resides.

If you can stop the execution process after Petya was executed but before the system has completely restarted, you can simply reverse the operations that Petya performed and restore the drive to its previous state.
Additionally, you may be able to read the encryption keys of the ONION_SECTOR structure;  if the drive is encrypted accidentally, you can still extract the encryption keys and decrypt it with this code:

fig 6

Stage 1 “MFT Encryption”

Stage 1 is loaded by the bootstrap code implanted in Stage 0. Its first operation is to try and locate the ONION_SECTOR structure so it can verify that Stage 0 was successfully completed.
If this check returns a positive value, Petya begins enumerating the drive’s Master File Table (MFT) records, while masquerading as a legitimate file repair application.

fig 7

Petya uses an encryption method called SALSA20, which is where its second and more serious encryption flaw resides.

The original SALSA20 implementation uses a 32-byte encryption key and an 8-byte initialization vector to produce the final 512-bit key-stream:

fig 8

Petya’s implementation of this simple encryption key generation is seriously flawed, which allows us to predict 256 bits out of the total 512 used in the key-stream.
With this knowledge, we can brute force the encryption in a very reasonable time-frame, breaking the encryption and subverting Petya’s malicious actions without paying any ransom at all.

Encryption Flaw 1

The first encryption flaw is located in the variable type containing the 64-bit stream position.
It appears that Petya’s developers mistakenly used a 32-bit value, forcing the high part of the stream position buffer to have the predictable constant value of 0.

Encryption Flaw 2

Due to another developer mistake, the rotate-left (ROL) operation performed by the SALSA20 algorithm was incorrectly implemented.
The original implementation uses uint32_t as input and return values, as shown in this C language implementation:

fig 9

However, Petya’s ROL implementation uses the exact same algorithm (including the constant value 32) but with uint16_t value types.

fig 10

Encryption Flaw 3

The hashing function used in the SALSA20 responsible for producing a key stream (core function) receives a 512-bit input key buffer which is split into two internal 256-bit buffers, as shown in this source code:

fig 11

Petya’s implementation of the same code uses the exact same function, but the internal buffers are wrongly downsized to 16-bit values, producing code similar to this:


fig 12

This flaws forces Petya to generate a 512-bit key stream containing 256 bits of constant and predictable values.

The illustration below shows the entire key stream. The bytes in gray represent the non-used values.

fig 13

Stage 2 “Ransom Demand”

This is Petya’s most  straight-forward stage. After MBR and MFT encryption is complete, the computer boots and displays the scary skull logo seen below. After the victim presses any key, the ransom note containing instructions for payment and decryption is displayed.

fig 14


While Petya is not the most prevalent ransomware in the cybercrime scene and its implementation is seriously flawed, it does mark a potential change in the approach ransomware authors are willing to take to reach their final goal. Further, we can likely expect to see better implemented ransomware which breaks borders of traditional OS execution to move into low-level system implementations.