Oh what a fun day I just had piecing together a few SSL changes for vsftpd!
Let's start with a brief background on SSL. SSL provides not just secrecy but also integrity - an attacker cannot change your data stream in flight. This includes obviously changing data in the stream, and less obviously, truncating the stream. The interesting attack to truncate the stream is to fake a TCP packet with FIN set. Truncated data is still an integrity violation and could have interesting consequences depending on what is being transferred. Anyway, as of SSLv3 and newer, the protocol protects against this. So, we're all good right?
Well, no, not really. Let's look at how SSL_read() indicates a problem. We all know how read() behaves, of course. It returns 0 on a healthy EOF. SSL_read() does the same on a healthy, cryptographically guaranteed EOF. But what does it do it if the attacker forces the TCP stream to close with a faked FIN? It also returns 0. That's right - no indication of any problem at the API level. If you want to check what is going on, you need to either check the SSL error code, in case there is one, or call SSL_get_shutdown(). (This double option in itself leads to confusion and random variance in code, which isn't great but that's another topic).
The OpenSSL API for SSL_read() is broken. You can phrase why in various ways: it violates the principle of least surprise. Or, perhaps best said, it provides an API that is easy to abuse. Good, secure APIs are hard to abuse. Contrast strcat() with string::operator+=() for the classic example.
A quick survey of popular FTP servers reveals that they universally fail to check for this condition when accepting an SSL secured upload. vsftpd v2.0.7 now optionally checks for this condition but it is off by default! Why? The majority of FTP clients have an interoperability bug in that they don't SSL_shutdown() their uploads. It's a direct knock-on from the SSL_read() broken API. If it returned error on forced connection shutdown, then FTP servers wouldn't have ever tolerated buggy clients, and clients would have been forced to correctly shutdown their connections.
Thanks to Tim Kosse of FileZilla fame for putting me on to this area by checking for secure connection shutdown in the latest version of FileZilla, exposing an interoperability bug in vsftpd's SSL downloads.
Post a Comment