Documentation
¶
Index ¶
- Constants
- Variables
- func AddBuilder(builder *clientpb.Builder) error
- func AddCrackstation(crack *Crackstation) error
- func AllBuilders() []*clientpb.Builder
- func AllCrackstations() []*clientpb.Crackstation
- func ClosePivotSession(pivotID string) bool
- func EnvelopeID() int64
- func GetBuilder(builderName string) *clientpb.Builder
- func NewTunnelID() uint64
- func NextJobID() int
- func RemoveBuilder(builderName string)
- func RemoveCrackstation(hostUUID string)
- func RemoveExternalBuildAssignment(buildID string)
- func StartEventAutomation()
- func TrackExternalBuildAssignment(buildID string, builderName string, operatorName string)
- type Client
- type Crackstation
- type Event
- type ExternalBuildAssignment
- type ImplantConnection
- func (c *ImplantConnection) ClaimReverseTunnelID(tunnelID uint64) bool
- func (c *ImplantConnection) Close()
- func (c *ImplantConnection) DeliverResponse(envelope *sliverpb.Envelope) bool
- func (c *ImplantConnection) Done() <-chan struct{}
- func (c *ImplantConnection) GetLastMessage() time.Time
- func (c *ImplantConnection) RequestResend(data []byte)
- func (c *ImplantConnection) SendEnvelope(envelope *sliverpb.Envelope, timeout time.Duration) error
- func (c *ImplantConnection) SendEnvelopeUntil(envelope *sliverpb.Envelope, ownerDone <-chan struct{}, timeout time.Duration) error
- func (c *ImplantConnection) SetCleanup(callback func()) bool
- func (c *ImplantConnection) TryClaimReverseTunnelID(tunnelID uint64) ReverseTunnelIDClaimResult
- func (c *ImplantConnection) UpdateLastMessage()
- type Job
- type Pivot
- type PivotGraphEntry
- type ReverseTunnelIDClaimResult
- type Session
- func (s *Session) IsDead() bool
- func (s *Session) LastCheckin() time.Time
- func (s *Session) Request(msgType uint32, timeout time.Duration, data []byte) ([]byte, error)
- func (s *Session) RequestContext(ctx context.Context, msgType uint32, data []byte) ([]byte, error)
- func (s *Session) ToProtobuf() *clientpb.Session
- type SocksClient
- type SocksClientLifecycle
- type SocksDataSender
- type TcpTunnel
- func (t *TcpTunnel) AcknowledgementsToClient() <-chan uint64
- func (t *TcpTunnel) AcknowledgementsToImplant() <-chan uint64
- func (t *TcpTunnel) AdmitToImplant(data *sliverpb.SocksData) error
- func (t *TcpTunnel) AdmitToImplantContext(ctx context.Context, data *sliverpb.SocksData) error
- func (t *TcpTunnel) BindClient(client *SocksClient) (owned bool, newlyBound bool)
- func (t *TcpTunnel) BindClientWithCapabilities(client *SocksClient, username string, password string, sendsTerminal bool) (owned bool, newlyBound bool, err error)
- func (t *TcpTunnel) BindClientWithCredentials(client *SocksClient, username string, password string) (owned bool, newlyBound bool, err error)
- func (t *TcpTunnel) BindClientWithNegotiatedCapabilities(client *SocksClient, username string, password string, sendsTerminal bool, ...) (owned bool, newlyBound bool, err error)
- func (t *TcpTunnel) Capabilities() uint64
- func (t *TcpTunnel) Client() *SocksClient
- func (t *TcpTunnel) ClientLifecycle() SocksClientLifecycle
- func (t *TcpTunnel) CompleteFromImplant(data *sliverpb.SocksData)
- func (t *TcpTunnel) CompleteToImplant(data *sliverpb.SocksData)
- func (t *TcpTunnel) Credentials() (string, string)
- func (t *TcpTunnel) DeliverFromImplant(data *sliverpb.SocksData) bool
- func (t *TcpTunnel) Done() <-chan struct{}
- func (t *TcpTunnel) FlowControlEnabled() bool
- func (t *TcpTunnel) FromImplant() <-chan *sliverpb.SocksData
- func (t *TcpTunnel) FromImplantSpaceChange() <-chan struct{}
- func (t *TcpTunnel) ImplantConnection() *ImplantConnection
- func (t *TcpTunnel) LegacyImplantTerminalPending() <-chan struct{}
- func (t *TcpTunnel) LegacyImplantTerminalState() (pending bool, generation uint64, changed <-chan struct{})
- func (t *TcpTunnel) ProcessDataFromImplant(data *sliverpb.SocksData) error
- func (t *TcpTunnel) RelayClientAcknowledgement(client *SocksClient, ack uint64) error
- func (t *TcpTunnel) RelayImplantAcknowledgement(connection *ImplantConnection, ack uint64) error
- func (t *TcpTunnel) ToImplant() <-chan *sliverpb.SocksData
- func (t *TcpTunnel) TryFlushLegacyImplantTerminal(observedGeneration uint64) (done bool, err error)
- type Tunnel
- func (t *Tunnel) AcknowledgeDataToImplant(ack uint64) error
- func (t *Tunnel) BindClient(client rpcpb.SliverRPC_TunnelDataServer) bool
- func (t *Tunnel) ClaimClientTerminalDelivery(client rpcpb.SliverRPC_TunnelDataServer) bool
- func (t *Tunnel) ClaimFromImplantClose() bool
- func (t *Tunnel) ClaimImplantTerminalDelivery() bool
- func (t *Tunnel) ClaimToImplantClose() bool
- func (t *Tunnel) ClientBindLeaseExpired() bool
- func (t *Tunnel) ClientBound() <-chan struct{}
- func (t *Tunnel) Close()
- func (t *Tunnel) CompleteDataFromImplantForward(sequence uint64) error
- func (t *Tunnel) CompleteDataToImplant()
- func (t *Tunnel) CompleteDataToImplantForward(sequence uint64) error
- func (t *Tunnel) Done() <-chan struct{}
- func (t *Tunnel) FromImplantTerminalReady() <-chan struct{}
- func (t *Tunnel) GetLastMessageTime() time.Timedeprecated
- func (t *Tunnel) ImplantConnection() *ImplantConnection
- func (t *Tunnel) IsClient(client rpcpb.SliverRPC_TunnelDataServer) bool
- func (t *Tunnel) LastFromImplantTime() time.Time
- func (t *Tunnel) LastToImplantTime() time.Time
- func (t *Tunnel) MarkClientBound(client rpcpb.SliverRPC_TunnelDataServer) bool
- func (t *Tunnel) MarkFromImplantTerminal(terminal *sliverpb.TunnelData) (bool, error)
- func (t *Tunnel) NextDataToImplant(data []byte) (*sliverpb.TunnelData, error)
- func (t *Tunnel) ProcessDataFromImplant(tunnelData *sliverpb.TunnelData) error
- func (t *Tunnel) QuiesceDataToImplant()
- func (t *Tunnel) ResendDataToImplant(sequence uint64) (*sliverpb.TunnelData, bool, error)
- func (t *Tunnel) SendDataFromImplant(tunnelData *sliverpb.TunnelData) bool
- func (t *Tunnel) SendDataToImplant(data []byte) bool
- func (t *Tunnel) ToImplantTerminalSequence() uint64
- func (t *Tunnel) Touch()deprecated
- func (t *Tunnel) TunnelTerminalEnabled() bool
Constants ¶
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.
const ( // MaxSocksFrameBytes is the per-frame SOCKS payload limit in either // direction. It intentionally matches the generic tunnel wire contract. MaxSocksFrameBytes = sliverpb.MaxTunnelFrameBytes )
const ( // MaxTunnelFrameBytes limits one generic tunnel data frame. MaxTunnelFrameBytes = sliverpb.MaxTunnelFrameBytes )
const (
PivotTransportName = "pivot"
)
Variables ¶
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") )
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") )
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") )
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") )
var ( // Clients - Manages client active Clients = &clients{ active: map[int]*Client{}, mutex: &sync.Mutex{}, } )
var (
ErrDuplicateExternalBuilderName = errors.New("builder name must be unique, this name is already in use")
)
var (
ErrDuplicateHosts = errors.New("only one crackstation instance per host")
)
var (
// EventBroker - Distributes event messages
EventBroker = newBroker()
)
var ( // Jobs - Holds pointers to all the current jobs Jobs = &jobs{ active: &sync.Map{}, } )
var (
PivotSessions = &sync.Map{} // ID -> Pivot
)
var ( // SocksTunnels manages server-side duplex SOCKS tunnels. SocksTunnels = tcpTunnel{ // contains filtered or unexported fields } )
Functions ¶
func AddBuilder ¶ added in v1.5.30
func AddCrackstation ¶ added in v1.6.0
func AddCrackstation(crack *Crackstation) error
func AllBuilders ¶ added in v1.5.30
func AllCrackstations ¶ added in v1.6.0
func AllCrackstations() []*clientpb.Crackstation
func ClosePivotSession ¶ added in v1.7.7
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 GetBuilder ¶ added in v1.5.30
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
TrackExternalBuildAssignment stores the builder/operator assignment for a build.
Types ¶
type Client ¶
Client - Single client connection
func (*Client) ToProtobuf ¶
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
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
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 ¶
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
NewPivotSession - Creates a new pivot session
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) LastCheckin ¶
LastCheckin - Get the last time a session message was received
func (*Session) Request ¶
Request - Sends a protobuf request to the active sliver and returns the response
func (*Session) RequestContext ¶ added in v1.7.7
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 ¶
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.
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
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
AcknowledgementsToClient returns the fixed-size ACK control mailbox.
func (*TcpTunnel) AcknowledgementsToImplant ¶ added in v1.7.7
AcknowledgementsToImplant returns the fixed-size ACK control mailbox.
func (*TcpTunnel) AdmitToImplant ¶ added in v1.7.7
AdmitToImplant validates and orders an operator frame without retaining its Request metadata or protobuf unknown fields.
func (*TcpTunnel) AdmitToImplantContext ¶ added in v1.7.7
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
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
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
CompleteToImplant releases the combined admission reservation after the worker has sent or discarded a frame.
func (*TcpTunnel) Credentials ¶ added in v1.7.7
Credentials returns the username and password captured at bind time.
func (*TcpTunnel) DeliverFromImplant ¶ added in v1.7.7
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
FlowControlEnabled reports whether both endpoints negotiated SOCKS flow control for this exact tunnel generation.
func (*TcpTunnel) FromImplant ¶ added in v1.5.0
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
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
ToImplant returns ordered operator frames awaiting implant delivery.
func (*TcpTunnel) TryFlushLegacyImplantTerminal ¶ added in v1.7.7
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 (*Tunnel) AcknowledgeDataToImplant ¶ added in v1.7.7
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
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
ClaimImplantTerminalDelivery lets one concurrent tunnel owner publish the exact generation's terminal to its implant peer.
func (*Tunnel) ClaimToImplantClose ¶ added in v1.7.7
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
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
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
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 (*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
LastFromImplantTime returns the last implant-to-client activity used to delay an implant terminal close.
func (*Tunnel) LastToImplantTime ¶ added in v1.7.7
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
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
SendDataToImplant queues tunnel data unless the tunnel has already closed.
func (*Tunnel) ToImplantTerminalSequence ¶ added in v1.7.7
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) TunnelTerminalEnabled ¶ added in v1.7.7
TunnelTerminalEnabled reports whether the exact implant generation waits for an exclusive terminal sequence before detaching a generic tunnel.