core

package
v1.7.7 Latest Latest
Warning

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

Go to latest
Published: Sep 3, 2026 License: GPL-3.0 Imports: 24 Imported by: 24

README

server/core

Overview

Core server runtime coordination, state, and dispatch. Oversees lifecycle management, hub services, and shared state. Key routines cover clients, connnection, crackstations, and events within the core subsystem.

Go Files

  • builders.go – Tracks builder jobs and integration with the core scheduler.
  • clients.go – Manages connected operators and their state.
  • connnection.go – Handles active connection bookkeeping (typo in filename retained).
  • core.go – Initializes core services and orchestrates shared state.
  • crackstations.go – Maintains crackstation worker metadata and status.
  • events.go – Broadcasts and records core events for subscribers.
  • hosts.go – Tracks discovered hosts and associated metadata.
  • jobs.go – Manages background jobs and status reporting.
  • pivots.go – Coordinates pivot graphs and routing information.
  • sessions.go – Manages implant sessions and lifecycle hooks.
  • socks.go – Tracks SOCKS proxy instances managed by the server.
  • tunnels.go – Maintains tunnel state and routing entries.

Sub-packages

  • rtunnels/ – Reverse tunnel coordination within the server core. Handles tunnel registration, negotiation, and multiplexing.

Documentation

Index

Constants

View Source
const (

	// DefaultImplantSendTimeout bounds server producers when a transport has
	// stopped consuming outbound envelopes without closing its connection yet.
	DefaultImplantSendTimeout = 10 * time.Second
)

maxClaimedReverseTunnelIDsPerConnection bounds the permanent replay-defense history for one C2 connection. Reverse tunnel IDs cannot be reused safely because the wire protocol has no generation number. A connection that uses the entire history is therefore closed and must establish a fresh ID domain. The limit is deliberately much larger than the concurrent reverse-tunnel quota while still bounding attacker-controlled memory growth.

View Source
const (
	// MaxSocksFrameBytes is the per-frame SOCKS payload limit in either
	// direction. It intentionally matches the generic tunnel wire contract.
	MaxSocksFrameBytes = sliverpb.MaxTunnelFrameBytes
)
View Source
const (

	// MaxTunnelFrameBytes limits one generic tunnel data frame.
	MaxTunnelFrameBytes = sliverpb.MaxTunnelFrameBytes
)
View Source
const (
	PivotTransportName = "pivot"
)

Variables

View Source
var (
	// ErrImplantConnectionClosed indicates that an outbound envelope could not
	// be queued because the connection is closing or already closed.
	ErrImplantConnectionClosed = errors.New("implant connection closed")

	// ErrImplantSendTimeout indicates that an outbound transport queue did not
	// accept an envelope before its bounded deadline.
	ErrImplantSendTimeout = errors.New("implant send timeout")

	// ErrInvalidImplantSend indicates a nil connection, envelope, or send queue.
	ErrInvalidImplantSend = errors.New("invalid implant send")
)
View Source
var (

	// Sessions - Manages implant connections
	Sessions = &sessions{
		sessions: &sync.Map{},
	}

	// ErrUnknownMessageType - Returned if the implant did not understand the message for
	//                         example when the command is not supported on the platform
	ErrUnknownMessageType = errors.New("unknown message type")

	// ErrImplantTimeout - The implant did not respond prior to timeout deadline
	ErrImplantTimeout = errors.New("implant timeout")
)
View Source
var (
	// ErrSocksSequenceConflict reports a duplicate sequence with different content.
	ErrSocksSequenceConflict = errors.New("conflicting duplicate SOCKS sequence")
	// ErrSocksTerminalPayload reports a terminal frame containing payload data.
	ErrSocksTerminalPayload = errors.New("SOCKS terminal frame carries data")
	// ErrSocksCredentialSize reports credentials exceeding the protocol limit.
	ErrSocksCredentialSize = errors.New("SOCKS credential exceeds the size limit")
	// ErrSocksTunnelLimit reports exhaustion of a session's SOCKS tunnel quota.
	ErrSocksTunnelLimit = errors.New("SOCKS tunnel limit reached for session")
	// ErrSocksCapabilityMismatch rejects a bind that does not echo the exact
	// capability set negotiated by CreateSocks.
	ErrSocksCapabilityMismatch = errors.New("SOCKS capability negotiation mismatch")
	// ErrSocksFlowControl reports an acknowledgement on a tunnel that did not
	// negotiate cumulative flow control.
	ErrSocksFlowControl = errors.New("SOCKS flow control was not negotiated")
	// ErrSocksAcknowledgement rejects zero or future cumulative acknowledgements.
	ErrSocksAcknowledgement = errors.New("SOCKS acknowledgement exceeds the sent sequence")
	// ErrSocksOwner rejects a flow-control message from a different tunnel owner.
	ErrSocksOwner = errors.New("SOCKS flow-control owner mismatch")
)
View Source
var (
	// Tunnels - Interacting with duplex tunnels
	Tunnels = tunnels{
			// contains filtered or unexported fields
	}

	// ErrInvalidTunnelID - Invalid tunnel ID value
	ErrInvalidTunnelID = errors.New("invalid tunnel ID")

	// ErrInvalidSessionID - Invalid session ID value
	ErrInvalidSessionID = errors.New("invalid session ID")

	// ErrTunnelClosed indicates that work retained an exact tunnel generation
	// after it had already been detached.
	ErrTunnelClosed = errors.New("tunnel is closed")

	// ErrTunnelFrameTooLarge rejects one wire frame before it can enter a
	// generation's reorder or resend state.
	ErrTunnelFrameTooLarge = errors.New("tunnel frame exceeds the size limit")

	// ErrTunnelSequenceWindow bounds untrusted out-of-order sequence numbers.
	ErrTunnelSequenceWindow = errors.New("tunnel sequence exceeds the pending window")

	// ErrTunnelSequenceConflict rejects two different payloads claiming the
	// same inbound sequence number.
	ErrTunnelSequenceConflict = errors.New("tunnel sequence conflicts with an accepted frame")

	// ErrTunnelPendingBytes bounds data retained while an earlier frame is
	// missing.
	ErrTunnelPendingBytes = errors.New("tunnel pending data exceeds the byte limit")

	// ErrTunnelIngressLimit bounds all admitted and retained frames for one
	// tunnel generation.
	ErrTunnelIngressLimit = errors.New("tunnel inbound frame limit reached")

	// ErrTunnelAcknowledgement rejects an acknowledgement for data that the
	// server has not assigned yet.
	ErrTunnelAcknowledgement = errors.New("tunnel acknowledgement exceeds the send sequence")

	// ErrTunnelTerminal rejects contradictory terminal sequence state or data
	// at or beyond an accepted exclusive terminal sequence.
	ErrTunnelTerminal = errors.New("tunnel terminal sequence is invalid")
)
View Source
var (
	// Clients - Manages client active
	Clients = &clients{
		active: map[int]*Client{},
		mutex:  &sync.Mutex{},
	}
)
View Source
var (
	ErrDuplicateExternalBuilderName = errors.New("builder name must be unique, this name is already in use")
)
View Source
var (
	ErrDuplicateHosts = errors.New("only one crackstation instance per host")
)
View Source
var (
	// EventBroker - Distributes event messages
	EventBroker = newBroker()
)
View Source
var (
	// Jobs - Holds pointers to all the current jobs
	Jobs = &jobs{

		active: &sync.Map{},
	}
)
View Source
var (
	PivotSessions = &sync.Map{} // ID -> Pivot
)
View Source
var (
	// SocksTunnels manages server-side duplex SOCKS tunnels.
	SocksTunnels = tcpTunnel{
		// contains filtered or unexported fields
	}
)

Functions

func AddBuilder added in v1.5.30

func AddBuilder(builder *clientpb.Builder) error

func AddCrackstation added in v1.6.0

func AddCrackstation(crack *Crackstation) error

func AllBuilders added in v1.5.30

func AllBuilders() []*clientpb.Builder

func AllCrackstations added in v1.6.0

func AllCrackstations() []*clientpb.Crackstation

func ClosePivotSession added in v1.7.7

func ClosePivotSession(pivotID string) bool

ClosePivotSession atomically removes and closes a synthetic pivot connection. It also handles key exchanges that created a pivot before the downstream implant registered a core Session.

func EnvelopeID

func EnvelopeID() int64

EnvelopeID - Generate random ID of 8 bytes

func GetBuilder added in v1.5.30

func GetBuilder(builderName string) *clientpb.Builder

func NewTunnelID

func NewTunnelID() uint64

NewTunnelID - New 64-bit identifier

func NextJobID

func NextJobID() int

NextJobID - Returns an incremental nonce as an id

func RemoveBuilder added in v1.5.30

func RemoveBuilder(builderName string)

func RemoveCrackstation added in v1.6.0

func RemoveCrackstation(hostUUID string)

func RemoveExternalBuildAssignment added in v1.7.2

func RemoveExternalBuildAssignment(buildID string)

RemoveExternalBuildAssignment clears any assignment for a build.

func StartEventAutomation added in v1.5.0

func StartEventAutomation()

StartEventAutomation - Starts an event automation goroutine

func TrackExternalBuildAssignment added in v1.7.2

func TrackExternalBuildAssignment(buildID string, builderName string, operatorName string)

TrackExternalBuildAssignment stores the builder/operator assignment for a build.

Types

type Client

type Client struct {
	ID       int
	Operator *clientpb.Operator
}

Client - Single client connection

func NewClient

func NewClient(operatorName string) *Client

NewClient - Create a new client object

func (*Client) ToProtobuf

func (c *Client) ToProtobuf() *clientpb.Client

ToProtobuf - Get the protobuf version of the object

type Crackstation added in v1.6.0

type Crackstation struct {
	HostUUID string
	Station  *clientpb.Crackstation
	Events   chan *clientpb.Event
	// contains filtered or unexported fields
}

func GetCrackstation added in v1.6.0

func GetCrackstation(hostUUID string) *Crackstation

func NewCrackstation added in v1.6.0

func NewCrackstation(station *clientpb.Crackstation) *Crackstation

func (*Crackstation) GetStatus added in v1.6.0

func (c *Crackstation) GetStatus() *clientpb.CrackstationStatus

func (*Crackstation) UpdateStatus added in v1.6.0

func (c *Crackstation) UpdateStatus(status *clientpb.CrackstationStatus)

type Event

type Event struct {
	Session *Session
	Job     *Job
	Client  *Client
	Beacon  *models.Beacon

	EventType string

	Data []byte
	Err  error
}

Event - An event is fired when there's a state change involving a

session, job, or client.

type ExternalBuildAssignment added in v1.7.2

type ExternalBuildAssignment struct {
	BuildID      string
	BuilderName  string
	OperatorName string
}

ExternalBuildAssignment tracks which remote builder is allowed to access a build.

func GetExternalBuildAssignment added in v1.7.2

func GetExternalBuildAssignment(buildID string) *ExternalBuildAssignment

GetExternalBuildAssignment returns the assignment for a build, if present.

type ImplantConnection added in v1.5.0

type ImplantConnection struct {
	ID               string
	Send             chan *sliverpb.Envelope
	RespMutex        *sync.RWMutex
	Resp             map[int64]chan *sliverpb.Envelope
	Transport        string
	RemoteAddress    string
	LastMessage      time.Time
	LastMessageMutex *sync.RWMutex
	// contains filtered or unexported fields
}

ImplantConnection - Abstract connection to an implant

func NewImplantConnection added in v1.5.0

func NewImplantConnection(transport string, remoteAddress string) *ImplantConnection

NewImplantConnection - Creates a new implant connection

func (*ImplantConnection) ClaimReverseTunnelID added in v1.7.7

func (c *ImplantConnection) ClaimReverseTunnelID(tunnelID uint64) bool

ClaimReverseTunnelID is the compatibility boolean wrapper for callers that do not need to distinguish duplicate IDs from a closed ID domain.

func (*ImplantConnection) Close added in v1.7.7

func (c *ImplantConnection) Close()

Close marks the implant connection closed and runs its cleanup callback. The Done signal is closed first so blocked work can fail closed even if cleanup takes time. It is safe for transport, protocol, and rejection paths to call Close concurrently; cleanup is performed exactly once.

func (*ImplantConnection) DeliverResponse added in v1.7.7

func (c *ImplantConnection) DeliverResponse(envelope *sliverpb.Envelope) bool

DeliverResponse completes a pending synchronous request without ever blocking a transport reader. Request response channels are single-message buffers, so a duplicate or late delivery is safely rejected.

func (*ImplantConnection) Done added in v1.7.7

func (c *ImplantConnection) Done() <-chan struct{}

Done is closed when the implant connection begins closing.

func (*ImplantConnection) GetLastMessage added in v1.5.14

func (c *ImplantConnection) GetLastMessage() time.Time

GetLastMessage - Retrieves the last message time

func (*ImplantConnection) RequestResend added in v1.5.27

func (c *ImplantConnection) RequestResend(data []byte)

func (*ImplantConnection) SendEnvelope added in v1.7.7

func (c *ImplantConnection) SendEnvelope(envelope *sliverpb.Envelope, timeout time.Duration) error

SendEnvelope queues an outbound envelope while the connection remains live. Every producer must use this method instead of writing to Send directly so a stalled transport cannot strand the producer forever.

func (*ImplantConnection) SendEnvelopeUntil added in v1.7.7

func (c *ImplantConnection) SendEnvelopeUntil(envelope *sliverpb.Envelope, ownerDone <-chan struct{}, timeout time.Duration) error

SendEnvelopeUntil is SendEnvelope with an additional owner lifecycle. This is used by tunnel and pivot producers, where the narrower owner may close while the underlying C2 connection remains healthy.

func (*ImplantConnection) SetCleanup added in v1.7.7

func (c *ImplantConnection) SetCleanup(callback func()) bool

SetCleanup installs the connection's one-shot cleanup callback. It returns false for a duplicate registration or a connection that already closed. Callers must install cleanup before publishing connection-owned state.

func (*ImplantConnection) TryClaimReverseTunnelID added in v1.7.7

func (c *ImplantConnection) TryClaimReverseTunnelID(tunnelID uint64) ReverseTunnelIDClaimResult

TryClaimReverseTunnelID permanently reserves a wire tunnel ID for this C2 connection. The protocol has no generation number, so never reusing an ID is what prevents a delayed frame from targeting a newer relay generation. Once the bounded ID domain is exhausted, the connection is failed closed after releasing lifecycleMutex so cleanup can safely re-enter connection methods.

func (*ImplantConnection) UpdateLastMessage added in v1.5.0

func (c *ImplantConnection) UpdateLastMessage()

UpdateLastMessage - Updates the last message time

type Job

type Job struct {
	ID           int
	Name         string
	Description  string
	Protocol     string
	Port         uint16
	Domains      []string
	JobCtrl      chan bool
	PersistentID string
	ProfileName  string
}

Job - Manages background jobs

func (*Job) ToProtobuf

func (j *Job) ToProtobuf() *clientpb.Job

ToProtobuf - Get the protobuf version of the object

type Pivot added in v1.5.0

type Pivot struct {
	ID                   string
	OriginID             int64
	ImplantConn          *ImplantConnection
	ImmediateImplantConn *ImplantConnection
	CipherCtx            *cryptography.CipherContext
	Peers                []*sliverpb.PivotPeer
}

Pivot - Wraps an ImplantConnection

func NewPivotSession added in v1.5.0

func NewPivotSession(chain []*sliverpb.PivotPeer) *Pivot

NewPivotSession - Creates a new pivot session

func (*Pivot) Start added in v1.5.0

func (p *Pivot) Start()

Start - Starts the pivot send loop which forwards envelopes from the pivot ImplantConnection to the ImmediateImplantConnection (the closest peer in the chain)

type PivotGraphEntry added in v1.5.0

type PivotGraphEntry struct {
	PeerID    int64
	SessionID string
	Name      string

	// PeerID -> Child
	Children map[int64]*PivotGraphEntry
}

PivotGraphEntry - A single entry in the pivot graph

func PivotGraph added in v1.5.0

func PivotGraph() []*PivotGraphEntry

PivotGraph - Creates a graph structure of sessions/pivots

func (*PivotGraphEntry) AllChildren added in v1.5.0

func (e *PivotGraphEntry) AllChildren() []*PivotGraphEntry

AllChildren - Flat list of all children (including children of children)

func (*PivotGraphEntry) FindEntryByPeerID added in v1.5.0

func (e *PivotGraphEntry) FindEntryByPeerID(peerID int64) *PivotGraphEntry

FindEntryByPeerID - Finds a pivot graph entry by peer ID, recursively

func (*PivotGraphEntry) Insert added in v1.5.0

func (e *PivotGraphEntry) Insert(input *PivotGraphEntry)

Insert - Inserts a pivot into the graph, if it doesn't yet exist

func (*PivotGraphEntry) ToProtobuf added in v1.5.0

func (e *PivotGraphEntry) ToProtobuf() *clientpb.PivotGraphEntry

ToProtobuf - Recursively converts the pivot graph to protobuf

type ReverseTunnelIDClaimResult added in v1.7.7

type ReverseTunnelIDClaimResult uint8

ReverseTunnelIDClaimResult distinguishes a replayed ID from exhaustion of the per-connection ID domain. Callers should reject duplicates while leaving the connection live; capacity exhaustion has already failed it closed.

const (
	// ReverseTunnelIDClaimed indicates that the connection accepted a new ID.
	ReverseTunnelIDClaimed ReverseTunnelIDClaimResult = iota
	// ReverseTunnelIDDuplicate indicates that the connection already owns the ID.
	ReverseTunnelIDDuplicate
	// ReverseTunnelIDCapacityExhausted indicates that no more IDs may be claimed.
	ReverseTunnelIDCapacityExhausted
	// ReverseTunnelIDConnectionClosed indicates that the connection is closing.
	ReverseTunnelIDConnectionClosed
)

type Session

type Session struct {
	ID                string
	Name              string
	Hostname          string
	Username          string
	UUID              string
	UID               string
	GID               string
	OS                string
	Version           string
	Arch              string
	PID               int32
	Filename          string
	Connection        *ImplantConnection
	ActiveC2          string
	ReconnectInterval int64
	ProxyURL          string
	PollTimeout       int64
	Burned            bool
	Extensions        []string
	ConfigID          string
	PeerID            int64
	Locale            string
	FirstContact      int64
	Integrity         string
	Capabilities      uint64
}

Session - Represents a connection to an implant

func NewSession added in v1.5.0

func NewSession(implantConn *ImplantConnection) *Session

NewSession - Create a new session

func (*Session) IsDead

func (s *Session) IsDead() bool

IsDead - See if last check-in is within expected variance

func (*Session) LastCheckin

func (s *Session) LastCheckin() time.Time

LastCheckin - Get the last time a session message was received

func (*Session) Request

func (s *Session) Request(msgType uint32, timeout time.Duration, data []byte) ([]byte, error)

Request - Sends a protobuf request to the active sliver and returns the response

func (*Session) RequestContext added in v1.7.7

func (s *Session) RequestContext(ctx context.Context, msgType uint32, data []byte) ([]byte, error)

RequestContext sends a request and uses one context budget across both outbound queueing and the response wait. A canceled context is checked before a response waiter is installed, and every return path removes that waiter.

func (*Session) ToProtobuf

func (s *Session) ToProtobuf() *clientpb.Session

ToProtobuf - Get the protobuf version of the object

type SocksClient added in v1.7.7

type SocksClient struct {
	// contains filtered or unexported fields
}

SocksClient serializes sends on one SocksProxy stream. gRPC permits one concurrent sender and one concurrent receiver, but not multiple senders.

func NewSocksClient added in v1.7.7

func NewSocksClient(stream SocksDataSender) *SocksClient

NewSocksClient creates a serialized sender for one SOCKS proxy stream.

func (*SocksClient) Done added in v1.7.7

func (c *SocksClient) Done() <-chan struct{}

Done is closed after the first terminal stream error.

func (*SocksClient) Err added in v1.7.7

func (c *SocksClient) Err() error

Err returns the first terminal stream error, if any.

func (*SocksClient) Fail added in v1.7.7

func (c *SocksClient) Fail(err error)

Fail records the first terminal stream error.

func (*SocksClient) Send added in v1.7.7

func (c *SocksClient) Send(data *sliverpb.SocksData) error

Send serializes and forwards one SOCKS frame.

type SocksClientLifecycle added in v1.7.7

type SocksClientLifecycle struct {
	BoundAt         time.Time
	LastActivity    time.Time
	ReceivedPayload bool
	SendsTerminal   bool
}

SocksClientLifecycle is an atomic snapshot used by the RPC lifecycle monitor. Timestamps use the server's monotonic clock component.

type SocksDataSender added in v1.7.7

type SocksDataSender interface {
	Send(*sliverpb.SocksData) error
}

SocksDataSender is the send half of a server-side SOCKS proxy stream.

type TcpTunnel added in v1.5.0

type TcpTunnel struct {
	ID                  uint64
	ToImplantSequence   uint64
	FromImplantSequence uint64
	SessionID           string
	ToImplantMux        sync.Mutex
	FromImplantMux      sync.Mutex
	// contains filtered or unexported fields
}

TcpTunnel holds one server-side SOCKS tunnel generation.

func (*TcpTunnel) AcknowledgementsToClient added in v1.7.7

func (t *TcpTunnel) AcknowledgementsToClient() <-chan uint64

AcknowledgementsToClient returns the fixed-size ACK control mailbox.

func (*TcpTunnel) AcknowledgementsToImplant added in v1.7.7

func (t *TcpTunnel) AcknowledgementsToImplant() <-chan uint64

AcknowledgementsToImplant returns the fixed-size ACK control mailbox.

func (*TcpTunnel) AdmitToImplant added in v1.7.7

func (t *TcpTunnel) AdmitToImplant(data *sliverpb.SocksData) error

AdmitToImplant validates and orders an operator frame without retaining its Request metadata or protobuf unknown fields.

func (*TcpTunnel) AdmitToImplantContext added in v1.7.7

func (t *TcpTunnel) AdmitToImplantContext(ctx context.Context, data *sliverpb.SocksData) error

AdmitToImplantContext waits for bounded operator-to-implant capacity instead of treating ordinary transport backpressure as a terminal protocol failure. Validation, duplicate, and sequence-window errors remain fail-fast. The queue's frame and byte reservations remain unchanged while this call waits.

func (*TcpTunnel) BindClient added in v1.7.7

func (t *TcpTunnel) BindClient(client *SocksClient) (owned bool, newlyBound bool)

BindClient binds the first stream that presents this tunnel. owned reports whether client owns the tunnel; newlyBound is true only for the first bind.

func (*TcpTunnel) BindClientWithCapabilities added in v1.7.7

func (t *TcpTunnel) BindClientWithCapabilities(client *SocksClient, username string, password string, sendsTerminal bool) (owned bool, newlyBound bool, err error)

BindClientWithCapabilities binds a proxy stream and records whether its client emits explicit per-connection terminal frames. Legacy clients did not emit terminals and therefore retain a bounded inactivity lease; current clients may remain idle after their first protocol payload (for example RDP).

func (*TcpTunnel) BindClientWithCredentials added in v1.7.7

func (t *TcpTunnel) BindClientWithCredentials(client *SocksClient, username string, password string) (owned bool, newlyBound bool, err error)

BindClientWithCredentials captures authentication exactly once from the ownership bind. RFC 1929 limits each username/password field to 255 octets; bounding them here prevents per-frame metadata from escaping Data budgets.

func (*TcpTunnel) BindClientWithNegotiatedCapabilities added in v1.7.7

func (t *TcpTunnel) BindClientWithNegotiatedCapabilities(client *SocksClient, username string, password string, sendsTerminal bool, capabilities uint64) (owned bool, newlyBound bool, err error)

BindClientWithNegotiatedCapabilities requires the first ownership marker to echo the exact capability set returned by CreateSocks. Subsequent payloads do not repeat capability metadata; a repeated ownership marker must still match.

func (*TcpTunnel) Capabilities added in v1.7.7

func (t *TcpTunnel) Capabilities() uint64

Capabilities returns the immutable per-tunnel negotiated capability set.

func (*TcpTunnel) Client added in v1.5.0

func (t *TcpTunnel) Client() *SocksClient

Client returns the proxy stream currently bound to the tunnel.

func (*TcpTunnel) ClientLifecycle added in v1.7.7

func (t *TcpTunnel) ClientLifecycle() SocksClientLifecycle

ClientLifecycle returns an atomic snapshot of client lifecycle state.

func (*TcpTunnel) CompleteFromImplant added in v1.7.7

func (t *TcpTunnel) CompleteFromImplant(data *sliverpb.SocksData)

CompleteFromImplant releases the combined admission reservation after the operator-stream worker has sent or discarded a frame.

func (*TcpTunnel) CompleteToImplant added in v1.7.7

func (t *TcpTunnel) CompleteToImplant(data *sliverpb.SocksData)

CompleteToImplant releases the combined admission reservation after the worker has sent or discarded a frame.

func (*TcpTunnel) Credentials added in v1.7.7

func (t *TcpTunnel) Credentials() (string, string)

Credentials returns the username and password captured at bind time.

func (*TcpTunnel) DeliverFromImplant added in v1.7.7

func (t *TcpTunnel) DeliverFromImplant(data *sliverpb.SocksData) bool

DeliverFromImplant is retained as a compatibility wrapper. Callers that need to distinguish a stale replay from a protocol violation should use ProcessDataFromImplant directly.

func (*TcpTunnel) Done added in v1.7.7

func (t *TcpTunnel) Done() <-chan struct{}

Done is closed when this exact tunnel generation is retired.

func (*TcpTunnel) FlowControlEnabled added in v1.7.7

func (t *TcpTunnel) FlowControlEnabled() bool

FlowControlEnabled reports whether both endpoints negotiated SOCKS flow control for this exact tunnel generation.

func (*TcpTunnel) FromImplant added in v1.5.0

func (t *TcpTunnel) FromImplant() <-chan *sliverpb.SocksData

FromImplant returns ordered implant frames awaiting operator delivery.

func (*TcpTunnel) FromImplantSpaceChange added in v1.7.7

func (t *TcpTunnel) FromImplantSpaceChange() <-chan struct{}

FromImplantSpaceChange returns the current capacity generation used by the provisional legacy-terminal actor when the data queue is full.

func (*TcpTunnel) ImplantConnection added in v1.7.7

func (t *TcpTunnel) ImplantConnection() *ImplantConnection

ImplantConnection returns the exact transport generation associated with this tunnel at creation. The association is immutable even after the owning session is detached from the global registry.

func (*TcpTunnel) LegacyImplantTerminalPending added in v1.7.7

func (t *TcpTunnel) LegacyImplantTerminalPending() <-chan struct{}

LegacyImplantTerminalPending is signaled once when a capability-zero implant emits its unsequenced terminal. The exact tunnel's scheduler owns the bounded reorder grace and terminal materialization.

func (*TcpTunnel) LegacyImplantTerminalState added in v1.7.7

func (t *TcpTunnel) LegacyImplantTerminalState() (pending bool, generation uint64, changed <-chan struct{})

LegacyImplantTerminalState snapshots the provisional terminal generation. Later admitted implant data advances the generation so an expired waiter cannot overtake it.

func (*TcpTunnel) ProcessDataFromImplant added in v1.7.7

func (t *TcpTunnel) ProcessDataFromImplant(data *sliverpb.SocksData) error

ProcessDataFromImplant validates and orders an implant frame. Delivery is non-blocking and does not rely on the global handler mutex.

func (*TcpTunnel) RelayClientAcknowledgement added in v1.7.7

func (t *TcpTunnel) RelayClientAcknowledgement(client *SocksClient, ack uint64) error

RelayClientAcknowledgement validates a cumulative ACK from the exact bound operator and coalesces it for delivery to the implant. FromImplantMux closes the small race between a successful stream Send and its high-water update.

func (*TcpTunnel) RelayImplantAcknowledgement added in v1.7.7

func (t *TcpTunnel) RelayImplantAcknowledgement(connection *ImplantConnection, ack uint64) error

RelayImplantAcknowledgement validates a cumulative ACK from the exact implant connection and coalesces it for delivery to the bound operator.

func (*TcpTunnel) ToImplant added in v1.7.7

func (t *TcpTunnel) ToImplant() <-chan *sliverpb.SocksData

ToImplant returns ordered operator frames awaiting implant delivery.

func (*TcpTunnel) TryFlushLegacyImplantTerminal added in v1.7.7

func (t *TcpTunnel) TryFlushLegacyImplantTerminal(observedGeneration uint64) (done bool, err error)

TryFlushLegacyImplantTerminal queues the provisional terminal only if no data has advanced its observed generation during the reorder grace. done is true when the actor has no further work or successfully queued the terminal.

type Tunnel

type Tunnel struct {
	ID        uint64
	SessionID string

	ToImplant         chan []byte
	ToImplantSequence uint64

	FromImplant         chan *sliverpb.TunnelData
	FromImplantSequence uint64

	Client rpcpb.SliverRPC_TunnelDataServer
	// contains filtered or unexported fields
}

Tunnel - Essentially just a mapping between a specific client and sliver with an identifier, these tunnels are full duplex. The server doesn't really care what data gets passed back and forth it just facilitates the connection

func NewTunnel added in v1.5.14

func NewTunnel(id uint64, sessionID string) *Tunnel

func (*Tunnel) AcknowledgeDataToImplant added in v1.7.7

func (t *Tunnel) AcknowledgeDataToImplant(ack uint64) error

AcknowledgeDataToImplant cumulatively retires frames below ack. A future ACK is a protocol violation; stale ACKs are harmless and idempotent.

func (*Tunnel) BindClient added in v1.7.7

func (t *Tunnel) BindClient(client rpcpb.SliverRPC_TunnelDataServer) bool

BindClient reserves this tunnel for the first client stream.

func (*Tunnel) ClaimClientTerminalDelivery added in v1.7.7

func (t *Tunnel) ClaimClientTerminalDelivery(client rpcpb.SliverRPC_TunnelDataServer) bool

ClaimClientTerminalDelivery lets one concurrent tunnel owner publish the exact generation's terminal to its operator peer. Once a client owns the tunnel, a different stream that merely retained the pointer cannot consume the owner's terminal claim. An unbound racing client may still be notified.

func (*Tunnel) ClaimFromImplantClose added in v1.7.7

func (t *Tunnel) ClaimFromImplantClose() bool

ClaimFromImplantClose records the first terminal frame for this exact tunnel generation. Duplicate terminal envelopes must not refresh the quiet period or create additional close schedulers.

func (*Tunnel) ClaimImplantTerminalDelivery added in v1.7.7

func (t *Tunnel) ClaimImplantTerminalDelivery() bool

ClaimImplantTerminalDelivery lets one concurrent tunnel owner publish the exact generation's terminal to its implant peer.

func (*Tunnel) ClaimToImplantClose added in v1.7.7

func (t *Tunnel) ClaimToImplantClose() bool

ClaimToImplantClose records the first client close request for this exact tunnel generation. Duplicate unary requests must not refresh the quiet period or create additional close schedulers.

func (*Tunnel) ClientBindLeaseExpired added in v1.7.7

func (t *Tunnel) ClientBindLeaseExpired() bool

ClientBindLeaseExpired reports whether bind expiry won before the client completed its stream acknowledgement.

func (*Tunnel) ClientBound added in v1.7.7

func (t *Tunnel) ClientBound() <-chan struct{}

ClientBound is closed after a client stream binds to the tunnel.

func (*Tunnel) Close added in v1.7.7

func (t *Tunnel) Close()

Close publishes Done, which unblocks channel operations, then synchronously joins and clears this generation's protocol actors. It does not depend on an external client or implant reader making progress.

func (*Tunnel) CompleteDataFromImplantForward added in v1.7.7

func (t *Tunnel) CompleteDataFromImplantForward(sequence uint64) error

CompleteDataFromImplantForward records one ordered frame after the operator stream Send has succeeded. It intentionally does not take fromImplantMutex: ProcessDataFromImplant holds that mutex while handing frames to the unbuffered worker channel, so coupling completion to the producer lock would deadlock whenever more than one queued frame drains in a single pass.

func (*Tunnel) CompleteDataToImplant added in v1.7.7

func (t *Tunnel) CompleteDataToImplant()

CompleteDataToImplant releases one client-to-implant forwarding reservation. The TunnelData worker calls it only after the corresponding bounded implant send has completed or failed.

func (*Tunnel) CompleteDataToImplantForward added in v1.7.7

func (t *Tunnel) CompleteDataToImplantForward(sequence uint64) error

CompleteDataToImplantForward advances the contiguous prefix after the exact frame has been accepted by the implant transport. The tunnel has one client-to-implant forwarding worker, so completion must remain sequential.

func (*Tunnel) Done added in v1.7.7

func (t *Tunnel) Done() <-chan struct{}

Done is closed when the tunnel is removed from the server registry.

func (*Tunnel) FromImplantTerminalReady added in v1.7.7

func (t *Tunnel) FromImplantTerminalReady() <-chan struct{}

FromImplantTerminalReady closes after every sequence below the accepted capability-bearing terminal has been sent successfully to the operator.

func (*Tunnel) GetLastMessageTime deprecated added in v1.5.14

func (t *Tunnel) GetLastMessageTime() time.Time

GetLastMessageTime returns implant-to-client activity for the legacy implant-originated close path.

Deprecated: use LastToImplantTime or LastFromImplantTime explicitly.

func (*Tunnel) ImplantConnection added in v1.7.7

func (t *Tunnel) ImplantConnection() *ImplantConnection

ImplantConnection returns the exact transport generation that owned this tunnel at creation. The association is immutable after publication.

func (*Tunnel) IsClient added in v1.7.7

func (t *Tunnel) IsClient(client rpcpb.SliverRPC_TunnelDataServer) bool

IsClient reports whether client owns this tunnel's stream binding.

func (*Tunnel) LastFromImplantTime added in v1.7.7

func (t *Tunnel) LastFromImplantTime() time.Time

LastFromImplantTime returns the last implant-to-client activity used to delay an implant terminal close.

func (*Tunnel) LastToImplantTime added in v1.7.7

func (t *Tunnel) LastToImplantTime() time.Time

LastToImplantTime returns the last client-to-implant activity used to delay a client-requested close.

func (*Tunnel) MarkClientBound added in v1.7.7

func (t *Tunnel) MarkClientBound(client rpcpb.SliverRPC_TunnelDataServer) bool

MarkClientBound signals that the reserved stream accepted its bind frame.

func (*Tunnel) MarkFromImplantTerminal added in v1.7.7

func (t *Tunnel) MarkFromImplantTerminal(terminal *sliverpb.TunnelData) (bool, error)

MarkFromImplantTerminal records the exclusive final data sequence supplied by a capability-bearing implant. It serializes with data admission so a terminal can neither contradict retained data nor race a frame at or beyond the terminal boundary.

func (*Tunnel) NextDataToImplant added in v1.7.7

func (t *Tunnel) NextDataToImplant(data []byte) (*sliverpb.TunnelData, error)

NextDataToImplant assigns one outbound sequence and retains only the history that can still be useful to a peer with the advertised 128-frame receive window. The returned message is immutable and may be marshaled directly.

func (*Tunnel) ProcessDataFromImplant added in v1.7.7

func (t *Tunnel) ProcessDataFromImplant(tunnelData *sliverpb.TunnelData) error

ProcessDataFromImplant validates and serializes one generic tunnel frame. Reorder and pending-byte state belongs to this exact Tunnel pointer, so a retained handler can never poison a newer generation that happens to reuse the same numeric ID. Resend controls bypass data sequencing but share the same bounded admission and delivery actor.

func (*Tunnel) QuiesceDataToImplant added in v1.7.7

func (t *Tunnel) QuiesceDataToImplant()

QuiesceDataToImplant prevents new client payload admission and joins every payload already handed to the TunnelData forwarding worker. It is used only for a graceful client-requested close; failure and session teardown still publish Done immediately so bounded sends are canceled promptly.

func (*Tunnel) ResendDataToImplant added in v1.7.7

func (t *Tunnel) ResendDataToImplant(sequence uint64) (*sliverpb.TunnelData, bool, error)

ResendDataToImplant returns an immutable cached frame when it remains inside the useful receive window. Older evicted requests fail without growing state.

func (*Tunnel) SendDataFromImplant added in v1.5.14

func (t *Tunnel) SendDataFromImplant(tunnelData *sliverpb.TunnelData) bool

SendDataFromImplant forwards tunnelData to the client stream and reports whether the send was accepted rather than canceled by tunnel closure.

func (*Tunnel) SendDataToImplant added in v1.7.7

func (t *Tunnel) SendDataToImplant(data []byte) bool

SendDataToImplant queues tunnel data unless the tunnel has already closed.

func (*Tunnel) ToImplantTerminalSequence added in v1.7.7

func (t *Tunnel) ToImplantTerminalSequence() uint64

ToImplantTerminalSequence returns the exclusive successfully-enqueued prefix understood by a capability-bearing implant. An assigned frame whose bounded transport send failed must not make the implant wait for data that was never enqueued. Legacy implants require sequence zero.

func (*Tunnel) Touch deprecated added in v1.7.7

func (t *Tunnel) Touch()

Touch records implant-to-client activity for the legacy implant-originated close path.

Deprecated: direction-aware relay paths update their activity internally.

func (*Tunnel) TunnelTerminalEnabled added in v1.7.7

func (t *Tunnel) TunnelTerminalEnabled() bool

TunnelTerminalEnabled reports whether the exact implant generation waits for an exclusive terminal sequence before detaching a generic tunnel.

Directories

Path Synopsis
Package rtunnels owns reverse-port-forward authorization and relay state.
Package rtunnels owns reverse-port-forward authorization and relay state.

Jump to

Keyboard shortcuts

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