Back to Home

Compare #NotPetya and #Petya - is it possible to decrypt your files? Updated

Positive Technologies expert Dmitry Sklyarov presented a comparative analysis of the sensational NotPetya ransomware virus that attacked the company this Tuesday · with a 2016 Petya sample and ...

Compare #NotPetya and #Petya - is it possible to decrypt your files? Updated



    Positive Technologies expert Dmitry Sklyarov presented a comparative analysis of the sensational NotPetya ransomware virus that attacked the company this Tuesday with a 2016 Petya sample and shared his observations on the possibility of recovering the data encrypted by them.

    We examined the parts of two viruses that are responsible for MFT encryption. This encryption is performed if the ransomware has administrator rights.

    What does NotPetya do


    At the time of infection (even under Windows), the virus writes code to the beginning of the disk that will be launched after reboot, and in certain sectors its configuration, data for verification and the original MBR.

    First of all, let's look at the sector 0x20 of the disk, which is something like a “config” for a specific machine. When infected, the following values ​​are written to the 0x20 sector:

    - A sign that the MFT was not encrypted (value 0)
    - EncryptionKey (random sequence of 32 bytes long)
    - Nonce (random sequence of 8 bytes long)
    - Personal installation key (random sequence of 60 characters from the alphabet “123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz”)

    Random data is obtained through the CryptGenRandom function, which is considered cryptographically secure.

    512 bytes with a value of 0x07 are written to sector 0x21.

    In sector 0x22, the original MBR is written, in which each byte is XORen with a value of 0x07.

    After the first reboot, MFT is encrypted. Before this:

    - sector 0x20 is read,
    - the MFT encryption flag is set (value 1),
    - EncryptionKey is copied to the temporary buffer,
    - the field with EncryptionKey is erased by zero bytes
    - sector 0x20 is written to disk,
    - sector 0x21 is read (all 0x07),
    - it 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 for the encryption algorithm is very similar to the Salsa20 algorithm, but there are differences. Instead of the constant “expand 32-byte k”, the constant “-1nvalid s3ct-id" is used. And so far I have not been able to repeat the encryption results on a known key. Perhaps they have a mistake somewhere, which seems to be confirmed by this post .

    The Salsa20 algorithm is considered persistent .

    When everything is encrypted, the machine reboots again, a ransom demand text is displayed, and you are prompted to enter the decryption key.

    The key must be a character string from the set “0123456789abcdef” with a length of 32. This string is run through a certain function that takes an arbitrary number of bytes to the input and produces 32 bytes. Presumably this is a hash function SPONGENT (must be checked). Then the output is cyclically run through the same function 128 times, and this result is accepted as EncryptionKey. To verify the correctness of the key, an attempt is made to decrypt the contents of the 0x21 sector, and if the expected plaintext appears (all 0x07), the process of decrypting the MFT and recovering the MBR is started.

    Can attackers decrypt user files


    In my opinion, the possibility of recovery after payment was not provided by the authors. And that's why:

    1. The personal installation key, which must be reported to the authors of the virus after the ransom is paid, is not connected in any way with EncryptionKey. Both are random data. It is impossible to get the other out of 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 nobody seems to have reported such activity (and I did not see it in the code, although this is not 100% possible).

    2. If I guessed with the SPONGENT hash function, the decryption key must be the hash output, and to calculate what the user must enter, it is necessary to reverse this hash (129 times), which is hardly realizable with modern technology.

    3. The EncryptionKey entropy 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. From 32 hexadecimal characters, it is not possible to get 32 ​​bytes with specific values.

    Differences from Petya sample January 9, 2016


    Petya did not want to infect my test machine. Maybe he needs a network or something else. I had to dump from memory.

    I did not have time to look at the code that forms the sectors used from the MBR installed by the malware, but I looked at the screenshots and the code that will be executed after the reboot.

    Differences:

    1. Sectors 0x36-0x39 are used (against 0x20-0xx23 for NotPetya).
    2. Most of the service functions (text output, read / write sectors) are identical to Petya.
    3. There is a function and lines for displaying a banner with a skull. NotPetya also has a very similar function, but probably it is never called, and the lines are reset.
    4. 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, a maximum of 527 bits of information can be encoded (versus 351 for NotPetya).
    5. In the Petya dump, the secp256k1 and secp192k1 lines are visible, which leads to the idea that the Personal installation key is derived from the EncryptionKey and is calculated using cryptography on elliptic curves.
    6. The key entered by the user to start decryption must be a string from the alphabet "123456789abcdefghijkmnopqrstuvwxABCDEFGHJKLMNPQRSTUVWX" with a length of 16 characters.
    7. There is nothing like SPONGENT (or some other hash).
    8. Salsa20 uses the original expand 32-byte k constant. At the same time, the function code is almost identical, and if Petya code was probably generated by the compiler (optimization on repeated characters worked), then in NotPetya, it seems, just the constants were replaced.

    Petya:



    NotPetya:



    I would suggest that there was another Petya pattern based on which NotPetya was created by replacing constants and strings.

    I repeat again that NotPetya most likely did not provide for the ability to decrypt the files of its victims, and in Petya, everything was fine with this. As for self-repairing a disk, this may turn out to be real. Both viruses have very similar errors in the implementation of encryption algorithms, which makes it possible to quickly select an encryption key and restore all encrypted data. In 2016, researchers described a method for recovering data encrypted by Petya without paying a ransom.

    UPD



    Among the various versions of the 2016 Petya malware, which, under different colors ( 1 , 2 ), performed in a duet with the ransomware mischa and in this form, you should pay attention to PetyaGoldenEye.malware , first sent to VirusTotal last December.

    The code that NotPetya writes when it gets infected to the beginning of the disk, and which is launched from the MBR, is extremely similar to the code written by PetyaGoldenEye: SHA256: b5ef16922e2c76b09edd71471dd837e89811c5e658406a8495c1364d0d9dc690.

    Discovered differences between NotPetya and Petya GoldenEye:



    • Many text lines were changed (the text of the ransom message was fixed, the picture with the skull was removed);
    • Offsets have been changed to some lines (the beginning of the lines “moved out” due to the resizing of messages);
    • In the function at the address 0000: 86E0, a piece of code is jumped (never executed), which is responsible for displaying the banner (flashing “skull with bones”) before pressing any key;
    • There, the banner color was changed from yellow (0xE) to red (0xC), but the banner still does not appear;
    • Address 0000: 848E removed (replaced by three NOP instructions) call to the function that clears the keyboard buffer (not required, as it was not expected to be pressed);
    • In the function at address 0000: 96D4 (expand for Salsa20), the initial state of the line is changed from “expand 32-byte k” to “-1nvalid s3ct-id”;
    • In the 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 were found. Now let's look at cryptography.

    Hash function SPONGENT



    The code implementing SPONGENT was probably taken from here . If we replace the initial value of the variable “lfsr” in the permute () function and rewrite the spongent () function so that it receives not a Null-terminated string, but a pointer to the array and the length of the array, the code will be equivalent to that used in NotPetya.
    It is noteworthy that the initial value LFSR == 0x9E (as described in the original specification for SPONGENT-256/256/16) gives 140 rounds, and the initial value 0xA3 used in NotPetya gives 152 rounds (cryptographic strength is slightly increased).

    Salsa20 Encryption Function



    The code that implements Salsa20 was probably borrowed from here . If we replace the value of the array “o” in the s20_expand32 () function and replace the body of the s20_littleendian () function 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 not implemented correctly (probably due to an incorrect determination of the type or error of the 16-bit compiler), the values ​​of two out of every four bytes in the keystream array are not used in any way. This actually makes the encryption key 128-bit rather than 256-bit. However, a complete search of 128-bit key space at the current level of technology is considered an unsolvable task.

    Conclusions and Assumptions



    Petya authors implemented MFT encryption using strong (albeit not very widespread) cryptographic primitives, the code of which was borrowed from repositories on GitHub.

    In the process of preparing the first version (Petya Red), mistakes were made , and this allowed to decrypt the data without paying a ransom.

    In subsequent versions (Petya Green, PetyaGoldenEye), the errors were partially corrected, and there was only a type conversion error that halves the effective key length. Attempts were made to implement an attack on the fixed version , but they did not lead to success.

    The authors of NotPetya probably did not have access to the Petya source code and could not make the necessary changes to them and recompile the project. They took the existing code from Petya GoldenEye as a basis, analyzed it using a disassembler and made changes using a hex editor.

    The search for ways to return files encrypted by NotPetya continues.

    Read Next