Sniffing SSL: RFC 4366 and TLS Extensions

Published: 2009-10-28
Last Updated: 2009-10-28 12:04:27 UTC
by Johannes Ullrich (Version: 1)
4 comment(s)

About once a week, we have a reader complain about a bad certificate for "". Many years ago, this site was  known as "", not "" or "". As a result, you may still come across a reference to "". The domain still points to the same IP address as, but our SSL certificate is issued for "", not "", which causes the bad certificate warnings.

This is a common issue: It is trivial to use "Name Based Virtual Hosting" for regular web sites. The browser will send a "Host" header indicating which host it would like to connect to. This host header is mandatory ever since HTTP/1.1. But for https, this doesn't work. The host header is now encrypted, and in order to decrypt it, the server needs the correct key... if the key is different for each host, then you got a catch 22. As a result, each https host needs a dedicated IP (or port, but that's ugly).

In order to solve this problem, the Internet gods brought us RFC 4366 and "TLS Extensions" . Or as the RFC will tell us right in the beginning:

Allow TLS clients to provide to the TLS server the name of the server they are contacting. This functionality is desirable in order to facilitate secure connections to servers that host multiple 'virtual' servers at a single underlying network address. [1]

More and more browsers and web servers start to support RFC 4366. With this, we solve another problem (at least partially): Monitoring https traffic. It was always possible to log the IP address. But with RFC 4366, the host name is now transmitted in the clear, as the following fragment of a packet capture shows:

19:28:02.363758 IP browser.60299 > Flags [P.], ack 1, win 32850, length 167
        0x0000:  4500 00cf cb8c 4000 4006 0000 0000 0000  E.....@.@.......
        0x0010:  41ad da4b eb8b 01bb 8537 8bc0 6340 3c7a  A..K.....7..c@<z
        0x0020:  5018 8052 26dd 0000 1603 0100 a201 0000  P..R&...........
        0x0030:  9e03 014a e782 0201 a72f 0250 7a55 ec2d  ...J...../.PzU.-
        0x0040:  9878 d405 65b2 402d e00e 0054 70a1 9c7e  .x..e.@-...Tp..~
        0x0050:  72e0 8e00 0044 c00a c014 0088 0087 0039  r....D.........9
        0x0060:  0038 c00f c005 0084 0035 c007 c009 c011  .8.......5......
        0x0070:  c013 0045 0044 0033 0032 c00c c00e c002  ...E.D.3.2......
        0x0080:  c004 0041 0004 0005 002f c008 c012 0016  ...A...../......
        0x0090:  0013 c00d c003 feff 000a 0100 0031 0000  .............1..
        0x00a0:  0017 0015 0000 1273 6563 7572 652e 6473
        0x00b0:  6869 656c 642e 6f72 6700 0a00 0800 0600
        0x00c0:  1700 1800 1900 0b00 0201 0000 2300 00    ............#..

In this case, I connected to "". Wireshark will recognize the extension (so does tshark). The following display filter will select all packets with the "sever_name" ssl extension: ssl.handshake.extension.type == 0x0000 .

Now you may ask: Is this a problem? Well, if you want to keep the host name secret, then it is. But without it, there is a one-to-one relationship between hostname and IP address, so not much is lost, and the host name is revealed in clear text in the server's certificate. Is there the possibility of a known plain text attack? Maybe... (e.g. we know there has to be a "Host: ..." header with known content). But I am not enough of a crypto geek to know. From my perspective, there is plenty of known plain text in https traffic.

But there is also an opportunity here. Maybe a tool to log the hostname. Or a tool that compares the certificate coming back to the host name requests and alerts of a mismatch.

Of course, once I get around to it, may get its own, valid, SSL certificate.


Johannes B. Ullrich, Ph.D.
SANS Technology Institute

4 comment(s)
Diary Archives