CVE-2020-13777 GnuTLS audit: be scared
So CVE-2020-13777 came out while I wasn't looking last week. The GnuTLS advisory (GNUTLS-SA-2020-06-03) is pretty opaque so I'll refer instead to this tweet from @FiloSottile (Go team security lead):
PSA: don't rely on GnuTLS, please.
CVE-2020-13777 Whoops, for the past 10 releases most TLS 1.0–1.2 connection could be passively decrypted and most TLS 1.3 connections intercepted. Trivially.
You are reading this correctly: supposedly encrypted TLS connections made with affected GnuTLS releases are vulnerable to passive cleartext recovery attack (and active for 1.3, but who uses that anyways). That is extremely bad. It's pretty close to just switching everyone to HTTP instead of HTTPS, more or less. I would have a lot more to say about the security of GnuTLS in particular -- and security in general -- but I am mostly concerned about patching holes in the roof right now, so this article is not about that.
This article is about figuring out what, exactly, was exposed in our infrastructure because of this.
Affected packages
Assuming you're running Debian, this will show a list of packages that
Depends
on GnuTLS:
apt-cache --installed rdepends libgnutls30 | grep '^ ' | sort -u
This assumes you run this only on hosts running Buster or above. Otherwise you'll need to figure out a way to pick machines running GnuTLS 3.6.4 or later.
Note that this list only first level dependencies! It is perfectly
possible that another package uses GnuTLS without being listed
here. For example, in the above list I have libcurl3-gnutls
, so the
be really thorough, I would actually need to recurse down the
dependency tree.
On my desktop, this shows an "interesting" list of targets:
apt
cadaver
- AKA WebDAVcurl
&wget
fwupd
- another attack on top of this onegit
(through thelibcurl3-gnutls
dependency)mutt
- all your emailsweechat
- your precious private chats
Arguably, fetchers like apt
, curl
, fwupd
, and wget
rely on HTTPS for
"authentication" more than secrecy, although apt
has its own
OpenPGP-based authentication so that wouldn't matter anyways. Still,
this is truly distressing. And I haven't mentioned here things like
gobby
, network-manager
, systemd
, and others - the scope of this is
broad. Hell, even good old lynx
links against GnuTLS.
In our infrastructure, the magic command looks something like this:
cumin -o txt -p 0 'F:lsbdistcodename=buster' "apt-cache --installed rdepends libgnutls30 | grep '^ ' | sort -u" | tee gnutls-rdepds-per-host | awk '{print $NF}' | sort | uniq -c | sort -n
There, the result is even more worrisome, as those important packages seem to rely on GnuTLS for their transport security:
mariadb
- all MySQL traffic and passwordsmandos
- full disk encryptionslapd
- LDAP passwords
mandos
is especially distressing although it's probably not
vulnerable because it seems it doesn't store the cleartext -- it's
encrypted with the client's OpenPGP public key -- so the TLS tunnel
never sees the cleartext either.
Other reports have also mentioned the following servers link against GnuTLS and could be vulnerable:
exim
rsyslog
samba
- various
VNC
implementations
Not affected
Those programs are not affected by this vulnerability:
apache2
gnupg
python
nginx
openssh
This list is not exhaustive, naturally, but serves as an example of common software you don't need to worry about.
The vulnerability only exists in GnuTLS, as far as we know, so programs linking against other libraries are not vulnerable.
Because the vulnerability affects session tickets -- and those are set
on the server side of the TLS connection -- only users of GnuTLS as a
server are vulnerable. This means, for example, that while weechat
uses GnuTLS, it will only suffer from the problem when acting as a
server (which it does, in relay mode) or, of course, if the remote IRC
server also uses GnuTLS. Same with apt, curl, wget, or git: it is
unlikely to be a problem because it is only used as a client; the
remote server is usually a webserver -- not git itself -- when using
TLS.
Caveats
Keep in mind that it's not because a package links against GnuTLS that
it uses it. For example, I have been told that, on Arch Linux, if
both GnuTLS and OpenSSL are available, the mutt
package will use the
latter, so it's not affected. I haven't confirmed that myself nor have I
checked on Debian.
Also, because it relies on session tickets, there's a time window after which the ticket gets cycled and properly initialized. But that is apparently 6 hours by default so it is going to protect only really long-lasting TLS sessions, which are uncommon, I would argue.
Update: according to the Tweet's author:
The author of this blog post is misinterpreting the problem. It's not the session ticket which is rotated after 6 hours, but the session ticket encryption key (STEK). This has nothing to do with the length of the TLS session, but rather the lifetime of the process using GnuTLS. For the first 6 hours, connections made to the GnuTLS server are vulnerable. After the process has been running for 6 hours, new connections are safe (assuming there's no other GnuTLS vulnerability). This reduces the impact of the vulnerability considerably (although it's still really bad).
I stand corrected.
My audit is limited. For example, it might have been better to walk the shared library dependencies directly, instead of relying on Debian package dependencies.
Other technical details
It seems the vulnerability might have been introduced in this merge
request, itself following a (entirely reasonable) feature request
to make it easier to rotate session tickets. The merge request was
open for a few months and was thoroughly reviewed by a peer before
being merged. Interestingly, the vulnerable function
(_gnutls_initialize_session_ticket_key_rotation
), explicitly says:
* This function will not enable session ticket keys on the server side. That is done
* with the gnutls_session_ticket_enable_server() function. This function just initializes
* the internal state to support periodical rotation of the session ticket encryption key.
In other words, it thinks it is not responsible for session ticket initialization, yet it is. Indeed, the merge request fixing the problem unconditionally does this:
memcpy(session->key.initial_stek, key->data, key->size);
I haven't reviewed the code and the vulnerability in detail, so take the above with a grain of salt.
The full patch is available here. See also the upstream issue 1011, the upstream advisory, the Debian security tracker, and the Redhat Bugzilla.
Moving forward
The impact of this vulnerability depends on the affected packages and how they are used. It can range from "meh, someone knows I downloaded that Debian package yesterday" to "holy crap my full disk encryption passwords are compromised, I need to re-encrypt all my drives", including "I need to change all LDAP and MySQL passwords".
It promises to be a fun week for some people at least.
Looking ahead, however, one has to wonder whether we should follow @FiloSottile's advice and stop using GnuTLS altogether. There are at least a few programs that link against GnuTLS because of the OpenSSL licensing oddities but that has been first announced in 2015, then definitely and clearly resolved in 2017 -- or maybe that was in 2018? Anyways it's fixed, pinky-promise-I-swear, except if you're one of those weirdos still using GPL-2, of course. Even though OpenSSL isn't the simplest and secure TLS implementation out there, it could preferable to GnuTLS and maybe we should consider changing Debian packages to use it in the future.
But then again, the last time something like this happened, it was Heartbleed and GnuTLS wasn't affected, so who knows... It is likely that people don't have OpenSSL in mind when they suggest moving away from GnuTLS and instead think of other TLS libraries like mbedtls (previously known as PolarSSL), NSS, BoringSSL, LibreSSL and so on. Not that those are totally sinless either...
Correction, OpenSSL is actually what those people have in mind:
No, OpenSSL is exactly what we have in mind, including Filippo: https://twitter.com/FiloSottile/status/1270130358634283008
OpenSSL isn't perfect but it has improved considerably since Heartbleed and has the resources (funding and competent people) that a crypto project needs.
"This is fine", as they say...
Mandos co-author here. You are correct about Mandos; only OpenPGP encrypted data is sent over the TLS connection. Also, Mandos does use TLS1.3, so only active connections could ever have been intercepted and decrypted.
If one would suspect that this actually has been done, what one should do on each Mandos client is change the OpenPGP key, generate a new encrypted blob for the Mandos server configuration, using the same password for the encrypted disk; the password can not have been compromised unless the OpenPGP secret key from the client also was compromised. (Of course, changing the encrypted disk password is also an option, but that would also mean generating a new encrypted blob for the Mandos server configuration, which would mean more work than the other option.)
Regarding your comment about Heartbleed; I agree; in using GnuTLS, we have been able to avoid being affected by most of the TLS vulnerabilities in recent years. Also, we do not know of any other TLS library which provides either OpenPGP keys as session keys (RFC 6091), or raw public keys (RFC 7250). We prefer to avoid X.509 certificates, so we need either one; GnuTLS recently switched from the former to the latter.
Unfortunately, the OpenSSL license is only fixed on the branches leading up to OpenSSL 3.0, which hasn't been released yet; it's still in alpha.
And what about:
https://www.libressl.org/
You seem to be assuming that this vulnerability affects gnutls clients, but my reading of the advisory is that it is an issue with gnutls servers.
Can anyone with deeper knowledge of the vulnerability clarify?