
Positive Technologies expert Dmitry Sklyarov presented a comparative analysis of the notorious extortioner virus NotPetya, which attacked the company this Tuesday, with a sample of Petya from 2016 and shared his observations on the possibility of recovering the data encrypted by them.
We investigated the parts of two viruses responsible for MFT encryption. This encryption is performed when the ransomware has administrative rights.
What makes NotPetya
At the moment of infection (still under Windows), the virus writes code to the beginning of the disk, which will be launched after a reboot, and in certain sectors it writes its configuration, data for testing and the original MBR.
')
First of all, let's take a look at the 0x20 sector of the disk, which is something like a “config” for a particular machine. When infected, the following values ​​are recorded in sector 0x20:
- A sign that the MFT was not encrypted (value 0)
- EncryptionKey (32-byte random sequence)
- Nonce (random sequence with a length of 8 bytes)
- Personal installation key (a random sequence of 60 characters in length from the alphabet "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz")
Random data is obtained through the function CryptGenRandom, which is considered to be cryptographically stable.
In sector 0x21 512 bytes are written with a value of 0x07.
In sector 0x22, the original MBR is written, in which each byte is XOREN with a value of 0x07.
After the first reboot, the MFT is encrypted. Before that:
- read sector 0x20,
- set the sign of encryption MFT (value 1),
- EncryptionKey is copied to a temporary buffer,
- field with EncryptionKey is overwritten by zero bytes
- sector 0x20 is written to disk,
- sector 0x21 is read (all 0x07),
- its contents are encrypted on EncryptionKey + Nonce,
- sector 0x21 is written to disk.
Then the MFT sectors are encrypted on the same EncryptionKey + Nonce. The code of the encryption algorithm is very similar to the Salsa20 algorithm, but there are differences. Instead of the "expand 32-byte k" constant, the "-1nvalid s3ct-id" constant is used. And while I was not able to repeat the results of encryption in a known manner. Perhaps they have an error somewhere, which seems to be confirmed by
this post .
The Salsa20 algorithm is considered
persistent .
When everything is encrypted, the machine reboots again, the text with the ransom request is displayed, and it is proposed to enter the decryption key.
The key must be a string of characters from the “0123456789abcdef” set with a length of 32. This string is run through a certain function that accepts an arbitrary number of bytes and gives 32 bytes. Presumably this is a hash function SPONGENT (must be checked). Then the output is cycled through the same function 128 times, and this result is accepted as an EncryptionKey. To verify the correctness of the key, an attempt is made to decrypt the contents of sector 0x21, and if the expected plaintext is there (all 0x07), the MFT decryption and MBR recovery process starts.
Can attackers decrypt user files?
In my opinion, the possibility of recovery after payment was not provided by the authors. And that's why:
- The personal installation key, which must be communicated to the authors of the virus after paying the ransom, has nothing to do with EncryptionKey. Both are random data. It is impossible to get another from one unless the attackers know something about CryptGenRandom. Another option is that they should send a pair of EncryptionKey + Personal installation key to their server, but no one reported about such activity (and I did not see it in the code, although this is not excluded by 100%).
- If I guessed with the SPONGENT hash function, the decryption key must be the output of the hash, and in order to calculate what the user must enter, you must reverse this hash (129 times), which is hardly realizable on modern technology.
- Entropy EncryptionKey is 32 * 8 == 256 bits. The entropy of the hex key entered by the user is 32 * 4 == 128 bits. Any operation can only reduce entropy. Of the 32 hexadecimal characters, it is impossible to get 32 ​​bytes with certain values.
Differences from Petya sample January 9, 2016
Petya didn't want to infect my test machine. Maybe he needs a network or something else. I had to dump the memory.
I did not have time to see the code that forms the sectors used from the MBR installed by the malware, but I looked at the screenshots and the code that runs after the reboot.
Differences:
- Sectors are used 0x36-0x39 (against 0x20-0x23 for NotPetya).
- Most of the service functions (text output, read / write sectors) are identical to Petya.
- There is a function and a line to display a banner with a skull. NotPetya has a very similar function too, but probably it is never called and the lines are reset.
- The length of the Personal installation key is 90 characters (15 groups of 6 characters) versus 60 for NotPetya. Using an alphabet of 58 characters, you can encode a maximum of 527 bits of information (versus 351 for NotPetya).
- In the Petya dump, the lines secp256k1 and secp192k1 are visible, which pushes the idea that the Personal installation key is derived from EncryptionKey, and is calculated using cryptography on elliptic curves.
- The key entered by the user to start decryption must be a string from the alphabet “123456789abcdefghijkmnopqrstuvwxABCDEFGHJKLMNPQRSTUVWX” with a length of 16 characters.
- There is nothing like SPONGENT (or some other hash).
- In Salsa20, the original constant expand 32-byte k is used. At the same time, the function code is almost identical, and if the Petya code was probably generated by the compiler (optimization on repeated characters worked), then in NotPetya, it seems, they simply replaced the constants.
Petya:

NotPetya:

I would suggest that there was another Petya pattern, on the basis of which NotPetya was created by replacing constants and strings.
Once again, NotPetya most likely did not provide for the possibility of decrypting the files of their victims, and in Petya everything was fine with that. As for self-recovery disk - it may be real. Both viruses have very similar errors in the implementation of encryption algorithms, which leads to the possibility of quick selection of the encryption key and recovery of all encrypted data. In 2016, researchers
described a Petya encrypted data recovery
method without paying a ransom.
UPD
Among the different versions of the Petya malware from 2016, which, under different colors (
1 ,
2 ), performed a duet with extortioner mischa and also in
this form, you should pay attention to
PetyaGoldenEye.malware , first sent to VirusTotal last December.
The code that NotPetya writes to the beginning of the disk when it is infected, and which runs from the MBR, is extremely similar to the code written by PetyaGoldenEye: SHA256: b5ef16922e2c76b09edd71471dd837e89811c5e658406a8495c1364d0d9dc690.
NotPetya found differences from PetyaGoldenEye:
- Many text lines have been changed (the text of the ransom message has been corrected, the picture with the skull has been removed);
- Changed the offset to some lines (the beginning of the lines "moved out" because of the change in the size of messages);
- In the function at address 0000: 86E0, a piece of code that is responsible for displaying a banner (blinking “skull with bones”) is jumped (never executed) before pressing any key;
- There's also changed the color of the banner from yellow (0xE) to red (0xC), but the banner is still not shown;
- At address 0000: 848E, removed (replaced by three NOP instructions) a call to the function that clears the keyboard buffer (not required, since it was not expected to press);
- In the function at address 0000: 96D4 (expand for Salsa20), the initial state of the string is replaced with “expand 32-byte k” to “-1nvalid s3ct-id”;
- In function at address 0000: 998E (permute for SPONGENT), the initial value of LFSR (linear-feedback shift register) is changed, instead of 0x9E, 0xA3 is used.
No more code changes found. Now look at cryptography.
SPONGENT Hash Function
The code implementing the SPONGENT was probably taken
from here . If in the permute () function we replace the initial value of the variable “lfsr” and rewrite the spongent () function so that it accepts not a Null-terminated string, but a pointer to an array and an array length, the code is equivalent to that used in NotPetya.
It is noteworthy that the initial value LFSR == 0x9E (as described in the original SPONGENT-256/256/16 specification) gives 140 rounds, and the initial value 0xA3 used in NotPetya gives 152 rounds (cryptographic resistance is slightly increased).
Encryption function Salsa20
The code implementing Salsa20 was probably borrowed
from here . If in the s20_expand32 () function we replace the value of the array “o” and replace the body of the function s20_littleendian () with the string “return * (__ int16 *) b;”, we get the code equivalent to that used in NotPetya.
Due to the fact that the s20_littleendian () function is implemented incorrectly (probably due to an incorrect type definition or a 16-bit compiler error), the values ​​of two out of every four bytes in the keystream array are not used at all. This actually makes the encryption key 128-bit, not 256-bit. However, a complete search of the 128-bit key space at the modern level of technology is considered an unsolvable task.
Conclusions and assumptions
The authors of Petya implemented MFT encryption using persistent (although not very common) cryptographic primitives, the code of which was borrowed from GitHub repositories.
In the process of preparing the first version (Petya Red),
mistakes were made, and this allowed deciphering the data without paying the ransom.
In subsequent versions (Petya Green, PetyaGoldenEye), the errors were partially corrected, and only a type conversion error remained, reducing the effective key length by half. Attempts were made to realize an attack on the corrected
version , but they did not lead to success.
The authors of NotPetya probably did not have access to the Petya source texts and could not make the necessary changes to them and recompile the project. They took the existing code from PetyaGoldenEye as a basis, analyzed it using a disassembler, and made changes using a hex editor.
Finding ways to get back files encrypted with NotPetya continues.