A modern operator almost never drops a tool to disk and runs it. The whole toolkit —
credential dumpers, .NET enumerators, service-abuse helpers — is executed in the memory
of an existing process, so antivirus never scans a file and the
PowerShell logging layers never see a
script. This page is how that is done: injection, the fork-and-run vs inline choice,
execute-assembly and BOFs, and the OPSEC of process lineage. It is the mechanism
behind a large share of the commands in the Toolkit.
The core primitive: process injection
Injection means placing your code into a process's address space and getting a thread to run
it. Classically: allocate executable memory in a target process, write your shellcode there,
and start execution (a remote thread, a queued APC, a hijacked thread). Whether the target is
a brand-new process you spawn or one already running, the point is the same — your
code runs under another process's identity and image, so on the surface it is
svchost.exe or explorer.exe doing the work, not an unknown binary.
Which process you pick is an OPSEC decision, not a detail. Some choices signal intent
(lsass.exe for credential theft), some are chosen purely to blend in
(svchost.exe, dllhost.exe, RuntimeBroker.exe,
taskhostw.exe), and some help defeat application-control
(regsvr32.exe, backgroundtaskhost.exe). Injecting into a process
that runs often and lives briefly is a way to disappear into normal activity.
Fork-and-run vs inline
When an implant runs an external tool, it has two strategies, and the difference is central to both stealth and stability.
| Technique | How it works | Trade-off |
|---|---|---|
| Fork-and-run | Spawn a temporary sacrificial process, inject the tool's code into it, run it, capture output, then kill the process | Safe — a crash takes the sacrificial process, not the implant. But spawning a process (and the parent/child relationship it creates) is a detection opportunity |
| Inline / self-inject | Run the tool inside the implant's own process, no new process spawned | Quieter — no new process, no telltale lineage. But a crash or a detected action takes the implant with it, so it is riskier |
This is the same stealth-versus-safety dial as beacon-versus-session, one level down. Fork-and-run is the resilient default; inline execution is what you reach for when the extra process itself would be the thing that gets you caught — and it is where the implant's built-in AMSI/ETW bypass applies, since the code runs in a process the implant already controls.
execute-assembly: running .NET in memory
The bulk of the offensive C# toolset — Rubeus, SharpUp, Seatbelt, Certify, SharpHound and the rest — are .NET assemblies. execute-assembly loads the .NET runtime (CLR) into a process and runs the assembly's bytes straight from memory, passing arguments as if it were launched normally. Nothing is written to disk, and because it never goes through the PowerShell engine, script-block and transcription logging are blind to it. It works in both modes: fork-and-run into a chosen (optionally PPID-spoofed) process, or inline into the implant with AMSI/ETW patched first.
Not every assembly is compatible, and a tool that shells out or spawns children reintroduces the very process events inline execution was meant to avoid. The tradecraft is choosing the right execution method for each tool, not applying one blindly.
BOFs — the lighter alternative
A Beacon Object File (BOF/COFF) is a small compiled object loaded and run inside the implant's own process, using the implant as a mini-linker. Because there is no new process, no CLR to host, and a tiny footprint, BOFs are the quiet way to do focused post-exploitation tasks. Frameworks distribute them as extensions (Sliver's armory does exactly this), which is why an operator can run many “native” commands that are really in-process modules.
PPID spoofing and process migration
Endpoint detection leans heavily on process lineage — who spawned whom. An
illegitimate parent/child pair (WINWORD.exe spawning cmd.exe, or
rundll32.exe with no parent reason) is a classic indicator. Two techniques bend
this to the operator's advantage.
| Technique | What it does |
|---|---|
| PPID spoofing | Start a process with an arbitrary parent, so the new process appears to have been launched by a benign, expected one. Mimic real relationships (e.g. svchost.exe → RuntimeBroker.exe / taskhostw.exe) so a fork-and-run doesn't stand out in a process tree |
| Process migration | Move the running implant from its current host process into a different, longer-lived or more plausible one — leaving the original process (and its risk) behind |
Getting a tool into shellcode
Injection needs position-independent shellcode, but most tools are PE executables or .NET
assemblies. Packers bridge the gap: Donut turns a .NET/PE payload into
shellcode that reflectively loads and runs it, and wrappers like PEzor add
evasion (unhooking, anti-debug, sleep obfuscation, output as .NET or shellcode) so the result
both runs in memory and resists inspection. This is how a stock mimikatz.exe or a
PowerShell-derived executable becomes something an implant can inject and
execute-assembly.
Unhooking
EDR products insert user-mode hooks into common API functions to watch calls from
inside a process. Loaders counter this by unhooking — restoring the original,
clean copies of those functions (typically by reloading a pristine ntdll from
disk) — or by calling the underlying syscalls directly, so the sensitive operations happen out
of the EDR's view. It is the endpoint-level equivalent of the AMSI/ETW patch: quietly remove
the observation point before doing the noisy thing.
The takeaway
In-memory tradecraft is a stack of choices around one idea — run your code inside a process
that is already trusted, and touch disk as little as possible. Injection provides the
primitive; fork-and-run versus inline sets the stealth/safety balance;
execute-assembly and BOFs run the standard toolset without dropping files; PPID
spoofing and migration launder process lineage; and packers, unhooking and AMSI/ETW bypasses
smooth over what defenders watch. Every one is a deliberate trade of noise for control. The
tools that implement these — and the Sliver commands that drive them — are in the
Toolkit.