XMPP man-in-the-middle via tor

Update: It was pointed out to us that the word ‘wide-spread’ below is misleading since the cumulative exit probability of those nodes was probably below .5%. What we wanted to say instead is that the number of domains affected was large, when a bad exit was involved.

We saw some wide-spread XMPP man-in-the-middle via malicious tor exit nodes during the last 24h. The attacks where only targeting starttls connections on port 5222. The mitm served forged self-signed certificates for various Jabber domains, one of them being our imsg.ch. The attack was orchestrated between multiple exit nodes acting in sync. All of them served the same set of forged certificates, allegedly created around midnight March 2nd to 3rd, using common names tailored to various XMPP servers.

We tried a small sample of XMPP servers. Out of which we recorded the following domains being intercepted:

  • freifunk.im
  • jabber.ccc.de
  • jabber.systemli.org
  • jappix.org
  • jodo.im
  • pad7.de
  • swissjabber.ch
  • tigase.me

For a handful other domains the connection attempts where dropped and google xmpp was the only one we found to be unaffected.

The exit nodes involved in this attack were reported to the tor project and seem to be dysfunctional by now. The ones we know of are:

  • FAFE24D8CF973BC38B54500DA666EEE44F02C642
  • 6269E9B3549012C44F518D2D123E41A4F320157E
  • 04DDEEAB315956AD956AF046338FB8E5B52B2DAF
  • DB213B8BD383A955CC383CAB76F8DD71A7198F47
  • 0276C54A43ABF27AB0247AF377952A306605FB8A
  • A1B3C065339D11AC361D85B0A3F9B59A23BD818A
  • CAD72B06527F8534640E8E47AEE38E2A3321B2D4
  • 5CBDC2AB702784154E7EFE7E6F87645EB107E8FA
  • BAB1FA3492162DB8058F464AD99203144F2AAF87
  • 187C2945109982516002FE6620E46A94B9B81A6E
  • 6269E9B3549012C44F518D2D123E41A4F320157E
  • FAFE24D8CF973BC38B54500DA666EEE44F02C642
  • FB134ED5DEE131B707270D9E99D72201CC96D668
  • E46021F7921EBB836B318863BDD432982BAA7BD0

Here is the certificate which was presented when you tried to access imsg.ch:

        Version: 1 (0x0)
        Serial Number: 12273528369637281981 (0xaa54550634e8d0bd)
    Signature Algorithm: sha1WithRSAEncryption
        Issuer: CN=imsg.ch
            Not Before: Mar  3 12:08:43 2016 GMT
            Not After : Jan 10 12:08:43 2026 GMT
        Subject: CN=imsg.ch
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
SHA1 Fingerprint=2C:F2:07:E8:19:ED:4E:CA:81:59:6E:3F:D8:59:52:B8:12:22:88:DB

What was curious is that the mitm SSL endpoint was sending a TLS session ticket. Does anybody have an idea if that could lead to an additional attack being carried out, or if it was merely an artifact of their SSL stack. E.g. one explanation we have is that the SSL terminator might have seen all packets originating from the same local tor daemon IP.

Here’s more log, for your convenience:

Certificate chain
 0 s:/CN=imsg.ch
Server certificate
No client certificate CA names sent
Peer signing digest: SHA512
Server Temp Key: ECDH, P-256, 256 bits
SSL handshake has read 1948 bytes and written 490 bytes
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES256-GCM-SHA384
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
    Protocol  : TLSv1.2
    Cipher    : ECDHE-RSA-AES256-GCM-SHA384
    Session-ID: [... 64 bytes ...]
    Master-Key: [... 96 bytes ...]
    Key-Arg   : None
    Krb5 Principal: None
    PSK identity: None
    PSK identity hint: None
    TLS session ticket lifetime hint: 300 (seconds)
    TLS session ticket: [... 0x100 bytes ...]

    Start Time: [...]
    Timeout   : 300 (sec)
    Verify return code: 18 (self signed certificate)

The state of Forward Secrecy in OpenSSL

It could be possible that your SSL services are not providing
forward secrecy and you haven’t noticed yet!

Many SSL ciphers provide forward secrecy by using ephedermal Diffie-Hellman (EDH) keys. This means that for every SSL session a temporary encryption key is negotiated and the normal key is only used for verifying authenticity. As the OpenSSL documentation states:

“By generating a temporary DH key inside the server application that is lost when the application is left, it becomes impossible for an attacker to decrypt past sessions, even if he gets hold of the normal (certified) key, as this key was only used for signing.”

Although ciphers using EDH will most probably be available in your setup, often they are disabled because the application fails to provide DH params to OpenSSL. Since it is costly to generate those parameters – which are needed to negotiate a DH key exchange – OpenSSL suggests to create them when an application is installed.

Many application will not do this, but rather let the user generate and include the parameters in the configuration manually. Since (i) most administrators are not aware of this problem, (ii) those applications do not yield any warnings if the parameters are missing and (iii) OpenSSL silently disables ciphers with unsatisfied requirements, forward secrecy is not available in many SSL connections.

Update: Also see Bernats blog for a nice roundup on the cryptographic background of perfect forward secrecy and the new, faster elliptic curve implementations.

Verify your Setup

Try to open an SSL session to your service (https, imap, smtp, jabber, irc, …) with

openssl s_client -port <port> -host <yourdomain.tld>

this will show you the details of the SSL session and you can verify that the used cipher includes EDH:

New, TLSv1/SSLv3, Cipher is DHE-RSA-AES256-SHA

or not:

New, TLSv1/SSLv3, Cipher is AES256-SHA

Fix your Setup

Applications which we found to work with EDH ciphers are Apache and Dovecot.

Update: Applications which we found to not support EDH out of the box are: squid, exim, courier

In most applications you can configure a dhparams variable somewhere. The dhparams can be generated with the following command:

openssl dhparam -out dhparams.pem 2048

We already fixed the problem in the following services:

Squid (reverse proxy)

In /etc/squid/include.d/https_port add dhparams=/path/dhparams.pem to every line


In /etc/exim.conf add the line tls_dhparam = /path/dhparams.pem

Fix the general Problem

This problem has two main reasons:

  1. Applications do not check whether the requirements of the user selected ciphers are satisfied. The requirements are listed in the OpenSSL doku. Or they could just always generate dhparams when they are installed, since EDH ciphers should be preferred anyway.
  2. The OpenSSL API does not provide any means to verify the state of the configuration. There is no function to check if cipher requirements are met and the SSL_CTX setup is consistent. As long as at least a single cipher (even the least secure) in the acceptable ciphers list can be initialized OpenSSL will not complain to the application.

If you find any application which exhibits this problem, please file a bug report and convince the maintainers to at least generate a warning to the user and state the consequences in the documentation.

If you are a developer of an application which uses OpenSSL please consider shipping install scripts that generate dhparams or generate them on the fly if they are missing. Please do not just let OpenSSL silently disable a key feature of SSL.