Description
Spawns a new process and uses various techniques for injection.
Spawn-Inject
Overview
Spawn-Inject spawns a new host process in a suspended state and injects a payload into it before the process begins normal execution. Unlike remote-injection techniques that target an existing process, Spawn-Inject creates and controls the target process from the start, giving the operator full control over the injection window.
The payload can be sourced in three ways:
- Pipeline — fetches shellcode from a named server pipeline (e.g.
srdi_x64,http). The build identifier selects which implant configuration to embed. - Shellcode — injects caller-supplied raw shellcode bytes directly.
- Migrate — fetches an sRDI payload automatically using the current agent’s build and architecture.
Architecture is detected automatically from the running agent: a 64-bit agent spawns and injects 64-bit targets; a 32-bit (WoW64) agent spawns and injects 32-bit targets. To target a 32-bit process from a 64-bit system, run the agent in 32-bit mode or pass the full path to the 32-bit executable (e.g. C:\Windows\SysWOW64\notepad.exe).
Parameters
| Parameter | Type | Parameter Set | Mandatory | Default | Description |
|---|---|---|---|---|---|
FullPath |
string |
Pipeline, Specter | Yes | — | Full path to the executable to spawn (e.g. notepad.exe or C:\Windows\SysWOW64\notepad.exe). |
Technique |
string |
Pipeline, Specter | Yes | — | The injection method to use. See the Techniques table below. |
Pipeline |
string |
Pipeline | Yes | — | Name of the server payload pipeline to fetch shellcode from (e.g. srdi_x64, srdi_x86, http). |
Build |
string |
Pipeline, Specter | Yes | Current agent build | Implant build identifier. Determines the C2 configuration embedded in the fetched payload. Accepts the [Build] attribute for UI auto-complete. |
Note: The
Shellcodeparameter set accepts abyte[]directly and does not requirePipelineorBuild. It is not exposed in the script wrapper above but is available when calling the cmdlet directly.
Techniques
| Technique | Supported Architectures | Description |
|---|---|---|
EarlyCascadeInjection |
x64, x86 | Abuses the Windows shim engine (g_pfnSE_DllLoaded / g_ShimsEnabled) in ntdll.dll to execute the payload during the very first DLL-load event in the suspended process — before EDR hooks have had a chance to initialize. See Technique Detail below. |
Technique Detail
EarlyCascadeInjection
The technique exploits the Windows application compatibility shim engine callback registered in ntdll.dll. When a process loads its first DLL, ntdll fires the function pointer stored in g_pfnSE_DllLoaded if g_ShimsEnabled is non-zero. By planting a stub pointer here before the thread resumes, the payload executes at the earliest possible point in process initialization.
Execution sequence:
- Spawn the target process suspended via
CreateProcessA(CREATE_SUSPENDED). - Dynamically resolve
g_ShimsEnabledandg_pfnSE_DllLoadedinside the in-processntdllimage using one of two strategies:- Strategy A (preferred): Disassemble the body of the exported
LdrSetDllManifestProberfunction and extract the.dataand.mrdatawrite addresses directly. - Strategy B (fallback): Scan the
.textsection for thecmp byte ptr [rip+disp], 0/ REX MOV /SharedUserData→Cookieaccess pattern.
- Strategy A (preferred): Disassemble the body of the exported
- Allocate RWX regions in the target for the cascade stub and payload.
- Build a position-independent cascade stub:
- x64: Disables
g_ShimsEnabled, then callsNtQueueApcThread(-2, payload, context, 0)to queue the payload as an APC against the current thread. - x86: Same logic using 32-bit registers and the
stdcallAPC calling convention.
- x64: Disables
- Prepend a short trampoline (
MOV RAX, stubAddr; JMP RAX) before the stub sog_pfnSE_DllLoadedcan reach it regardless of encoding. - Bypass Control Flow Guard (CFG):
- x64: Overwrite
guard_check_icall_fptrin the Load Config with aRETbyte found inLdrSetDllManifestProber, and redirectguard_dispatch_icall_fptrto the trampoline. - x86: Call
SetProcessValidCallTargetsto register the stub as a valid indirect call destination.
- x64: Overwrite
- Write the patched stub and payload bytes to the remote process via
WriteProcessMemory. - Enable the shim engine in the target:
WriteProcessMemory(hProcess, g_ShimsEnabled, 1). - Plant the stub address in
g_pfnSE_DllLoaded:- Windows 11: Encode the pointer with
SysEncodeFnPointer(ROR64 withSharedUserData→Cookieas key) to matchRtlEncodeSystemPointersemantics. - Windows 10 ≤ 19041: Write the raw pointer.
- Windows 11: Encode the pointer with
- Resume the main thread. The first DLL load fires
g_pfnSE_DllLoaded, executing the stub, which queues the payload APC and clearsg_ShimsEnabledbefore returning cleanly.
Dependencies
lateralmodule
Operating Systems
- Windows (x64 and x86)
Example Usage
Inject a pipeline payload into a 64-bit notepad:
load lateral;
Spawn-Inject -SpawnTarget 'notepad.exe' -Technique 'EarlyCascadeInjection' -Pipeline 'srdi_x64' -Build $Build
Inject into a 32-bit process (from a 32-bit agent):
load lateral;
Spawn-Inject -SpawnTarget 'C:\Windows\SysWOW64\notepad.exe' -Technique 'EarlyCascadeInjection' -Pipeline 'srdi_x86' -Build $Build
Example Output
On success, the cmdlet writes a single PSObject to the pipeline:
ProcessName : notepad.exe
Architecture : x64
SpawnTarget : notepad.exe
Technique : EarlyCascadeInjection
| Property | Type | Description |
|---|---|---|
ProcessName |
string |
The executable name or path that was spawned. |
Architecture |
string |
Architecture of the spawned process (x64 or x86). |
SpawnTarget |
string |
The value passed to -SpawnTarget. |
Technique |
string |
The injection technique that was used. |
On failure, a terminating exception is thrown with an NTSTATUS code, for example:
CascadeInject failed with NTSTATUS 0xC0000001.
Diagnostic output written to the console during execution:
[*] g_ShimsEnabled : 0x00007FFE89A3C210
[*] g_pfnSE_DllLoaded: 0x00007FFE89B10048
[*] Pointer encoding : encoded (Win11)
