Scenario A:

A user points his web browser to https://users.server.com. The website completes the SSL handshake and continues with the HTTP protocol inside SSL.

Scenario B:

(server-side) Now, let's say users.server.com is modified to run this socat:

socat OPENSSL-LISTEN:443,cert=path_to_cert TCP4:

(client-side) Then, the user has the following socat running:

socat TCP4-listen:6666 OPENSSL:the.server.host.com:443

Then, the user points his PuTTY client to localhost:6666 effectively establishing an SSL'd SSH connection to the.server.host.com:22.

Is there any way to distinguish the traffic from the above scenarios? My concern is that a user inside my network could effectively circumvent our firewall by piping any TCP traffic out through SSL on port 443. Would this traffic look any different than HTTPS traffic? Are there differences in the SSL handshake types? We have mechanisms in place to drop any non-HTTP on port 80 and non-SSL traffic on port 443 through our HTTP proxy. (all other outbound is blocked). I'm hoping I can only allow HTTPS (SSL'd HTTP) on port 443.

The attack is detailed here (pdf).

I'm aware that if I can install a root CA certificate on the user's machine, I could mitm the SSL. But that's not feasible. I am more interested in detecting this at the network layer. Preventing may be another measure.

  • ajaxterm anyone? Jan 16, 2014 at 6:20
  • I am aware of Web-based SSH clients. These clients are not as much of a concern because they lack the tunneling features of native SSH. The scenario above is different because it could allow a full SOCKS proxy to the outside (and even back inside).
    – aus
    Jan 16, 2014 at 14:25

2 Answers 2


As @aus indicates, you can try to observe the exact characteristics of the ClientHello and other SSL features (e.g. how messages are split over records) to get some indication about whether the client is a genuine Web browser, or not. However, this is not robust:

  • Different browsers act differently in that matter. You may be engaging into a never-ending uphill quest, with continuous evaluation of all major browser versions.
  • An OS/browser update may change its usage patterns (e.g. some cipher suite becomes enabled by default), so your detection mechanism may be plagued with surges of false positives at some unpredictable moments (when Microsoft / Mozilla / Google decides to push some technical update).
  • If users are aware of such fingerprinting then they may begin to use clients who mimic the features that you are trying to detect. "Perfect" emulation of the SSL characteristics of a "normal Internet Explorer" is possible. Provide an incentive (a detection mechanism which triggers retaliation), and it will happen.

You might want to make some traffic analysis based on the timing and size of requests; when a browser connects to a server, it will first send a request with a header whose size depends on a lot of things, but will not be too small. In the specific case of SSH-within-SSL, there is a nifty underhanded way by which distinction is easy: add a delay.

Specifically, when a Web server receives a connection, it waits: the client is supposed to send a request. From the outside, you observe a SSL handshake, culminating in the two Finished messages (they would show up as "encrypted handshake" since you are monitoring from the outside), then the client will send an "application data" record (in SSL, record contents are encrypted, but the type of the record is not: it is either handshake, alert, change_cipher_spec, or application data). As long as the "application data" from the client is not sent, the server will wait.

With SSH, however, things are different. As soon as the connection is established, the client and the server send each other their "banner" (which indicates protocol version and so on), in no particular order. Therefore, when your monitoring tool sees a new SSL handshake, it may temporarily delay the first application data record from the client (by, say, 0.5 seconds), to see whether the server would spontaneously send an "application data" record of its own without waiting for the record from the client. If the server does it, then it is not speaking HTTP within the SSL tunnel.

Of course, if you begin implementing such a detection mechanism, users will adapt, by modifying their SSH clients and servers to make the servers wait for the client banner before talking. This is likely to degenerate into the same kind of sterile warfare as between virus and antivirus. This is, in the long run, exhausting.

Apart from SSH, your biggest problem will be Web proxies. Namely, the user:

  • Controls an external Web proxy.
  • Runs on that external machine a SSL server which simply forwards data bytes to the Web proxy.
  • Runs on his local machine a simple process which listens on local port 3128 and forwards all data to the SSL server.
  • Configures his browser to use "localhost:3128" as proxy for Web requests.

With this setup, all the user's Web browsing of the server will go through the SSL connection, out of reach of your monitoring systems; and, crucially, all the requests will be HTTP requests from a normal Web browser, thus indistinguishable from HTTP requests from a normal Web browser. This ultimately defeats traffic analysis.

The conclusion is that what you are trying to do is to fight a war that you cannot win. I suggest you begin looking for alternate models. One way to look at it is the following: if you allow BYOD on your workplace, then you must trust employees for not abusing it, and for enforcing good security practices on themselves.


After some additional research, I believe I have found the answer to my question. The technique used to identify SSL clients is called SSL Client Fingerprinting. By looking at the various components of the ClientHello during the SSL handshake, we can take an educated guess of whether the SSL client is a browser or something else.

This blog post details the idea pretty well:

In my previous article I've described the structure of SSL/TLS ClientHello packet.

Importantly, it contains a list of supported ciphers and extensions.

Unsurprisingly, those lists differ between clients and often it is possible to identify an SSL client by looking at them. In other words

  • it is possible to distinguish Firefox, Chrome, Opera and IE apart by just looking at the initial HTTPS packet, which is unencrypted.

Therefor, under normal circumstances, it would be possible to distinguish between HTTPS and Application SSL.

The author goes on to talk about how to use p0f with his patch to fingerprint SSL against a a database of predefined signatures.

The post and research from Ivan Ristić are both pretty fascinating.

There is one exception, however. With enough granularity in the settings of an SSL client, one could easily emulate a similar ClientHello appearing to be from a certain browser. Given enough attention to detail, I am not sure there would be any other way to distinguish between browser SSL and another application's SSL with a carefully crafted handshake.

Since the rest of the TCP stream is encrypted, the only other hints would be the "chatty-ness" between server and client, and the amount of data being transferred.

  • 1
    you could try to do a traffic analyses. HTTP is a request/response protocol whith usually short requests (but POST/PUT might be long) and longer responses. And, there are usually only a few of them. So it should be different than an interactive session like SSH or telnet. Of course, these are all just more heuristics and can be circumvented with enough effort. Jan 16, 2014 at 5:11

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .