Merlin v0.9 Beta releases: cross-platform post-exploitation HTTP/2 Command & Control server and agent
Merlin is a cross-platform post-exploitation HTTP/2 Command & Control server and agent written in golang.
An introductory blog post can be found here.
Evade network detection during a penetration test/red team exercise by using a protocol that existing tools aren’t equipped to understand or inspect. Merlin is post-exploitation tool that is easily cross-compiled to run on any platform to achieve command and control of a host.
HTTP/2 is a newly ratified protocol documented under RFC 7540 that aims to solve some of the problems with HTTP/1.x and provide functionality to support current web application operations. HTTP/2 communications are multiplexed, bi-direction connections that do not end after one request and response. Additionally, HTTP/2 is a binary protocol that makes it more compact, easy to parse, and not human readable without the use of an interpreting tool.
An HTTP/2 connection can be setup by upgrading a HTTP/1.x connection using the `Upgrade` header or during the negotiation of a TLS encrypted channel. Application-Layer Protocol Negotiation (ALPN) is a TLS 1.2 extension that is required to setup a HTTP/2 connection identified with the `h2` protocol string. TLS versions less than 1.2 are not equipped to negotiate a HTTP/2 connection. Oddly enough, the client will perform one final check to ensure that the server can speak HTTP/2 by sending the string PRISM. This reminds me of the NSA PRISM program.
The HTTP/2 RFC also requires the use of Perfect Forward Secrecy (PFS) cipher suites and recommends that all non-PFS-enable cipher suites are black listed. The RFC reads: “An HTTP/2 implementation MAY treat the negotiation of any of the following cipher suites with TLS 1.2 as a connection error of type INADEQUATE_SECURITY”. The list of adequate cipher suites are comprised of Elliptic Curve Diffie-Helman Exchange (ECDHE) and ephemeral Diffie-Helman Exchange (DHE) key exchange methods that benefit from PFS. When PFS cipher suites are used, captured traffic cannot be decrypted using only the server’s private key. In order to decrypt the traffic, the client’s session keying information is required. If you don’t control the client or you’re not using a client built on the NSS library (i.e. Firefox or cURL), this information can be hard to obtain.
HTTP/2 communications are expected to take place over TLS encrypted channels using PFS enabled cipher suites. Therefore, inspecting HTTP/2 traffic proves difficult. Another obstacle is that currently available WAF/IDS/IPS solutions are incapable of understanding the HTTP/2 protocol even if they were able to decrypt traffic for inspection. This combination of encryption and the lack of protocol support from inspecting tools, provide a great opportunity to evade inspection. Some possible solutions are to terminate HTTP/2 connections and downgrade them to HTTP/1.1, but that would remove all of the efficiencies gained with using HTTP/2. Additional options include downgrading the encryption to a non-PFS enable cipher suite or use a terminating proxy.
You can find additional information on HTTP/2 in a paper I wrote titled Practical Approach to Detecting and Preventing Web Application Attacks over HTTP/2.
Changelog v0.9 Beta
- Incorporated a fork of
github.com/CUCyber/ja3clientallowing the Merlin agent to establish TLS connections from a JA3 signature
ja3to agent.New() function
-ja3to agent command line arguments and JA3 to Make file for hard coding initial signature
PSK=to Make file
set ja3to Agent menu allowing operators to change TLS client profile at any time
- Created new
merlinClientinterface to handle abstract http clients and changed the Agent.Client to that interface
- Updated Dockerfile to support Go modules
- Added support for plain-text HTTP/1.1 (http) and plain-text HTTP/2.0 (h2c)
- Increased initial JWT lifetime from 10 seconds to 60 seconds
- BASH module
linux\x64\bash\exec\bash.jsonto run a single BASH command across all agents
- PowerShell module
windows\x64\powershell\exec\powershell.jsonto run a single PowerShell command across all agents
- macOS Orchard module
- macOS HealthInspector module
- macOS Bifrost module
darwin\x64\objective-c\kerberos\bifrost.jsonan Objective-C library and console to interact with Heimdal APIs for macOS Kerberos
- macOS Venator module
darwin\x64\python\enumeration\venator.jsona python tool used to gather data for proactive detection of malicious activity on macOS devices
- macOS SwiftBelt module
darwin\x64\swift\enumeration\swiftbelt.jsonA MacOS enumerator similar to @harmjoy’s Seatbelt
unsetcommand to modules to reset an option to nil
- Job result messages now include the agent ID
- Added new Listeners menu to create or remove multiple agent listeners per running Merlin Server instance
- Added new
listenerspackages to handle new Listeners menu
- A single listener can now handle multiple URLS instead of just
- Can enable/disable verbose and debug output from CLI main menu with
set vervose true
- Added API packages for agents, listeners, modules, and messages to separate the CLI from the server
- Added a channel for user messages that the CLI reads from and then prints them to STDOUT
- Added 4 modules from the D(COM) V(ulnerability) S(canner) Framework to
- Added Sphinx documentation to
docs\to replace GitHub wiki with ReadTheDocs
- Catch errors returned when starting a server (i.e insufficient privileges to bind to a port)
- hq listener would fail when in-memory x.509 certificates were used
- Invoke-M.i.m.i.k.a.t.z module points to the updated version of M.i.m.i.k.a.t.z (2.2.0) in the Empire 3.0 repository
- Issue 88 – Set option will now take all arguments after a space
- Added module type to LinEnum, MimiPenguin, and SwapDigger
- Issue 71 – Run a module against all agents
- Made module variables case-insensitive. Values will still match input case
CheckInsecureFingerprint()to utils package
- Moved JWT create, validate, decrypt functions to the utils package
- Moved Agent handling code to a new handlers package
- All packages should be sending messages to the CLI through the message API package
- Upgraded gopaque library to v0.1.0
- Upgraded kyber library to v3.0.12
- Removed all command line arguments from Merlin Server executable in favor of run-time Listeners menu
- OPAQUE go library used static decryption key and allowed EnvU to be decrypted without the correct password (PwdU) gopaque – Issue 2
- Symmetric encryption key was use with OPAQUE User Authentication instead of OPAQUE password (PwdU)
The quickest and easiest way to start using Merlin is to download the pre-compiled binary files found in the Releases section. The files are compressed into 7z archives and are password protected to prevent Anti-Virus inspection when downloading. The password is merlin.
In order to run Merlin from source, or to compile Merlin yourself, the Go programing language must be installed on the system. However, if you just want to run a pre-compiled version, you do not need to install Go.
Download and install GO: https://golang.org/doc/install
Ensure your GOPATH environment variable is set
Running Merlin Server
Merlin Server can be run as a script or compiled and run as a standalone binary file.
It is recommended to download the compiled binaries from the Releases section
Run Merlin Server as a script:
git clone https://github.com/Ne0nd0g/merlin/ go run cmd/merlinserver/main.go
Compile Merlin Server into an executable:
make server-windows or make server-linux or make server-darwin
Merlin Server Usage
Merlin Server Commands
Merlin is equipped with a tab completion system that can be used to see what commands are available at any given time. Hit double tab to get a list of all available commands.
exit Exit and close Merlin help Show Merlin help menu quit Exit and close Merlin ? Show Merlin help menu
These are the commands to control an agent from the server. Tab completion can be used to select an Agent’s identifier.
agent cmd <agent id> <command> A command to run on a remote agent
agent control <agent id> <command> Configure/Control a remote agent (not the host)
agent info <agent id> Display all information for an agent
agent list List agents
By default, Merlin will load server.crt and server.key from the data/x509/ directory. You must generate your own certificate pair and place them in this directory.
Third Party Libraries
The 3rd party libraries used with Merlin are kept in the vendor directory. This project will default to using the library files in that folder.
Running Merlin Agent
The agent portion of Merlin should be run as a compiled binary file on a target host.
It is recommended to download the compiled binaries from the Releases section
Ensure your GOPATH environment variable is set!
Compile Merlin Agent into an executable
make agent-windows or make agent-linux or make agent-darwin
Merlin Agent can also be compiled without Make, using just go. To compile Merlin Agent with your hard-coded Merlin Server’s address, so it doesn’t have to specify on the command line, including -ldflags -X main.URL=https://acme.com:443/
Example: go build -o merlinagent.exe -ldflags “-X main.URL=https://acme.com:443/” cmd/merlinagent/main.go
Run Merlin Agent as a script: go run cmd/merlinagent/main.go
Copyright (C) 2017 Ne0nd0g