7
SSH
7.1
Introduction
Historically, telnet, ftp, and the BSD r-commands (rcp, rsh, rexec, and rlogin)
have been used to handle interactive sessions and file transfers between a local and a
remote host. Although these utilities are still popular and in widespread use, their
severe security problems make them unsuitable for use in settings where security is a
concern. For example, telnet and ftp provide no encryption or authentication ser-
vices, so any data transferred using them is vulnerable to eavesdroppers using simple
passive attacks. More seriously, these utilities send the user’s password as plaintext,
allowing the attacker to recover it and subsequently log on to the remote system as the
user.
The r-commands are even worse. They share the same problems as telnet and
ftp and are often configured to use a convenience mode that does not require the user
to present any credentials. This mode is easily subverted to allow an attacker on any
machine to log on to or run commands on the target machine as any user authorized to
use the r-commands.
The Secure Shell (SSH) suite is a set of programs that serve as drop-in replacements
for telnet, ftp, and the r-commands.
More accurately, SSH is a set of protocols. Because their most popular implementations are the
UNIX programs ssh and sshd, most users think of SSH as its implementation rather than the
underlying protocols.
Despite its name, SSH has nothing to do with a shell, such as sh, csh, or bash. Rather,
SSH provides a secure connection over which a user may, among other things, run a
remote shell session.
207
208
SSH
Chapter 7
When we examine this connection, we will see that it meets our requirements for a
VPN. Data sent, for example, over the public Internet is encrypted and authenticated,
ensuring that it is safe from snooping and alteration. From the user’s perspective, these
VPN functions are transparent. The user need merely call ssh rather than, say, rsh to
enjoy the benefits of VPN-like security.
Two versions of SSH are in use today. These are not program versions; they are pro-
tocol versions. That is, the SSH protocol has two independent versions. Fortunately,
most implementations support both versions and will negotiate which version to use at
session start-up time.
In 1995, Helsinki University of Technology researcher Tatu Ylo..nen developed the
first version of SSH. As often happens, he designed it for his own use, in this case, as a
response to a password-sniffing attack on his university’s network. As also often hap-
pens, Ylo..nen released his code for others to benefit from, and its use exploded all over
the world. To deal with the increasing support issues, Ylo..nen formed SSH Communica-
tions Security (SCS, ) that same year. This version of the
software is now known as SSH version 1 (SSHv1).
Actually version 1 of the protocol underwent steady refinement. What is now known as
SSHv1 is really version 1.5 of the protocol.
As with SSL, there were no formal design documents for the first version of SSH,
but Ylo..nen did document the protocol after the fact as an Internet Draft (draft-ylonen-
ssh-protocol-00.txt). This draft has long since expired, of course, but is still distributed
with the SSH source code and is available in various repositories on the Web (see, for
example, ).
Because of security problems with SSHv1, SCS released version 2 of the protocol in
1996. SSHv2 is a complete rewrite of the SSH protocol and is incompatible with SSHv1.
The IETF became involved by forming the Secure Shell working group (SECSH). Their
Web site is at .
In late 1999, in response to increasingly restrictive licenses from SCS, the OpenSSH
project () released an SSHv1 implementation based on
SCS’s 1.2.12 release. This version supported protocol versions 1.3 and 1.5. In June 2000,
OpenSSH released support for SSHv2, and support for Secure FTP (SFTP) followed
soon afterward in November of that year. At this time, the OpenSSH suite is the most
common implementation of the SSH protocols.
7.2
The SSHv1 Protocol
Like SSL, SSH is a transport-layer protocol and uses TCP to carry its packets. This has
the usual advantages of providing an underlying reliable transport, freeing SSH from
having to worry about retransmissions, packet ordering, and flow control. Unlike SSL,
SSH does not require that either the local or remote application be SSH-aware. The situ-
ation is more analogous to an stunnel environment, such as that in Figure 6.24. That
is, SSH provides a secure tunnel through which local and remote applications may com-
municate.
Section 7.2
The SSHv1 Protocol
209
The most common case is shown in Figure 7.1: A local user is communicating with a
remote shell. In this case, the ssh client is providing the local user with a terminal
interface, but this is merely a convenience. This use of ssh is as a secure replacement
for rsh and is virtually identical from the user’s perspective.
ssh
SSH tunnel
sshd
shell
(sh, csh, etc.)
Figure 7.1 SSH as a Remote Shell
Because the use of ssh as a replacement for rsh and telnet is so common, we
first examine the SSH protocol from the point of view of the remote shell application.
Later, we consider other applications and capabilities of the SSH protocols.
Let’s start with a simple interactive session and watch the protocol in action as SSH
connects; authenticates the server, client, and user; transfers user data securely; and
finally disconnects. In order to see the unencrypted packets, we specify null encryption
(-c none). As we see, ssh warns us that there will be no encryption and that the pass-
word will be passed in the clear, just as it is for, say, telnet.
Although the SSH protocol recommends that null encryption should be available for debug-
ging purposes and although OpenSSH does provide support for it, there is no way to request it
from the command line. We are using a patched version that recognizes the -c none option.
Our patched server is listening on port 2022 instead of the normal port 22; that is why we spec-
ify -p 2022 on the call to ssh.
The -1 and -4 specify the version 1 protocol and IPv4, respectively.
$ ./ssh -1 -4 -c none -p 2022 guest@localhost
WARNING: Encryption is disabled! Password will be transmitted
in clear text.
guest@localhost’s password:
Last login: Sat May 15 14:55:16 2004 from localhost
Have a lot of fun...
guest@linuxlt:˜> ls
Documents public_html
guest@linuxlt:˜> exit
logout
Connection to localhost closed.
After we supply our password, sshd starts a shell for us, and we list the home
directory of user guest. Finally, we exit from the shell, and the connection is torn down.
Before studying the protocol messages for this session in detail, we must examine
the SSHv1 binary protocol packet. Figure 7.2 shows the format of these packets.
As with the SSL packets from Chapter 6, the SSH packet does not necessarily align its data on
word boundaries, so we display them as we did for SSL.
The length field is the size of the packet, not including the length field itself or the
variable-length random padding field that follows it. The padding field is intended to
210
SSH
Chapter 7
length
(4 bytes)
CRC
(4 bytes)
random padding
(1–8 bytes)
data
(length−5 bytes)
type
(1 byte)
s
e
t
y
b
h
t
g
n
e
l
d
e
t
p
y
r
c
n
e
Figure 7.2 The SSHv1 Binary Packet
make known text attacks more difficult. Its size is chosen to make the size of the
encrypted part of the packet a multiple of 8 bytes.
This is presumably because all the block ciphers originally supported by SSHv1 have a 64-bit
block size. The OpenSSH version 1 protocol supports only DES, 3DES, and Blowfish, all of
which use a 64-bit block size.
Following the padding is a 1-byte type field that identifies the type of message that
the packet contains. The type values are shown in Figure 7.3.
The type field is followed by the message data. The CRC field, which serves as a
MAC, ends the packet. When encryption is enabled, everything except the length field
is encrypted.
The protocol allows for optional compression of the data. This can be useful when
SSH is used in low-bandwidth situations such as dial-up lines. If the client and server
negotiate compression, only the type and data fields are compressed.
Many of these messages either carry no arguments—they consist of only the length,
padding, type, and CRC fields—or have a single argument consisting of a string, inte-
ger, or extended integer. In these cases, we won’t bother showing the message layout
but will merely indicate what type of argument, if any, the message carries.
Ser ver Authentication
The server authentication phase of the session, as shown in Figure 7.4, begins with the
exchange of identification strings. When the SSH client, ssh, connects to the SSH
Section 7.2
The SSHv1 Protocol
211
No.
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
Message Name
Message
SSH_MSG_NONE
SSH_MSG_DISCONNECT
SSH_SMSG_PUBLIC_KEY
SSH_CMSG_SESSION_KEY
SSH_CMSG_USER
SSH_CMSG_AUTH_RHOSTS
SSH_CMG_AUTH_RSA
SSH_SMSG_AUTH_RSA_CHALLENGE
SSH_CMSG_AUTH_RESPONSE
SSH_CMSG_AUTH_PASSWORD
SSH_CMSG_REQUEST_PTY
SSH_CMSG_WINDOW_SIZE
SSH_CMSG_EXEC_SHELL
SSH_CMSG_EXEC_CMD
SSH_SMSG_SUCCESS
SSH_SMSG_FAILURE
SSH_CMSG_STDIN_DATA
SSH_SMSG_STDOUT_DATA
SSH_SMSG_STDERR_DATA
SSH_CMSG_EOF
SSH_SMSG_EXITSTATUS
SSH_MSG_CHANNEL_OPEN_CONFIRMATION
SSH_MSG_CHANNEL_OPEN_FAILURE
SSH_MSG_CHANNEL_DATA
SSH_MSG_CHANNEL_CLOSE
SSH_MSG_CHANNEL_CLOSE_CONFIRMATION
SSH_SMSG_X11_OPEN
SSH_CMSG_PORT_FORWARD_REQUEST
SSH_MSG_PORT_OPEN
SSH_CMSG_AGENT_REQUEST_FORWARDING
SSH_SMSG_AGENT_OPEN
SSH_MSG_IGNORE
SSH_CMSG_EXIT_CONFIRMATION
SSH_CMSG_X11_REQUEST_FORWARDING
SSH_CMSG_AUTH_RHOSTS_RSA
SSH_MSG_DEBUG
SSH_CMG_REQUEST_COMPRESSION
never sent
causes immediate connection teardown
server’s public key
client choice of cipher and session key
user logon name
request for user rhosts type authentication
request for user RSA authentication
server challenge for RSA authentication
client response to RSA challenge
request for password authentication
request for a server pseudoterminal
client’s window size
request to start a user shell
request to run a command
server accepts last request
server does not accept last request
client input data for shell/command
output data from shell/command
STDERR output from shell/command
client is finished sending data
exit status from shell/command
indicates channel opened
indicates channel could not be opened
data transmitted over channel
sender is closing channel
sender acknowledges channel close
obsolete
client is connected to proxy X-server
client requests server port be forwarded
connection made on forwarded port
requests authentication agent forwarding
requests channel to authentication agent
no op
response to SSH_SMSG_EXITSTATUS
requests a proxy X-server
requests rhosts/RSA authentication
debugging information for peer
client requests compression
Figure 7.3 SSHv1 Message Types
212
SSH
Chapter 7
client
server
IDENT
IDENT
SSH_SMSG_PUBLIC_KEY
SSH_CMSG_SESSION_KEY
SSH_SMSG_SUCCESS
Figure 7.4 SSHv1 Server Authentication
server, sshd, the server sends an identification string indicating which of the protocols
it supports and, perhaps, additional program version information. For example, if we
connect to the SSH server with netcat, the server responds with its identification string:
$ nc linux 22
SSH-1.99-OpenSSH_3.5p1
The SSH-1.99 is a special version number that tells the client that the server supports
protocol versions 1 and 2. The -OpenSSH_3.5p1 is meant for human consumption
and specifies the version of the OpenSSH SSH server. The client will respond with its
own identification string, so that the peers will know which protocol to use.
After the server receives the client’s identification string, the peers switch to the
binary protocol, and the server sends the SSH_SMSG_PUBLIC_KEY message shown in
Figure 7.5.
The cookie is 8 random bytes that are intended to make IP spoofing more difficult.
The client must return these bytes to the server unchanged.
The host key is a permanent RSA public key that the client uses to verify the identity
of the server. Unlike with SSL, this key is not signed by a third party. Rather, the client
is expected to have a database of known host keys. In practice, this database is built by
accepting the key as valid the first time a user connects to a host. Thereafter, the host
must present the known key to the client for the session to proceed. SSH also supports
a key-fingerprinting mechanism that allows a user to manually verify a site’s key with
the site’s system administrator. There is also a proposal to make these fingerprints
available through DNS by means of SSHFP (SSH key fingerprint) records.
The server also sends a second key, the server key. This key is regenerated periodi-
cally, once every hour by default, to help improve security. As we shall see, the client
uses both of these keys to form its response to the server.
Section 7.2
The SSHv1 Protocol
213
cookie
(8 bytes)
server key bits
(32 bits)
host key bits
(32 bits)
server public key exponent
server public key modulus
host public key exponent
host public key modulus
protocol flags
(32 bits)
supported ciphers mask
(32 bits)
supported authentication
methods mask
(32 bits)
Figure 7.5 SSH_SMSG_PUBLIC_KEY Message
Finally, the message includes three 32-bit bit masks. The protocol flags bit mask is
intended for protocol extension. The supported ciphers mask indicates which ciphers the
server can use. The client will choose one of these for the session’s cipher. The sup-
ported authentications mask indicates which user authentications the server supports.
Again, the client will try one or more of these methods to authenticate the user.
Both sides use the information in this message to calculate a session ID by taking
the MD5 hash of the concatenation of the moduli of the server and host keys and the
cookie. As we’ll see, the session ID is used in generating the session key and thus
ensures that both the client and server contribute to the session key.
From Figure 7.4, we see that the client responds to the SSH_SMSG_PUBLIC_KEY
message with an SSH_CMSG_SESSION_KEY message, shown in Figure 7.6.
cipher
type
(1 byte)
cookie
(8 bytes)
encrypted session key
protocol flags
(32 bits)
Figure 7.6 SSH_CMSG_SESSION_KEY Message
214
SSH
Chapter 7
The cipher type field contains the number of the cipher that the client has chosen for the
session. The cookie and protocol flags fields are just as they were for the
SSH_SMSG_PUBLIC_KEY message. In particular, the cookie must be returned to the
server exactly as it was received by the client.
The encrypted session key field is a random 32-byte value chosen by the client. The
session ID, calculated from the values in the SSH_SMSG_PUBLIC_KEY message, is
exclusive-ORed into the first 16 bytes of the random value. This result is then encrypted
twice: first by the smaller (usually the server) RSA key and then by the other (usually
host) key.
Although this operation seems complicated, it accomplishes three separate tasks.
First, by exclusive-ORing the session ID into the random value used for the session key,
the client ensures that both the server and the client contribute to the final session key.
Then, by encrypting with the host key, the client verifies the identity of the server,
because the server must have the corresponding private key in order to recover the ses-
sion key. Finally, by encrypting with the server key, the client ensures perfect forward
secrecy by using the periodically changing server key.
Both sides now begin encrypting their packets. The server completes the server
authentication phase by sending an SSH_SMSG_SUCCESS message. At this point, the
peers have established a secure channel, and the server has authenticated itself to the
client.
User Authentication
The next step is for the user to authenticate himself to the server. This can be done in
several ways. SSH allows, but discourages, the insecure rhosts trusted-host model.
Because it is easily spoofed, this model should never be used when security is impor-
tant. SSH also supports a variation of the rhosts model in which the identity of the
client machine is verified with an RSA key. This is an improvement but still relies on
the client to certify the identity of the user. Once again, this method should not be used
when security or user identity is a concern. The rhosts and rhosts/RSA methods are
discussed in detail in [Barrett and Silverman 2002], so we will not belabor them further
here.
A third authentication method is to use Kerberos. With this method the user
obtains a ‘‘ticket’’ from the Kerberos server and sends it to the SSH server as authentica-
tion. Although Kerberos is a complicated system and requires a separate server, it may
make sense when there is a large user base, especially if Kerberos is already in place.
See [Garman 2003] for more information on Kerberos.
Next, there is a class of methods known as password authentication. In the simplest
of these, which we’ll examine shortly, the user merely supplies a password, which the
server checks against its password file. Recall that after server authentication, the peers
have established a secure channel, so this password is not passed in the clear as it is in,
say, the telnet protocol.
The other password methods are variations of a one-time-password scheme. One
example is the popular RSA SecurID system, which is described at RSA’s Web site
(). With SecurID, the user