Freeze.rs is a payload toolkit for bypassing EDRs using suspended processes, direct syscalls written in RUST

Overview



Freeze.rs

More Information

If you want to learn more about the techniques utilized in this framework, please take a look at SourceZero Blog and the original tool.

Description

Freeze.rs is a payload creation tool used for circumventing EDR security controls to execute shellcode in a stealthy manner. Freeze.rs utilizes multiple techniques to not only remove Userland EDR hooks, but to also execute shellcode in such a way that it circumvents other endpoint monitoring controls.

Creating A Suspended Process

When a process is created, Ntdll.dll is the first DLL that is loaded; this happens before any EDR DLLs are loaded. This means that there is a bit of a delay before an EDR can be loaded and start hooking and modifying the assembly of system DLLs. In looking at Windows syscalls in Ntdll.dll, we can see that nothing is hooked yet. If we create a process in a suspend state (one that is frozen in time), we can see that no other DLLs are loaded, except for Ntdll.dll. You can also see that no EDR DLLs are loaded, meaning that the syscalls located in Ntdll.dll are unmodified.

Address Space Layout Randomization

To use this clean suspended process to remove hooks from Freeze.rs loader, we need a way to programmatically find and read the clean suspended process' memory. This is where address space layout randomization (ASLR) comes into play. ASLR is a security mechanism to prevent stack memory corruption-based vulnerabilities. ASLR randomizes the address space inside of a process, to ensure that all memory-mapped objects, the stack, the heap, and the executable program itself, are unique. Now, this is where it gets interesting because while ASLR works, it does not work for position-independent code such as DLLs. What happens with DLLs, (specifically known system DLLs) is that the address space is randomized once at boot time. This means that we don't need to enumerate a remote process information to find the base address of its ntdll.dll because it is the same in all processes, including the one that we control. Since the address of every DLL is the same place per boot, we can pull this information from our own process and never have to enumerate the suspended process to find the address.

With this information, we can use the API ReadProcessMemory to read a process' memory. This API call is commonly associated with the reading of LSASS as part of any credential-based attack; however, on its own it is inherently not malicious, especially if we are just reading an arbitrary section of memory. The only time ReadProcessMemory will be flagged as part of something suspicious is if you are reading something you shouldn't (like the contents of LSASS). EDR products should never flag the fact that ReadProcessMemory was called, as there are legitimate operational uses for this function and would result in many false positives.

We can take this a step further by only reading a section of Ntdll.dll where all syscalls are stored - its .text section, rather than reading the entire DLL.

Combining these elements, we can programmatically get a copy of the .text section of Ntdll.dll to overwrite our existing hooked .text section prior to executing shellcode.

ETW Patching

ETW utilizes built-in syscalls to generate this telemetry. Since ETW is also a native feature built into Windows, security products do not need to "hook" the ETW syscalls to access the information. As a result, to prevent ETW, Freeze.rs patches numerous ETW syscalls, flushing out the registers and returning the execution flow to the next instruction. Patching ETW is now default in all loaders.

Shellcode

Since only Ntdll.dll is restored, all subsequent calls to execute shellcode need to reside in Ntdll.dll. Using Rust's NTAPI Crate (note you can do this in other languages but in Rust, its quite easy to implement) we can define and call the NT syscalls needed to allocate, write, and protect the shellcode, effectively skipping the standard calls that are located in Kernel32.dll, and Kernelbase.dll, as these may still be hooked.

With Rust's NTAPI crate, you can see that all these calls do not show up under ntdll.dll, however they do still exist with in the process.

As a result:

Why Rust?

This started out a fun project to learn Rust and has grown into its own framework.

Contributing

Freeze.rs was developed in Rust.

Install

If Rust and Rustup is not installed please install them. If you are compiling it from OSX or Linux sure you have the target "x86_64-pc-windows-gnu" added. To so run the following command:

rustup target add x86_64-pc-windows-gnu

Once done you can compile Freeze.rs, run the following commands, or use the compiled binary:

cargo build --release

From there the compiled version will be found in in target/release (note if you don't put --release the file will be in target/debug/ )

Help


    ___________                                                      
    \_   _____/______   ____   ____ ________ ____     _______  ______
     |    __) \_  __ \_/ __ \_/ __ \\___   // __ \    \_  __ \/  ___/
     |     \   |  | \/\  ___/\  ___/ /    /\  ___/     |  | \/\___ \ 
     \___  /   |__|    \___  >\___  >_____ \\___  > /\ |__|  /____  >
         \/                \/     \/      \/    \/  \/            \/    
                                        (@Tyl0us)
    Soon they will learn that revenge is a dish... best served COLD & Rusty...
    
     

USAGE:
    Freeze-rs [FLAGS] [OPTIONS]

FLAGS:
    -c, --console    Only for Binary Payloads - Generates verbose console information when the payload is executed. This
                     will disable the hidden window feature
    -h, --help       Prints help information
    -n, --noetw      Disables the ETW patching that prevents ETW events from being generated.
    -s, --sandbox    Enables sandbox evasion by checking:
                                 Is Endpoint joined to a domain?
                                 Does the Endpoint have more than 2 CPUs?
                                 Does the Endpoint have more than 4 gigs of RAM?
    -V, --version    Prints version information

OPTIONS:
    -E, --Encrypt <ENCRYPT>    Encrypts the shellcode using either AES 256, ELZMA or RC4 encryption
    -I, --Input <INPUT>        Path to the raw 64-bit shellcode.
    -O, --Output <OUTPUT>      Name of output file (e.g. loader.exe or loader.dll). Depending on what file extension
                               defined will determine if Freeze makes a dll or exe.
    -p, --process <PROCESS>    The name of process to spawn. This process has to exist in C:\Windows\System32\. Example
                               'notepad.exe'  
    -e, --export <export>      Defines a custom export function name for any DLL.

Binary vs DLL

Freeze.rs can generate either a .exe or .dll file. To specify this, ensure that the -O command line option ends with either a .exe for binaries or .dll for dlls. No other file types are currently supported. In the case of DLL files, Freeze.rs can also add additional export functionality. To do this use the -export with specific export function name.

Encryption

Encrypting shellcode is an important technique used to protect it from being detected and analyzed by EDRs and other security products. Freeze.rs comes with multiple methods to encrypt shellcode, these include AES, ELZMA, and RC4.

AES

AES (Advanced Encryption Standard) is a symmetric encryption algorithm that is widely used to encrypt data. Freeze.rs uses AES-256 bit size to encrypt the shellcode. The advantage of using AES to encrypt shellcode is that it provides strong encryption and is widely supported by cryptographic libraries. However, the use of a fixed block size can make it vulnerable to certain attacks, such as the padding oracle attack.

ELZMA

ELZMA is a compression and encryption algorithm that is often used in malware to obfuscate the code. To encrypt shellcode using ELZMA, the shellcode is first compressed using the ELZMA algorithm. The compressed data is then encrypted using a random key. The encrypted data and the key are then embedded in the exploit code. The advantage of using ELZMA to encrypt shellcode is that it provides both compression and encryption in a single algorithm. This can help to reduce the size of the exploit code and make it more difficult to detect.

RC4

RC4 is a symmetric encryption algorithm that is often used in malware to encrypt shellcode. It is a stream cipher that can use variable-length keys and is known for its simplicity and speed.

Console

Freeze.rs utilizes a technique to first create the process and then move it into the background. This does two things - first it helps keep the process hidden, and second, avoids being detected by any EDR product. Spawning a process right away in the background can be very suspicious and an indicator of maliciousness. Freeze.rs does this by calling the ‘GetConsoleWindow’ and ‘ShowWindow’ Windows function after the process is created and the EDR’s hooks are loaded, and then changes the windows attributes to hidden.

If the -console command-line option is selected, Freeze.rs will not hide the process in the background. Instead, Freeze.rs will add several debug messages displaying what the loader is doing.

You might also like...
call rest api using rust + yew
call rest api using rust + yew

Call Rest API With Rust and Yew: USA Weather Service API Open Data YEW Complete Tutorial YouTube Video https://youtu.be/dSJULWtd3y0 How to run trunk s

plugy empowers you to construct agnostic dynamic plugin systems using Rust and WebAssembly.

plugy plugy is a plugin system designed to enable the seamless integration of Rust-based plugins into your application. It provides a runtime environm

Lisp but using indentations

Calcit Runner An interpreter for Calcit snapshot file. Home http://calcit-lang.org/ APIs http://apis.calcit-lang.org/ Running Calcit Editor with compa

Python bindings for akinator-rs using pyo3

Akinator-py python bindings for akinator-rs using pyo3 Installation Prebuilt wheels are uploaded onto pypi, if you platform is supported, you can inst

Low level tooling for WebAssembly in JavaScript using wasm-tools

js-wasm-tools js-wasm-tools compiles some of the API of wasm-tools to JavaScript and WebAssembly via wasm-bindgen. This offers low level tooling for W

A macro to generate constructor to instanicate structs from JsValue using duck-typing.

ducktor ducktor is a Rust crate that allows you to create types from wasm_bindgen::JsValue using duck typing. With ducktor, you can define a struct th

RDF playground using WASM-compiled Sophia

SoWasm: an RDF playground based on Sophia This started as an experiment of compiling Sophia into WebAssembly, and grew into a (hopefully) useful playg

Native Ruby extensions written in Rust

Ruru (Rust + Ruby) Native Ruby extensions in Rust Documentation Website Have you ever considered rewriting some parts of your slow Ruby application? J

A script language like Python or Lua written in Rust, with exactly the same syntax as Go's.

A script language like Python or Lua written in Rust, with exactly the same syntax as Go's.

Comments
  • Error report while using your program

    Error report while using your program

    Hello,

    I wanted to inform you that I encountered some issues while using your program. The following errors were detected: E0405, E0412, E0432, E0433, E0463.

    I found that these errors come with detailed explanations and that more information can be obtained by using the command rustc --explain E0405.

    When attempting to compile typenum using the cargo build command, it was reported that there were 150 previous errors, and the command ultimately failed.

    I hope you can assist me in resolving this issue. Thank you in advance for your efforts.

    Best regards,

    opened by majid-derkaoui 9
  • Freeze Encrypting error

    Freeze Encrypting error

    Hi, I am looking to find a way to use freeze to encrypt cobalt payloads, I was attempting with golang version but didn't work, I now, I am trying to make this Rust version work.

    I am facing this error posted below, it says "No such file or directory" }', build/src/build.rs:23:10 Could you help to understand what I am missing? Thank you

    image

    opened by calex80 4
  • Failed to open Cargo.toml: Os

    Failed to open Cargo.toml: Os

    [!] Selected Process to Suspend: notepad.exe [*] Encrypting Shellcode Using AES Encryption [*] Shellcode Encrypted [*] Created new Rust project: 1 thread 'main' panicked at 'Failed to open Cargo.toml: Os { code: 3, kind: NotFound, message: "系统找不到指定的路径。" }', build\src/build.rs:30:10 note: run with RUST_BACKTRACE=1 environment variable to display a backtrace

    opened by Burden-xy 9
  • Msfvenom shellcode not executing on Windows 11 Workstation

    Msfvenom shellcode not executing on Windows 11 Workstation

    Hello,

    I'm testing your packer, and it seems that the embedded shellcode is not executing properly.

    I generated the shellcode with the following command: msfvenom --platform Windows -p windows/x64/exec CMD=calc.exe -f raw -o calc.raw

    Then, I used Freeze.rs like this:

    git clone https://github.com/optiv/Freeze.rs.git
    cd Freeze.rs/
    cargo run -- --Input calc.raw --console -O calc.exe
    

    image

    When executed, the packer is looping and spamming suspended Notepad.exe processes. The shellcode is thus not executed: image

    To make sure that the shellcode is working properly, I tested with RustPacker using the following command: cargo run -- -f shared/calc.raw -i syscrt -e aes

    This time, the shellcode is properly executed: image

    The target system I tested Freeze.rs against is a Windows 11 Pro 21H2.

    All the best, Nariod

    opened by Nariod 3
Releases(v1.1)
Owner
Optiv Security
Optiv Security is a security solutions integrator that enables clients to reduce risk by taking a strategic approach to cybersecurity.
Optiv Security
A timer toolkit that is generic over the underlying timer implementation.

timer-kit A timer toolkit that is generic over the underlying timer implementation. This crate does not implement any platform-specific timer but uses

null 4 Mar 4, 2023
A Web-App written in Rust with Yew, using the same SyntaxHighlighter from Google Code Archive as planetb.ca

PlanetB SyntaxHighlighter About This is a small app, providing static files to have a frontend to format your code so you can paste it with styles to

Christof Weickhardt 2 Dec 14, 2022
Lua bytecode parser written in Rust using nom, part of metaworm's lua decompiler

luac-parser (中文) lua字节码解析器, 目前支持 lua51, lua53, lua54 这是目前效果最好的lua反编译器 metaworm's luadec 的一部分 可以基于此代码定制你所需的lua字节码解析器,编译成WASM,让metaworm's luadec加载使用,来反编

metaworm 4 Mar 16, 2023
Rust-ffi-guide - A guide for doing FFI using Rust

Using unsafe for Fun and Profit A guide to traversing the FFI boundary between Rust and other languages. A rendered version is available here. This gu

Michael Bryan 261 Dec 1, 2022
Easy way to write Node.js module using Rust

node-bindgen Easy way to write native Node.js module using idiomatic Rust Features Easy: Just write idiomatic Rust code, node-bindgen take care of gen

InfinyOn 346 Jan 3, 2023
Safe Rust <---> GraalVM Polyglot bindings using procedural macros

The class macro is the primary way to generate bindings to Java types; it will generate a struct (with generics if specified) that implements Pass and Receive and has all the methods you give stubs for. The methods generated can be used like normal rust methods, however mutability is not enforced. The fully-qualified type name should precede a block containing method and constructor stubs. Java primitives like char, int, and byte are aliased to corresponding Rust types.

Alec Petridis 33 Dec 28, 2022
Rust Lambda using Serverless

Rust Serverless Lambda Template

섹스 신청서 4 May 31, 2022
Parametric surfaces drawn using the Rust + WASM toolchain with WebGL, React, and TypeScript.

Parametric Surfaces in the Browser My.Movie.3.mp4 Wanted to experiment with WebGL using the Rust + WASM toolchain, with React and TypeScript to glue e

Benji Nguyen 45 Oct 21, 2022
A collection of unsound rust functions using entirly *safe* code

A collection of unsound rust functions using entirly *safe* code

null 2 Sep 6, 2022
Realtime audio processing / synthesis using Rust/WASM in the browser.

Rust Audio About This repo is my investigation into using Rust for creative audio coding on various platforms (e.g. desktop, web, etc.), but especiall

Austin Theriot 30 Jan 5, 2023