tcpmitm

package
v1.4.4-alpha1202-diff-... Latest Latest
Warning

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

Go to latest
Published: Dec 2, 2025 License: AGPL-3.0 Imports: 14 Imported by: 0

Documentation

Index

Constants

View Source
const (
	// ClientToServer indicates data flowing from client to server.
	ClientToServer = DirectionClientToServer

	// ServerToClient indicates data flowing from server to client.
	ServerToClient = DirectionServerToClient
)

FrameDirection type aliases for easy use

View Source
const (
	// TimeGap splits based on silence intervals.
	TimeGap = SplitByTimeGap

	// Direction splits when data direction changes.
	Direction = SplitByDirection

	// FixedSize splits when buffer reaches a fixed size.
	FixedSize = SplitBySize

	// NoSplit performs transparent forwarding.
	NoSplit = SplitNone
)

Split strategy aliases

View Source
const (
	// DefaultTimeGapThreshold is the default silence duration to trigger a split.
	// Can be configured to 100ms, 200ms, 300ms, etc.
	DefaultTimeGapThreshold = 100 * time.Millisecond

	// DefaultMaxBufferSize is the default maximum buffer size (8KB).
	// When buffer exceeds this size, a frame is automatically emitted.
	DefaultMaxBufferSize = 8 * 1024

	// DefaultReadBufferSize is the default read buffer size for I/O operations.
	DefaultReadBufferSize = 4 * 1024
)

Default configuration constants

Variables

View Source
var (
	TimeGap50ms  = 50 * time.Millisecond
	TimeGap100ms = 100 * time.Millisecond
	TimeGap200ms = 200 * time.Millisecond
	TimeGap300ms = 300 * time.Millisecond
)

Common time gap thresholds for convenience

View Source
var Exports = map[string]interface{}{

	"Start": _start,

	"context":            _withContext,
	"dialer":             _withDialer,
	"timeGapThreshold":   _withTimeGapThreshold,
	"maxBufferSize":      _withMaxBufferSize,
	"hijackTCPFrame":     _hijackTCPFrame,
	"hijackTCPConn":      _hijackTCPConn,
	"protocolAwareSplit": _withProtocolAwareSplit,
}

Exports provides yaklang bindings for tcpmitm functionality Style follows mitm package conventions: lowercase option functions, uppercase entry points

Functions

This section is empty.

Types

type ConnHijackCallback

type ConnHijackCallback func(conn net.Conn, operator *ConnOperator)

ConnHijackCallback is the callback function signature for connection hijacking. It receives the hijacked connection and an operator to control the connection.

type ConnOperator

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

ConnOperator provides operations on a hijacked TCP connection. It allows the user to control how the hijacked connection is handled.

func NewConnOperator

func NewConnOperator(conn net.Conn, flow *ConnectionFlow) *ConnOperator

NewConnOperator creates a new ConnOperator for the given hijacked connection.

func (*ConnOperator) AttachConnection

func (op *ConnOperator) AttachConnection(remoteConn net.Conn)

AttachConnection bridges the hijacked connection with a new remote connection. Data will be transparently forwarded between the two connections. This is useful for redirecting traffic to a different destination.

func (*ConnOperator) CloseHijackedConn

func (op *ConnOperator) CloseHijackedConn() error

CloseHijackedConn forcefully closes the hijacked connection. This will terminate the connection immediately.

func (*ConnOperator) GetFlow

func (op *ConnOperator) GetFlow() *ConnectionFlow

GetFlow returns the connection flow information.

func (*ConnOperator) GetHijackedConn

func (op *ConnOperator) GetHijackedConn() net.Conn

GetHijackedConn returns the hijacked connection for manual handling. Note: After calling this, you are responsible for closing the connection.

func (*ConnOperator) Hold

func (op *ConnOperator) Hold()

Hold indicates that the connection is being handled elsewhere. No further automatic processing will be done on this connection. Use this when you want to take full control of the connection.

func (*ConnOperator) IsAttached

func (op *ConnOperator) IsAttached() bool

IsAttached returns whether the connection has been attached to another connection.

func (*ConnOperator) IsClosed

func (op *ConnOperator) IsClosed() bool

IsClosed returns whether the connection has been closed.

func (*ConnOperator) IsHeld

func (op *ConnOperator) IsHeld() bool

IsHeld returns whether the connection is being held for external handling.

type ConnectionContext

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

ConnectionContext holds the context for a single hijacked connection. It manages frame queues for both directions and provides methods for accessing buffered data across the connection.

func NewConnectionContext

func NewConnectionContext(parentCtx context.Context, flow *ConnectionFlow) *ConnectionContext

NewConnectionContext creates a new ConnectionContext for the given flow.

func (*ConnectionContext) Close

func (cc *ConnectionContext) Close()

Close closes the connection context and all queues.

func (*ConnectionContext) Context

func (cc *ConnectionContext) Context() context.Context

Context returns the connection's context.

func (*ConnectionContext) GetClientToServerQueue

func (cc *ConnectionContext) GetClientToServerQueue() *FrameQueue

GetClientToServerQueue returns the C->S frame queue.

func (*ConnectionContext) GetCreatedAt

func (cc *ConnectionContext) GetCreatedAt() time.Time

GetCreatedAt returns when the connection was established.

func (*ConnectionContext) GetDuration

func (cc *ConnectionContext) GetDuration() time.Duration

GetDuration returns how long the connection has been active.

func (*ConnectionContext) GetFlow

func (cc *ConnectionContext) GetFlow() *ConnectionFlow

GetFlow returns the connection flow information.

func (*ConnectionContext) GetFrameCount

func (cc *ConnectionContext) GetFrameCount() uint64

GetFrameCount returns the total number of frames processed.

func (*ConnectionContext) GetMetadata

func (cc *ConnectionContext) GetMetadata(key string) (interface{}, bool)

GetMetadata retrieves user-defined metadata.

func (*ConnectionContext) GetQueue

func (cc *ConnectionContext) GetQueue(direction FrameDirection) *FrameQueue

GetQueue returns the frame queue for the specified direction.

func (*ConnectionContext) GetServerToClientQueue

func (cc *ConnectionContext) GetServerToClientQueue() *FrameQueue

GetServerToClientQueue returns the S->C frame queue.

func (*ConnectionContext) IncrementFrameCounter

func (cc *ConnectionContext) IncrementFrameCounter() uint64

IncrementFrameCounter atomically increments and returns the frame counter.

func (*ConnectionContext) IsClosed

func (cc *ConnectionContext) IsClosed() bool

IsClosed returns whether the connection context is closed.

func (*ConnectionContext) SetMetadata

func (cc *ConnectionContext) SetMetadata(key string, value interface{})

SetMetadata stores user-defined metadata.

func (*ConnectionContext) TotalBufferedBytes

func (cc *ConnectionContext) TotalBufferedBytes() int

TotalBufferedBytes returns the total bytes buffered in both queues.

func (*ConnectionContext) TotalBufferedFrames

func (cc *ConnectionContext) TotalBufferedFrames() int

TotalBufferedFrames returns the total frames buffered in both queues.

type ConnectionFlow

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

ConnectionFlow represents the flow information of a TCP connection. It contains the client and server endpoint information.

func NewConnectionFlow

func NewConnectionFlow(conn net.Conn, clientIP string, clientPort int, serverIP string, serverPort int) *ConnectionFlow

NewConnectionFlow creates a new ConnectionFlow from the given connection. For hijacked connections from TUN device: - RemoteAddress/RemotePort represents the client (the one initiating the connection) - LocalAddress/LocalPort represents the server (the original destination)

func (*ConnectionFlow) GetClientAddr

func (cf *ConnectionFlow) GetClientAddr() string

GetClientAddr returns the client address in "ip:port" format.

func (*ConnectionFlow) GetClientIP

func (cf *ConnectionFlow) GetClientIP() string

GetClientIP returns the client IP address.

func (*ConnectionFlow) GetClientPort

func (cf *ConnectionFlow) GetClientPort() int

GetClientPort returns the client port number.

func (*ConnectionFlow) GetClientToServerQueue

func (cf *ConnectionFlow) GetClientToServerQueue() *FrameQueue

GetClientToServerQueue returns the C->S frame queue for this connection. Returns nil if no connection context has been set.

func (*ConnectionFlow) GetConnectionContext

func (cf *ConnectionFlow) GetConnectionContext() *ConnectionContext

GetConnectionContext returns the connection context. Returns nil if no context has been set.

func (*ConnectionFlow) GetServerAddr

func (cf *ConnectionFlow) GetServerAddr() string

GetServerAddr returns the server address in "ip:port" format.

func (*ConnectionFlow) GetServerIP

func (cf *ConnectionFlow) GetServerIP() string

GetServerIP returns the server IP address (original destination).

func (*ConnectionFlow) GetServerPort

func (cf *ConnectionFlow) GetServerPort() int

GetServerPort returns the server port number (original destination).

func (*ConnectionFlow) GetServerToClientQueue

func (cf *ConnectionFlow) GetServerToClientQueue() *FrameQueue

GetServerToClientQueue returns the S->C frame queue for this connection. Returns nil if no connection context has been set.

func (*ConnectionFlow) GetTotalBufferedBytes

func (cf *ConnectionFlow) GetTotalBufferedBytes() int

GetTotalBufferedBytes returns the total bytes buffered in both directions.

func (*ConnectionFlow) GetTotalBufferedFrames

func (cf *ConnectionFlow) GetTotalBufferedFrames() int

GetTotalBufferedFrames returns the total frames buffered in both directions.

func (*ConnectionFlow) PeekNextClientToServerRawData

func (cf *ConnectionFlow) PeekNextClientToServerRawData() []byte

PeekNextClientToServerRawData returns the raw bytes of the next C->S frame.

func (*ConnectionFlow) PeekNextServerToClientRawData

func (cf *ConnectionFlow) PeekNextServerToClientRawData() []byte

PeekNextServerToClientRawData returns the raw bytes of the next S->C frame.

func (*ConnectionFlow) SetConnectionContext

func (cf *ConnectionFlow) SetConnectionContext(ctx *ConnectionContext)

SetConnectionContext sets the connection context for this flow.

func (*ConnectionFlow) String

func (cf *ConnectionFlow) String() string

String returns a string representation of the connection flow.

type Frame

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

Frame represents a chunk of TCP data that has been segmented. It provides methods to inspect, modify, and control the data flow.

func NewFrame

func NewFrame(data []byte, direction FrameDirection, injector func([]byte) error) *Frame

NewFrame creates a new Frame with the given data and direction.

func (*Frame) Drop

func (f *Frame) Drop()

Drop marks the frame to be dropped (not forwarded). A dropped frame will not be sent to its destination.

func (*Frame) Forward

func (f *Frame) Forward()

Forward explicitly marks the frame to be forwarded. This is the default behavior if neither Drop nor Forward is called.

func (*Frame) GetBinParserNode

func (f *Frame) GetBinParserNode() (*base.Node, error)

GetBinParserNode attempts to parse the frame data using bin-parser. The result is cached - subsequent calls return the cached result. Returns the parsed node and any error encountered during parsing.

func (*Frame) GetBinParserNodeWithRule

func (f *Frame) GetBinParserNodeWithRule(rule string, keys ...string) (*base.Node, error)

GetBinParserNodeWithRule parses the frame data using a specific bin-parser rule. The result is NOT cached to allow re-parsing with different rules.

func (*Frame) GetBufferedBytes

func (f *Frame) GetBufferedBytes() int

GetBufferedBytes returns the total bytes currently buffered in the queue.

func (*Frame) GetBufferedFrameCount

func (f *Frame) GetBufferedFrameCount() int

GetBufferedFrameCount returns the number of frames currently buffered in the queue.

func (*Frame) GetDetectedProtocol

func (f *Frame) GetDetectedProtocol() Protocol

GetDetectedProtocol returns the detected protocol type.

func (*Frame) GetDirection

func (f *Frame) GetDirection() FrameDirection

GetDirection returns the direction of this frame.

func (*Frame) GetRawBytes

func (f *Frame) GetRawBytes() []byte

GetRawBytes returns a copy of the raw data bytes.

func (*Frame) GetSequenceNum

func (f *Frame) GetSequenceNum() uint64

GetSequenceNum returns the sequence number of this frame within the connection.

func (*Frame) GetTimestamp

func (f *Frame) GetTimestamp() time.Time

GetTimestamp returns when this frame was captured.

func (*Frame) Inject

func (f *Frame) Inject(data []byte)

Inject queues data to be sent immediately before this frame is forwarded. Multiple calls to Inject will queue multiple payloads in order.

func (*Frame) InjectImmediate

func (f *Frame) InjectImmediate(data []byte) error

InjectImmediate sends data immediately to the target without waiting. This bypasses the normal frame processing queue.

func (*Frame) IsDropped

func (f *Frame) IsDropped() bool

IsDropped returns whether this frame is marked for dropping.

func (*Frame) IsModified

func (f *Frame) IsModified() bool

IsModified returns whether this frame has been modified.

func (*Frame) IsUnknownProtocol

func (f *Frame) IsUnknownProtocol() bool

IsUnknownProtocol returns true if the frame's protocol could not be identified.

func (*Frame) PeekAllBufferedRawData

func (f *Frame) PeekAllBufferedRawData() []byte

PeekAllBufferedRawData returns all buffered raw bytes concatenated. This includes all frames currently waiting in the queue.

func (*Frame) PeekNextFrame

func (f *Frame) PeekNextFrame() *Frame

PeekNextFrame returns the next frame in the queue without removing it. Returns nil if no more frames are available in the buffer.

func (*Frame) PeekNextFrameRawData

func (f *Frame) PeekNextFrameRawData() []byte

PeekNextFrameRawData returns the raw bytes of the next frame in the queue without removing it. This allows looking ahead at data that hasn't been processed by the callback yet. Returns nil if no more frames are available in the buffer.

func (*Frame) PeekNextNFrames

func (f *Frame) PeekNextNFrames(n int) []*Frame

PeekNextNFrames returns up to n frames from the queue without removing them.

func (*Frame) SetRawBytes

func (f *Frame) SetRawBytes(modified []byte)

SetRawBytes modifies the frame's data. This marks the frame as modified and invalidates cached parse results.

func (*Frame) SetSequenceNum

func (f *Frame) SetSequenceNum(seq uint64)

SetSequenceNum sets the sequence number for this frame.

func (*Frame) SetUnknownProtocol

func (f *Frame) SetUnknownProtocol(unknown bool)

SetUnknownProtocol marks this frame as having an unknown protocol.

func (*Frame) Size

func (f *Frame) Size() int

Size returns the current size of the frame data.

type FrameDirection

type FrameDirection int

FrameDirection indicates the direction of data flow.

const (
	// DirectionClientToServer indicates data flowing from client to server.
	DirectionClientToServer FrameDirection = iota
	// DirectionServerToClient indicates data flowing from server to client.
	DirectionServerToClient
)

func (FrameDirection) String

func (d FrameDirection) String() string

type FrameHijackCallback

type FrameHijackCallback func(flow *ConnectionFlow, frame *Frame)

FrameHijackCallback is the callback function signature for frame hijacking. It receives the connection flow and the frame instance for inspection/modification.

type FrameQueue

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

FrameQueue manages a queue of frames for a single direction of a connection. It provides peek functionality to look ahead at buffered frames while maintaining sequential callback invocation within the same connection.

func NewFrameQueue

func NewFrameQueue(direction FrameDirection, connCtx *ConnectionContext) *FrameQueue

NewFrameQueue creates a new FrameQueue for the given direction.

func (*FrameQueue) BufferedBytes

func (q *FrameQueue) BufferedBytes() int

BufferedBytes returns the total bytes currently buffered in the queue.

func (*FrameQueue) Close

func (q *FrameQueue) Close()

Close closes the queue and signals any waiting consumers.

func (*FrameQueue) Dequeue

func (q *FrameQueue) Dequeue() *Frame

Dequeue removes and returns the next frame from the queue. Returns nil if the queue is empty.

func (*FrameQueue) DequeueWait

func (q *FrameQueue) DequeueWait(ctx context.Context) *Frame

DequeueWait waits for and returns the next frame from the queue. Returns nil if the context is cancelled or queue is closed.

func (*FrameQueue) Enqueue

func (q *FrameQueue) Enqueue(frame *Frame)

Enqueue adds a frame to the queue.

func (*FrameQueue) IsClosed

func (q *FrameQueue) IsClosed() bool

IsClosed returns whether the queue is closed.

func (*FrameQueue) PeekAllRawBytes

func (q *FrameQueue) PeekAllRawBytes() []byte

PeekAllRawBytes returns all buffered raw bytes concatenated.

func (*FrameQueue) PeekNext

func (q *FrameQueue) PeekNext(offset int) *Frame

PeekNext returns the next frame(s) in the queue without removing them. The offset parameter specifies how many frames ahead to look. offset=0 means the next frame, offset=1 means the one after that, etc.

func (*FrameQueue) PeekNextN

func (q *FrameQueue) PeekNextN(n int) []*Frame

PeekNextN returns up to n frames from the queue without removing them.

func (*FrameQueue) PeekNextRawBytes

func (q *FrameQueue) PeekNextRawBytes() []byte

PeekNextRawBytes returns the raw bytes of the next frame without removing it. Returns nil if no more frames are available.

func (*FrameQueue) Size

func (q *FrameQueue) Size() int

Size returns the number of frames in the queue.

func (*FrameQueue) WaitForFrameOrTimeout

func (q *FrameQueue) WaitForFrameOrTimeout(timeout time.Duration) bool

WaitForFrameOrTimeout waits for a new frame with timeout. Returns true if a frame arrived, false on timeout.

type Option

type Option func(*TCPMitm)

Option is a function that configures TCPMitm.

func WithContext

func WithContext(ctx context.Context) Option

WithContext sets a custom context for the TCPMitm instance.

func WithDialer

func WithDialer(dialer func(addr string) (net.Conn, error)) Option

WithDialer sets a custom dialer for connecting to real servers.

func WithMaxBufferSize

func WithMaxBufferSize(size int) Option

WithMaxBufferSize sets the maximum buffer size before forcing a frame split. Default is 8KB. When buffer exceeds this, a frame is automatically emitted.

func WithProtocolAwareSplit

func WithProtocolAwareSplit(enable bool) Option

WithProtocolAwareSplit enables protocol-aware frame splitting.

func WithReadBufferSize

func WithReadBufferSize(size int) Option

WithReadBufferSize sets the I/O read buffer size.

func WithSplitStrategy

func WithSplitStrategy(strategy SplitStrategy) Option

WithSplitStrategy sets the split strategy.

func WithSplitterConfig

func WithSplitterConfig(config *SplitterConfig) Option

WithSplitterConfig sets a custom splitter configuration.

func WithTimeGapThreshold

func WithTimeGapThreshold(d time.Duration) Option

WithTimeGapThreshold sets the time gap threshold for frame splitting.

type Protocol

type Protocol int

Protocol represents a detected protocol type.

const (
	ProtocolUnknown Protocol = iota
	ProtocolHTTP
	ProtocolHTTPS
	ProtocolTLS
	ProtocolSSH
	ProtocolRedis
	ProtocolMySQL
	ProtocolPostgreSQL
	ProtocolMongoDB
	ProtocolSMTP
	ProtocolFTP
	ProtocolDNS
)

func (Protocol) String

func (p Protocol) String() string

type ProtocolDetector

type ProtocolDetector struct{}

ProtocolDetector detects the protocol from initial bytes.

func NewProtocolDetector

func NewProtocolDetector() *ProtocolDetector

NewProtocolDetector creates a new protocol detector.

func (*ProtocolDetector) Detect

func (pd *ProtocolDetector) Detect(data []byte) Protocol

Detect attempts to identify the protocol from the first few bytes.

func (*ProtocolDetector) DetectFromFrame

func (pd *ProtocolDetector) DetectFromFrame(frame *Frame) Protocol

DetectFromFrame detects protocol from a frame.

func (*ProtocolDetector) IsEncrypted

func (pd *ProtocolDetector) IsEncrypted(protocol Protocol) bool

IsEncrypted returns whether the detected protocol uses encryption.

type SplitStrategy

type SplitStrategy int

SplitStrategy defines how to segment raw TCP streams into frames.

const (
	// SplitByTimeGap segments based on silence intervals.
	// If no data arrives within a threshold, the current buffer is treated as a complete frame.
	SplitByTimeGap SplitStrategy = iota

	// SplitByDirection segments when data direction changes.
	// Useful for request-response protocols.
	SplitByDirection

	// SplitBySize segments when buffer reaches a fixed size.
	// Used for logging/forensics, not protocol-aware.
	SplitBySize

	// SplitNone performs no segmentation - raw transparent forwarding.
	SplitNone
)

type SplitterConfig

type SplitterConfig struct {
	// Strategy to use for splitting
	Strategy SplitStrategy

	// TimeGapThreshold is the silence duration to trigger a split (for SplitByTimeGap).
	// Default: 100ms. Common values: 50ms, 100ms, 200ms, 300ms
	TimeGapThreshold time.Duration

	// MaxBufferSize is the maximum buffer size before forcing a frame split.
	// Default: 8KB. When buffer exceeds this, a frame is automatically emitted.
	MaxBufferSize int

	// MaxFrameSize is the target frame size for SplitBySize strategy.
	// Default: 4096 bytes
	MaxFrameSize int

	// ReadBufferSize is the I/O read buffer size.
	// Default: 4KB
	ReadBufferSize int

	// EnableProtocolAwareSplit enables protocol-aware frame splitting.
	// When true, the splitter will try to respect protocol boundaries.
	EnableProtocolAwareSplit bool
}

SplitterConfig holds configuration for frame splitting.

func DefaultSplitterConfig

func DefaultSplitterConfig() *SplitterConfig

DefaultSplitterConfig returns a default splitter configuration. Uses 100ms time gap threshold and 8KB max buffer size.

func NewSplitterConfig

func NewSplitterConfig(timeGap time.Duration) *SplitterConfig

NewSplitterConfig creates a splitter config with custom time gap threshold. Common values: 50ms, 100ms, 200ms, 300ms

type StreamSplitter

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

StreamSplitter handles reading from a stream and splitting into frames.

func NewStreamSplitter

func NewStreamSplitter(reader io.Reader, writer io.Writer, direction FrameDirection, config *SplitterConfig) *StreamSplitter

NewStreamSplitter creates a new stream splitter.

func (*StreamSplitter) Frames

func (ss *StreamSplitter) Frames() <-chan *Frame

Frames returns the channel of parsed frames.

func (*StreamSplitter) Start

func (ss *StreamSplitter) Start()

Start begins reading from the stream and splitting into frames.

func (*StreamSplitter) Stop

func (ss *StreamSplitter) Stop()

Stop stops the splitter.

func (*StreamSplitter) WriteFrame

func (ss *StreamSplitter) WriteFrame(frame *Frame) error

WriteFrame writes a frame to the output writer.

type TCPMitm

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

TCPMitm is the main controller for TCP MITM operations. It loads connections from a channel and provides frame-level and connection-level hijacking.

func LoadConnectionChannel

func LoadConnectionChannel(connChan <-chan net.Conn, opts ...Option) (*TCPMitm, error)

LoadConnectionChannel creates a new TCPMitm instance from a connection channel. The channel should receive hijacked TCP connections (e.g., from TUN device).

func (*TCPMitm) Run

func (m *TCPMitm) Run() error

Run starts the MITM processing loop. It will block until the context is cancelled or an error occurs.

func (*TCPMitm) SetHijackTCPConn

func (m *TCPMitm) SetHijackTCPConn(callback ConnHijackCallback)

SetHijackTCPConn sets the callback for connection-level hijacking. This callback is invoked when a new connection is established.

func (*TCPMitm) SetHijackTCPFrame

func (m *TCPMitm) SetHijackTCPFrame(callback FrameHijackCallback)

SetHijackTCPFrame sets the callback for frame-level hijacking. This callback is invoked for each segmented data frame.

func (*TCPMitm) Stop

func (m *TCPMitm) Stop()

Stop stops the MITM processing.

Jump to

Keyboard shortcuts

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