Back to Home

SOCKS5 via WebRTC TURN: Go implementation

Tool masks SOCKS5 traffic as WB Stream WebRTC video conference. Reverse API, minimal protobuf parser, KCP via TURN-relay with yamux. Full automation in pure Go.

SOCKS5 Tunnel in Video Conferences: Full Breakdown
Advertisement 728x90

SOCKS5 Tunnel via WebRTC TURN Wildberries: Implementation in Go

A tool has been developed to hide SOCKS5 traffic within WebRTC TURN sessions on the WB Stream platform. Traffic is disguised as a video conference using LiveKit SFU. Full cycle: reverse HTTP API, protobuf parsing, KCP over TURN relay, yamux multiplexing. Works without a browser, with a single launch command.

Reverse Engineering the stream.wb.ru API

Traffic collection via puppeteer revealed a sequence of four HTTP requests and a WebSocket connection. The main page blocks requests without a browser (code 498), but API endpoints are accessible.

Sequence:

Google AdInline article slot
  • POST /auth/api/v1/auth/user/guest-register — Guest JWT token with displayName.
  • POST /api-room/api/v2/room — Create a room with roomType: ROOM_TYPE_ALL_ON_SCREEN, roomPrivacy: ROOM_PRIVACY_FREE.
  • POST /api-room/api/v1/room/{id}/join — Join (GET returns 501).
  • GET /api-room-manager/api/v1/room/{id}/token — LiveKit token (account for gzip in Accept-Encoding).

WebSocket: wss://wbstream01-el.wb.ru:7880/rtc?access_token=...&sdk=js&version=2.15.3&protocol=16. ICE servers: turn:wb-stream-turn-1.wb.ru:3478.

Implemented with net/http without cookies/CSRF.

rr, _ := wb(cl, "POST", "/auth/api/v1/auth/user/guest-register",
    []byte(`{"displayName":"lh_42"}`), "")

Protobuf Parser for LiveKit SignalResponse

LiveKit transmits ICE servers in SignalResponse > JoinResponse > ICEServer (fields 1>5/9). Full google.golang.org/protobuf is overkill — a minimal 40-line parser was written.

Google AdInline article slot

Varint decoding:

func pbVar(d []byte, o int) (uint64, int) {
    var v uint64
    for s := 0; o < len(d) && s < 64; s += 7 {
        b := d[o]; o++
        v |= uint64(b&0x7f) << s
        if b < 0x80 { return v, o }
    }
    return 0, o
}

Extracting length-delimited fields:

func pbAll(d []byte, f uint64) (r [][]byte) {
    for o := 0; o < len(d); {
        t, n := pbVar(d, o)
        if n == o { break }
        o = n
        switch t & 7 {
        case 2:
            l, n := pbVar(d, o); o = n
            e := o + int(l)
            if e > len(d) || e < o { return }
            if t>>3 == f { r = append(r, d[o:e]) }
            o = e
        // ...
        }
    }
    return
}

The parser searches for ICE servers in field 5 (WB fork) and 9 (standard), extracting urls, username, credential.

Google AdInline article slot

Tunnel Architecture: KCP + TURN + yamux

TCP from SOCKS5 → yamux stream → KCP (AES-256) → TURN relay → VPS → internet.

Key components:

  • TURN allocation via pion/turn: tc.Allocate() returns net.PacketConn.
  • KCP over relay: kcp.NewConn(peerVPS, blk, 10, 3, relay).
  • Yamux for stream multiplexing.
  • SOCKS5 server on VPS.
uc, _ := net.ListenUDP("udp", nil)
tc, _ := turn.NewClient(&turn.ClientConfig{...})
relay, _ := tc.Allocate()
kc, _ := kcp.NewConn(peerVPS, blk, 10, 3, relay)

Server: KCP listener + yamux server + SOCKS5.

Automation and Fault Tolerance

  • Smart key: base64(IP|SHA256(password)).
  • Reconnection: yamux ping/15s, backoff 2-60s, TURN credentials cache 5min.
  • Self-cleanup: pgrep + kill previous instances, systemd overwrite.
  • Graceful shutdown: Ctrl+C → 2s cleanup.

Launch and Limitations

go build -o lionheart .
# Server
./lionheart  # copy key
# Client
./lionheart  # paste key → 127.0.0.1:1080

Limitations: dependency on WB Stream API, hardcoded wbstream01-el.wb.ru. Plans: gomobile for Android/iOS (VpnService/NEPacketTunnelProvider).

Key Points

  • Masquerading as WebRTC traffic for DPI/firewalls at gigabit speeds.
  • Minimal protobuf parser without dependencies.
  • TURN relay as net.PacketConn for KCP.
  • Full automation without browser/API keys.
  • Pure Go, gomobile-ready.

— Editorial Team

Advertisement 728x90

Read Next