c2

package
v0.1.1 Latest Latest
Warning

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

Go to latest
Published: Jul 20, 2026 License: GPL-3.0 Imports: 9 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var DisplayFieldsAgent = map[string]func(h *c2.Agent) string{
	"ID": func(h *c2.Agent) string {
		id := display.FormatSmallID(h.Id)

		if h.IsDead {
			return color.HiRedString(id)
		}

		activeC2 := ActiveChannelFor(h)

		next := time.Unix(activeC2.NextCheckin, 0)
		jitter := time.Duration(activeC2.Jitter)

		if activeC2.NextCheckin != 0 && next.Add(jitter).Before(time.Now()) {
			return color.HiYellowString(id)
		}

		return color.HiGreenString(id)
	},
	"Tool": func(h *c2.Agent) string {
		return h.Tool
	},
	"Name": func(h *c2.Agent) string {
		return h.Name
	},
	"Host ID": func(h *c2.Agent) string {
		if h.Host == nil {
			return "No host"
		}
		return display.FormatSmallID(h.Host.Id)
	},
	"User/Hostname": func(h *c2.Agent) string {
		user, host := "", ""
		if h.User != nil {
			user = h.User.Name
		}

		if h.Host != nil && len(h.Host.Hostnames) > 0 {
			for _, hostname := range h.Host.Hostnames {
				if hostname.Name == "localhost" {
					continue
				}
				host = hostname.Name
				break
			}
		}

		return fmt.Sprintf("%s@%s", color.HiWhiteString(user), color.HiWhiteString(host))
	},
	"OS": func(h *c2.Agent) string {
		name, family := host.GetOperatingSystem(h.Host)

		if name == "" && family == "" {
			return color.HiRedString("Undefined")
		}

		return fmt.Sprintf("%s %s", family, name)
	},
	"Process": func(h *c2.Agent) string {
		if h.Process == nil {
			return "No process information"
		}

		process := fmt.Sprintf("%d", h.Process.Pid)
		if h.Process.Owner != nil && h.Process.Owner.Name != "" {
			process += fmt.Sprintf(" - %s -", h.Process.Owner.Name)
		}

		if h.Process.Ppid != 0 {
			process += color.HiBlackString(fmt.Sprintf("(P %d)", h.Process.Ppid))
		}
		if len(h.Process.CmdLine) != 0 {
			process += fmt.Sprintf("[%s]", strings.Join(h.Process.CmdLine, " "))
		}

		return process
	},
	"Working directory": func(h *c2.Agent) string {
		return color.HiBlueString(h.WorkingDirectory)
	},

	"Last/Next Check-in": func(h *c2.Agent) string {
		last := time.Unix(h.LastCheckin, 0)
		next := time.Unix(h.NextCheckin, 0)
		lastTime := util.FormatDateDelta(last, false, false)
		nextTime := util.FormatDateDelta(next, false, true)
		return fmt.Sprintf("%s/%s", lastTime, nextTime)
	},
	"Tasks": func(h *c2.Agent) string {
		tasks := ""
		completed := h.TasksCountCompleted
		if completed < h.TasksCount {
			tasks = color.HiYellowString("%d", completed)
		}
		return fmt.Sprintf("%s/%d", tasks, h.TasksCount)
	},

	"Channels": func(h *c2.Agent) string {
		channels := ""
		for _, channel := range h.Channels {
			if !channel.Running {
				continue
			}

			direction := ""
			if strings.ToLower(channel.Direction) == "bind" {
				direction = "==>"
			} else {
				direction = "<=="
			}
			channels += fmt.Sprintf("[%s] %s %s %s\n",
				channel.Protocol,
				channel.LocalAddress,
				direction,
				channel.RemoteAddress,
			)
		}
		return strings.TrimSuffix(channels, "\n")
	},
	"Channel Details": func(h *c2.Agent) string {
		table := display.Table(h.Channels, DisplayFieldsChannel, DisplayHeadersChannel()...)
		return table.Render()
	},

	"Route": func(h *c2.Agent) string {
		return ""
	},
}

Fields maps field names to their value generators.

View Source
var DisplayFieldsChannel = map[string]func(h *c2.Channel) string{

	"Order": func(h *c2.Channel) string {
		return color.HiBlackString(fmt.Sprintf("%d", h.Order))
	},
	"ID": func(h *c2.Channel) string {
		if h.Running {
			return color.HiGreenString(display.FormatSmallID(h.Id))
		}
		return display.FormatSmallID(h.Id)
	},
	"Protocol": func(h *c2.Channel) string {
		return h.Protocol
	},
	"Connection": func(h *c2.Channel) string {
		direction := ""
		if strings.ToLower(h.Direction) == "bind" {
			direction = "==>"
		} else {
			direction = "<=="
		}

		return fmt.Sprintf("%s %s %s", h.LocalAddress, direction, h.RemoteAddress)
	},
	"Try/Fails": func(h *c2.Channel) string {
		tries := fmt.Sprintf("%d", h.Attempts)
		failures := fmt.Sprintf("%d", h.Failures)
		if h.Failures > 0 {
			return color.HiRedString(fmt.Sprintf("%d", h.Failures))
		}
		return fmt.Sprintf("%s/%s", tries, failures)
	},
	"Beaconing": func(h *c2.Channel) string {
		if strings.ToLower(h.Type) == "session" {
			return color.HiBlackString("none")
		}

		stats := fmt.Sprintf("%s (+/-%s)", time.Duration(h.Interval).String(), time.Duration(h.Jitter).String())
		return stats
	},
	"Last/Next Check-in": func(h *c2.Channel) string {
		last := time.Unix(h.LastCheckin, 0)
		next := time.Unix(h.NextCheckin, 0)
		lastTime := util.FormatDateDelta(last, false, false)
		nextTime := util.FormatDateDelta(next, false, true)
		return fmt.Sprintf("%s/%s", lastTime, nextTime)
	},
	"Proxy": func(h *c2.Channel) string {
		return h.ProxyURL
	},
}

Fields maps field names to their value generators.

Functions

func ActiveChannelFor

func ActiveChannelFor(agent *c2.Agent) *c2.Channel

ActiveChannelFor returns the first active channel for a given agent.

func CompletionsAgent

func CompletionsAgent() []display.Options

CompletionsAgent returns some columns to be combined into completion candidates and/or their descriptions.

func CompletionsChannel

func CompletionsChannel() []display.Options

Completions returns some columns to be combined into completion candidates and/or their descriptions.

func DisplayDetailsAgent

func DisplayDetailsAgent() []display.Options

DetailHeaders returns the headers for a detailed.Agent view.

func DisplayDetailsChannel

func DisplayDetailsChannel() []display.Options

DetailHeaders returns the headers for a detailed.Channel view.

func DisplayHeadersAgent

func DisplayHeadersAgent() []display.Options

DisplayHeadersAgent returns all weighted table headers for a table of.Agents.

func DisplayHeadersChannel

func DisplayHeadersChannel() []display.Options

DisplayHeaders returns all weighted table headers for a table of.Channels.

func FilterIdenticalChannel

func FilterIdenticalChannel(raw []c2.ChannelORM, dbHosts []*c2.ChannelORM) (filtered []c2.ChannelORM)

FilterIdentical returns a list of.Channels from which have been removed all.Channels that are already in the database, with a very high degree of certitude. This avoids redundance when manipulating new.Channels.

Types

type Agent

type Agent c2.Agent

Agent represents a C2 agent (implant).

type Channel

type Channel c2.Channel

Channel represents a C2 communication channel (transport).

Directories

Path Synopsis
pb
rpc

Jump to

Keyboard shortcuts

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