1 Copyright 2007 Sun Microsystems, Inc. All rights reserved.
2 Use is subject to license terms.
3
4 #ident "%Z%%M% %I% %E% SMI"
5
6 Sun's Alternative "Privilege Separation" for OpenSSH
7
8
9 Table of Contents
10
11 1. Introduction
12 2. What is "Privilege?"
13 3. Analysis of the SSH Protocols
14 3.1. Privileged Resources, Operations, in the SSH Protocols
15 4. OpenSSH's Privilege Separation
16 5. SUNWssh's Alternative Privilege Separation
17 6. Comparison of the OpenSSH and SUNWssh PrivSep Models
18 7. Future Directions
19 8. Guide to the AltPrivSep Source Code
20 A. References
21
22
23
24
25
26 1. Introduction
27
28 Implementations of SSH servers require some degree of privilege in
29 order to function properly. Often such implementations retain such
30 privilege throughout normal operation even while users are logged
31 in. This means that vulnerabilities in the implementation of the
32 protocols can be exploited in such ways as to escalate the privilege
33 that would normally be accorded to mer-mortal users.
34
35 The OpenSSH team introduced support for "privilege separation" in
36 the OpenSSH ssh server some years ago to minimize the extent of
37 extant, undiscovered vulnerabilities in the OpenSSH server source
38 code. The basic concept is to have a multi-process server
39 implementation where one process, the "monitor" is privileged and
40 implements a smaller protocol than the ssh protocols, and thus is,
41 hopefully, less likely to sport exploitable security bugs.
42
43 The ssh team at Sun agrees with the basic OpenSSH privilege
44 separation concept, but disagrees with its design.
45
46 Here we present our alternative to the OpenSSH design. We begin
47 with the question of just what is "privilege" and follow on with an
48 analysis of the SSH protocols vis-a-vis privilege. Then we briefly
49 describe the OpenSSH model, followed by an exposition of our
50 alternative model.
51
52
53 2. What is "Privilege?"
54
55 Privilege, in a traditional Unix sense, is that which the "root"
56 user can do that other users cannot directly do. In Solaris 10
57 there is a new approach to this sort of privilege with the aim of
58 running much of the operating system with the Least Privilege
59 required; root's privilege is broken down into many privileges and
60 these are managed through privilege sets. We won't go into the
61 details of Solaris 10's Least Privilege facility here.
62
63 But privilege is also access to data and resources that can be used
64 to escalate the privilege of those who have access to them. For
65 example: secret, or private cryptographic keys used in
66 authentication. Network security typically requires the use of
67 cryptographic keys for authentication.
68
69
70 3. Analysis of the SSH Protocols
71
72 There are two or, rather three SSH protocols:
73
74 - version 1
75 - version 1.5
76 - version 2
77
78 Version 1 and 1.5 are much the same, from our point of view; version
79 2 is significantly different from the other two.
80
81 Familiarity by the reader with the specifications for these
82 protocols is not assumed, but would be beneficial to the reader.
83
84 Quite roughly, these protocols consist of the following:
85
86 a) initial version exchange (for protocol version negotiation)
87 b) a binary encoding of message data
88 c) message syntaxes for the protocols' messages
89 d) specifications on use of cryptography for transport
90 privacy (encryption) and integrity protection
91 e) a key exchange protocol (which also authenticates servers to
92 clients)
93 f) a protocol for user authentication
94 g) a session protocol
95 h) a re-keying protocol (v2-only)
96
97 Some of these parts of the ssh protocols are quite complex, some
98 quite straightforward. Altogether implementation of the ssh
99 protocols requires a source code base of significant size.
100
101 The OpenSSH implementation relies on OpenSSL for cryptographic
102 service, on libz for compression service and miscellaneous other
103 libraries. Besides these OpenSSH consists of several tens of
104 thousands of lines of source code in C.
105
106 SUNWssh is based on OpenSSH, so it is comparable in size and
107 complexity to OpenSSH.
108
109 There is, then, plenty of space for security bugs in the OpenSSH,
110 and, therefore, also in the SUNWssh source code bases.
111
112 The OpenSSH team designed and implemented a "privilege separation"
113 feature in their ssh server to reduce the risk that a security bug
114 in OpenSSH could be successfully exploited and an attacker's
115 privilege escalated.
116
117
118 3.1. Privileged Resources, Operations, in the SSH Protocols
119
120 What privileges does an SSH server need then?
121
122 Observation with Solaris 10's ppriv(1) and truss(1) commands as well
123 as analysis of the ssh protocols leads to conclude as follows.
124
125 No privilege or privileged resources are needed to implement the
126 parts (a)-(d) mentioned in section 3.
127
128
129 For key exchange and server authentication (e) an ssh server requires:
130
131 - Access to the host's ssh private keys.
132
133 - Access to the host's GSS-API acceptor credentials. [SSHv2-only]
134
135
136 An ssh server requires practically all privileges for user
137 authentication (f) (at least PAM does), particularly
138 PRIV_PROC_SETID, for logging the user in.
139
140
141 Post-authentication an ssh server requires the following privileges:
142
143 - Those required for auditing a user's subsequent logout.
144
145 That is, PRIV_PROC_AUDIT.
146
147
148 - Those required for record keeping (i.e., utmpx/wtmpx logging).
149
150 That is, either open file descriptor for those files or
151 PRIV_FILE_DAC_WRITE or otherwise access to those files, perhaps
152 through a special user id or group id which would be granted
153 write access through the ACLs on those files.
154
155 Since SSHv2 allows clients to open many channels with
156 pseudo-terminals a server may need to open and close utmpx/wtmpx
157 records multiple times in the lifetime of an SSHv2 connection.
158
159
160 - Those required for accessing the host's ssh private keys for
161 SSHv2 re-keying. [SSHv2-only]
162
163 These keys can be (and are) loaded at server startup time,
164 requiring PRIV_FILE_DAC_READ, or access through file ACLs, at
165 that time, but not thence.
166
167
168 - Those required for accessing the host's GSS-API acceptor
169 credentials for SSHv2 re-keying.
170
171 These credentials may require a large set of privileges. The
172 Solaris 10 Kerberos V GSS-API mechanism, for example, requires
173 PRIV_FILE_DAC_READ (for access to the system keytab) and
174 PRIV_FILE_DAC_WRITE (for access to the Kerberos V replay cache).
175
176
177 It is worth pointing out that because of a wrinkle in the
178 specification of the SSHv2 protocol and various implementations,
179 access to a host's ssh private keys can allow one not only to
180 impersonate the host as a server (which is, in practice, difficult),
181 but also to impersonate the host as a client (which is quite easy to
182 do) using "hostbased" user authentication.
183
184 It is entirely possible to have one-process server implementation
185 that drops most privileges and access to privileged resources after
186 user authentication succeeds. Such an implementation would make
187 some privileges, such as PRIV_PROC_SETID, available to any attacker
188 that successfully exploited a security bug in the ssh server.
189
190 But such an implementation would also have to retain access to
191 resources needed for authenticating the server, which, as described
192 above, can be used to impersonate the server, in some cases with
193 ease.
194
195
196 4. OpenSSH's Privilege Separation
197
198 The OpenSSH privilege separation model is quite complex.
199
200 It consists of a monitor, which retains all privileges and access to
201 privileged resources, and two processes which run with much less
202 privilege: one process running as a special user, "sshd," for
203 hosting all phases of the SSH protocols up to and including
204 authentication, and one process running as the actual user that logs
205 in and which hosts all phases of the SSH protocols post-user-
206 authentication.
207
208 The monitor and its companion processes speak a private protocol
209 over IPC. This protocol is intended to be smaller and simpler than
210 the SSH wire protocols.
211
212 In practice the OpenSSH monitor protocols relating to user
213 authentication are neither smaller nor simpler than the SSH user
214 authentication protocols; and though they are different they also
215 transport much the same data, including RSA/DSA signatures,
216 usernames, PAM conversations, and GSS-API context and MIC tokens.
217
218 The key exchange protocols have been broken down into their
219 essentials and the monitor serves only services such as signing
220 server replies with private host keys.
221
222 Note also that the OpenSSH monitor protocol uses the same encodings
223 as the SSH protocols and uses the same implementation of those
224 encodings.
225
226
227 5. SUNWssh's Alternative Privilege Separation
228
229 The Sun Microsystems ssh team believes that the OpenSSH team has
230 reached the point of diminishing returns in attempting to separate
231 processing of the user authentication protocols and that the OpenSSH
232 approach to privilege separation of the key exchange protocols has
233 led to a situation in which the monitor acts as an oracle, willing
234 to sign anything provided by the unprivileged processes that talk to
235 it.
236
237 The Sun ssh team proposes a somewhat different privilege separation
238 implementation that shares with the OpenSSH model the goal of
239 minimizing and simplifying the protocol spoken by the monitor, but
240 little source code.
241
242 We eschew any temptation to apply the privilege separation concept
243 to the version negotiation, initial key exchange and user
244 authentication phases of the ssh protocols (but see section 7).
245
246 Instead we focus on separating processing of auditing, record
247 keeping and re-keying from processing of the session protocols. We
248 also wish to avoid creating any oracles in the monitor.
249
250 This approach allows us to have a very simple monitor protocol. Our
251 monitor protocol consists of the following operations:
252
253 - record a new pseudo-terminal session
254 - record the end of a pseudo-terminal session
255 - process a re-key protocol messages
256 - get keys negotiated during re-keying to the session process to it
257 can use them
258
259 Logout auditing is done when the session process dies and so does
260 not require a monitor protocol message.
261
262 By processing all re-key protocol messages in the monitor we prevent
263 the creation of oracles in the monitor. This is so because the
264 monitor signs only material which it has generated and over which an
265 attacker would have little influence (through the attackers offered
266 DH public key, for example).
267
268 Odds and ends:
269
270 - If the monitor receives SIGHUP, SIGTERM or SIGINT it will call
271 fatal_cleanup(), and thence will forcibly shutdown(3SOCKET) the
272 ssh connection socket, causing its child to exit, and audit a
273 logout.
274
275 - The monitor does not attempt to update utmpx/wtmpx independently
276 of its child -- it depends on the child asking it to.
277
278 - The child now is unable to chown() ptys back to root. That's Ok,
279 other services on Solaris do the same and everything still works
280 because of grantpt(3C).
281
282
283 6. Comparison of the OpenSSH and SUNWssh PrivSep Models
284
285 The OpenSSH server involves three processes which we will term
286 "pre-session," "session" and "monitor."
287
288 The OpenSSH pre-session process implements:
289
290 - the ssh version string exchange
291 - the ssh message encoding/decoding
292 - most of the initial key exchange protocols
293 - transport protection
294 - part of the user authentication protocols
295
296 The OpenSSH session process implements:
297
298 - the ssh message encoding/decoding
299 - transport protection
300 - most of the re-keying protocols
301 - the session protocols
302
303 The OpenSSH monitor process implements:
304
305 - the ssh message encoding/decoding
306 - parts of the key exchange and re-key protocols (primarily signing
307 of server replies with host private keys)
308 - most of the user authentication protocols, specifically:
309
310 - evaluation of ~/.ssh/authorized_keys (for pubkey userauth)
311 - evaluation of known hosts files (for hostbased userauth)
312 - evaluation of .shosts/.rhosts files (for hostbased userauth)
313 - verification of signatures w/ public keys (pubkey, hostbased)
314 - PAM API calls, conversation function
315 - GSS-API calls
316
317 Note that any vulnerabilities in the parsing of authorized_keys,
318 known hosts and .shosts/rhosts files are as exploitable in the
319 monitor as in a server w/o privilege separation.
320
321 Similarly for any vulnerabilities in PAM modules and GSS-API
322 mechanisms.
323
324 The SUNWssh server involves two processes which we will term
325 "session" and "monitor."
326
327 The SUNWssh monitor process implements:
328
329 - the ssh version string exchange
330 - the ssh message encoding/decoding
331 - transport protection
332 - all of the key exchange and re-key protocols
333 - all of the user authentication protocols
334
335 The SUNWssh session process implements:
336
337 - the ssh message encoding/decoding
338 - transport protection
339 - the session protocols
340
341 Obviously all of these processes also implement their side of the
342 monitor protocols.
343
344 The OpenSSH 3.5p1 monitor protocol, on Solaris, has approximately 20
345 monitor request and corresponding response messages.
346
347 The SUNWssh monitor protocol has 3 monitor request and response
348 messages; additionally, the monitor processes standard re-key
349 messages (but note: the monitor and the session process IPC is
350 completely unencrypted), which amounts to about 14 more messages
351 altogether.
352
353 Much of the OpenSSH monitor protocol is a variation of the
354 on-the-wire ssh protocols, with some contents re-packaging. We
355 believe this does not afford the monitor much additional, if any
356 protection from attacks in the key exchange and user authentication
357 protocols.
358
359 The re-packaging that is done in the OpenSSH monitor protocol is
360 risky business. By separating the act of signing some blob of data
361 from computing that blob of data one can create an oracle; this is
362 exactly what happened in the OpenSSH case.
363
364 As you can see in the next section, the SUNWssh privilege separation
365 could evolve somewhat in the OpenSSH direction by saving the monitor
366 all transport protection work, but we cannot save the monitor much,
367 if any work relating to authentication or key exchange.
368
369
370 7. Future Directions
371
372 The SUNWssh server privilege separation implementation could stand
373 several improvements.
374
375 The first improvement would be to have a single system-wide monitor.
376 This would reduce resource consumption. The work needed to
377 implement such an enhancement is very similar to the work needed to
378 produce an SSH API and library, and it is not trivial. If this is
379 not done then at least dropping PRIV_PROC_SETID and instead setting
380 the saved-set-user-id in the monitor to that of the logged in user
381 would be nice.
382
383 The second enhancement would be to add a "none" host key algorithm
384 to SSHv2 and a corresponding option in SUNWssh to disallow re-keying
385 with any other host key algorithm. This would allow customers to
386 configure their server and monitor so that no re-key protocol
387 messages need be processed by the monitor.
388
389 A third enhancement would be to enhance the GSS-API mechanisms to
390 require fewer privileges. In practice this means overhauling the
391 Kerberos V mechanism's replay cache. This would allow the monitor
392 to run with fewer privileges.
393
394 Further, even without improving the Kerberos V mechanism's replay
395 cache it should be possible to drop at least PRIV_PROC_FORK/EXEC/
396 SESSION.
397
398 A fourth enhancement would to have the unprivileged process handle
399 all transport protection and proxy to the monitor all key exchange
400 and user authentication protocol messages. This is a variation on
401 the OpenSSH model, but without the re-packaging of ssh message
402 contents seen there. After authentication succeeds the monitor
403 could either change the unprivileged process' credentials (as can be
404 done with ppriv(1) or the unprivileged process would, as in OpenSSH,
405 pass the session keys/IVs/keystate to the monitor which would then
406 pass them to a new process, the session process, that would then run
407 as the logged in user.
408
409
410 8. Guide to the AltPrivSep Source Code
411
412
413 First, a brief introduction to the SUNWssh/OpenSSH source code.
414
415 The source code is organized as follows:
416
417 $SRC/cmd/ssh/etc/
418 |
419 +-> config files
420
421 $SRC/cmd/ssh/include/
422 |
423 +-> header files (note: none are installed/shipped)
424
425 $SRC/cmd/ssh/libopenbsd-compat/common/
426 |
427 +-> misc. portability source code
428
429 $SRC/cmd/ssh/libssh/common/
430 |
431 +-> implementation of encoding, transport protection,
432 various wrappers around cryptography, the key exchange
433 and host authentication protocols, the session
434 protocols, and misc. other code
435
436 cipher.c
437 mac.c
438 compress.c
439 packet.c
440 |
441 +-> transport protocol
442
443 buffer.c
444 bufaux.c
445 |
446 +-> encoding
447
448 channels.c
449 nchan.c
450 |
451 +-> session protocol
452
453 kex.c
454 kexdh.c
455 kexgex.c
456 |
457 +-> key exchange/re-key code common to ssh and sshd
458
459 kexdhs.c
460 kexgexs.c
461 kexgsss.c
462 |
463 +-> key exchange/re-key code (server only)
464
465 kexdhc.c
466 kexgexc.c
467 kexgssc.c
468 |
469 +-> key exchange/re-key code (client only)
470
471 dh.c
472 rsa.c
473 mpaux.c
474 ssh-rsa.c
475 ssh-dss.c
476 ssh-gss.c
477 |
478 +-> crypto wrappers/utilities
479
480 log.c
481 |
482 +-> logging, including debug logging, on stderr or
483 syslog
484
485
486 $SRC/cmd/ssh/ssh/
487 |
488 +-> ssh(1)
489
490 $SRC/cmd/ssh/sshd/
491 |
492 +-> sshd(1M), including auditing, implementation of user
493 authentication and the OpenSSH and SUNWssh monitors
494
495 sshd.c
496 |
497 +-> main()
498
499 auth*.c
500 |
501 +-> user authentication
502
503 serverloop.c
504 session.c
505 |
506 +-> session protocols
507
508 bsmaudit.[ch]
509 sshlogin.c
510 loginrec.c
511 |
512 +-> auditing and record-keeping
513
514 $SRC/cmd/ssh/<misc commands>/
515 |
516 +-> scp, sftp, sftp-server, ssh-agent, ssh-add, ...
517
518
519 The SUNWssh altprivsep adds two new source files:
520
521 $SRC/cmd/ssh/include/altprivsep.h
522 $SRC/cmd/ssh/sshd/altprivsep.c
523 |
524 +-> monitor start routine, altprivsep_packet_*() routines
525 for communication with the monitor, routines to help
526 with key exchanges, service procedures for the monitor,
527 etc...
528
529 and modifies the following:
530
531 $SRC/cmd/ssh/include/config.h
532 |
533 +> adds cpp define "ALTPRIVSEP"
534
535 $SRC/cmd/ssh/include/ssh2.h
536 |
537 +-> adds private message type "SSH2_PRIV_MSG_ALTPRIVSEP" (254)
538
539 $SRC/cmd/ssh/include/packet.h
540 |
541 +-> adds prototypes for several simple utility functions,
542 some of which are specifically meant to avoid having to
543 link altprivsep.c into ssh(1)
544
545 $SRC/cmd/ssh/libssh/common/kex.c
546 $SRC/cmd/ssh/libssh/common/packet.c
547 |
548 +-> implements the hooks needed to proxy re-key messages
549 to/from the monitor
550
551 $SRC/cmd/ssh/sshd/Makefile
552 |
553 +-> adds altprivsep.o to list of objects linked into sshd(1M)
554
555 $SRC/cmd/ssh/sshd/serverloop.c
556 |
557 +-> adds an event loop for the monitor
558 modifies the usual event loops for SSHv2
559
560 $SRC/cmd/ssh/sshd/session.c
561 |
562 +-> modifies do_login() and session_pty_cleanup2() to call
563 altprivsep_record_login/logout() instead of
564 record_login/logout().
565
566 modifies do_exec_pty() so that the server waits for the
567 call to altprivsep_record_login() in child process to
568 complete before returning so that the server and the
569 child processes do not compete for monitor IPC I/O.
570
571 $SRC/cmd/ssh/include/log.h
572 $SRC/cmd/ssh/libssh/common/log.c
573 |
574 +-> adds an internal interface, set_log_txt_prefix() so that
575 the monitor's debug and log messages get prefixed with a
576 string ("monitor ") that indicates they are from the
577 monitor
578
579 $SRC/cmd/ssh/sshd/sshd.c
580 |
581 +-> modifies the body of code that follows the user
582 authentication phase of the ssh protocols so as to start
583 the monitor and move the relevant code into the monitor
584 or session processes as appropriate while dropping
585 privileges and access to privileged resources in the
586 session process
587
588 The monitor uses the packet.h interfaces to communicate with the
589 session process as though it were its ssh client peer, but always
590 uses the "none" cipher, mac and compression algorithms and installs
591 even handlers only for the relevant key exchange messages and the
592 private monitor message used for the other monitor services.
593
594 The monitor serves the following services:
595
596 - APS_MSG_NEWKEYS_REQ -> used to obtain keys/IVs after re-keys
597 - APS_MSG_RECORD_LOGIN -> used to update utmpx/wtmpx
598 - APS_MSG_RECORD_LOGOUT -> used to update utmpx/wtmpx
599
600 The session and monitor processes communicate over a pipe.
601
602 All monitor IPC I/O from the session process is blocking (though the
603 pipe is set to non-blocking I/O). The monitor protocol is entirely
604 synchronous and relies on the re-key protocols being entirely
605 synchronous also (which they are, unlike the session protocols).
606
607 The kex.c and packet.c files are minimally modified, primarily to
608 prevent the monitor from handling SSH_MSG_NEWKEYS messages as a
609 normal ssh server should, instead letting the session process
610 process SSH_MSG_NEWKEYS messages by requesting the new keys
611 negotiated with client from the monitor.
612
613 Note that for SSHv1 no on-the-wire messages are processed by the
614 monitor after authentication. In fact, the monitor thinks it's
615 running SSHv2, even if the on-the-wire protocol is v1.
616
617
618 A. References
619
620 The IETF SECSH Working Group:
621
622 http://www.ietf.org/html.charters/secsh-charter.html
623
624 The SSHv2 architecture, assigned numbers:
625
626 http://www.ietf.org/internet-drafts/draft-ietf-secsh-architecture-16.txt
627 http://www.ietf.org/internet-drafts/draft-ietf-secsh-assignednumbers-06.txt
628
629 New cipher modes for SSHv2:
630
631 http://www.ietf.org/internet-drafts/draft-ietf-secsh-newmodes-02.txt
632
633 The SSHv2 "transport," including initial key exchange and re-key
634 protocols, but excluding negotiable DH group size and GSS-API-based
635 key exchange:
636
637 http://www.ietf.org/internet-drafts/draft-ietf-secsh-transport-18.txt
638
639 Additional key exchange protocols for SSHv2:
640
641 http://www.ietf.org/internet-drafts/draft-ietf-secsh-gsskeyex-08.txt
642 http://www.ietf.org/internet-drafts/draft-ietf-secsh-dh-group-exchange-04.txt
643
644 Base user authentication spec for SSHv2 (includes none, password,
645 pubkey and hostbased user authentication):
646
647 http://www.ietf.org/internet-drafts/draft-ietf-secsh-userauth-21.txt
648
649 SSHv2 user authentication using PAM-style prompting:
650
651 http://www.ietf.org/internet-drafts/draft-ietf-secsh-auth-kbdinteract-06.txt
652
653 SSHv2 user authentication using the GSS-API:
654
655 http://www.ietf.org/internet-drafts/draft-ietf-secsh-gsskeyex-08.txt
656
657 SSHv2 "session" protocol (i.e., the protocol used for pty sessions,
658 port forwarding, agent forwarding, X display forwarding, etc...):
659
660 http://www.ietf.org/internet-drafts/draft-ietf-secsh-connect-19.txt
661