Process injection through entry points hijacking.

Overview

EPI

EPI (Entry Point Injection) is a tool that leverages a new threadless process injection technique that relies on hijacking loaded dll's entry points. To achieve this goal, EPI patches the target process' PEB such that one of the already loaded dll's entry point is redirected to a injected shellcode (which by default is the Loader previously converted to sRDI). Once a new thread is naturally spawned by the process or whenever a running thread exits, all loaded modules' entry points will be called which includes our injected shellcode.

Since we want the target process to continue its execution smoothly, generally speaking it is a bad idea to run our payload direcly on the thread that is calling the hijacked entry point. For example, the direct execution of a C2 becon would completely hijack the thread which would surely lead to the program crash in case that the application is expecting the thread to perform a certain task. To deal with this situation, EPI by default does not directly inject the desired payload but a custom Loader, which is a regular dll converted to sRDI. The Loader has embedded the encrypted final payload (for example, the previously commented C2 beacon), and its main task is to decrypt, allocate and run this payload in a stable way. To achieve the execution keeping the "threadless" nature of the technique, the Loader will use the process' thread pool to run the payload by calling QueueUserWorkItem. The use of QueueUserWorkItem ensures that, even in the case that a new thread is spawned (it depends on the thread pool availability), the start routine's address will never point to our payload avoiding that particular IOC.

Before exiting, the Loader restores the PEB and other modified structures to their previous state, preventing the multiple execution of our payload and allowing the process to continue its normal execution.

By default, this tool hijacks kernelbase.dll entry point. Feel free to target a different dll, but make sure that the dll is loaded in both processes involved in this activity.

The provided shellcode embbeded in the Loader spawns a new cmd.exe /k msg "hello from kudaes" process.

The advantages of this technique are the following:

  • Both threadless or threaded execution, at will.
  • No hooking (i.e. no RX memory regions are patched).
  • No generation of private memory regions on well known dll's RX memory pages.
  • No RWX memory permissions required.
  • The targeted process can continue its regular execution.
  • No new threads with a start address pointing to our shellcode.

Compilation

Since we are using LITCRYPT plugin to obfuscate string literals, it is required to set up the environment variable LITCRYPT_ENCRYPT_KEY before compiling the code:

C:\Users\User\Desktop\EPI> set LITCRYPT_ENCRYPT_KEY="setarandomkeyeachtime"

Then, depending on how you want to use the tool we have three diferent compilation processes.

Use the tool as it is provided

In this case, you just need to compile the EPI project:

C:\Users\User\Desktop\EPI\EPI> cargo build --release

After that, run the tool:

C:\Users\User\Desktop\EPI\EPI\target\release> epi.exe -h 

No Loader - Custom payload

If you just want to directly execute your custom shellcode without using the Loader, you have to replace the value of the bytes variable (EPI::src::main.rs:13) with the hexadecimal content of your payload. Then, compile the project and run the tool:

C:\Users\User\Desktop\EPI\EPI> cargo build --release
C:\Users\User\Desktop\EPI\EPI\target\release> epi.exe -h 

Be aware that, depending on the behaviour of your shellcode, you might end up hijacking the thread and potentially causing a process crash.

Loader & Custom payload

This is my recommended choice, since it allows you to fully customize the execution in the most reliable way. This is the right option if you want to run a different payload than the one provided and use the functionality of the Loader to avoid the crash of the target process.

First, you have to replace the value of the bytes variable in the Loader (Loader::src::lib.rs:17) with the hexadecimal content of your payload. Then, compile the project as usual:

C:\Users\User\Desktop\EPI\Loader> cargo build --release

Then, use the provided Python script ConvertToShellcode.py to convert the generated loader.dll into sRDI. I've obtained this script from the fantastic sRDI project after fixing some issues that were generating multi-hour long delays.

C:\Users\User\Desktop\EPI\sRDI> python3 ConvertToShellcode.py -f run loader.dll

This execution should generate a loader.bin file. Again, get its hex content and use it to replace the value of the bytes variable in the EPI project (EPI::src::main.rs:13). Finally, compile EPI and run the tool:

C:\Users\User\Desktop\EPI\EPI> cargo build --release
C:\Users\User\Desktop\EPI\EPI\target\release> epi.exe -h 

Usage

The basic usage is by passing to the tool the PID of the target process and waiting for a thread to spawn/exit:

C:\Users\User\Desktop\EPI\EPI\target\release> epi.exe -p 1337

In case that you need to enable the DEBUG privilege to perform the injection, you can use the flag -d.

C:\Users\User\Desktop\EPI\EPI\target\release> epi.exe -p 1337 -d

If you do not want to wait until a new thread is naturally spawned, you can use the flag -f to spawn a new dummy thread. This dummy thread will run ExitThread (i.e. it's a self destructing thread), but before that will call every single loaded module's entry point, including our shellcode. The good part of this is that despite making the technique threaded, the new spawned thread's initial routine will point to ExitThread and not to our injected shellcode.

C:\Users\User\Desktop\EPI\EPI\target\release> epi.exe -p 1337 -f

Finally, you can also force the execution of the injected shellcode by sending a WM_QUIT message to ALL threads of the target process. If there is any thread listening for this kind of messages it will exit itself by calling ExitThread, which internally calls every loaded module's entry point to allow them to uninitialize and free resources. In this scenario, our shellcode will be executed as well. BE AWARE that this most likely will "terminate" the process, meaning that the user won't be able to interact with it anymore although the shellcode execution will continue in the background. This method is not recommended to run any long-term payload.

C:\Users\User\Desktop\EPI\EPI\target\release> epi.exe -p 1337 -s

Tips

If you want to exploit the threadless nature of this technique, you need to chose wisely the target process. The best processes are those with user interaction, since they are constantly creating and destroying threads.

To test EPI, I like to target my favourite text editor: Sublime Text. Besides the fact that I love it, it's also very simple to force it to spawn a new thread, allowing me to easily test EPI. If you want to do it as well, just follow these simple steps:

  • Run Sublime Text.
  • Inject on it using EPI's basic usage.
  • Click on "File" -> "Open File". This will create a new thread and your shellcode will be executed.
  • Keep using Sublime to verify that the process continues to run normally.

Sublime Text injection.

In case that you want to test the execution of the shellcode when a thread exits, you can do so as well with Sublime Text this way:

  • Run Sublime Text.
  • Click on "File" -> "Open File".
  • Inject your shellcode using EPI's basic usage.
  • Click on "Cancel" to exit the previously generated thread. Your shellcode will be executed by the terminating thread.
  • Keep using Sublime to verify that the process continues to run normally.

Actually, you could also just wait for a minute or less since most of this kind of apps are constantly creating new threads in the background even without any user interaction.

TODO

  • Clean memory artifacts.
  • Test other sRDI generators.
  • Allow to target other dll than kernelbase.dll.
  • Indirect syscalls and other maldev stuff.

Credits

  • monoxgas for the astonishing sRDI project that I have leveraged to convert the Loader dll into PIC.
  • memN0ps for the hard work and all the effort shown in improving srdi-rs.
You might also like...
A fast 24 points game solver written in rust.

Solver024 This is a simple 24 points solver written in rust. Example 1 9 7 8 (1 * 7) + (8 + 9) 1 * (7 + (8 + 9)) ((1 * 7) + 8) + 9 ((1 - 7) + 9) * 8 (

A collection of CC-BY-SA course material to teach the Rust programming language, in different formats, levels, and focus points

A collection of CC-BY-SA course material to teach the Rust programming language, in different formats, levels, and focus points. Contact me for remote and on-site trainings!

Ludum Dare 48 compo entry

ld48 My entry in the Ludum Dare 48 Compo License ld48 is licensed under any of: MIT License LICENSE-MIT

Improved Notion data entry, at the command line

notion-entry NOTE: This project is a work in progress and has a pile of FIXMEs This program lets you input data into Notion from the command line. It

A systemd-boot configuration and boot entry configuration parser library

A systemd-boot configuration and boot entry configuration parser library

Fermi Paradox - ludum dare 46 compo entry

Fermi Paradox How come we don’t see any life from other planets? What does an intergalactic society need to do to survive? Play Play it directly in yo

Select any exported function in a dll as the new dll's entry point.

Description This tool will patch the entry point of the input dll and replace it with the RVA of another exported function in that same dll. This allo

Runtime dependency injection in Rust

This library provides an easy to use dependency injection container with a focus on ergonomics and configurability at the cost of runtime performance. For a more performance-oriented container, look for a compile-time dependency injection library.

A new shellcode injection technique. Given as C++ header, standalone Rust program or library.
A new shellcode injection technique. Given as C++ header, standalone Rust program or library.

FunctionStomping Description This is a brand-new technique for shellcode injection to evade AVs and EDRs. This technique is inspired by Module Stompin

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

Rusty Reflective DLL Injection - A small reflective loader in Rust 4KB in size
Rusty Reflective DLL Injection - A small reflective loader in Rust 4KB in size

Reflective Loader in Rust (4KB in size) A small reflective loader PoC in Rust. I remade this from my old project (https://github.com/memN0ps/arsenal-r

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

Shellcode Reflective DLL Injection (sRDI) Shellcode reflective DLL injection (sRDI) is a process injection technique that allows us to convert a given

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

secmem-proc is a crate designed to harden a process against low-privileged attackers running on the same system trying to obtain secret memory contents of the current process.

secmem-proc is a crate designed to harden a process against low-privileged attackers running on the same system trying to obtain secret memory contents of the current process. More specifically, the crate disables core dumps and tries to disable tracing on unix-like OSes.

A Rust on-site channel benchmarking helper. Inter-Process (async / busy) & Intra-Process (async single threaded / async multi threaded)

On-Site Rust Channel Benchmarking Helper Deploy on server to determine which public crates are the fastest for communicating in different architecture

Provides a single TUI-based registry for drm-free, wine and steam games on linux, accessed through a rofi launch menu.
Provides a single TUI-based registry for drm-free, wine and steam games on linux, accessed through a rofi launch menu.

eidolon A conversion of steam_suite to rust with additional features. Provides a single TUI-based registry for drm-free, wine and steam games on linux

⏮ ⏯ ⏭ A Rust library to easily read forwards, backwards or randomly through the lines of huge files.

EasyReader The main goal of this library is to allow long navigations through the lines of large files, freely moving forwards and backwards or gettin

A simple scanner that loops through ips and checks if a minecraft server is running on port 25565

scanolotl Scanolotl is a simple scanner that loops through ips and checks if a minecraft server is running on port 25565. Scanolotl can also preform a

Owner
Kurosh Dabbagh Escalante
nt authority\kurosh
Kurosh Dabbagh Escalante
A simple scanner that loops through ips and checks if a minecraft server is running on port 25565

scanolotl Scanolotl is a simple scanner that loops through ips and checks if a minecraft server is running on port 25565. Scanolotl can also preform a

JustFr33z 3 Jul 28, 2022
Rapidly Search and Hunt through Windows Event Logs

Rapidly Search and Hunt through Windows Event Logs Chainsaw provides a powerful ‘first-response’ capability to quickly identify threats within Windows

F-Secure Countercept 1.8k Dec 28, 2022
Security advisory database for Rust crates published through crates.io

RustSec Advisory Database The RustSec Advisory Database is a repository of security advisories filed against Rust crates published via https://crates.

RustSec 682 Jan 1, 2023
Rslide - A web service that allows you to move through multiple html pages in the browser like a slide, even without focusing on the app console or the browser. Currently only supports Windows.

rslide rslide is a web service that allows you to move through multiple html pages in the browser like a slide, even without focusing on the app conso

Jason Dongheng Lee 3 Jan 1, 2022
BONOMEN - Hunt for Malware Critical Process Impersonation

BOnum NOMEN - good name Hunt for Malware Critical Process Impersonation How it works The purpose of this tool is to detect process name impersonation

panda bear 42 Nov 10, 2022
Checks whether the process is running as root/sudo/admin permission in Windows and Unix systems

Is_sudo Checks if program is running as sudo in unix systems, or using admin permission in windows. Usage use is_sudo::check; use is_sudo::RunningAs;

Spark 2 Aug 12, 2022
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
Flexible DNS hijacking and proxy tool.

kungfu Flexible DNS hijacking and proxy tool. Features Flexible rules e.g. glob pattern domain, static routes, response CIDR Host file include /etc/ho

yinheli 30 Dec 22, 2022
The tool to make svg with triangles by length from two points.

The tool to make svg with triangles by length from two points.

null 2 Sep 27, 2021
Disaggregate zone-based origin/destination data to specific points

odjitter This crate contains an implementation of the ‘jittering’ technique for pre-processing origin-destination (OD) data. Jittering in a data visua

Dustin Carlino 5 Jun 29, 2022