Goldeneye Ransomware - the Petya/Mischa combo rebranded

Petya and Mischa – Ransomware Duet (Part 1)

After being defeated about a month ago, Petya comes back with new tricks. Now, not as a single ransomware, but in a bundle with another malicious payload – Mischa. Both are named after the satellites from the GoldenEye movie.

They deploy attacks on different layers of the system and are used as alternatives. That’s why, we decided to dedicate more than one post to this phenomenon. Welcome to part one! The main focus of this analysis is Petya (the Green version).

The second part (about Mischa) you can read about it here.

UPDATE: Improved version of Green Petya is out. More details given in the new article.

Let’s start with some background information.

This time authors also deployed a page with information for potential clients of their Ransomware-As-A-Service:

janus_info_page

Just like in the case of Chimera, the authors use bitmessage for communication with the new recruits of the criminal cooperation:

bitmessage

And post doxing threats, also known from Chimera:

dox_threat

Analyzed samples

8a241cfcc23dc740e1fadc7f2df3965e – main executable

f7596666d8080922d786f5892dd70742– main executable (from a different campaign)

Execution flow

Behavioral analysis

Just like the previous version, it is distributed via cloud storage and pretends to be a job application:

again

The executable is again packed with an icon of a PDF document:

sample_petyas

After deploying it, it can drop one of the two payloads – Petya – that works similarly to the previously described version, or Mischa – that has features of a typical ransomware. The decision which payload to deploy is based on privileges with which the sample runs – that implies accessibility to write to the MBR. If writing there is not possible, authors decided not to miss the chance of infecting the system and deploy more typical userland attack with Mischa.

From the point of view of the user – your decision taken on UAC pop-up will result in deploying one out of the two payloads. If you choose “No” – you get Mischa. If you choose “Yes” – you get Petya.

uac_popup

Petya

The infection process looks exactly the same as in the previous verison of Petya. User Account Control notification pops up, and in case the user accepts it, Petya installs itself in the MBR and crashes the system. Stage 2 of the infection also looks almost the same. First it runs the fake CHKDSK, that in reality encrypts the disc. Then, the user can see the ASCII art with the blinking skull and the ransom note. Only the color theme changed – instead of red, we have a black background with green text:

green_petya
mischa2

This theme is consistent for the full ransomware – the same colors we can find on the page for the victim, and on the HTML with the ransom note dropped by Mischa.

Page for the victim:

petya_site1

Inside

The new version of Petya uses exactly the same bootloader – again it loads 32 sectors starting from the sector 34 to the memory at 0x8000 and then jumps there.

Kernel start:

kernel_bgn

Again, checking if the data is already encrypted is performed, using a one byte flag that is saved at the beginning of sector 54. If this flag is unset (the value of first byte is 0), program proceeds to the fake CHKDSK scan. Otherwise (if the value of the byte is 1), it displays the main green screen.

check_infected

The key used for the encryption is again generated by the dropper and stored in the binary. That’s why if we catch Petya at Stage 1 – before the fake CHKDSK run and erase it, recovering system is still easy. A live CD to support Stage 1 key recovery has been already released (here).

Key verification

Key verification is performed in the following steps:

  1. Input (key) from the user is read.
    • Accepted charset: 123456789abcdefghijkmnopqrstuvwxABCDEFGHJKLMNPQRSTUVWX – if the character outside of this charset occurred, it is skipped.
    • Only the first 16 bytes are stored
  2. Data from sector 55 (512 bytes) is read into memory  // it will be denoted as verification buffer
  3. The value stored at physical address 0x6c21 (just before the Tor address) is read into memory. It is an 8 byte long array, unique for a specific infection. // it will be denoted as nonce
  4. The verification buffer is encrypted by Salsa20 with the 16 byte long key and the nonce
  5. If, as a result of the applied procedure, verification buffer is fully filled with 0x7 – it means the supplied key is correct.

What changed in the new Petya?

Storing the Salsa key (stage1)

This time it the key is saved differently, without scrambling. Probably the authors realized that scrambling does not provide them any protection, so they gave up this idea completely:

petya_key

Length of Salsa key

In the Red Petya authors used 16 byte long key – however, they were scrambling it and used it to make a 32 bit long key. Now they gave it up and they just use the 16 byte long key as it is. That’s why, instead of functions expand32 we will see in the new Petya the function expand16:

expand_green

Salsa implementation

Also this time, Salsa20 is used in several places in Petya’s code – for encryption, decryption and key verification. See the diagram below:

execution_flow

We made a comparison of Salsa implementation fragments, that have been found vulnerable in the previous implementation.

salsa20_rol

See below the original version of this function – copied from Salsa20 implementation:

static uint32_t rotl(uint32_t value, int shift) {   return (value << shift) | (value >> (32 - shift)); } 

Code comparison – old one vs the new one:

primary_salsa20_rol vs sub_9698

secondary_salsa20_rol vs sub_9698

That’s how it has been implemented in the Red Petya:

green_rol

The old version of this function was taking 2 arguments and it was an almost exact clone of the original function – the only difference was that it was using 16 bit variables. Reconstruction of the code:

static uint16_t rotl(uint16_t value, int16_t shift) {     return (value << shift) | (value >> (32 - shift)); } 

And the new version – from Green Petya:

green_rotl

The new version is more complex – it takes 3 arguments and uses calls to additional helper functions. To achieve the functionality of shifting a DWORD, two WORD-sized parameters have been used (one representing the lower part of the DWORD and another representing the higher):

static uint16_t rotl(uint16_t value_word1, uint16_t value_word2, int16_t shift)  {      return (shr(value_word1, value_word2, (32 - shift)) | shl(value_word1, value_word2, shift)); }

 

s20_hash

original version: https://github.com/alexwebr/salsa20/blob/master/salsa20.c#L59

Code comparison – old one vs the new one:

primary_s20_hash vs sub_9862

 

secondary_s20_hash vs sub_9862

First changed fragment corresponds to this part of the original Salsa20 implementation:

  for (i = 0; i < 16; ++i)     x[i] = z[i] = s20_littleendian(seq + (4 * i)); 

That's how it has been implemented in the Red Petya:

petya_red_hash_l1

And the new version - from the Green Petya:

petya_green_hash_l1

s20_littleendian also changed, but very slightly - a bit extension has been added:

bit_extension

Second changed fragment corresponds to this part of the original Salsa20 implementation:

  for (i = 0; i < 16; ++i) {     z[i] += x[i];     s20_rev_littleendian(seq + (4 * i), z[i]);   } 

That’s how it has been implemented in the Red Petya:

petya_red_hash_l2

And the new version - from Green Petya:

petya_green_hash_l2

Full reconstruction and comparison of implementations of this function: https://gist.github.com/hasherezade/f59939f5d20ebdfd36343dfcae66bfa9

New Petya, new bug

As we can see, the authors tried to fix the bug of using 16 bit long units where the 32 bit long units were required. The new implementation of Salsa looks almost correct... However, due to just one bug, it still needs only 8 valid characters of the key, out of 16!

The bug lies in invalid implementation of the function s20_littleendian. That's how this function looks in the origial Salsa20:

static uint32_t s20_littleendian(uint8_t *b) {   return b[0] +          (b[1] << 8) +          (b[2] << 16) +          (b[3] << 24); } 

And that's how the Petya's version looks:

static int16_t s20_littleendian(uint8_t *b) {   return b[0] +          (b[1] << 8); } 

In the previous, Red Petya every second character of the key had no importance to the encryption/decryption. The pattern was: c?c?c?c?c?c?c?c? - where the c means a valid character and ? means any random character from the set.

Valid key - hpLehdbjdcVaMDGj (revealed at Stage 1 by Antipetya Live CD)

stage1_red

Accepted key hxLxhxbxdxVxMxGx :

decrypting_red

In the current case, the pattern is a bit different (and more difficult to exploit): cc??cc??cc??cc??. See example below:

Valid key - sHbGrSTkpCrhoKRt (revealed at Stage 1 by Antipetya Live CD)

stage1_key

Accepted key - sHxxrSxxpCxxoKxx :

decrypting_petya_green

Verification buffer

Similar to the previous version, a verification buffer is used in order to check whether or not the provided key is valid. However, values expected in the verification buffer changed.  In the green Petya, a key was passed as valid if the verification buffer got filled by ASCII character '7' (that is byte 0x37). Now, the byte 0x7 has been used.

Checking characters of the validation buffer:

  • in red Petya:
check_red
  • in green Petya
check_green

Stability

In the Red Petya, interrupting the fake CHKDSK caused real problems. Even after having a correct key full disk was not decrypted correctly - because Petya didn't check which sectors are encrypted and which are not, and was applying Salsa again on everything. In the Green edition authors improved it.

Yet, some victims of Petya reported to us, that they encountered the situation, where they bought a valid key but still the disk wasn't decrypted properly. That's why we recommend making a dump of the full disk as soon as you notice that you are infected with Petya (before trying any decryption methods).

Fragment of the talk between the victim and the attackers. Till now, user didn't got either his data or his bitcoins back:

petya_communication

Conclusion

The new Petya comes with significant improvements. The authors realized the weakness and tried to make appropriate fixes in the code. However, they left another flaw that weakens the encryption. Unfortunately, the previous approach, based on genetic algorithm will not work this time - due to the different specifics of the generated output. The remaining solution seems to be only bruteforce of the 8 characters. Further research about the possibility of writing a decryptor is in progress.

The idea of making a bundle of two completely different ransomwares is new and creative.  The group of cybercriminals who released it seems to do everything in order to gain clients on the black market. Probably the same group released other ransomware before: Chimera and Rokku. The main method of distribution used by them is via targeted campaigns of malicious e-mails. That's why we recommend to pay more attention on the received attachments and be very cautious. We can expect, that they will come with some new ideas in the future.

Appendix

http://www.bleepingcomputer.com/news/security/petya-is-back-and-with-a-friend-named-mischa-ransomware/ - Bleeping Computer about Mischa

About the previous (red) version of Petya:

/blog/threat-analysis/2016/04/petya-ransomware/

ABOUT THE AUTHOR

hasherezade

Malware Intelligence Analyst

Unpacks malware with as much joy as a kid unpacking candies.