Documente Academic
Documente Profesional
Documente Cultură
Abstract
This paper presents a variety of plaintext-recovering
attacks against SSH. We implemented a proof of concept
of our attacks against OpenSSH, where we can verifiably
recover 14 bits of plaintext from an arbitrary block of
ciphertext with probability 214 and 32 bits of plaintext
from an arbitrary block of ciphertext with probability 218 .
These attacks assume the default configuration of a 128-bit
block cipher operating in CBC mode. The paper explains
why a combination of flaws in the basic design of SSH
leads implementations such as OpenSSH to be open to our
attacks, why current provable security results for SSH do
not cover our attacks, and how the attacks can be prevented
in practice.
1. Introduction
Alongside SSL/TLS and IPsec, SSH is one of the most
widely used secure protocol suites. SSH was originally
designed as a replacement for insecure remote login procedures such as rlogin and telnet. It has since become a
general purpose tool for securing Internet traffic. Version 2
of SSH is standardized by the IETF in a series of RFCs
[24], [25], [26], [27]. Throughout this paper, we use SSH
as shorthand for SSHv2 as defined in these RFCs. Although
many different implementations of SSH are available, the
OpenSSH implementation [13] dominates, with OpenSSH
and its derivatives accounting for more than 80% of SSH
implementations on the Internet [20]. We use OpenSSH
throughout as shorthand for any version of OpenSSH up
to and including version 5.1, the release that was current at
the time we carried out this work.
SSH has benefited from a long development process,
and the consensus seems to be that it is now a secure
design. Moreover, the OpenSSH community claims that
OpenSSH has been developed using a rigorous security
process [15]. Indeed there are few vulnerabilities that have
been discovered in the OpenSSH code over the years [15]
and no fundamental design flaws in SSHv2 or OpenSSH
have been revealed to date. Only some rather theoretical
and easily-circumvented cryptographic attacks have been
discovered [9], [1] see Section 1.1 for more discussion of
4 bytes
4 bytes
1 byte
Sequence
Number
Packet
Length
Padding
Length
> 4 bytes
Payload
Padding
ENCRYPT
MAC
Ciphertext
Message
MAC tag
Ciphertext Packet
Corrupted MAC on input. being sent on the connection. If this check passes, then OpenSSH performs a
series of further checks. These need not concern us here.
if (packet_length < 1 + 4 ||
packet_length > 256 * 1024) {
buffer_dump(&incoming_packet);
packet_disconnect("Bad packet length
%d.",packet_length); }
The packet_disconnect function terminates the session and sends an SSH2_MSG_DISCONNECT SSH error
message over the connection. This message contains the
passed string. Thus we see that the OpenSSH implementation does not accept any packets whose packet length field
is less than 5 or greater than 256 1024 = 218 . The value
218 is presumably chosen to limit the effectiveness of DoS
attacks; the value of 5 is the minimum possible value of this
field, given the mandatory presence of a padding length byte
and 4 bytes of padding.
This check is consistent with the recommendations of [26]
that a total packet size of 35000 must be supported, and that
longer packets should be supported.
3. Attacking OpenSSH
Here,
need = 4 + packet_length - block_size
denotes the number of bytes still awaited in this packet and
can be calculated from the packet length field. The fatal
function terminates the session but no error messages are
sent on the connection (in contrast to the previous check).
Instead, the passed string is only logged locally. However,
this error will result in the termination of the TCP connection
over which SSH is running.
2.1.3. MAC Check. OpenSSH then continues to accept data
on the connection until sufficient data has arrived. MAC
verification then takes place. The following OpenSSH code
controls how much data needs to be received before the
MAC check will be done:
if (buffer_len(&input) < need + maclen)
return SSH_MSG_NONE;
3.1. Notation
Before describing our attacks against OpenSSH let us first
define some notation. We will use K to denote the key
of our block cipher, which we can assume to be fixed for
1
the duration of a connection, and let FK , FK
denote the
encryption and decryption operations of the block cipher in
use. We let L denote the block size of this block cipher
in bytes (so L = 8 for 3des and L = 16 for aes128).
Then CBC mode in the SSH BPP operates as follows: given
a sequence p1 , p2 , . . . pn of plaintext blocks making up a
packet, we have:
ci = FK (ci1 pi ),
i = 1, 2, . . . , n
i = 1, 2, . . . , n.
(1)
2. Note that since the attacker cannot necessarily detect where one BPP
packet ends and the next begins, there is a chance that this injected block
is not processed as the first block of a new packet. This is not usually an
issue in practice because the attacker can wait until the SSH connection is
quiet before beginning his attack.
With exactly the same attack as above, if the SSH connection enters a wait state, then we can deduce that both the
length check and the block length check have passed. When
L = 16 (e.g. with aes), this implies that the first 14 bits
of the length field in p01 will all be zero, and that the last 4
bits of this field encode the value 12. In turn, this yields 18
bits of pi using equation (1). Reasoning as before, this event
will arise with probability roughly 218 . (When L = 8, the
last 3 bits of the length field should encode the value 4,
the event has probability roughly 217 , and reveals 17 bits
of pi .) We next explain how the attacker can continue the
attack to extract more plaintext.
Recall that, if the length check and block length check
pass, then the SSH connection will continue to wait for more
data until the following condition is no longer satisfied:
if (buffer_len(&input) < need + maclen)
return SSH_MSG_NONE;
4. Experimental Validation
We implemented a proof-of-concept of our attacks against
OpenSSH using Scapy [18] and tested it in a virtual TCP/IP
network. Using a local virtual network has the advantage
that we can ignore any latency issues, since the transport is
almost instantaneous. There is no reason to think that our
results would not be applicable to real networks.
For our experiments we used OpenSSH server version 4.7
as shipped with Debian GNU/Linux Lenny (the attack will
also apply to more recent versions of OpenSSH up to and
including OpenSSH 5.1). However, we made one patch to
the server in order to increase the success probability of the
experiments: we modified the packet length field so that its
12 most significant bits were set to zero before the length
check was performed. The only impact of this change is that
the probability of passing this check is increased from 214
the length check and the block length check have passed. In
either case, at least 14 bits of plaintext can be recovered.
Of course, if no TCP FIN (with or without an SSH
disconnect message as payload) is observed, we may assume
that the wait state has been reached, at which point 18 bits
of plaintext (for L = 16) can be recovered and our second
attack can begin. We then feed single blocks of ciphertext to
the SSH server until a SSH2_MSG_DISCONNECT message
is observed. This indicates a MAC failure after enough data
was received. At this point, 32 bits of plaintext can be
recovered.
Because the final MAC check could be on a potentially
large message (218 bytes), we must take care not to feed
blocks to the SSH server too quickly during the second attack. Otherwise, the SSH server may have stopped accepting
data and be engaged in MAC processing when we think it
is still waiting for further data. This would lead us to overestimate the amount of data that needs to be sent to the server
before the MAC check is triggered, distorting the low order
bits of our calculation of the content of the packet length
field. Thus we throttled the speed of our data injection. This
only affects the amount of time needed to carry out the
attack.
Using this proof-of-concept code (including the server
patch to increase the success probability), we were able to
reliably recover the value of the packet length field after
decryption, and hence recover the first 32 bits of the original
plaintext block corresponding to the target ciphertext block.
When we removed the server patch, we still observed several
successful 14-bit recovering attacks, but did not observe any
successful probability 218 attacks in the experimental time
available.
One of the main challenges for building an exploit based
on our proof-of-concept code would be to find a service
which tolerates SSH connection failures and reconnects on
these failures. One such client is for instance the Fuse
SSHFS [19] implementation which accepts a reconnect
flag and doesnt seem to care about the nature of the
connection termination. Even then, the attacks require large
numbers of reconnects and may consume a lot of bandwidth.
conditions might occur during decryption, the formal decryption algorithm for such a scheme in [1] only produces
one possible error message (). Therefore the model in [1]
is intended to not allow the adversary to distinguish between
the different types of error. The model does not allow for
the possibility that the amount of data needed to complete
the decryption process might be governed by data that is
produced during the decryption process itself (namely the
packet length field). Indeed, the packet length field does not
appear at all in the model used in [1]. The analysis in [1]
models a connection tear-down in the event of an error, by
having decryption always output in response to any
decryption query made after the first error has arisen.
However, as we have seen, in any conceivable implementation of SSH, the decryption process must depend
on the initially encrypted packet length field. Moreover,
in OpenSSH, the adversary is able to distinguish between
the different error types. Finally, in practice, an attacker is
able to feed ciphertext blocks one by one to the decryption
process, a feature exploited in our 32-bit-recovering attack.
These differences between the theoretical model and the
implementation reality explain why some of the schemes
proven secure in [1] would be insecure in practice if implemented by extending OpenSSH in the natural way.
Even if the model of [1] only allows one type of error message, it unintentionally introduces a timing channel which
can be used to distinguish the different types of error arising
during decryption. This channel arises because each of the
stages of decrypting, then decoding, and finally checking
the MAC is allowed to individually output the single error
message in the model of decryption used in [1]. But these
stages necessarily follow one after another in series and
would take different amounts of time to complete in any
implementation. So even having a single error message may
not be enough in practice to disguise the reasons for failure,
and would still leave open the possibility of attack.
In the remainder of this section, we estimate the extent to
which the various SSH BPP enhancements discussed in [1]
would be vulnerable to our attacks if they were implemented
in OpenSSH in the most obvious and natural way.
Suppose that SSH-NPC and SSH-$NPC were implemented in such a way that the attacker can distinguish
between a failure of an OpenSSH-style packet length check
and a MAC failure. This would be the case if OpenSSH
was extended in the obvious and natural way to support
IVs transmitted on the wire. Then our first two attacks from
Section 3 would be applicable directly to both SSH-NPC
and SSH-$NPC, with the attacker simply making a random
choice of IV and injecting this along with the target ciphertext block, instead of relying on the IV being determined by
the last block of the previous packet. The attacks success
probabilities would be as in Section 3. In our third attack
(where the attacker attempts to learn plaintext bits that are
fixed across multiple SSH connections), the attackers ability
to control the IV would allow him to systematically explore
the space of IVs to obtain a deterministic attack requiring at
most 214 + 24 connections and one injected ciphertext block
per connection (for all but the final connection) to recover
32 bits of plaintext.
An attacker can also exploit his control over the IV in
SSH-NPC and SSH-$NPC to obtain a simple distinguishing
attack that has a success probability of 1. We sketch this
attack here. The attacker chooses two BPP plaintexts M0 =
p1 , p2 and M1 = p1 , p02 such that the first 32 bits of p2 are all
zero while the first 32 bits of p02 are the binary representation
of the value 32. Here, we assume that block p1 contains an
appropriate length field and padding length field, and blocks
p2 , p02 contain appropriate SSH padding. We assume now
that the attacker observes the BPP packet c0 , c1 , c2 , MAC
corresponding to either M0 or M1 on the SSH connection.
The attacker then simply injects blocks c1 , c2 as the first
two blocks of a new BPP packet into the SSH connection,
followed by a random MAC value. Here c1 is interpreted
as the IV and the decryption of c2 as the first block of the
plaintext packet. From our choice of p2 , p02 it is clear that
if M0 was encrypted under C, then the injected blocks will
cause a failure of the packet length check and termination
of the SSH connection, while if M1 was encrypted under C,
then the SSH connection enters into its wait state. Thus the
adversary can distinguish which message was encrypted.
This attack still works even if the length check and the
block length check used by OpenSSH are combined into a
single uniform check.
Random IVs are therefore not the solution to securing the
SSH BPP.
6. Countermeasures
There are various actions which could be taken to make
the SSH BPP resistant to our attacks, even with the continued presence of an encrypted length field, length checking
and non-uniform error reporting.
In response to the vulnerability announcement concerning
our attacks [8], OpenSSH was initially updated to make
failure of the two block length checks more difficult to
distinguish. The block length check (c.f. Section 2.1.2) in
version 1.158 of the file packet.c no longer calls the
function fatal but instead logs the error and then called
the function packet_disconnect. This means that the
error message caused by both the length check (c.f. Section
2.1.1) and the block length check are be the same and hence
an attacker can no longer distinguish between these two
events. This prevents our 14-bit plaintext recovery attack,
but does not affect our attack recovering 32 bits. OpenSSH
also issued a public response [14] to our attacks as reported
in [8]. Subsequently, the OpenSSH team released OpenSSH
5.2. Unfortunately, we did not have time to analyse this
new version with respect to our attacks before finalising this
paper for publication. Our understanding is that OpenSSH
5.2 includes further countermeasures (in addition to uniform
error reporting) to protect OpenSSH against our attacks.
Another countermeasure was suggested to us by Denis
Bider of Bitvise [4]: simply randomise the length field if
the length check fails. The system then proceeds with this
new random length until an error is eventually sent when
the MAC check fails. With this modification a length error
and a MAC error are now indistinguishable and our attacks
are no longer possible.
Note that moving the length checks so that they are
executed after the MAC check, or removing the length
checks altogether, only increases the success probability of
our attacks to 1.
Another solution is to use one of the three schemes SSHCTR, SSH-CTRIV-CBC and SSH-EIV-CBC proposed by
Bellare et al., since they resist our plaintext recovery attacks.
An RFC already exists to standardise counter mode for
7. Conclusions
We have presented plaintext-recovering attacks against
SSH as implemented by OpenSSH. We have argued that
the attacks arise from a fundamental design flaw in the RFC
specifying the SSH BPP [26], and explained why the attacks
are possible against a variant of the SSH BPP that was
proven to be secure in [1]. We also described how schemes
that are resistant to our plaintext recovery attacks may in
some scenarios leak length information about the plaintext.
We have also proposed countermeasures to the attacks.
Our attacks highlight the difficulties inherent in developing complex cryptographic constructions such as that
employed in SSH, especially in view of the interactions
that are possible between cryptographic processing and error
reporting. At this point a quote from [1] seems appropriate:
in the modern era of strong cryptography it
would seem counterintuitive to voluntarily use a
protocol with low security when it is possible to
fix the security of SSH at low cost.
While we see great value in the use of strong cryptography
supported by arguments from the tradition of provable
security, this quote raises the question: how do we know
that making a change does fix the security of SSH? For
example, our analysis shows that the proven-secure SSH$NPC would be at least as vulnerable to our attacks as the
current version of SSH.
In future work, we plan to examine formal models for
the kinds of software side channels that seem to emerge
in any reasonably complex implementation of cryptography.
A start in this direction, in the specific context of padding
oracle attacks, is provided in a recent paper of Paterson and
Watson [16].
Acknowledgements
Martin Albrecht was supported by the Royal Holloway
Valerie Myerscough Scholarship. Gaven Watson was supported by an EPSRC Industrial CASE studentship sponsored
by BT Research Laboratories.
We thank the anonymous referees for their many constructive comments on the paper.
References
[1] M. Bellare, T. Kohno, and C. Namprempre. Breaking
and Provably Repairing the SSH Authenticated Encryption
Scheme: A Case Study of the Encode-then-Encrypt-and-MAC
Paradigm. ACM Transactions on Information and Systems
Security, 7(2):206241, 2004.
[2] M. Bellare, T. Kohno, and C. Namprempre. The Secure Shell
(SSH) Transport Layer Encryption Modes, RFC 4344, Jan.
2006. http://www.ietf.org/rfc/rfc4344.txt.
[6] D. Boneh and D. Brumley. Remote timing attacks are practical. In Proceedings of the 12th Usenix Security Symposium,
2003.
[7] B. Canvel, A.P. Hiltgen, S. Vaudenay, and M. Vuagnoux.
Password Interception in a SSL/TLS Channel. In D. Boneh,
editor, Proccedings of CRYPTO 2003, LNCS 2729, pp. 583
599. Springer-Verlag, 2003.
[8] CPNI Vulnerability Advisory. Plaintext Recovery Attack
Against SSH. http://www.cpni.gov.uk/Docs/Vulnerability
Advisory SSH.txt, 14/11/2008 (revised 17/11/2008).
[9] W. Dai. An Attack Against SSH2 Protocol. Email to
the SECSH Working Group available from ftp://ftp.ietf.org/
ietf-mail-archive/secsh/2002-02.mail, 6th Feb. 2002.
[10] J.-P. Degabriele and K.G. Paterson. Attacking the IPsec
Standards in Encryption-only Configurations. In IEEE Symposium on Security and Privacy, pp. 335349, IEEE Computer
Society, 2007.
[11] T. Dierks and E. Rescorla. The Transport Layer Security
(TLS) Protocol, Version 1.1, RFC4346, April 2006. http:
//www.ietf.org/rfc/rfc4346.txt.
[12] A. Joux, G. Martinet and F. Valette. Blockwise-adaptive
attackers: Revisiting the (in)security of some provably secure
encryption models: CBC, GEM, IACBC. In Moti Yung,
editor, CRYPTO, LNCS 2442, pp. 1730, Springer-Verlag,
2002.
[27] T. Ylonen and C. Lonvick. The Secure Shell (SSH) Connection Protocol, RFC 4254, Jan. 2006. http://www.ietf.org/rfc/
rfc4254.txt.