SOCKS5-Tunnel über WebRTC TURN Wildberries: Implementierung in Go
Es wurde ein Tool entwickelt, um SOCKS5-Datenverkehr innerhalb von WebRTC TURN-Sitzungen auf der WB Stream-Plattform zu verbergen. Der Traffic tarnt sich als Videokonferenz mithilfe von LiveKit SFU. Vollständiger Zyklus: Reverse HTTP-API, Protobuf-Parsing, KCP über TURN-Relay, Yamux-Multiplexing. Funktioniert ohne Browser mit einem einzigen Startbefehl.
Reverse Engineering der stream.wb.ru API
Die Traffic-Erfassung via Puppeteer offenbarte eine Abfolge von vier HTTP-Anfragen und einer WebSocket-Verbindung. Die Hauptseite blockiert Anfragen ohne Browser (Code 498), aber API-Endpunkte sind zugänglich.
Abfolge:
- POST /auth/api/v1/auth/user/guest-register — Gast-JWT-Token mit displayName.
- POST /api-room/api/v2/room — Raum erstellen mit
roomType: ROOM_TYPE_ALL_ON_SCREEN,roomPrivacy: ROOM_PRIVACY_FREE. - POST /api-room/api/v1/room/{id}/join — Beitreten (GET liefert 501).
- GET /api-room-manager/api/v1/room/{id}/token — LiveKit-Token (gzip in Accept-Encoding berücksichtigen).
WebSocket: wss://wbstream01-el.wb.ru:7880/rtc?access_token=...&sdk=js&version=2.15.3&protocol=16. ICE-Server: turn:wb-stream-turn-1.wb.ru:3478.
Implementiert mit net/http ohne Cookies/CSRF.
rr, _ := wb(cl, "POST", "/auth/api/v1/auth/user/guest-register",
[]byte(`{"displayName":"lh_42"}`), "")
Protobuf-Parser für LiveKit SignalResponse
LiveKit überträgt ICE-Server in SignalResponse > JoinResponse > ICEServer (Felder 1>5/9). Vollständiges google.golang.org/protobuf ist übertrieben — ein minimaler 40-Zeilen-Parser wurde geschrieben.
Varint-Decodierung:
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
}
Extraktion längenbegrenzter Felder:
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
}
Der Parser sucht ICE-Server in Feld 5 (WB-Fork) und 9 (Standard), extrahiert URLs, Benutzername und Passwort.
Tunnel-Architektur: KCP + TURN + yamux
TCP von SOCKS5 → Yamux-Stream → KCP (AES-256) → TURN-Relay → VPS → Internet.
Schlüsselkomponenten:
- TURN-Allokation via
pion/turn:tc.Allocate()liefertnet.PacketConn. - KCP über Relay:
kcp.NewConn(peerVPS, blk, 10, 3, relay). - Yamux für Stream-Multiplexing.
- SOCKS5-Server auf 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.
Automatisierung und Fehlertoleranz
- Smart Key: base64(
IP|SHA256(Passwort)). - Wiederherstellung: Yamux-Ping/15s, Backoff 2-60s, TURN-Credential-Cache 5min.
- Selbstbereinigung:
pgrep+ vorherige Instanzen beenden, systemd überschreiben. - Graceful Shutdown: Ctrl+C → 2s Bereinigung.
Start und Einschränkungen
go build -o lionheart .
# Server
./lionheart # Key kopieren
# Client
./lionheart # Key einfügen → 127.0.0.1:1080
Einschränkungen: Abhängigkeit von WB Stream API, hartkodiertes wbstream01-el.wb.ru. Pläne: Gomobile für Android/iOS (VpnService/NEPacketTunnelProvider).
Wichtige Punkte
- Tarnung als WebRTC-Datenverkehr für DPI/Firewalls bei Gigabit-Geschwindigkeiten.
- Minimaler Protobuf-Parser ohne Abhängigkeiten.
- TURN-Relay als
net.PacketConnfür KCP. - Vollständige Automatisierung ohne Browser/API-Schlüssel.
- Pure Go, gomobile-ready.
— Editorial Team
Noch keine Kommentare.