查看原文
其他

Satan3.1勒索病毒文件解密(附解密程序源码和病毒样本)

逆向实习生 看雪学院 2019-05-26

Satan病毒被揭密似乎已经不是一个秘密了,很多厂商包括瑞星,360,腾讯等公司相继推出了解密的工具。让还是小白的我有了很大的兴趣。于是查看他们的分析报告,病毒,其实仅仅是能对一款或者指定的几款进行解密。原因很简单,使用的对称加密密钥,而且能够找到并重组。有了密钥再解密就不是很难了。自己写了个程序用来专门解密Satan3.1病毒。该病毒的特性是在加密文件的后尾会加上HardwareID和Public两个数值,使用的是RC4加密。把源码发出来和大家分享下,小弟C写的很烂,大神勿喷。



Satan病毒加密


为了加快加密的速度加密方式为如下两种:

1、小于等于100000000字节

(1)特殊后缀,完全加密。

(2)其它后缀,部分加密,加密大小的算法 CryptSize = (FileSize / 2000) *1000,约为文件的二分之一。


举个例子,文件小于等于100000000字节时,zip格式的压缩包就会被完全加密,而RAR格式的只会被加密大约二分之一,因为zip是病毒指定的特殊后缀,而RAR不在列表中。


2、大于100000000 字节的文件

(1)特殊后缀,完全加密。

(2)其它后缀,部分加密,加密大小的算法 CryptSize = (FileSize / 5000) *1000,约为文件的五分之一。


举个例子,文件大于100000000字节时,zip格式的压缩包就会被完全加密,而RAR格式的 只会被加密大约五分之一,因为zip是病毒指定的特殊后缀,而RAR不在列表中。


特殊后缀包括:

sql, zip, php, asp, jsp, cpp, ini, aspx, cs, py, h, vbs, bat, conf, sh, inc, e, c, pl, csv, asm, doc, docx, xls, xlsx, ppt 这些后缀没有


以下后缀不会被加密:

Dbger, cab, pol, dll, msi, exe, lib, iso, bin, tmp, log, ocx, chm, dat, sys, dic, myd, sdi, lnk, gho, pbk


Satan病毒CryptAPI进行加密,加密的算法是RC,密钥结构如下:

[HardWareID]+k_str1+k_str2+k_str3+[PUBLIC]


k_str1, k_str2, k_str3都是硬编在程序当中的:

k_str1 = “dfsa#@FGDS!dsaKJiewiu*#&*))__=22121kD()@#(*#@#@!DSKL909*(!#!@AA”

k_str2 = “*@#AdJJMLDML#SXAIO98390d&th2nfd%%u2j312&&dsjdAa”

k_str3 = “@!FS#@DSKkop()(290#0^^^2920-((__!#*$gf4SAddAA”


Public的大小是0x20,病毒每次加密一个文件时候会生成一个,HardWareID和PUBLIC都会生成在文件的末尾:




Satan病毒加密过程:


MD5算法哈希密钥,加密算法为RC4




参考自:全新“撒旦”Satan勒索病毒来袭 瑞星独家提供解密工具


Satan病毒解密:


由于使用的是RC4对称加密的算法,所以解密也就很简单了,唯一不同的地方就是将CryptEncrypt函数更改为CryptDecrypt。其次就是对于不同的后缀要知道被加密文件加密内容的大小。本人写的程序是需要手动输入选择是解密全文件,半个文件或者是五分之一文件:




对被半加密的文件进行解密:




对全加密的文件进行解密:




解密函数代码:


int SatanDecrypt(char* HardWareID, char* Public, char* OutPutFileName, char* tmpFile, int count)
{
   FILE *ptrFile1 = NULL;
   FILE *ptrFile2 = NULL;
   int KeyLen = 0;
   char k_str1[] = "dfsa#@FGDS!dsaKJiewiu*#&*))__=22121kD()@#(*#@#@!DSKL909*(!#!@AA";
   char k_str2[] = "*@#AdJJMLDML#SXAIO98390d&th2nfd%%u2j312&&dsjdAa";
   char k_str3[] = "@!FS#@DSKkop()(290#0^^^2920-((__!#*$gf4SAddAA";
   char Key[252];
   strcpy(Key, HardWareID);
   strcat(Key, k_str1);
   strcat(Key, k_str2);
   strcat(Key, k_str3);
   strcat(Key, Public);
   printf("* KEY: %s \n\n", Key);
   BYTE *bKey = (BYTE*)Key;
   KeyLen = strlen(Key);
   HCRYPTPROV hCryptProv = NULL;
   HCRYPTHASH hHash = NULL;
   HCRYPTKEY hKey = NULL;

   if (CryptAcquireContext(
       &hCryptProv,
       0,
       NULL,
       PROV_RSA_FULL,
       0))
   {
       //printf("hCryptProv has been acquired.\n");
       if (CryptCreateHash(
           hCryptProv,
           CALG_MD5,
           0,
           0,
           &hHash))
       {
           //printf("An empty hash object has been created. \n");
           if (CryptHashData(
               hHash,
               bKey,
               KeyLen,
               0))
           {
               //printf("CryptHashData succeed! \n");
               if (CryptDeriveKey(
                   hCryptProv,
                   CALG_RC4,
                   hHash,
                   0x800000u,
                   &hKey))
               {
                   //printf("CryptDeriveKey Succeed! \n");
                   BYTE *bBuffer = (BYTE*)malloc(sizeof(BYTE) * 1008);
                   if (bBuffer)
                   {
                       ptrFile1 = fopen(tmpFile, "rb");
                       ptrFile2 = fopen(OutPutFileName, "wb+");
                       int FileFlag = 0;
                       bool decrypt = TRUE;
                       while (TRUE)
                       {
                           DWORD pdDataLen = fread(bBuffer, 10x3E8, ptrFile1);
                           if (ferror(ptrFile1))
                           {
                               printf("Original file error! \n");
                               break;
                           }
                           FileFlag = feof(ptrFile1);
                           if (decrypt)
                           {
                               CryptDecrypt(hKey, 0, FileFlag, 0, bBuffer, &pdDataLen);
                               count--;
                               if (count == 0)
                                   decrypt = FALSE;
                           }
                                
                           fwrite(bBuffer, 1, pdDataLen, ptrFile2);
                           if (ferror(ptrFile2))
                           {
                               printf("Decrypt file Error! \n");
                               break;
                           }
                           if (FileFlag)
                           {
                               printf("*** Decrypt Success! ***\n");
                               break;
                           }
                       }
                       fclose(ptrFile1);
                       fclose(ptrFile2);
                   }

               }
               else
               {
                   printf("CryptDeriveKey Error! \n");
               }

           }
           else
           {
               printf("CryptHashData Error! \n");
           }
       }
       else
       {
           printf("Error on CryptCreateHash! \n");
       }
   }
   else
   {
       printf("CryptAcquireContext function Error!");
   }


   return 0;
}



PS:附件中包含解密程序的源码,对应病毒样本。(点击阅读原文下载)


Having fun!




看雪ID:逆向实习生

bbs.pediy.com/user-813298



本文由看雪论坛 逆向实习生 原创

转载请注明来自看雪社区





热门技术文章推荐:





戳原文,看看大家都是怎么说的?

    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存