Skip to content

Commit

Permalink
Merge branch 'dev'
Browse files Browse the repository at this point in the history
  • Loading branch information
Ne0nd0g committed Feb 13, 2021
2 parents 8a21cee + a640080 commit be117de
Show file tree
Hide file tree
Showing 123 changed files with 21,261 additions and 4,500 deletions.
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "data/src/cobbr/SharpGen"]
path = data/src/cobbr/SharpGen
url = https://github.com/cobbr/SharpGen
32 changes: 28 additions & 4 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,41 @@ FROM golang:stretch
# > sudo docker build -t merlin .

# To start the Merlin Server, run
# > sudo docker run -it -p 443:443 --mount type=bind,src=/tmp,dst=/go/src/github.com/Ne0nd0g/merlin/data merlin
# > sudo docker run -it -p 443:443 -v merlinAgents:/go/src/github.com/Ne0nd0g/merlin/data/agents -v merlinLog:/go/src/github.com/Ne0nd0g/merlin/data/log -v merlinTemp:/go/src/github.com/Ne0nd0g/merlin/data/temp merlin:latest

RUN apt-get update && apt-get install -y git make vim gcc-mingw-w64
# Update APT
RUN apt-get update
RUN apt-get upgrade -y
RUN apt-get install -y apt-transport-https

# Install Microsoft package signing key
RUN wget --quiet -O - https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > microsoft.asc.gpg
RUN mv microsoft.asc.gpg /etc/apt/trusted.gpg.d/
RUN wget --quiet https://packages.microsoft.com/config/debian/9/prod.list
RUN mv prod.list /etc/apt/sources.list.d/microsoft-prod.list
RUN chown root:root /etc/apt/trusted.gpg.d/microsoft.asc.gpg
RUN chown root:root /etc/apt/sources.list.d/microsoft-prod.list

# Install Microsoft .NET Core 2.1 SDK
RUN apt-get update
RUN apt-get install -y dotnet-sdk-2.1

RUN apt-get install -y git make vim gcc-mingw-w64

# Clone Merlin
WORKDIR $GOPATH/src/github.com/Ne0nd0g
RUN git clone https://github.com/Ne0nd0g/merlin
RUN git clone --recurse-submodules https://github.com/Ne0nd0g/merlin

# Build SharpGen
WORKDIR $GOPATH/src/github.com/Ne0nd0g/merlin/data/src/cobbr/SharpGen
RUN dotnet build -c release

WORKDIR $GOPATH/src/github.com/Ne0nd0g/merlin
RUN go mod download
RUN make generate-agents

VOLUME ["data"]
# > sudo docker volume inspect merlinAgents to find data location on host OS
#VOLUME ["merlinAgents:data/agents", "merlinLog:data/log", "merlinTemp:data/temp"]
EXPOSE 443

CMD ["go", "run", "cmd/merlinserver/main.go"]
21 changes: 19 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,21 @@ PROTO ?= h2
XPROTO =-X main.protocol=$(PROTO)
JA3 ?=
XJA3 =-X main.ja3=$(JA3)
LDFLAGS=-ldflags "-s -w ${XBUILD} ${XPROTO} ${XURL} ${XHOST} ${XPSK} ${XPROXY} -buildid="
WINAGENTLDFLAGS=-ldflags "-s -w ${XBUILD} ${XPROTO} ${XURL} ${XHOST} ${XPSK} ${XPROXY} -H=windowsgui -buildid="
KILLDATE ?= 0
XKILLDATE =-X main.killdate=$(KILLDATE)
MAXRETRY ?= 7
XMAXRETRY =-X main.maxretry=$(MAXRETRY)
PADDING ?= 4096
XPADDING =-X main.padding=$(PADDING)
SKEW ?= 0
XSKEW =-X main.skew=$(SKEW)
USERAGENT ?= Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.85 Safari/537.36
XUSERAGENT =-X "main.useragent=$(USERAGENT)"
SLEEP ?= 30s
XSLEEP = -X main.sleep=$(SLEEP)
LDFLAGS=-ldflags '-s -w ${XBUILD} ${XPROTO} ${XURL} ${XHOST} ${XPSK} ${XPROXY} ${XKILLDATE} ${XMAXRETRY} ${XPADDING} ${XSKEW} ${XUSERAGENT} ${XSLEEP} -buildid='
WINAGENTLDFLAGS=-ldflags '-s -w ${XBUILD} ${XPROTO} ${XURL} ${XHOST} ${XPSK} ${XPROXY} ${XKILLDATE} ${XMAXRETRY} ${XPADDING} ${XSKEW} ${XUSERAGENT} ${XSLEEP} -H=windowsgui -buildid='
WINAGENTLDFLAGSDEBUG=-ldflags '-s -w ${XBUILD} ${XPROTO} ${XURL} ${XHOST} ${XPSK} ${XPROXY} ${XKILLDATE} ${XMAXRETRY} ${XPADDING} ${XSKEW} ${XUSERAGENT} ${XSLEEP} -buildid='
# TODO Update when Go1.13 is released https://stackoverflow.com/questions/45279385/remove-file-paths-from-text-directives-in-go-binaries
GCFLAGS=-gcflags=all=-trimpath=$(GOPATH)
ASMFLAGS=-asmflags=all=-trimpath=$(GOPATH)# -asmflags=-trimpath=$(GOPATH)
Expand Down Expand Up @@ -68,6 +81,10 @@ server-windows:
agent-windows:
export GOOS=windows GOARCH=amd64;go build ${WINAGENTLDFLAGS} ${GCFLAGS} ${ASMFLAGS} -o ${DIR}/${MAGENT}-${W}.exe cmd/merlinagent/main.go

# Compile Agent - Windows x64 with DEBUG output
agent-windows-debug:
export GOOS=windows GOARCH=amd64;go build ${WINAGENTLDFLAGSDEBUG} ${GCFLAGS} ${ASMFLAGS} -o ${DIR}/${MAGENT}-${W}-DEBUG.exe cmd/merlinagent/main.go

# Compile Agent - Windows x64 DLL - main() - Console
agent-dll:
export GOOS=windows GOARCH=amd64 CC=x86_64-w64-mingw32-gcc CXX=x86_64-w64-mingw32-g++ CGO_ENABLED=1; \
Expand Down
68 changes: 56 additions & 12 deletions cmd/merlinagent/main.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Merlin is a post-exploitation command and control framework.
// This file is part of Merlin.
// Copyright (C) 2019 Russel Van Tuyl
// Copyright (C) 2021 Russel Van Tuyl

// Merlin is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
Expand All @@ -22,14 +22,14 @@ import (
"flag"
"fmt"
"os"
"time"

// 3rd Party
"github.com/fatih/color"

// Merlin
"github.com/Ne0nd0g/merlin/pkg"
// Internal
"github.com/Ne0nd0g/merlin/pkg/agent"
"github.com/Ne0nd0g/merlin/pkg/agent/clients/http"
"github.com/Ne0nd0g/merlin/pkg/agent/core"
)

// GLOBAL VARIABLES
Expand All @@ -40,6 +40,13 @@ var psk = "merlin"
var proxy = ""
var host = ""
var ja3 = ""
var useragent = "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.85 Safari/537.36"
var sleep = "30s"
var skew = "3000"
var killdate = "0"
var maxretry = "7"
var padding = "4096"
var opaque []byte

func main() {
verbose := flag.Bool("v", false, "Enable verbose output")
Expand All @@ -51,31 +58,68 @@ func main() {
flag.StringVar(&proxy, "proxy", proxy, "Hardcoded proxy to use for http/1.1 traffic only that will override host configuration")
flag.StringVar(&host, "host", host, "HTTP Host header")
flag.StringVar(&ja3, "ja3", ja3, "JA3 signature string (not the MD5 hash). Overrides -proto flag")
sleep := flag.Duration("sleep", 30000*time.Millisecond, "Time for agent to sleep")
flag.StringVar(&sleep, "sleep", sleep, "Time for agent to sleep")
flag.StringVar(&skew, "skew", skew, "Amount of skew, or variance, between agent checkins")
flag.StringVar(&killdate, "killdate", killdate, "The date, as a Unix EPOCH timestamp, that the agent will quit running")
flag.StringVar(&maxretry, "maxretry", maxretry, "The maximum amount of failed checkins before the agent will quit running")
flag.StringVar(&padding, "padding", padding, "The maximum amount of data that will be randomly selected and appended to every message")
flag.StringVar(&useragent, "useragent", useragent, "The HTTP User-Agent header string that the Agent will use while sending traffic")

flag.Usage = usage
flag.Parse()

if *version {
color.Blue(fmt.Sprintf("Merlin Agent Version: %s", merlin.Version))
color.Blue(fmt.Sprintf("Merlin Agent Version: %s", core.Version))
color.Blue(fmt.Sprintf("Merlin Agent Build: %s", build))
os.Exit(0)
}

core.Debug = *debug
core.Verbose = *verbose

// Setup and run agent
a, err := agent.New(protocol, url, host, psk, proxy, ja3, *verbose, *debug)
agentConfig := agent.Config{
Sleep: sleep,
Skew: skew,
KillDate: killdate,
MaxRetry: maxretry,
}
a, err := agent.New(agentConfig)
if err != nil {
if *verbose {
color.Red(err.Error())
}
os.Exit(1)
}
a.WaitTime = *sleep
errRun := a.Run()
if errRun != nil {

// Get the client
var errClient error
clientConfig := http.Config{
AgentID: a.ID,
Protocol: protocol,
Host: host,
URL: url,
Proxy: proxy,
UserAgent: useragent,
PSK: psk,
JA3: ja3,
Padding: padding,
AuthPackage: "opaque",
Opaque: opaque,
}
a.Client, errClient = http.New(clientConfig)
if errClient != nil {
if *verbose {
color.Red(errRun.Error())
color.Red(errClient.Error())
}
}

// Start the agent
err = a.Run()
if err != nil {
if *verbose {
color.Red(err.Error())
}
os.Exit(1)
}
}

Expand Down
39 changes: 38 additions & 1 deletion cmd/merlinagentdll/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,22 +26,59 @@ import (

// Merlin
"github.com/Ne0nd0g/merlin/pkg/agent"
"github.com/Ne0nd0g/merlin/pkg/agent/clients/http"
)

var url = "https://127.0.0.1:443"
var psk = "merlin"
var proxy = ""
var host = ""
var ja3 = ""
var useragent = "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.85 Safari/537.36"
var sleep = "30s"
var skew = "3000"
var killdate = "0"
var maxretry = "7"
var padding = "4096"
var opaque []byte
var protocol = "h2"

func main() {}

// run is a private function called by exported functions to instantiate/execute the Agent
func run(URL string) {
a, err := agent.New("h2", URL, host, psk, proxy, ja3, false, false)
// Setup and run agent
agentConfig := agent.Config{
Sleep: sleep,
Skew: skew,
KillDate: killdate,
MaxRetry: maxretry,
}
a, err := agent.New(agentConfig)
if err != nil {
os.Exit(1)
}

// Get the client
var errClient error
clientConfig := http.Config{
AgentID: a.ID,
Protocol: protocol,
Host: host,
URL: URL,
Proxy: proxy,
UserAgent: useragent,
PSK: psk,
JA3: ja3,
Padding: padding,
AuthPackage: "opaque",
Opaque: opaque,
}
a.Client, errClient = http.New(clientConfig)
if errClient != nil {
os.Exit(1)
}

errRun := a.Run()
if errRun != nil {
os.Exit(1)
Expand Down
Loading

0 comments on commit be117de

Please sign in to comment.