UP-01-008 Churn reveals uProxy Peers via UDP Keepalive
Once the UDP connection and WebRTC handshake is successfully established, uProxy sends a great number of UDP packets which follow a predictable pattern:
- Packet protocol: UDP (i.e. not DTLS)
- Packet length: 1459 bytes (1423 bytes without the IP headers)
- Packet data contains the string: "abc.netascii" towards the end of the first 32 bytes
- Packet data is obfuscated
- If the UDP stream is followed, all this is preceded by a clear WebRTC handshake, which contains the string "WebRTC" in clear-text as reported under UP-01-005.
- These packets are sent continously: 326 packets were recorded in 12 seconds, an average of 27.16 packets / second.
In wireshark these packets can be easily identified using the following filter:
udp.length == 1423
This issue was verified using the simple socks chrome sample app, using Ubuntu. This pattern makes it easy for a censor to identify and block peers. During testing, it was found that these packets are not sent by Skype or various WebRTC demos, like for example:
- http://webrtc-chat-demo.pusher.io/
- https://apprtc.appspot.com/
The problem seems to be located in the churn source code, in particular, the following section explains the “abc.netascii” string sent in clear-text in these packets:
File: typescript-src/churn/churn.ts
Code:
JSON.stringify({
'plaintext_dfa': regex2dfa('^.*$'),
'plaintext_max_len': 1400,
// TFTP read request for file with name "abc", by netascii.
// By default, Wireshark only looks for TFTP
//traffic if the packet's destination
// port is 69; you can change this in Preferences.
'ciphertext_dfa': regex2dfa('^\x00\x01\x61\x62\x63\x00netascii.*$'),
'ciphertext_max_len': 1450
}))
While WebRTC keep alives are considered normal WebRTC behavior, the obfuscation added by churn turns WebRTC keep alives into rare uProxy-specific packets. To solve this problem, we propose to make this traffic less predictable, for example, churn could:
- Vary packet length
- Vary packet frequency
- Remove the clear-text “abc.netascii” signature
Additionally, uProxy could consider using Dust, in future non-WebRTC dependent, implementations and/or attempt to incorporate it into churn as deemed feasible.
(trevor)
Two possibilities:
- use a different output regex (the abc.netascii thing was just me playing around with TFTP regexes, not meant to be for final release)
- do not obfuscate STUN pings
Either requires quite a bit more thought.
This is largely pending on additions to web-browsers of the ability to route webrtc by a TURN proxy. That will allow doing all the suggested tricks.
I think what would help a lot for now would be to change our output regular expression to .*.
Due to how libFTE works, I believe this is equivalent to using a rabbit cipher.
Seems like an improvement over my hacking about with TFTP.