example: secret, or private cryptographic keys used in
authentication. Network security typically requires the use of
cryptographic keys for authentication.
3. Analysis of the SSH Protocols
There are two or, rather three SSH protocols:
Version 1 and 1.5 are much the same, from our point of view; version
2 is significantly different from the other two.
Familiarity by the reader with the specifications for these
protocols is not assumed, but would be beneficial to the reader.
Quite roughly, these protocols consist of the following:
a) initial version exchange (for protocol version negotiation)
b) a binary encoding of message data
c) message syntaxes for the protocols' messages
d) specifications on use of cryptography for transport
privacy (encryption) and integrity protection
e) a key exchange protocol (which also authenticates servers to
f) a protocol for user authentication
h) a re-keying protocol (v2-only)
Some of these parts of the ssh protocols are quite complex, some
quite straightforward. Altogether implementation of the ssh
protocols requires a source code base of significant size.
The OpenSSH implementation relies on OpenSSL for cryptographic
service, on libz for compression service and miscellaneous other
libraries. Besides these OpenSSH consists of several tens of
thousands of lines of source code in C.
SUNWssh is based on OpenSSH, so it is comparable in size and
There is, then, plenty of space for security bugs in the OpenSSH,
and, therefore, also in the SUNWssh source code bases.
The OpenSSH team designed and implemented a "privilege separation"
feature in their ssh server to reduce the risk that a security bug
in OpenSSH could be successfully exploited and an attacker's
3.1. Privileged Resources, Operations, in the SSH Protocols
What privileges does an SSH server need then?
Observation with Solaris 10's ppriv(1) and truss(1) commands as well
as analysis of the ssh protocols leads to conclude as follows.
No privilege or privileged resources are needed to implement the
parts (a)-(d) mentioned in section 3.
An ssh server requires practically all privileges for user
authentication (e) (at least PAM does), particularly
PRIV_PROC_SETID, for logging the user in.
For key exchange and server authentication an ssh server requires:
- Access to the host's ssh private keys.
- Access to the host's GSS-API acceptor credentials. [SSHv2-only]
Post-authentication an ssh server requires the following privileges:
- Those required for auditing a user's subsequent logout.
That is, PRIV_PROC_AUDIT.
That is, either open file descriptor for those files or
PRIV_FILE_DAC_WRITE or otherwise access to those files, perhaps
through a special user id or group id which would be granted
write access through the ACLs on those files.
Since SSHv2 allows clients to open many channels with
pseudo-terminals a server may need to open and close
utmpx/wtmpx records multiple times in the lifetime of an SSHv2 connection.
- Those required for accessing the host's ssh private keys for
SSHv2 re-keying. [SSHv2-only]
These keys can be (and are) loaded at server startup time,
requiring PRIV_FILE_DAC_READ, or access through file ACLs, at
that time, but not thence.
- Those required for accessing the host's GSS-API acceptor
credentials for SSHv2 re-keying.
These credentials may require a large set of privileges. The
Solaris 10 Kerberos V GSS-API mechanism, for example, requires
PRIV_FILE_DAC_READ (for access to the system keytab) and
PRIV_FILE_DAC_WRITE (for access to the Kerberos V replay cache).
It is worth pointing out that because of a wrinkle in the
specification of the SSHv2 protocol and various implementations,
access to a host's ssh private keys can allow one not only to
impersonate the host as a server (which is, in practice, difficult),
but also to impersonate the host as a client (which is quite easy to
do) using "hostbased" user authentication.
It is entirely possible to have one-process server implementation
that drops most privileges and access to privileged resources after
user authentication succeeds. Such an implementation would make
some privileges, such as PRIV_PROC_SETID, available to any attacker
that successfully exploited a security bug in the ssh server.
But such an implementation would also have to retain access to
resources needed for authenticating the server, which, as described
above, can be used to impersonate the server, in some cases with
4. OpenSSH's Privilege Separation
The OpenSSH privilege separation model is quite complex.
It consists of a monitor, which retains all privileges and access to
privileged resources, and two processes which run with much less
privilege: one process running as a special user, "sshd," for
hosting all phases of the SSH protocols up to and including
authentication, and one process running as the actual user that logs
in and which hosts all phases of the SSH protocols post-user-
The monitor and its companion processes speak a private protocol
over IPC. This protocol is intended to be smaller and simpler than
In practice the OpenSSH monitor protocols relating to user
authentication are neither smaller nor simpler than the SSH user
authentication protocols; and though they are different they also
transport much the same data, including
RSA/DSA signatures,
usernames, PAM conversations, and GSS-API context and MIC tokens.
The key exchange protocols have been broken down into their
essentials and the monitor serves only services such as signing
server replies with private host keys.
Note also that the OpenSSH monitor protocol uses the same encodings
as the SSH protocols and uses the same implementation of those
5. SUNWssh's Alternative Privilege Separation
The Sun Microsystems ssh team believes that the OpenSSH team has
reached the point of diminishing returns in attempting to separate
processing of the user authentication protocols and that the OpenSSH
approach to privilege separation of the key exchange protocols has
led to a situation in which the monitor acts as an oracle, willing
to sign anything provided by the unprivileged processes that talk to
The Sun ssh team proposes a somewhat different privilege separation
implementation that shares with the OpenSSH model the goal of
minimizing and simplifying the protocol spoken by the monitor, but
We eschew any temptation to apply the privilege separation concept
to the version negotiation, initial key exchange and user
authentication phases of the ssh protocols (but see section 7).
Instead we focus on separating processing of auditing, record
keeping and re-keying from processing of the session protocols. We
also wish to avoid creating any oracles in the monitor.
This approach allows us to have a very simple monitor protocol. Our
monitor protocol consists of the following operations:
- record a new pseudo-terminal session
- record the end of a pseudo-terminal session
- process a re-key protocol messages
- get keys negotiated during re-keying to the session process to it
Logout auditing is done when the session process dies and so does
not require a monitor protocol message.
By processing all re-key protocol messages in the monitor we prevent
the creation of oracles in the monitor. This is so because the
monitor signs only material which it has generated and over which an
attacker would have little influence (through the attackers offered
DH public key, for example).
- If the monitor receives SIGHUP, SIGTERM or SIGINT it will call
fatal_cleanup(), and thence will forcibly shutdown(3SOCKET) the
ssh connection socket, causing its child to exit, and audit a
- The monitor does not attempt to update
utmpx/wtmpx independently
of its child -- it depends on the child asking it to.
- The child now is unable to chown() ptys back to root. That's Ok,
other services on Solaris do the same and everything still works
6. Comparison of the OpenSSH and SUNWssh PrivSep Models
The OpenSSH server involves three processes which we will term
"pre-session," "session" and "monitor."
The OpenSSH pre-session process implements:
- the ssh version string exchange
- most of the initial key exchange protocols
- part of the user authentication protocols
The OpenSSH session process implements:
- most of the re-keying protocols
The OpenSSH monitor process implements:
- parts of the key exchange and re-key protocols (primarily signing
of server replies with host private keys)
- most of the user authentication protocols, specifically:
- evaluation of ~/.ssh/authorized_keys (for pubkey userauth)
- evaluation of known hosts files (for hostbased userauth)
- evaluation of .shosts/.rhosts files (for hostbased userauth)
- verification of signatures w/ public keys (pubkey, hostbased)
- PAM API calls, conversation function
Note that any vulnerabilities in the parsing of authorized_keys,
known hosts and .shosts/rhosts files are as exploitable in the
monitor as in a server w/o privilege separation.
Similarly for any vulnerabilities in PAM modules and GSS-API
The SUNWssh server involves two processes which we will term
The SUNWssh monitor process implements:
- the ssh version string exchange
- all of the key exchange and re-key protocols
- all of the user authentication protocols
The SUNWssh session process implements:
Obviously all of these processes also implement their side of the
The OpenSSH 3.5p1 monitor protocol, on Solaris, has approximately 20
monitor request and corresponding response messages.
The SUNWssh monitor protocol has 3 monitor request and response
messages; additionally, the monitor processes standard re-key
messages (but note: the monitor and the session process IPC is
completely unencrypted), which amounts to about 14 more messages
Much of the OpenSSH monitor protocol is a variation of the
on-the-wire ssh protocols, with some contents re-packaging. We
believe this does not afford the monitor much additional, if any
protection from attacks in the key exchange and user authentication
The re-packaging that is done in the OpenSSH monitor protocol is
risky business. By separating the act of signing some blob of data
from computing that blob of data one can create an oracle; this is
exactly what happened in the OpenSSH case.
As you can see in the next section, the SUNWssh privilege separation
could evolve somewhat in the OpenSSH direction by saving the monitor
all transport protection work, but we cannot save the monitor much,
if any work relating to authentication or key exchange.
The SUNWssh server privilege separation implementation could stand
The first improvement would be to have a single system-wide monitor.
This would reduce resource consumption. The work needed to
implement such an enhancement is very similar to the work needed to
produce an SSH API and library, and it is not trivial. If this is
not done then at least dropping PRIV_PROC_SETID and instead setting
the saved-set-user-id in the monitor to that of the logged in user
The second enhancement would be to add a "none" host key algorithm
to SSHv2 and a corresponding option in SUNWssh to disallow re-keying
with any other host key algorithm. This would allow customers to
configure their server and monitor so that no re-key protocol
messages need be processed by the monitor.
A third enhancement would be to enhance the GSS-API mechanisms to
require fewer privileges. In practice this means overhauling the
Kerberos V mechanism's replay cache. This would allow the monitor
to run with fewer privileges.
Further, even without improving the Kerberos V mechanism's replay
A fourth enhancement would to have the unprivileged process handle
all transport protection and proxy to the monitor all key exchange
and user authentication protocol messages. This is a variation on
the OpenSSH model, but without the re-packaging of ssh message
contents seen there. After authentication succeeds the monitor
could either change the unprivileged process' credentials (as can be
done with ppriv(1) or the unprivileged process would, as in OpenSSH,
pass them to a new process, the session process, that would then run
8. Guide to the AltPrivSep Source Code
The source code is organized as follows:
+-> misc. portability source code
+-> implementation of encoding, transport protection,
various wrappers around cryptography, the key exchange
and host authentication protocols, the session
protocols, and misc. other code
+-> logging, including debug logging, on stderr or
+-> sshd(1M), including auditing, implementation of user
authentication and the OpenSSH and SUNWssh monitors
+-> auditing and record-keeping
+-> scp, sftp, sftp-server, ssh-agent, ssh-add, ...
The SUNWssh altprivsep adds two new source files:
+-> monitor start routine, altprivsep_packet_*() routines
for communication with the monitor, routines to help
with key exchanges, service procedures for the monitor,
and modifies the following:
+> adds cpp define "ALTPRIVSEP"
+-> adds private message type "SSH2_PRIV_MSG_ALTPRIVSEP" (254)
+-> adds prototypes for several simple utility functions,
some of which are specifically meant to avoid having to
+-> implements the hooks needed to proxy re-key messages
+-> adds
altprivsep.o to list of objects linked into sshd(1M)
+-> adds an event loop for the monitor
modifies the usual event loops for SSHv2
+-> modifies do_login() and session_pty_cleanup2() to call
modifies do_exec_pty() so that the server waits for the
call to altprivsep_record_login() in child process to
complete before returning so that the server and the
child processes do not compete for monitor IPC I/O.
+-> adds an internal interface, set_log_txt_prefix() so that
the monitor's debug and log messages get prefixed with a
string ("monitor ") that indicates they are from the
+-> modifies the body of code that follows the user
authentication phase of the ssh protocols so as to start
the monitor and move the relevant code into the monitor
or session processes as appropriate while dropping
privileges and access to privileged resources in the
The monitor uses the
packet.h interfaces to communicate with the
session process as though it were its ssh client peer, but always
uses the "none" cipher, mac and compression algorithms and installs
even handlers only for the relevant key exchange messages and the
private monitor message used for the other monitor services.
The monitor serves the following services:
- APS_MSG_NEWKEYS_REQ -> used to obtain
keys/IVs after re-keys
The session and monitor processes communicate over a pipe.
All monitor IPC I/O from the session process is blocking (though the
pipe is set to non-blocking I/O). The monitor protocol is entirely
synchronous and relies on the re-key protocols being entirely
synchronous also (which they are, unlike the session protocols).
The
kex.c and
packet.c files are minimally modified, primarily to
prevent the monitor from handling SSH_MSG_NEWKEYS messages as a
normal ssh server should, instead letting the session process
process SSH_MSG_NEWKEYS messages by requesting the new keys
negotiated with client from the monitor.
Note that for SSHv1 no on-the-wire messages are processed by the
monitor after authentication. In fact, the monitor thinks it's
running SSHv2, even if the on-the-wire protocol is v2.
The IETF SECSH Working Group:
The SSHv2 architecture, assigned numbers:
New cipher modes for SSHv2:
The SSHv2 "transport," including initial key exchange and re-key
protocols, but excluding negotiable DH group size and GSS-API-based
Additional key exchange protocols for SSHv2:
Base user authentication spec for SSHv2 (includes none, password,
pubkey and hostbased user authentication):
SSHv2 user authentication using PAM-style prompting:
SSHv2 user authentication using the GSS-API:
SSHv2 "session" protocol (
i.e., the protocol used for pty sessions,
port forwarding, agent forwarding, X display forwarding, etc...):