User Defined Reflective Loader (UDRL)
Introduction
The User Defined Reflective Loader (UDRL) is a way for Cobalt Strike operators to write their own reflective loader for Beacons. They are particularly helpful for increasing evasiveness by allowing operators the flexibility of not being constrained to the default loader.
In general, reflective DLL injection is typically used as a persistence mechanism after initial access has been achieved through other means like malicious Office macros or executable files.
Reflective Loading
A Cobalt Strike beacon is just a DLL. Fundamentally, a reflective loader must:
Allocate some memory.
Copy the target DLL into that memory allocation.
Parse the target DLL’s imports/load the required modules/resolve function addresses.
Fix DLL base relocations.
Locate the DLL’s Entry Point.
Execute the Entry Point.
Configuring Compiler
To compile the project and ensure it executes properly we need to add the following flags in our compiler options. I'm using Mingw32.
Set Entrypoint:
-e DllMain
Link Windows DLL's
-lntdll -luser32 -DWIN_X64
Create standalone, and add extra:
-g -s -w -Wall -Wextra -masm=intel -shared
These are the outlines from Fortas site:
Optimization – We’ve enabled several of Visual Studio’s different Optimization settings and opted to favor smaller code where possible. However, at certain points in the template we’ve disabled it to ensure our code works as expected.\
Building Reflective Loader
There are many methods we can use to create a Reflective Loader. Here are some common ones.
Double Pulsar Approach
The Double Pulsar approach differs from traditional Reflective Loaders as it is not compiled directly into the DLL, but prepended in front of it. This approach allows it to reflectively load ANY DLL.
This works by extracting the loader from the compiled executable and prepending it to the Beacon.
Below shows the difference between Double Pulsar & Stephen Fewers Reflective Loader.
Function Positioning
As stated above, the Double Pulsar approach prepends the loader at the very start of the Beacon file. For this to work we need to know the following:
Make sure the loaders entry point sits at the very start of the Beacons shellcode.
Make sure we can find the end of the loader. (In order to find the start of the Beacon). (code_seg)
We will place
ReflectiveLoader()
function within.text$a
to ensure that it is positioned at the start of the.text.
All remaining functions will be in
.text$b
to ensure they come after ReflectiveFunction().The final
LdrEnd
function will be.text$z
. This is an important function as it allows us to find the end of the loader, and the start of the Beacons shellcode.
Last updated