Tunnels
Tunnel Types
Type
Description
Flow (SOCKS/Local Port Forward)

Flow Reverse Port Forward

Teamserver API for Tunnel
Last updated


Last updated
┌──────────────────────────────────────────────────────────────────────────────────┐
│ TUNNEL FLOW (SOCKS/LPORTFWD) │
├──────────────────────────────────────────────────────────────────────────────────┤
│ │
│ ╔════════════════════════════════════════════════════════════════════════════╗ │
│ ║ CREATE TUNNEL ║ │
│ ╚════════════════════════════════════════════════════════════════════════════╝ │
│ │
│ GUI ──> POST /tunnel/start/socks5 (socks5 start 127.0.0.1:1080) │
│ │ │
│ V │
│ ┌─────────────────────────────────────────────────────────────────────────────┐ │
│ │ TEAMSERVER │ │
│ │ │ │ │
│ │ V │ │
│ │ TsTunnelCreateSocks5(AgentId, Info, Lhost, Lport, ...) │ │
│ │ │ │ │
│ │ ├──> Create Tunnel object with agent Callbacks │ │
│ │ │ │ │
│ │ V │ │
│ │ TsTunnelStart(TunnelId) │ │
│ │ │ │ │
│ │ └──> net.Listen("tcp", "127.0.0.1:1080") │ │
│ │ Start Accept() goroutine for incoming connections │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────────────────────┘ │
│ │
│ ╔════════════════════════════════════════════════════════════════════════════╗ │
│ ║ CLIENT CONNECTION ║ │
│ ╚════════════════════════════════════════════════════════════════════════════╝ │
│ │
│ Browser/App ──> TCP connect to 127.0.0.1:1080 │
│ │ │
│ V │
│ ┌─────────────────────────────────────────────────────────────────────────────┐ │
│ │ TEAMSERVER (TunnelManager) │ │
│ │ │ │ │
│ │ V │ │
│ │ handleTunChannelCreate() │ │
│ │ │ │ │
│ │ ├──> Generate unique channelId │ │
│ │ ├──> proxy.CheckSocks5() ←── Parse SOCKS handshake │ │
│ │ ├──> Create TunnelChannel with Pipes │ │
│ │ │ │ │
│ │ V │ │
│ │ ┌───────────────────────────────────────────────────────────────────────┐ │ │
│ │ │ EXTENDER (Agent Plugin) │ │ │
│ │ │ │ │ │ │
│ │ │ V │ │ │
│ │ │ TunnelCallbacks.ConnectTCP(channelId, host, port) │ │ │
│ │ │ │ │ │ │
│ │ │ └──> return TaskData (added to agent queue) │ │ │
│ │ │ │ │ │
│ │ └───────────────────────────────────────────────────────────────────────┘ │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────────────────────┘ │
│ │
│ ╔════════════════════════════════════════════════════════════════════════════╗ │
│ ║ AGENT RESPONSE ║ │
│ ╚════════════════════════════════════════════════════════════════════════════╝ │
│ │
│ Agent ──> COMMAND_TUNNEL_OPEN / COMMAND_TUNNEL_CLOSE │
│ │ │
│ V │
│ ┌─────────────────────────────────────────────────────────────────────────────┐ │
│ │ EXTENDER (Agent Plugin - ProcessTasksResult) │ │
│ │ │ │ │
│ │ V │ │
│ │ ┌───────────────────────────────────────────────────────────────────────┐ │ │
│ │ │ TEAMSERVER │ │ │
│ │ │ │ │ │ │
│ │ │ ├──> Success: TsTunnelConnectionResume(channelId) │ │ │
│ │ │ │ └──> proxy.ReplySocks5Status(SUCCESS) │ │ │
│ │ │ │ Start relay goroutines │ │ │
│ │ │ │ │ │ │
│ │ │ └──> Failed: TsTunnelConnectionHalt(channelId, errorCode) │ │ │
│ │ │ └──> proxy.ReplySocks5Status(ERROR) │ │ │
│ │ │ │ │ │
│ │ └───────────────────────────────────────────────────────────────────────┘ │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────────────────────┘ │
│ │
│ ╔════════════════════════════════════════════════════════════════════════════╗ │
│ ║ DATA FLOW (bidirectional) ║ │
│ ╚════════════════════════════════════════════════════════════════════════════╝ │
│ │
│ Browser ──write──> Socket ──> pwSrv ──> prSrv ──read──> │
│ ──> TunnelCallbacks.WriteTCP(channelId, data) │
│ ──> TaskData ──> Agent ──> Target │
│ │
│ Target ──> Agent ──> TsTunnelConnectionData(channelId, data) │
│ ──> pwTun ──> prTun ──read──> Socket ──write──> Browser │
│ │
│ ╔════════════════════════════════════════════════════════════════════════════╗ │
│ ║ CONNECTION CLOSE ║ │
│ ╚════════════════════════════════════════════════════════════════════════════╝ │
│ │
│ Browser closes ──> TunnelCallbacks.Close(channelId) ──> TaskData ──> Agent │
│ Agent closes ──> TsTunnelConnectionClose(channelId, write) ──> Close Socket │
│ │
└──────────────────────────────────────────────────────────────────────────────────┘┌──────────────────────────────────────────────────────────────────────────────────┐
│ REVERSE PORT FORWARD FLOW │
├──────────────────────────────────────────────────────────────────────────────────┤
│ │
│ ╔════════════════════════════════════════════════════════════════════════════╗ │
│ ║ CREATE RPORTFWD ║ │
│ ╚════════════════════════════════════════════════════════════════════════════╝ │
│ │
│ GUI ──> POST /tunnel/start/rportfwd (rportfwd 8080 127.0.0.1:80) │
│ │ │
│ V │
│ ┌─────────────────────────────────────────────────────────────────────────────┐ │
│ │ TEAMSERVER │ │
│ │ │ │ │
│ │ V │ │
│ │ TsTunnelCreateRportfwd(AgentId, Info, 8080, "127.0.0.1", 80) │ │
│ │ │ │ │
│ │ V │ │
│ │ ┌───────────────────────────────────────────────────────────────────────┐ │ │
│ │ │ EXTENDER (Agent Plugin) │ │ │
│ │ │ │ │ │ │
│ │ │ V │ │ │
│ │ │ TunnelCallbacks.Reverse(tunnelId, 8080) │ │ │
│ │ │ │ │ │ │
│ │ │ └──> return TaskData ──> Agent listens on port 8080 │ │ │
│ │ │ │ │ │
│ │ └───────────────────────────────────────────────────────────────────────┘ │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────────────────────┘ │
│ │
│ ╔════════════════════════════════════════════════════════════════════════════╗ │
│ ║ REMOTE CLIENT CONNECTION ║ │
│ ╚════════════════════════════════════════════════════════════════════════════╝ │
│ │
│ Remote Client ──> TCP connect to Agent:8080 │
│ │ │
│ V │
│ ┌─────────────────────────────────────────────────────────────────────────────┐ │
│ │ EXTENDER (Agent Plugin - ProcessTasksResult) │ │
│ │ │ │ │
│ │ V │ │
│ │ Agent sends COMMAND_TUNNEL_OPEN(tunnelId, channelId) │ │
│ │ │ │ │
│ │ V │ │
│ │ ┌───────────────────────────────────────────────────────────────────────┐ │ │
│ │ │ TEAMSERVER │ │ │
│ │ │ │ │ │ │
│ │ │ V │ │ │
│ │ │ TsTunnelConnectionAccept(tunnelId, channelId) │ │ │
│ │ │ │ │ │ │
│ │ │ └──> net.Dial("tcp", "127.0.0.1:80") │ │ │
│ │ │ Relay: Agent:8080 ←→ Server ←→ 127.0.0.1:80 │ │ │
│ │ │ │ │ │
│ │ └───────────────────────────────────────────────────────────────────────┘ │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────────────────────┘ │
│ │
└──────────────────────────────────────────────────────────────────────────────────┘type Teamserver interface {
// Create tunnel
TsTunnelCreate(AgentId string, Type int, Info string, Lhost string, Lport int, Client string, Thost string, Tport int, AuthUser string, AuthPass string) (string, error)
TsTunnelCreateSocks4(AgentId string, Info string, Lhost string, Lport int) (string, error)
TsTunnelCreateSocks5(AgentId string, Info string, Lhost string, Lport int, UseAuth bool, Username string, Password string) (string, error)
TsTunnelCreateLportfwd(AgentId string, Info string, Lhost string, Lport int, Thost string, Tport int) (string, error)
TsTunnelCreateRportfwd(AgentId string, Info string, Lport int, Thost string, Tport int) (string, error)
// Start/stop
TsTunnelStart(TunnelId string) (string, error)
TsTunnelStop(TunnelId string) error
TsTunnelStopSocks(AgentId string, Port int)
TsTunnelStopLportfwd(AgentId string, Port int)
TsTunnelStopRportfwd(AgentId string, Port int)
// Connection management
TsTunnelChannelExists(channelId int) bool
TsTunnelGetPipe(AgentId string, channelId int) (*io.PipeReader, *io.PipeWriter, error)
TsTunnelConnectionData(channelId int, data []byte)
TsTunnelConnectionResume(AgentId string, channelId int, ioDirect bool)
TsTunnelConnectionClose(channelId int, writeOnly bool)
TsTunnelConnectionHalt(channelId int, errorCode byte)
TsTunnelConnectionAccept(tunnelId int, channelId int)
TsTunnelPause(channelId int)
TsTunnelResume(channelId int)
// Update Reverse Port Forward
TsTunnelUpdateRportfwd(tunnelId int, result bool) (string, string, error)
}