Process Injection
Process Injection
The process-inject block in Malleable C2 profiles shapes injected content and controls process injection behavior for the Beacon payload. It also controls the behavior of Beacon Object Files (BOF) execution within the current beacon.
The process-inject block accepts several options that control the process injection process in Beacon:
The transform-x86 and transform-x64 blocks pad content injected by Beacon. These blocks support two commands: prepend and append.
The prepend command inserts a string before the injected content. The append command adds a string after the injected content. Make sure that prepended data is valid code for the injected content’s architecture (x86, x64). The c2lint program does not have a check for this.
The execute block controls the methods Beacon will use when it needs to inject code into a process. Beacon examines each option in the execute block, determines if the option is usable for the current context, tries the method when it is usable, and moves on to the next option if code execution did not happen.
The execute options include:
The CreateThread and CreateRemoteThread options have variants that spawn a suspended thread with the address of another function, update the suspended thread to execute the injected code, and resume that thread. Use [function]“module!function+0x##”to specify the start address to spoof. For remote processes, ntdll and kernel32 are the only recommended modules to pull from. The optional 0x##part is an offset added to the start address. These variants work x86 -> x86 and x64 -> x64 only.
The execute options you choose must cover a variety of corner cases. These corner cases include self injection, injection into suspended temporary processes, cross-session remote process injection, x86 -> x64 injection, x64 -> x86 injection, and injection with or without passing an argument. The c2lint tool will warn you about contexts that your execute block does not cover.
Controlling Process Injection
Cobalt Strike 4.5 added support to allow users to define their own process injection technique instead of using the built-in techniques. This is done through the PROCESS_INJECT_ SPAWN and PROCESS_INJECT_EXPLICIT hook functions. Cobalt Strike will call one of these hook functions when executing post exploitation commands. See the section on the hook for a table of supported commands.
The two hooks will cover most of the post exploitation commands. However, there are some exceptions which will not use these hooks and will continue to use the built-in technique.
To implement your own injection technique, you will be required to supply a Beacon Object File (BOF) containing your executable code for x86 and/or x64 architectures and an Aggressor Script file containing the hook function. See the Process Injection Hook Examples in the Community Kit.
Since you are implementing your own injection technique, the process-inject settings in your Malleable C2 profile will not be used unless your BOF calls the Beacon API function BeaconInjectProcess or BeaconInjectTemporaryProcess. These functions implement the default injection and most likely will not be used unless it is to implement a fallback to the default technique.
Beacon Command -> Aggressor Script Function
Process Injection Spawn
The PROCESS_INJECT_SPAWN hook is used to define the fork&run process injection technique. The following beacon commands, aggressor script functions, and UI interfaces listed in the table below will call the hook and the user can implement their own technique or use the built-in technique.
Note the following:
Process Injection Explicit
The PROCESS_INJECT_EXPLICIT hook is used to define the explicit process injection technique. The following beacon commands, aggressor script functions, and UI interfaces listed in the table below will call the hook and the user can implement their own technique or use the built-in technique.
Note the following:
Last updated