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.

https://www.hybrid-analysis.com/sample/9da7d298691613a398e26ac3c4c4e4e9c93069d2162fa6639901dd7c62774ef5?environmentId=100

https://www.virustotal.com/en/file/9da7d298691613a398e26ac3c4c4e4e9c93069d2162fa6639901dd7c62774ef5/analysis/

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();
   for(;i<=maxfiles;i++){
    
    if(Decrypt(i,buffer,out mss)==1) break;
   
          

   }
   File.WriteAllBytes(@"C:\Users\PC\dec.bin",mss.ToArray());
    
   Console.Write("Press any key to continue . . . ");
   Console.ReadKey(true);
  }
 
  public static int Decrypt(int i, byte[] buffer, out MemoryStream msi)
  {   
   int ret=1;
   try{
   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);
                    
                     cs.FlushFinalBlock();
                     cs.Close();
                    
                   // Console.Write("good key");
                 // File.WriteAllBytes(@"c:\dec.bin",ms.ToArray());
                    
                }
                msi=ms;
                ms.Close();
            }
            
   }catch(Exception e){Console.WriteLine("error key"+i); 
        Console.WriteLine("IOException source: {0}", e.Message);
        msi=null;
   ret=0;
   }
   
  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.

Cheers,
RE Solver

Nessun commento:

Posta un commento