Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

telepath

A research prototype exploring what happens when you encode arbitrary network traffic inside a WebRTC video stream hosted on a nationally whitelisted conferencing platform.

Go 1.23 License: MIT Platform


Research question

Several countries maintain a national whitelist — a set of domestic services whose traffic is guaranteed to pass through internet filtering infrastructure untouched. The question this project investigates:

If a video conferencing platform is on a national whitelist and uses DTLS-SRTP over TURN relays, can its media stream carry arbitrary data in a way that is transparent to packet inspection?

telepath is a headless, pure-Go prototype that answers this question in practice. It encodes TCP/UDP payloads inside VP8 video frames sent through a real conference session, then exposes a SOCKS5 proxy on the receiving end.

The entire implementation runs without a browser — no Electron, no WebView, no JS injection. The signaling and media stacks are handled directly in Go via the pion/webrtc library.


How it works

Transport layer

A Yandex Telemost conference uses an SFU (Selective Forwarding Unit) architecture with dual PeerConnections: one for publishing media (pub) and one for subscribing (sub). Both go through TURN relays at turn.webrtc.yandex.net. The TURN traffic is DTLS-SRTP encrypted — the relay sees only opaque UDP datagrams.

┌──────────────────────────────────────────────────────────────────┐
│  Side A (creator)                  Side B (joiner)               │
│                                                                   │
│  TCP/UDP ← relay bridge            SOCKS5 :1080 → apps           │
│       │                                    │                     │
│  VP8 encode ──→ pub PC        sub PC ──→ VP8 decode              │
│                      │          │                                │
│               DTLS-SRTP / TURN relay                             │
│               turn.webrtc.yandex.net                             │
└──────────────────────────────────────────────────────────────────┘

VP8 data encoding

Standard VP8 frame headers have constrained first-byte values (keyframe: bit0=0; interframe: bit0=1, max tag byte 0xB1). The byte 0xFF never appears as a valid VP8 header, making it a safe out-of-band marker:

Data frame:      [ 0xFF | 4-byte length (big-endian) | payload ]
Keepalive frame: [ valid VP8 interframe, 17 bytes, 25 fps ]
                   (keyframe every 60th frame to reset decoder state)

The SFU forwards the sample as-is inside DTLS-SRTP. No modification at the network layer occurs.

Multiplexing

Multiple TCP/UDP connections share the single video stream via a framing protocol:

[ 4-byte total length | 4-byte connID | 1-byte msgType | payload ]

Message types: Connect, ConnectOK, ConnectErr, Data, Close, UDP, UDPReply.


Project structure

telepath/
├── cmd/
│   ├── sniffer/    ← MITM HTTPS/WS proxy — captures platform signaling
│   ├── creator/    ← conference creator + relay (unrestricted side)
│   └── joiner/     ← conference joiner + SOCKS5 :1080 (restricted side)
└── internal/
    ├── telemost/   ← HTTP conference API + WebSocket signaling client
    ├── pion/       ← dual PeerConnection, ICE relay-only, VP8+Opus tracks
    ├── tunnel/     ← VP8 frame encoding/decoding, keepalive scheduler
    └── relay/      ← TCP/UDP multiplexer + SOCKS5 server

Building

git clone https://github.com/Konstant1nov1ch/telepath
cd telepath
make all           # → bin/sniffer  bin/creator  bin/joiner

make linux         # cross-compile linux/amd64 for remote VPS

Requires Go 1.21+.


Usage

Step 1 — Capture the signaling protocol (first run)

The platform uses a WebSocket signaling protocol that needs to be observed once. The sniffer is a local MITM proxy that records the exchange:

./bin/sniffer --port 8080 --output telemost-dump.json

Trust the generated CA (macOS):

sudo security add-trusted-cert -d -r trustRoot \
  -k /Library/Keychains/System.keychain \
  ~/Library/Caches/suckrtunnel/ca.crt

Set your browser proxy to http://localhost:8080, open the conference page, create and join a conference. The full WebSocket frame dump is written to telemost-dump.json.

Step 2 — Creator (unrestricted machine or VPS)

./bin/creator
# prints a join link to stdout

For VPS deployment:

make linux
scp bin/creator-linux-amd64 user@vps:/tmp/telepath-creator
ssh user@vps "/tmp/telepath-creator"

Step 3 — Joiner (restricted machine)

./bin/joiner --link https://telemost.yandex.ru/j/XXXX
# SOCKS5 proxy starts at 127.0.0.1:1080

Configure any application to use socks5://127.0.0.1:1080.


Measured characteristics

From preliminary experiments:

Channel type Observed throughput
WebRTC DataChannel up to ~40 Mbps
VP8-encoded data limited by video bitrate budget

GoTurn probe (STUN/TURN reachability from Timeweb SPb VPS):

Endpoint Result
stun.rtc.yandex.net:3478 UDP responds, RTT ~20 ms
stun.rtc.yandex.net:3478 TCP responds, RTT ~39 ms
turn.webrtc.yandex.net:3478 timeout without SFU-issued credentials (expected)

TURN servers require credentials derived during signaling — they do not respond to unauthenticated allocation requests. This is consistent with standard TURN security practice and means the tunnel only works after a real conference session is established.


Limitations and open questions

  • Signaling accuracy: internal/telemost/signaling.go is based on the expected message shape. Running the sniffer and updating the message structs is required before the headless flow works end-to-end.
  • Bandwidth ceiling: VP8 video bitrate is negotiated at session setup; high-throughput data may trigger SFU rate limiting.
  • Session lifetime: It is unclear how long an idle (but keepalive-pinging) session remains open on the SFU side.
  • Detectability: While the payload is opaque to DPI, connection metadata (TURN server IP, session duration, absence of audio energy) could in principle be used for statistical classification.

Contributing

The most useful contribution right now is a real telemost-dump.json from a browser session. It resolves the only unknown: the exact signaling message format. Open a PR updating internal/telemost/signaling.go or attach the dump to an issue.


License

MIT — see LICENSE.

This is a research prototype. It is published for study and discussion of how video conferencing infrastructure interacts with network filtering. No warranty is provided.

About

Research prototype: encoding network traffic inside WebRTC video streams on whitelisted conferencing infrastructure

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages