domenica 27 gennaio 2019

Free decryption tool: .Happy Ransomware variant spotted in the wild

Hello everybody,
today I'm gonna write a very quick analysis about an Happy Ransomware variant spotted in the wild on Jan 24 2019.

sample hash details:
MD5 64f11aee7f21ec74a3f8f518e45c6d55
SHA1 1d06a6c7032c4ec4005a46ffe7c29135f26d3e15
SHA256 9da7d298691613a398e26ac3c4c4e4e9c93069d2162fa6639901dd7c62774ef5

This was a very easy ransomware, like many I've seen in the past it actually send an email with a PC screenshot, this.i (wich is the encrypted files counter) and some other stuffs... Actually the ransomware sends some of such informations also trough the UserAgent to a specific url but we dont care about that, we're focused to know how to get back our files.

In this ransomware a static analysis is enough to have an idea on how the sample works.

From the picture above, the circle number 1 is actually a search of all ("*") the files + all sub Directories of the following ones: ProgramFiles, PROGRAMFILES(X86), systemroot, appdata, tmp , Desktop and MyDocuments folder.
As you can see on the circle number 2or each file found, the encryption key string is composed by (this.i + 1) + "GbVjXehg"
The encryption function is called (2bis circle) and then the circle number 3 actually means this.i +=1;

This means that we have  different key for each file encrypted in a keyspace which is contained into 1 up to the number of files encrypted. If we suppose to have 1000 encrypted files (wich we can enumerate by a search of "*.happy")
Minium key string is from "1"+"GbVjXehg" to "1000" +"GbVjXehg"
Each key is actually hashed (sha256Cng.Computehash(byte[] in) in the encrypt function), but this does not change the size of the keyspace because we have just one hash match for each key string.

Source code (its just a proof of concept), here:

using System;
using System.Security.Cryptography;
using System.Text;
using System.IO;

namespace proofofcode
 class Program
  public static void Main(string[] args)
   var buffer = File.ReadAllBytes(@"c:\enc.happy");
   int maxfiles= 1000; //We suppose to have just 1000 encrypted files.
   int i=0;
   MemoryStream mss = new MemoryStream();
    if(Decrypt(i,buffer,out mss)==1) break;

   Console.Write("Press any key to continue . . . ");
  public static int Decrypt(int i, byte[] buffer, out MemoryStream msi)
   int ret=1;
   RijndaelManaged myRijndael = new RijndaelManaged();
   myRijndael.Mode = CipherMode.ECB;
    SHA256Cng asd = new SHA256Cng();
    var rijndael = new RijndaelManaged
                //                                            "135GbVjXehg"
                Key = asd.ComputeHash(Encoding.ASCII.GetBytes(i+"GbVjXehg")),
                Mode = CipherMode.ECB

            var transform = rijndael.CreateDecryptor();
            string decrypted;
            using (var ms = new MemoryStream())
                using (var cs = new CryptoStream(ms, transform, CryptoStreamMode.Write))
                    cs.Write(buffer, 0, buffer.Length);
                   // Console.Write("good key");
                 // File.WriteAllBytes(@"c:\dec.bin",ms.ToArray());
   }catch(Exception e){Console.WriteLine("error key"+i); 
        Console.WriteLine("IOException source: {0}", e.Message);
  return ret;

Obviously the code can be optimized by for example, starting from rewriting my whole code LOL :)) plus, as we know each key is used once for one file, so to speedup the process excluding the used key helps a lot.
You can extend the use searching all the .happy files and automate the decryption for each file found.

RE Solver

Nessun commento:

Posta un commento