Exploitation Tools

Caro Kann – Evading Kernel Scans with Encrypted Shellcode

In the ever-evolving game of cybersecurity, encrypted shellcode injection emerges as a formidable method to sidestep defenses.

This article unveils the “Caro Kann Defense”—a savvy technique designed to evade memory scans, drawing inspiration from the world of chess.

Dive in to uncover the strategy behind this stealthy approach. Encrypted shellcode Injection to avoid memory scans triggered from Kernel (ETWti / Kernel Callbacks).

Specific combinations of Windows APIs, e.g. for injection into a remote process can lead to a memory scan:

Typically, the scan can be triggered from Userland via hooks on the execute primitive such as NtCreateThreadEx.

But more and more EDR vendors also tend to trigger scans from Kernel, for example after the Kernel Callback PsSetCreateThreadNotifyRoutine() a scan could be triggered.

But what if there is no executable memory section with known malicious code? Well, no alert for an detection I guess.

The idea is as follows:

  • Inject encrypted known malicious payload into an RW section
  • Inject custom non known malicious shellcode into an RX section
  • Create a remote Thread on the second shellcode

The custom shellcode will than:

  • Sleep for an amount x (to avoid memory scans triggered by the execute primitive of Thread creation)
  • Decrypt the first known malicious shellcode
  • Protect the section from RW to RX
  • Make a direct JMP to the known malicious shellcode

Setup

On linux, the PIC-Code was found to be compiled correctly with mingw-w64 version version 10-win32 20220324 (GCC).

With that version installed, the shellcode can be compiled with a simple make and extracted from the .text section via bash extract.sh.

If you’d like to compile from Windows, you can use the following commands:

as -o adjuststack.o adjuststack_as.asm
gcc ApiResolve.c -Wall -m64 -ffunction-sections -fno-asynchronous-unwind-tables -nostdlib -fno-ident -O2 -c -o ApiResolve.o -Wl,--no-seh
gcc DecryptProtect.c -Wall -m64 -masm=intel -ffunction-sections -fno-asynchronous-unwind-tables -nostdlib -fno-ident -O2 -c -o decryptprotect.o -Wl,--no-seh
ld -s adjuststack.o ApiResolve.o decryptprotect.o -o decryptprotect.exe
gcc extract.c -o extract.exe
extract.exe

You also need to have Nim installed for this PoC.

After installation, the dependencies can be installed via the following oneliner:

nimble install winim ptr_math

The PoC can than be compiled with:

nim c -d:release -d=mingw -d:noRes CaroKann.nim # Cross compile
nim c -d:release CaroKann.nim # Windows

Any payload can be XOR encrypted with the given encrypt.cpp code:

Usage: encrypter.exe input_file output_file

The encrypted payload can than be embedded in the PoC via the following line:

const shellcode = slurp"<encrypted.bin>"

OPSec Improvement Ideas

  • Bypass Userland-Hooks for Injection (although not really needed, but for fun)
  • Back Payload(s) by legitimate DLL (Module Stomping)
  • Load C2-Dlls via the first Shellcode – which can avoid memory scans triggered by module loads
  • Use ThreadlessInject or DLLNotificationInjection instead of Remote Thread Creation

OPSec considerations For C2-Payloads

  • Should use Sleep encryption, otherwise the payload will get flagged later
  • Should use Unhooking first or (in)direct Syscalls
  • Should use Proxy module loading
Tamil S

Tamil has a great interest in the fields of Cyber Security, OSINT, and CTF projects. Currently, he is deeply involved in researching and publishing various security tools with Kali Linux Tutorials, which is quite fascinating.

Recent Posts

PwnedPasswordsDownloader – Efficient Downloading Of HIBP Password Hashes Using Curl Parallelism

Thanks for HIBP and this downloader. At first I was considering using it, but the…

3 days ago

Cybersecurity Conferences – A Comprehensive Slide Collection

Comprehensive repository for presentation slides from major cybersecurity conferences held in 2023 and 2024. It…

7 days ago

DLL Proxy Generator – Harnessing Advanced Proxy Capabilities

Generate a proxy dll for arbitrary dll, while also loading a user-defined secondary dll. In…

7 days ago

DLL Universal Patcher – A Comprehensive Guide To Advanced Binary Patching

DLL Universal Patcher is a flexible and convenient code patcher that doesn't touch the files…

7 days ago

RustiveDump : A Rust-Based Tool For Efficient Memory Dumping Of lsass.exe

RustiveDump is a Rust-based tool designed to dump the memory of the lsass.exe process using…

1 week ago

SharpExclusionFinder – Streamlining Windows Defender Exclusion Checks With Advanced Scanning Capabilities

This C# program finds Windows Defender folder exclusions using Windows Defender through its command-line tool…

1 week ago