Tunnel SOCKS5 via WebRTC TURN Wildberries : Implémentation en Go
Un outil a été développé pour dissimuler le trafic SOCKS5 dans des sessions WebRTC TURN sur la plateforme WB Stream. Le trafic est déguisé en visioconférence grâce à LiveKit SFU. Cycle complet : API HTTP inversée, analyse protobuf, KCP sur relais TURN, multiplexage yamux. Fonctionne sans navigateur, avec une simple commande de lancement.
Rétro-ingénierie de l'API stream.wb.ru
La collecte de trafic via puppeteer a révélé une séquence de quatre requêtes HTTP et une connexion WebSocket. La page principale bloque les requêtes sans navigateur (code 498), mais les points d'accès API sont accessibles.
Séquence :
- POST /auth/api/v1/auth/user/guest-register — Jeton JWT invité avec displayName.
- POST /api-room/api/v2/room — Créer une salle avec
roomType: ROOM_TYPE_ALL_ON_SCREEN,roomPrivacy: ROOM_PRIVACY_FREE. - POST /api-room/api/v1/room/{id}/join — Rejoindre (GET renvoie 501).
- GET /api-room-manager/api/v1/room/{id}/token — Jeton LiveKit (tenir compte du gzip dans Accept-Encoding).
WebSocket : wss://wbstream01-el.wb.ru:7880/rtc?access_token=...&sdk=js&version=2.15.3&protocol=16. Serveurs ICE : turn:wb-stream-turn-1.wb.ru:3478.
Implémenté avec net/http sans cookies/CSRF.
rr, _ := wb(cl, "POST", "/auth/api/v1/auth/user/guest-register",
[]byte(`{"displayName":"lh_42"}`), "")
Analyseur Protobuf pour LiveKit SignalResponse
LiveKit transmet les serveurs ICE dans SignalResponse > JoinResponse > ICEServer (champs 1>5/9). Le package complet google.golang.org/protobuf est excessif — un analyseur minimal de 40 lignes a été écrit.
Décodage varint :
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
}
Extraction des champs à longueur délimitée :
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
}
L'analyseur recherche les serveurs ICE dans le champ 5 (fork WB) et 9 (standard), extrayant les URLs, username et credential.
Architecture du tunnel : KCP + TURN + yamux
TCP depuis SOCKS5 → flux yamux → KCP (AES-256) → relais TURN → VPS → internet.
Composants clés :
- Allocation TURN via
pion/turn:tc.Allocate()renvoienet.PacketConn. - KCP sur relais :
kcp.NewConn(peerVPS, blk, 10, 3, relay). - Yamux pour le multiplexage de flux.
- Serveur SOCKS5 sur VPS.
uc, _ := net.ListenUDP("udp", nil)
tc, _ := turn.NewClient(&turn.ClientConfig{...})
relay, _ := tc.Allocate()
kc, _ := kcp.NewConn(peerVPS, blk, 10, 3, relay)
Serveur : écouteur KCP + serveur yamux + SOCKS5.
Automatisation et tolérance aux pannes
- Clé intelligente : base64(
IP|SHA256(password)). - Reconnexion : ping yamux/15s, backoff 2-60s, cache des identifiants TURN 5min.
- Nettoyage automatique :
pgrep+ tuer les instances précédentes, remplacement systemd. - Arrêt gracieux : Ctrl+C → nettoyage 2s.
Lancement et limitations
go build -o lionheart .
# Serveur
./lionheart # copier la clé
# Client
./lionheart # coller la clé → 127.0.0.1:1080
Limitations : dépendance à l'API WB Stream, wbstream01-el.wb.ru codé en dur. Projets : gomobile pour Android/iOS (VpnService/NEPacketTunnelProvider).
Points clés
- Masquage en trafic WebRTC pour DPI/pare-feux à des vitesses gigabit.
- Analyseur protobuf minimal sans dépendances.
- Relais TURN comme
net.PacketConnpour KCP. - Automatisation complète sans navigateur/clés API.
- Go pur, prêt pour gomobile.
— Editorial Team
Aucun commentaire pour le moment.