Re: Dropbear's usage of 'first_kex_packet_follows' may fail on broken SSH implementations

2022-01-19 Thread Matt Johnston
On Wed, Jan 19, 2022 at 04:23:29PM +0100, Thomas De Schampheleire wrote:
> I recently encountered connection issues when using dropbear as client 
> (2020.81)
> to certain SSH implementations. In both cases, the issue was related to the 
> host
> key verification. It took me a while to find the cause, and I send this mail
> mainly to help other Dropbear users that may have such problem.
> 
> The symptoms I encountered were for one case (a proprietary SSH server
> implementation):

Hi Thomas,

Thanks for the write up. I _think_ in the case of Dropbear
as a client it might be possible to defer sending the key
exchange until the server's version identification is
received, without incurring any extra round trip latency. I
will see if I can implement that. That would use an
allowlist of implementations known to correctly handle
first_kex_packet_follows.

If you could let me know the proprietary version with
problems it would be handy (off list is fine).

Thanks,
Matt


Dropbear's usage of 'first_kex_packet_follows' may fail on broken SSH implementations

2022-01-19 Thread Thomas De Schampheleire
Hello,

I recently encountered connection issues when using dropbear as client (2020.81)
to certain SSH implementations. In both cases, the issue was related to the host
key verification. It took me a while to find the cause, and I send this mail
mainly to help other Dropbear users that may have such problem.

The symptoms I encountered were for one case (a proprietary SSH server
implementation):

Host '127.0.0.1' is not in the trusted hosts file.
(ssh-rsa fingerprint sha1!!
ea:70:75:a2:51:e7:26:76:2c:da:06:e4:3e:0e:20:b0:23:6d:fc:9f)
Do you want to continue connecting? (y/n) y
TRACE  (14310) 6.104541: enter buf_get_rsa_pub_key
TRACE  (14310) 6.104589: leave buf_get_rsa_pub_key: success
TRACE  (14310) 6.114254: enter buf_put_rsa_pub_key
TRACE  (14310) 6.114276: leave buf_put_rsa_pub_key
TRACE  (14310) 6.114385: enter buf_verify
TRACE  (14310) 6.114396: enter buf_rsa_verify
TRACE  (14310) 6.114485: 17
TRACE  (14310) 6.114496: 17
TRACE  (14310) 6.114511: -1710064656
TRACE  (14310) 6.114515: -1710063472
TRACE  (14310) 6.114520: leave buf_rsa_verify: ret -1
TRACE  (14310) 6.114524: Exited, cleaning up: Bad hostkey signature
TRACE  (14310) 6.114530: enter session_cleanup
TRACE  (14310) 6.114540: enter chancleanup
TRACE  (14310) 6.114547: leave chancleanup
TRACE  (14310) 6.114560: enter cli_tty_cleanup
TRACE  (14310) 6.114566: leave cli_tty_cleanup: not in raw mode
TRACE  (14310) 6.114581: leave session_cleanup

./dbclient: Connection to admin@127.0.0.1:50513 exited: Bad
hostkey signature


and for another case (Erlang/OTP SSH), the connection was just closed by the
server end, with following messages seen on the server side:

=INFO REPORT 18-Jan-2022::17:36:27.706240 ===
Erlang SSH server 4.9.1.3 (OpenSSL 1.0.2k-fips 26 Jan 2017).
Client: "SSH-2.0-dropbear_2020.81"
Disconnects with code = 3 [RFC4253 11.1]: Key exchange failed
State = {key_exchange,server,init}
Module = ssh_transport, Line = 688.
Details:
ECDH compute key failed in server: error:badarg
Kex: 'ecdh-sha2-nistp521', Curve: secp521r1
PeerPublic:
<<30,53,212,179,177,229,82,113,59,128,70,84,240,27,175,218,68,218,
36,131,251,65,103,237,45,253,63,169,103,73,253,111>>


With OpenSSH as client, there were no such issues.

After digging a bit deeper, I learned that both issues are related to a feature
called 'first_key_packet_follows', part of RFC4253 ("The Secure Shell (SSH)
Transport Layer Protocol") [1]

The 'first_kex_packet_follows' feature is an optimization to reduce the time
needed to set up the connection. In the initial Key Exchange (KEX), one peer may
set the first_kex_packet_follows flag, and optimistically send the next packet
based on a guess of the preferred algorithm of the other peer. If the guess was
correct, that packet must be used as first packet, and otherwise it must be
ignored.
But for this to work, it is important that the other side correctly interprets
the flag and ignores or uses the next packet accordingly, also based on the
correctness of the preferred algorithm guess. If an SSH implementation does not
(correctly) handle this feature, the connection may fail to be set up.

Dropbear by default uses this 'first_kex_packet_follows' feature.

OpenSSH will not set the feature itself, but correctly interpret it if a peer
does. Note that this feature was broken between OpenSSH versions 6.8 and 7.1p2.
See [2].

The two SSH implementations I mentioned both accept the flag in the
communication, but completely ignore its value. This then causes a connection
failure.

Both implementations are independent from each other. The fact that they both
fail to handle first_kex_packet_follows correctly, is probably a consequence of
the fact that OpenSSH, the most common SSH implementation in UNIX world and
likely a testing reference, does not actively use it.

While the fault is really with these SSH implementations and not with Dropbear,
the problem can be bypassed by telling Dropbear to _not_ use the
'first_kex_packet_follows' feature, by setting the option
'DROPBEAR_KEX_FIRST_FOLLOWS' to 0 (in localoptions.h).

Thus, in case you experience similar issues as described, this could be
something to try.

Best regards,
Thomas



[1] https://datatracker.ietf.org/doc/html/rfc4253#section-7
[2] https://bugzilla.mindrot.org/show_bug.cgi?id=2515#c6