OpenSSH bug in decoding EXT_INFO extension values

"denis bider \(Bitvise\)" <[email protected]> Mon, 12 Jun 2017 21:53:07 -0600
Newsgroups gmane.ietf.secsh
Message-ID <FC64DEB4AC654FDFA7150BA5D0351CF8@Khan>
Bad news, everyone.

Again - there’s a bug in OpenSSH that’s now widely deployed, and will 
require workarounds to coexist with.

OpenSSH implements EXT_INFO. Excellent. Very nice. I'm grateful. Thank you.

But it does so incorrectly.

Suppose that a server sends the "delay-compression" extension to an OpenSSH 
client.

The client disconnects, without attempting to authenticate, as soon as it 
sees the extension's encoding.

It disconnects due to this choice of function in kex_input_ext_info:


if ((r = sshpkt_get_cstring(ssh, &val, NULL)) != 0) {
    free(name);
    return r;
}


This is an incorrect function to use for the extension value, because it 
contains the following logic:


/* Allow a \0 only at the end of the string */
if (len > 0 &&
    (z = memchr(p , '\0', len)) != NULL && z < p + len - 1) {
    SSHBUF_DBG(("SSH_ERR_INVALID_FORMAT"));
    return SSH_ERR_INVALID_FORMAT;
}


THIS IS NOT CORRECT LOGIC TO USE WHEN PROCESSING AN UNKNOWN EXTENSION VALUE, 
OF UNKNOWN FORMAT, WHERE THERE'S NO GUARANTEE IT WON'T CONTAIN ZEROS!

The value for the “delay-compression” extension, in particular, contains 
zeros.

The whole extension is defined as follows:


string         "delay-compression"
string:
  name-list    compression_algorithms_client_to_server
  name-list    compression_algorithms_server_to_client


Obviously, the lengths of both name-lists will have zeros, which will appear 
right at the start of the value.

So we implement an extension mechanism - and once again, it cannot be used 
with OpenSSH, because it deploys a fundamentally botched implementation.

Remember - the reason this "delay-compression" extension exists IN THE FIRST 
PLACE is that OpenSSH botched its delayed compression; designing it with a 
built-in, unescapable race condition.

God dammit, guys. God dammit.

What should I do with this?

Not send "delay-compression" to OpenSSH versions up to 7.5?

Or not send it to ANY OpenSSH version?

denis