OysterLoader Uncovered: Inside a Multi-Stage Evasion Loader
Detection stack
- AIDR
- Alert
- ETL
- Query
Summary
OysterLoader is a C++ multi-stage loader used to deploy ransomware and commodity malware such as Vidar. It spreads through compromised sites that impersonate legitimate software installers and is delivered as a Microsoft Installer (MSI). To complicate analysis, it uses API call flooding, custom dynamic API resolution, anti-debug checks, and a custom LZMA decompression routine. The loader talks to a tiered HTTPS C2 infrastructure using obfuscated HTTP headers and a proprietary Base64-like encoding.
Investigation
The report outlines four stages: a packed obfuscator (TextShell), a shellcode layer that inflates content with LZMA, a downloader that performs environment checks and creates a mutex, and a final stage that drops a DLL and installs a scheduled task. C2 traffic relies on hard-coded IPs/domains, custom user-agents, and steganographic payload delivery via PNG icons. Persistence is maintained by a scheduled task configured to run every 13 minutes.
Mitigation
Block unsigned MSI installers from untrusted sources and monitor for creation of the known mutex patterns. Alert on scheduled task name patterns and the use of rundll32.exe to load DLLs from %APPDATA%. Where feasible, enforce TLS inspection to identify the custom HTTP headers and user-agents used by the loader.
Response
If detected, isolate the host, terminate the scheduled task, and remove the dropped COPYING3.dll file. Hunt for additional payloads, enumerate processes matching the mutex values, block the listed C2 domains/IPs, and update detections for the API flooding behavior and custom Base64 encoding.
"graph TB %% Class definitions classDef action fill:#99ccff classDef malware fill:#ffcc99 classDef process fill:#ffeb99 classDef persistence fill:#c2f0c2 classDef c2 fill:#d9b3ff %% Nodes initial_access["<b>Initial Access</b> – <b>T1218.007 System Binary Proxy Execution: Msiexec</b><br/>Signed malicious MSI delivered via compromised website."] class initial_access action process_msiexec["<b>Process</b> – msiexec.exe<br/>Executes malicious MSI"] class process_msiexec process stage1["<b>Stage 1</b> – Packer/Obfuscator<br/><b>Techniques</b>: T1027 Obfuscated Files or Information, T1027.007 Dynamic API Resolution, T1614.001 System Language Discovery, T1480.002 Execution Guardrails: Mutual Exclusion, T1497.002 Virtualization/Sandbox Evasion: User Activity Based Checks"] class stage1 malware stage2["<b>Stage 2</b> – Shellcode<br/><b>Techniques</b>: T1140 Deobfuscate/Decode Files (RC4), LZMA decompression"] class stage2 malware stage3["<b>Stage 3</b> – Downloader & C2<br/><b>Techniques</b>: T1102 Web Service, T1001.003 Protocol or Service Impersonation, T1001.002 Steganography, T1102.001 Dead Drop Resolver"] class stage3 malware c2_server["<b>C2</b> – HTTPS Server<br/>Custom headers and fake Useru2011Agent"] class c2_server c2 dll_payload["<b>Malware</b> – Dropped DLL<br/>Stored in %APPDATA%"] class dll_payload malware process_rundll32["<b>Process</b> – rundll32.exe<br/>Executes DLL via DllRegisterServer"] class process_rundll32 process task_schtasks["<b>Persistence</b> – Scheduled Task<br/>Runs rundll32 with the dropped DLL"] class task_schtasks persistence stage4["<b>Stage 4</b> – Persistence & Execution<br/><b>Techniques</b>: T1546.009 Event Triggered Execution: AppCert DLLs, T1027.003 Steganography, T1102.002 Bidirectional Communication"] class stage4 malware %% Connections initial_access –>|executes| process_msiexec process_msiexec –>|delivers| stage1 stage1 –>|generates| stage2 stage2 –>|downloads| stage3 stage3 –>|communicates with| c2_server c2_server –>|provides payload to| stage3 stage3 –>|writes DLL to| dll_payload dll_payload –>|used by| process_rundll32 process_rundll32 –>|triggered by| task_schtasks task_schtasks –>|scheduled from| stage4 "
Attack Flow
Detections
Schtasks Points to Suspicious Directory / Binary / Script (via cmdline)
View
Rundll32 Dll Suspicious Path Execution (via process_creation)
View
IOCs (SourceIP) to detect: OysterLoader Unmasked: The Multi-Stage Evasion Loader
View
IOCs (DestinationIP) to detect: OysterLoader Unmasked: The Multi-Stage Evasion Loader
View
OysterLoader C2 Communication Detection [Windows Network Connection]
View
Detection of OysterLoader Anti-Analysis and Execution Techniques [Windows Process Creation]
View
Simulation Execution
Prerequisite: The Telemetry & Baseline Pre‑flight Check must have passed.
Rationale: This section details the precise execution of the adversary technique (TTP) designed to trigger the detection rule. The commands and narrative MUST directly reflect the TTPs identified and aim to generate the exact telemetry expected by the detection logic. Abstract or unrelated examples will lead to misdiagnosis.
-
Attack Narrative & Commands:
The adversary, having gained initial foothold on the endpoint, deploys the OysterLoader payload.- DLL Registration via Rundll32 – The loader copies a malicious DLL (
COPYING3.dll) into the temporary directory and registers it usingrundll32.exewith theDllRegisterServerentry point, producing a command line that matchesselection1. - Anti‑Debug Check – To evade analysis, the payload loads
ntdll.dlland callsIsDebuggerPresent. This generates a process record whereImagecontainsntdll.dlland the command line includesIsDebuggerPresent, satisfyingselection2. - Memory Allocation – For in‑memory execution, the loader invokes
NtAllocateVirtualMemoryviantdll.dll. The resulting process creation event containsNtAllocateVirtualMemoryin the command line, satisfyingselection3.
- DLL Registration via Rundll32 – The loader copies a malicious DLL (
-
Regression Test Script:
# OysterLoader detection validation script – PowerShell # ---------------------------------------------------- # 1. Create a dummy malicious DLL (empty file for simulation) $dllPath = "$env:TEMPCOPYING3.dll" New-Item -Path $dllPath -ItemType File -Force | Out-Null # 2. Trigger selection1 – rundll32 with DllRegisterServer Write-Host "Executing selection1 (rundll32 DLL registration)..." Start-Process -FilePath "rundll32.exe" -ArgumentList "`"$dllPath`" DllRegisterServer" -NoNewWindow # 3. Trigger selection2 – ntdll with IsDebuggerPresent Write-Host "Executing selection2 (IsDebuggerPresent)..." $scriptBlock = { Add-Type -MemberDefinition @" [DllImport("ntdll.dll", SetLastError = true)] public static extern bool IsDebuggerPresent(); "@ -Namespace WinAPI -Name NativeMethods [WinAPI.NativeMethods]::IsDebuggerPresent() | Out-Null } Start-Job -ScriptBlock $scriptBlock | Wait-Job | Receive-Job # 4. Trigger selection3 – ntdll with NtAllocateVirtualMemory Write-Host "Executing selection3 (NtAllocateVirtualMemory)..." $scriptBlock2 = { Add-Type -MemberDefinition @" [DllImport("ntdll.dll", SetLastError = true)] public static extern int NtAllocateVirtualMemory( IntPtr ProcessHandle, ref IntPtr BaseAddress, IntPtr ZeroBits, ref UIntPtr RegionSize, uint AllocationType, uint Protect); "@ -Namespace WinAPI -Name NativeMethods $process = [System.Diagnostics.Process]::GetCurrentProcess() $handle = $process.Handle $base = [IntPtr]::Zero $size = [UIntPtr]::Zero [WinAPI.NativeMethods]::NtAllocateVirtualMemory($handle, [ref]$base, [IntPtr]::Zero, [ref]$size, 0x1000, 0x04) | Out-Null } Start-Job -ScriptBlock $scriptBlock2 | Wait-Job | Receive-Job # Cleanup Remove-Item -Path $dllPath -Force Write-Host "Simulation completed." -
Cleanup Commands:
# Ensure any lingering rundll32 or job processes are terminated Get-Process -Name "rundll32" -ErrorAction SilentlyContinue | Stop-Process -Force Get-Job | Remove-Job -Force # Delete temporary DLL if still present $tempDll = "$env:TEMPCOPYING3.dll" if (Test-Path $tempDll) { Remove-Item $tempDll -Force }