Chasing Shadows: A security analysis of the ShadowTLS proxy (FOCI 2023)

Chasing Shadows: A security analysis of the ShadowTLS proxy
Gaukas Wang, Anonymous, Jackson Sippe, Hai Chi, Eric Wustrow
https://censorbib.nymity.ch/#Wang2023a
Presentation video

ShadowTLS is a circumvention proxy with a good trick for imitating a TLS connection: it forwards the first part of a connection, the TLS handshake, to an actual TLS server. After the handshake, the ShadowTLS relay starts forwarding traffic to a separate proxy server, for example Shadowsocks. (Similar to the idea of mask sites in Conjure.) This paper discusses flaws in V1 of the ShadowTLS protocol (中文) that made it vulnerable to passive and active distinguishing attacks.

Two attacks require only passive observation:

  • The ShadowTLS client has a distinctive and uncommon TLS fingerprint. (The server-side fingerprint is, of course, not a problem, because it comes from a genuine TLS server.)
  • The traffic after the TLS handshake does not look like TLS—it’s just raw Shadowsocks, or whatever the chosen proxy protocol is. In particular, traffic past the handshake does not have application_data record framing. (This property also leads to one of the active attacks.)

Three other attacks involve seeing how the server responds to bad data at different stages: before the handshake, after the handshake, and inside an application_data record:

  • Send a plaintext HTTP request at the beginning of the connection. Most TLS servers will terminate the TCP connection with a RST, or send back an HTTP error response; but the ShadowTLS relay closes the connection with a FIN/ACK.
  • Send random data after the TLS handshake. A real TLS server will raise an error or close the connection; but the ShadowTLS relay has already started forwarding traffic to the proxy at this point, so there are no further TLS error checks.
  • Send a well-formed application_data record after the handshake, but corrupt the record so that the integrity check fails. TLS is specific about what should happen in this situation: the server should send a bad_record_mac alert. The ShadowTLS relay does not, because no TLS server is involved by that point.

The authors do a ZMap scan and find about 15,000 TLS servers (0.05% of all TLS servers) that respond to the three active probes in the same way a ShadowTLS server would. While other evidence suggests that many of those 15,000 are not actually ShadowTLS relays, the small proportion means a censor could block this subset of TLS servers with little risk.

The paper then offers solutions against the distinguishers. For TLS handshake fingerprinting, they recommend adopting uTLS in the client. For the distinguishers that rely on non-TLS data, they recommend changing the post-handshake traffic to wrap data in application_data records, and then only forwarding records that are encrypted with a special key to the proxy; all other records go to the real TLS server. V2 of the protocol (中文), which began to be implemented in ShadowTLS v0.2.0, adopts a slightly different strategy: the client inserts a MAC using a shared secret at the beginning of one of its application_data records, and only after that does the ShadowTLS relay begin forwarding traffic to the proxy server.