diff --git a/phpseclib/Net/SSH2.php b/phpseclib/Net/SSH2.php index ce0885d2..ac44eaac 100644 --- a/phpseclib/Net/SSH2.php +++ b/phpseclib/Net/SSH2.php @@ -1157,6 +1157,19 @@ class SSH2 */ private $kex_buffer = []; + /** + * Strict KEX Flag + * + * If kex-strict-s-v00@openssh.com is present in the first KEX packet it need not + * be present in subsequent packet + * + * @see self::_key_exchange() + * @see self::exec() + * @var array + * @access private + */ + private $strict_kex_flag = false; + /** * Default Constructor. * @@ -1689,8 +1702,13 @@ class SSH2 $first_kex_packet_follows ) = Strings::unpackSSH2('L10C', $response); if (in_array('kex-strict-s-v00@openssh.com', $this->kex_algorithms)) { - if ($this->session_id === false && count($this->kex_buffer)) { - throw new \UnexpectedValueException('Possible Terrapin Attack detected'); + if ($this->session_id === false) { + // [kex-strict-s-v00@openssh.com is] only valid in the initial SSH2_MSG_KEXINIT and MUST be ignored + // if [it is] present in subsequent SSH2_MSG_KEXINIT packets + $this->strict_kex_flag = true; + if (count($this->kex_buffer)) { + throw new \UnexpectedValueException('Possible Terrapin Attack detected'); + } } } @@ -1926,11 +1944,11 @@ class SSH2 $packet = pack('C', NET_SSH2_MSG_NEWKEYS); $this->send_binary_packet($packet); - $response = $this->get_binary_packet_or_close(NET_SSH2_MSG_NEWKEYS); + $this->get_binary_packet_or_close(NET_SSH2_MSG_NEWKEYS); $this->keyExchangeInProgress = false; - if (in_array('kex-strict-s-v00@openssh.com', $this->kex_algorithms)) { + if ($this->strict_kex_flag) { $this->get_seq_no = $this->send_seq_no = 0; }