Command Line Flags
Merlin is composed of the following components:
Merlin Server - The program that receives and handles Agent traffic and operator CLI commands to control the server and Agents
Merlin Agent - The post-exploitation command and control Agent that runs on a compromised host
Merlin CLI - The command line interface that allows operators to interact with the Merlin Server and Agents
Note
This page cover the Merlin Server program
Command Line Flags
$ ./merlin-server -h
Usage of merlin-server:
-addr string
The address to listen on for client connections (default "127.0.0.1:50051")
-debug
Enable debug logging
-extra
Enable extra debug logging
-password string
the password to for CLI RPC clients to connect to this server (default "merlin")
-secure
Require client TLS certificate verification
-tlsCA string
TLS Certificate Authority file path to verify client certificates
-tlsCert string
TLS certificate file path
-tlsKey string
TLS private key file path
-trace
Enable trace logging
-version
Print the version number and exit
addr
Note
The default address is 127.0.0.1:50051
The addr
flag specifies the address to listen on for Merlin CLI connections. This IS NOT the interface for Merlin
Agents to connect to. The Merlin Server uses gRPC for over TLS for CLI connections.
debug
The debug
flag enables the debug
log level for the Merlin Server and writes debug logs to the log file at
data/log/merlinServerLog.txt
.
{"time":"2023-10-17T14:43:27.333763628-04:00","level":"DEBUG","source":{"function":"github.com/Ne0nd0g/merlin/pkg/authenticators/opaque.(*Authenticator).Authenticate","file":"/merlin/pkg/authenticators/opaque/opaque.go","line":78},"msg":"Received OPAQUE message","OPAQUE type":1,"Agent":"6b25e714-93fb-45e6-85c8-38963efd09d9"}
{"time":"2023-10-17T14:43:27.333886943-04:00","level":"DEBUG","source":{"function":"github.com/Ne0nd0g/merlin/pkg/authenticators/opaque.(*Authenticator).registrationInit","file":"/merlin/pkg/authenticators/opaque/opaque.go","line":128},"msg":"Received new agent OPAQUE user registration initialization from 6b25e714-93fb-45e6-85c8-38963efd09d9"}
extra
The extra
flag enables the extra
log level for the Merlin Server and writes extra debug logs to the log file at
data/log/merlinServerLog.txt
. The extra
level inherently enables the debug
and trace
levels as well.
This level is primarily used to log HTTP requests and responses that contain a lot of data.
{"time":"2023-10-18T21:04:12.653012066-04:00","level":"DEBUG-8","source":{"function":"github.com/Ne0nd0g/merlin/pkg/servers/http.(*Handler).agentHandler","file":"/merlin/pkg/servers/http/handler.go","line":60},"msg":"HTTP Connection Details","host":"127.0.0.1:443","uri":"/","method":"POST","protocol":"HTTP/2.0","headers":{"Accept-Encoding":["gzip"],"Authorization":["Bearer eyJhbGciOiJkaXIiLCJjdHkiOiJKV1QiLCJlbmMiOiJBMjU2R0NNIiwidHlwIjoiSldUIn0..71SU4sj_ilrDyCCJ.lQxvax0K4U1rcIBWAk8tF2rZ_9Jxw_hyatTMkXWAO1YKtr8F9IdNEnlK8tJE0TwnKxK0UGd5KzuwpKBvfkyJIaTPxMELRTqW71CxRgnRlsFt8GvJrnY2E8_btJthKmZAaCl3DJEPocZuYDp0rB5VQSufsG0FPoJAuCw_p-cZAJntSGzlJqrjjIHi6z_ZI60vpz4N-sQrJWbOc2et07ULute2UVKuOcDNMH5MRMOATZqyFJUJlwkw9HVsml4.gH1Z6HrchxY_9DlRMfR_NA"],"Content-Length":["735"],"Content-Type":["application/octet-stream; charset=utf-8"],"User-Agent":["Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.85 Safari/537.36"]},"content length":735,"tls negotiated protocol":"h2","tls cipher suite":4865,"tls server name":""}
{"time":"2023-10-18T21:04:12.663746773-04:00","level":"DEBUG-8","source":{"function":"github.com/Ne0nd0g/merlin/pkg/servers/http.(*Handler).agentHandler","file":"/merlin/pkg/servers/http/handler.go","line":60},"msg":"HTTP Connection Details","host":"127.0.0.1:443","uri":"/","method":"POST","protocol":"HTTP/2.0","headers":{"Accept-Encoding":["gzip"],"Authorization":["Bearer eyJhbGciOiJkaXIiLCJjdHkiOiJKV1QiLCJlbmMiOiJBMjU2R0NNIiwidHlwIjoiSldUIn0..71SU4sj_ilrDyCCJ.lQxvax0K4U1rcIBWAk8tF2rZ_9Jxw_hyatTMkXWAO1YKtr8F9IdNEnlK8tJE0TwnKxK0UGd5KzuwpKBvfkyJIaTPxMELRTqW71CxRgnRlsFt8GvJrnY2E8_btJthKmZAaCl3DJEPocZuYDp0rB5VQSufsG0FPoJAuCw_p-cZAJntSGzlJqrjjIHi6z_ZI60vpz4N-sQrJWbOc2et07ULute2UVKuOcDNMH5MRMOATZqyFJUJlwkw9HVsml4.gH1Z6HrchxY_9DlRMfR_NA"],"Content-Length":["883"],"Content-Type":["application/octet-stream; charset=utf-8"],"User-Agent":["Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.85 Safari/537.36"]},"content length":883,"tls negotiated protocol":"h2","tls cipher suite":4865,"tls server name":""}
password
Warning
The default password is merlin
and should always be changed to prevent unauthorized access
The password
flag sets the password that Merlin CLI clients need in order to authenticate all gRPC requests.
secure
The secure
flag enables mutual TLS authentication requiring Merlin CLI clients to authenticate to the server.
Use the tlsCA
flag to provide a Certificate Authority file to verify client certificates.
tlsCA
The tlsCA
flag specifies the path to a Certificate Authority file to verify client certificates when the secure
flag is set.
tlsCert
Note
The Server will auto generate a self-signed TLS certificate if one is not provided
The tlsCert
flag specifies the path to a TLS certificate file for the Server to use for TLS connections.
tlsKey
The tlsKey
flag specifies the path to a TLS private key file for the Server to use for TLS connections.
trace
The trace
flag enables the trace
log level for the Merlin Server and writes trace logs to the log file at
data/log/merlinServerLog.txt
. The trace
level inherently enables the debug
level as well.
This level is primarily used to log the entry and exit of functions to troubleshoot.
{"time":"2023-10-19T07:03:44.030764364-04:00","level":"DEBUG-4","source":{"function":"github.com/Ne0nd0g/merlin/pkg/services/rpc.(*Service).Run","file":"/merlin/pkg/services/rpc/rpc.go","line":331},"msg":"entering into function","addr":"127.0.0.1:50051"}
{"time":"2023-10-19T07:03:44.031342997-04:00","level":"INFO","msg":"Starting gRPC server on 127.0.0.1:50051"}
{"time":"2023-10-19T07:03:52.609812218-04:00","level":"DEBUG","source":{"function":"github.com/Ne0nd0g/merlin/pkg/services/rpc.(*Service).authenticationStream","file":"/merlin/pkg/services/rpc/rpc.go","line":325},"msg":"authentication successful","Method":"/rpc.Merlin/Listen","Client":"127.0.0.1:39536"}
{"time":"2023-10-19T07:03:52.610193878-04:00","level":"DEBUG-4","source":{"function":"github.com/Ne0nd0g/merlin/pkg/services/rpc.(*Server).Listen","file":"/merlin/pkg/services/rpc/rpc.go","line":129},"msg":"entering into function","in":{"id":"a07b33cd-5b46-4e5c-81bb-38d06f91f5ee"}}
{"time":"2023-10-19T07:04:06.235845947-04:00","level":"DEBUG","source":{"function":"github.com/Ne0nd0g/merlin/pkg/services/rpc.(*Service).authentication","file":"/merlin/pkg/services/rpc/rpc.go","line":296},"msg":"authentication successful","Method":"/rpc.Merlin/GetListenerTypes","Client":"127.0.0.1:39536"}
{"time":"2023-10-19T07:04:06.236009755-04:00","level":"DEBUG-4","source":{"function":"github.com/Ne0nd0g/merlin/pkg/services/rpc.(*Server).GetListenerTypes","file":"/merlin/pkg/services/rpc/listener.go","line":163},"msg":"entering into function","context":{"Context":{"Context":{"Context":{"Context":{"Context":{}}}}}},"empty":{}}
{"time":"2023-10-19T07:04:06.236749705-04:00","level":"DEBUG","source":{"function":"github.com/Ne0nd0g/merlin/pkg/services/rpc.(*Service).authentication","file":"/merlin/pkg/services/rpc/rpc.go","line":296},"msg":"authentication successful","Method":"/rpc.Merlin/GetListenerDefaultOptions","Client":"127.0.0.1:39536"}
{"time":"2023-10-19T07:04:06.236834196-04:00","level":"DEBUG-4","source":{"function":"github.com/Ne0nd0g/merlin/pkg/services/rpc.(*Server).GetListenerDefaultOptions","file":"/merlin/pkg/services/rpc/listener.go","line":59},"msg":"entering into function","context":{"Context":{"Context":{"Context":{"Context":{"Context":{}}}}}},"in":{"data":"HTTPS"}}
{"time":"2023-10-19T07:04:07.968606945-04:00","level":"DEBUG","source":{"function":"github.com/Ne0nd0g/merlin/pkg/services/rpc.(*Service).authentication","file":"/merlin/pkg/services/rpc/rpc.go","line":296},"msg":"authentication successful","Method":"/rpc.Merlin/CreateListener","Client":"127.0.0.1:39536"}
{"time":"2023-10-19T07:04:07.968773738-04:00","level":"DEBUG-4","source":{"function":"github.com/Ne0nd0g/merlin/pkg/services/rpc.(*Server).CreateListener","file":"/merlin/pkg/services/rpc/listener.go","line":44},"msg":"entering into function","context":{"Context":{"Context":{"Context":{"Context":{"Context":{}}}}}},"in":{"options":{"Authenticator":"OPAQUE","Description":"Default HTTP Listener","Interface":"127.0.0.1","JWTKey":"ZVdxdlFUVnJhcXNQV0doRkRoV2pwWk5PSk1mRXBLTkY=","JWTLeeway":"1m","Name":"My HTTP Listener","PSK":"merlin","Port":"443","Protocol":"HTTPS","Transforms":"jwe,gob-base","URLS":"/","X509Cert":"/merlin/data/x509/server.crt","X509Key":"/merlin/data/x509/server.key"}}}
version
The version
flag prints the version number of the Merlin Server and exits.
$ ./merlin-server -version
Merlin Version: 2.0.0, Build: nonRelease
Logging
Note
The Server typically requires administrative privileges so that it can bind to an interface and TCP port. The log file will be created with the permissions of the user that started the Merlin Server.
The Merlin Server creates a log file in the data/log
directory called merlinServerLog.txt
and ALSO writes
messages to STDOUT where the server was executed. The default logging level is INFO
. Use the debug
, trace
,
and extra
flags to enable more verbose logging.
{"time":"2023-10-17T15:37:38.91950926-04:00","level":"INFO","msg":"Created new TLS certificate","Serial":142904993534574102007199776395950920709,"Subject":["Merlin"],"NotBefore":"2023-10-17T15:37:38.91050229-04:00","NotAfter":"2024-10-22T15:37:38.910516592-04:00"}
{"time":"2023-10-17T15:37:38.921245266-04:00","level":"INFO","msg":"Starting gRPC server on 127.0.0.1:50051"}
{"time":"2023-10-17T15:39:27.784636096-04:00","level":"INFO","msg":"Registered new RPC client with ID 9d9a3e2a-ecee-49d5-bbc8-c95a6d5c54d6"}
{"time":"2023-10-17T15:39:34.801648979-04:00","level":"INFO","msg":"Create new listener","protocol":"HTTPS","address":"127.0.0.1:443","name":"My HTTP Listener","id":"f726d4b2-fd2f-44aa-bb60-ea8ab3731440","authenticator":"OPAQUE","transforms":"[jwe gob-base]"}
{"time":"2023-10-17T15:39:34.803925949-04:00","level":"INFO","msg":"Certificate was not found at: /merlin/data/x509/server.crt. Creating in-memory x.509 certificate used for this session only"}
{"time":"2023-10-17T15:39:48.885672042-04:00","level":"INFO","msg":"New authenticated agent checkin for 0db4203d-1b5a-40cb-9800-8e75cdf04013"}
Mutual TLS
The Merlin Server can be configured to use mutual TLS authentication with the Merlin CLI (not for Merlin Agent connections).
Use the secure
flag to enable mutual TLS authentication and the tlsCA
flag to provide a Certificate Authority
file that was used to sign the client certificates.