1*7574SJan.Pechanec@Sun.COM Copyright 2008 Sun Microsystems, Inc. All rights reserved. 20Sstevel@tonic-gate Use is subject to license terms. 30Sstevel@tonic-gate 40Sstevel@tonic-gate Sun's Alternative "Privilege Separation" for OpenSSH 50Sstevel@tonic-gate 60Sstevel@tonic-gate 70Sstevel@tonic-gateTable of Contents 80Sstevel@tonic-gate 90Sstevel@tonic-gate1. Introduction 100Sstevel@tonic-gate2. What is "Privilege?" 110Sstevel@tonic-gate3. Analysis of the SSH Protocols 120Sstevel@tonic-gate3.1. Privileged Resources, Operations, in the SSH Protocols 130Sstevel@tonic-gate4. OpenSSH's Privilege Separation 140Sstevel@tonic-gate5. SUNWssh's Alternative Privilege Separation 150Sstevel@tonic-gate6. Comparison of the OpenSSH and SUNWssh PrivSep Models 160Sstevel@tonic-gate7. Future Directions 170Sstevel@tonic-gate8. Guide to the AltPrivSep Source Code 180Sstevel@tonic-gateA. References 190Sstevel@tonic-gate 200Sstevel@tonic-gate 210Sstevel@tonic-gate 220Sstevel@tonic-gate 230Sstevel@tonic-gate 240Sstevel@tonic-gate1. Introduction 250Sstevel@tonic-gate 260Sstevel@tonic-gate Implementations of SSH servers require some degree of privilege in 270Sstevel@tonic-gate order to function properly. Often such implementations retain such 280Sstevel@tonic-gate privilege throughout normal operation even while users are logged 290Sstevel@tonic-gate in. This means that vulnerabilities in the implementation of the 300Sstevel@tonic-gate protocols can be exploited in such ways as to escalate the privilege 310Sstevel@tonic-gate that would normally be accorded to mer-mortal users. 320Sstevel@tonic-gate 330Sstevel@tonic-gate The OpenSSH team introduced support for "privilege separation" in 340Sstevel@tonic-gate the OpenSSH ssh server some years ago to minimize the extent of 350Sstevel@tonic-gate extant, undiscovered vulnerabilities in the OpenSSH server source 360Sstevel@tonic-gate code. The basic concept is to have a multi-process server 370Sstevel@tonic-gate implementation where one process, the "monitor" is privileged and 380Sstevel@tonic-gate implements a smaller protocol than the ssh protocols, and thus is, 390Sstevel@tonic-gate hopefully, less likely to sport exploitable security bugs. 400Sstevel@tonic-gate 410Sstevel@tonic-gate The ssh team at Sun agrees with the basic OpenSSH privilege 420Sstevel@tonic-gate separation concept, but disagrees with its design. 430Sstevel@tonic-gate 440Sstevel@tonic-gate Here we present our alternative to the OpenSSH design. We begin 450Sstevel@tonic-gate with the question of just what is "privilege" and follow on with an 460Sstevel@tonic-gate analysis of the SSH protocols vis-a-vis privilege. Then we briefly 470Sstevel@tonic-gate describe the OpenSSH model, followed by an exposition of our 480Sstevel@tonic-gate alternative model. 490Sstevel@tonic-gate 500Sstevel@tonic-gate 510Sstevel@tonic-gate2. What is "Privilege?" 520Sstevel@tonic-gate 530Sstevel@tonic-gate Privilege, in a traditional Unix sense, is that which the "root" 540Sstevel@tonic-gate user can do that other users cannot directly do. In Solaris 10 550Sstevel@tonic-gate there is a new approach to this sort of privilege with the aim of 560Sstevel@tonic-gate running much of the operating system with the Least Privilege 570Sstevel@tonic-gate required; root's privilege is broken down into many privileges and 580Sstevel@tonic-gate these are managed through privilege sets. We won't go into the 590Sstevel@tonic-gate details of Solaris 10's Least Privilege facility here. 600Sstevel@tonic-gate 610Sstevel@tonic-gate But privilege is also access to data and resources that can be used 620Sstevel@tonic-gate to escalate the privilege of those who have access to them. For 630Sstevel@tonic-gate example: secret, or private cryptographic keys used in 640Sstevel@tonic-gate authentication. Network security typically requires the use of 650Sstevel@tonic-gate cryptographic keys for authentication. 660Sstevel@tonic-gate 670Sstevel@tonic-gate 680Sstevel@tonic-gate3. Analysis of the SSH Protocols 690Sstevel@tonic-gate 700Sstevel@tonic-gate There are two or, rather three SSH protocols: 710Sstevel@tonic-gate 720Sstevel@tonic-gate - version 1 730Sstevel@tonic-gate - version 1.5 740Sstevel@tonic-gate - version 2 750Sstevel@tonic-gate 760Sstevel@tonic-gate Version 1 and 1.5 are much the same, from our point of view; version 770Sstevel@tonic-gate 2 is significantly different from the other two. 780Sstevel@tonic-gate 790Sstevel@tonic-gate Familiarity by the reader with the specifications for these 800Sstevel@tonic-gate protocols is not assumed, but would be beneficial to the reader. 810Sstevel@tonic-gate 820Sstevel@tonic-gate Quite roughly, these protocols consist of the following: 830Sstevel@tonic-gate 840Sstevel@tonic-gate a) initial version exchange (for protocol version negotiation) 850Sstevel@tonic-gate b) a binary encoding of message data 860Sstevel@tonic-gate c) message syntaxes for the protocols' messages 870Sstevel@tonic-gate d) specifications on use of cryptography for transport 880Sstevel@tonic-gate privacy (encryption) and integrity protection 890Sstevel@tonic-gate e) a key exchange protocol (which also authenticates servers to 900Sstevel@tonic-gate clients) 910Sstevel@tonic-gate f) a protocol for user authentication 920Sstevel@tonic-gate g) a session protocol 930Sstevel@tonic-gate h) a re-keying protocol (v2-only) 940Sstevel@tonic-gate 950Sstevel@tonic-gate Some of these parts of the ssh protocols are quite complex, some 960Sstevel@tonic-gate quite straightforward. Altogether implementation of the ssh 970Sstevel@tonic-gate protocols requires a source code base of significant size. 980Sstevel@tonic-gate 990Sstevel@tonic-gate The OpenSSH implementation relies on OpenSSL for cryptographic 1000Sstevel@tonic-gate service, on libz for compression service and miscellaneous other 1010Sstevel@tonic-gate libraries. Besides these OpenSSH consists of several tens of 1020Sstevel@tonic-gate thousands of lines of source code in C. 1030Sstevel@tonic-gate 1040Sstevel@tonic-gate SUNWssh is based on OpenSSH, so it is comparable in size and 1050Sstevel@tonic-gate complexity to OpenSSH. 1060Sstevel@tonic-gate 1070Sstevel@tonic-gate There is, then, plenty of space for security bugs in the OpenSSH, 1080Sstevel@tonic-gate and, therefore, also in the SUNWssh source code bases. 1090Sstevel@tonic-gate 1100Sstevel@tonic-gate The OpenSSH team designed and implemented a "privilege separation" 1110Sstevel@tonic-gate feature in their ssh server to reduce the risk that a security bug 1120Sstevel@tonic-gate in OpenSSH could be successfully exploited and an attacker's 1130Sstevel@tonic-gate privilege escalated. 1140Sstevel@tonic-gate 1150Sstevel@tonic-gate 1160Sstevel@tonic-gate3.1. Privileged Resources, Operations, in the SSH Protocols 1170Sstevel@tonic-gate 1180Sstevel@tonic-gate What privileges does an SSH server need then? 1190Sstevel@tonic-gate 1200Sstevel@tonic-gate Observation with Solaris 10's ppriv(1) and truss(1) commands as well 1210Sstevel@tonic-gate as analysis of the ssh protocols leads to conclude as follows. 1220Sstevel@tonic-gate 1230Sstevel@tonic-gate No privilege or privileged resources are needed to implement the 1240Sstevel@tonic-gate parts (a)-(d) mentioned in section 3. 1250Sstevel@tonic-gate 1260Sstevel@tonic-gate 1271789Sjp161948 For key exchange and server authentication (e) an ssh server requires: 1280Sstevel@tonic-gate 1290Sstevel@tonic-gate - Access to the host's ssh private keys. 1300Sstevel@tonic-gate 1310Sstevel@tonic-gate - Access to the host's GSS-API acceptor credentials. [SSHv2-only] 1320Sstevel@tonic-gate 1330Sstevel@tonic-gate 1341789Sjp161948 An ssh server requires practically all privileges for user 1351789Sjp161948 authentication (f) (at least PAM does), particularly 1361789Sjp161948 PRIV_PROC_SETID, for logging the user in. 1371789Sjp161948 1381789Sjp161948 1390Sstevel@tonic-gate Post-authentication an ssh server requires the following privileges: 1400Sstevel@tonic-gate 1410Sstevel@tonic-gate - Those required for auditing a user's subsequent logout. 1420Sstevel@tonic-gate 1430Sstevel@tonic-gate That is, PRIV_PROC_AUDIT. 1440Sstevel@tonic-gate 1450Sstevel@tonic-gate 1460Sstevel@tonic-gate - Those required for record keeping (i.e., utmpx/wtmpx logging). 1470Sstevel@tonic-gate 1480Sstevel@tonic-gate That is, either open file descriptor for those files or 1490Sstevel@tonic-gate PRIV_FILE_DAC_WRITE or otherwise access to those files, perhaps 1500Sstevel@tonic-gate through a special user id or group id which would be granted 1510Sstevel@tonic-gate write access through the ACLs on those files. 1520Sstevel@tonic-gate 1530Sstevel@tonic-gate Since SSHv2 allows clients to open many channels with 1540Sstevel@tonic-gate pseudo-terminals a server may need to open and close utmpx/wtmpx 1550Sstevel@tonic-gate records multiple times in the lifetime of an SSHv2 connection. 1560Sstevel@tonic-gate 1570Sstevel@tonic-gate 1580Sstevel@tonic-gate - Those required for accessing the host's ssh private keys for 1590Sstevel@tonic-gate SSHv2 re-keying. [SSHv2-only] 1600Sstevel@tonic-gate 1610Sstevel@tonic-gate These keys can be (and are) loaded at server startup time, 1620Sstevel@tonic-gate requiring PRIV_FILE_DAC_READ, or access through file ACLs, at 1630Sstevel@tonic-gate that time, but not thence. 1640Sstevel@tonic-gate 1650Sstevel@tonic-gate 1660Sstevel@tonic-gate - Those required for accessing the host's GSS-API acceptor 1670Sstevel@tonic-gate credentials for SSHv2 re-keying. 1680Sstevel@tonic-gate 1690Sstevel@tonic-gate These credentials may require a large set of privileges. The 1700Sstevel@tonic-gate Solaris 10 Kerberos V GSS-API mechanism, for example, requires 1710Sstevel@tonic-gate PRIV_FILE_DAC_READ (for access to the system keytab) and 1720Sstevel@tonic-gate PRIV_FILE_DAC_WRITE (for access to the Kerberos V replay cache). 1730Sstevel@tonic-gate 1740Sstevel@tonic-gate 1750Sstevel@tonic-gate It is worth pointing out that because of a wrinkle in the 1760Sstevel@tonic-gate specification of the SSHv2 protocol and various implementations, 1770Sstevel@tonic-gate access to a host's ssh private keys can allow one not only to 1780Sstevel@tonic-gate impersonate the host as a server (which is, in practice, difficult), 1790Sstevel@tonic-gate but also to impersonate the host as a client (which is quite easy to 1800Sstevel@tonic-gate do) using "hostbased" user authentication. 1810Sstevel@tonic-gate 1820Sstevel@tonic-gate It is entirely possible to have one-process server implementation 1830Sstevel@tonic-gate that drops most privileges and access to privileged resources after 1840Sstevel@tonic-gate user authentication succeeds. Such an implementation would make 1850Sstevel@tonic-gate some privileges, such as PRIV_PROC_SETID, available to any attacker 1860Sstevel@tonic-gate that successfully exploited a security bug in the ssh server. 1870Sstevel@tonic-gate 1880Sstevel@tonic-gate But such an implementation would also have to retain access to 1890Sstevel@tonic-gate resources needed for authenticating the server, which, as described 1900Sstevel@tonic-gate above, can be used to impersonate the server, in some cases with 1910Sstevel@tonic-gate ease. 1920Sstevel@tonic-gate 1930Sstevel@tonic-gate 194*7574SJan.Pechanec@Sun.COM4. OpenSSH's Privilege Separation 1950Sstevel@tonic-gate 1960Sstevel@tonic-gate The OpenSSH privilege separation model is quite complex. 1970Sstevel@tonic-gate 1980Sstevel@tonic-gate It consists of a monitor, which retains all privileges and access to 1990Sstevel@tonic-gate privileged resources, and two processes which run with much less 2000Sstevel@tonic-gate privilege: one process running as a special user, "sshd," for 2010Sstevel@tonic-gate hosting all phases of the SSH protocols up to and including 2020Sstevel@tonic-gate authentication, and one process running as the actual user that logs 2030Sstevel@tonic-gate in and which hosts all phases of the SSH protocols post-user- 2040Sstevel@tonic-gate authentication. 2050Sstevel@tonic-gate 2060Sstevel@tonic-gate The monitor and its companion processes speak a private protocol 2070Sstevel@tonic-gate over IPC. This protocol is intended to be smaller and simpler than 2080Sstevel@tonic-gate the SSH wire protocols. 2090Sstevel@tonic-gate 2100Sstevel@tonic-gate In practice the OpenSSH monitor protocols relating to user 2110Sstevel@tonic-gate authentication are neither smaller nor simpler than the SSH user 2120Sstevel@tonic-gate authentication protocols; and though they are different they also 2130Sstevel@tonic-gate transport much the same data, including RSA/DSA signatures, 2140Sstevel@tonic-gate usernames, PAM conversations, and GSS-API context and MIC tokens. 2150Sstevel@tonic-gate 2160Sstevel@tonic-gate The key exchange protocols have been broken down into their 2170Sstevel@tonic-gate essentials and the monitor serves only services such as signing 2180Sstevel@tonic-gate server replies with private host keys. 2190Sstevel@tonic-gate 2200Sstevel@tonic-gate Note also that the OpenSSH monitor protocol uses the same encodings 2210Sstevel@tonic-gate as the SSH protocols and uses the same implementation of those 2220Sstevel@tonic-gate encodings. 2230Sstevel@tonic-gate 2240Sstevel@tonic-gate 2250Sstevel@tonic-gate5. SUNWssh's Alternative Privilege Separation 2260Sstevel@tonic-gate 2270Sstevel@tonic-gate The Sun Microsystems ssh team believes that the OpenSSH team has 2280Sstevel@tonic-gate reached the point of diminishing returns in attempting to separate 2290Sstevel@tonic-gate processing of the user authentication protocols and that the OpenSSH 2300Sstevel@tonic-gate approach to privilege separation of the key exchange protocols has 2310Sstevel@tonic-gate led to a situation in which the monitor acts as an oracle, willing 2320Sstevel@tonic-gate to sign anything provided by the unprivileged processes that talk to 2330Sstevel@tonic-gate it. 2340Sstevel@tonic-gate 2350Sstevel@tonic-gate The Sun ssh team proposes a somewhat different privilege separation 2360Sstevel@tonic-gate implementation that shares with the OpenSSH model the goal of 2370Sstevel@tonic-gate minimizing and simplifying the protocol spoken by the monitor, but 2380Sstevel@tonic-gate little source code. 2390Sstevel@tonic-gate 2400Sstevel@tonic-gate We eschew any temptation to apply the privilege separation concept 2410Sstevel@tonic-gate to the version negotiation, initial key exchange and user 2420Sstevel@tonic-gate authentication phases of the ssh protocols (but see section 7). 2430Sstevel@tonic-gate 2440Sstevel@tonic-gate Instead we focus on separating processing of auditing, record 2450Sstevel@tonic-gate keeping and re-keying from processing of the session protocols. We 2460Sstevel@tonic-gate also wish to avoid creating any oracles in the monitor. 2470Sstevel@tonic-gate 2480Sstevel@tonic-gate This approach allows us to have a very simple monitor protocol. Our 2490Sstevel@tonic-gate monitor protocol consists of the following operations: 2500Sstevel@tonic-gate 2510Sstevel@tonic-gate - record a new pseudo-terminal session 2520Sstevel@tonic-gate - record the end of a pseudo-terminal session 2530Sstevel@tonic-gate - process a re-key protocol messages 2540Sstevel@tonic-gate - get keys negotiated during re-keying to the session process to it 2550Sstevel@tonic-gate can use them 2560Sstevel@tonic-gate 2570Sstevel@tonic-gate Logout auditing is done when the session process dies and so does 2580Sstevel@tonic-gate not require a monitor protocol message. 2590Sstevel@tonic-gate 2600Sstevel@tonic-gate By processing all re-key protocol messages in the monitor we prevent 2610Sstevel@tonic-gate the creation of oracles in the monitor. This is so because the 2620Sstevel@tonic-gate monitor signs only material which it has generated and over which an 2630Sstevel@tonic-gate attacker would have little influence (through the attackers offered 2640Sstevel@tonic-gate DH public key, for example). 2650Sstevel@tonic-gate 2660Sstevel@tonic-gate Odds and ends: 2670Sstevel@tonic-gate 2680Sstevel@tonic-gate - If the monitor receives SIGHUP, SIGTERM or SIGINT it will call 2690Sstevel@tonic-gate fatal_cleanup(), and thence will forcibly shutdown(3SOCKET) the 2700Sstevel@tonic-gate ssh connection socket, causing its child to exit, and audit a 2710Sstevel@tonic-gate logout. 2720Sstevel@tonic-gate 2730Sstevel@tonic-gate - The monitor does not attempt to update utmpx/wtmpx independently 2740Sstevel@tonic-gate of its child -- it depends on the child asking it to. 2750Sstevel@tonic-gate 2760Sstevel@tonic-gate - The child now is unable to chown() ptys back to root. That's Ok, 2770Sstevel@tonic-gate other services on Solaris do the same and everything still works 2780Sstevel@tonic-gate because of grantpt(3C). 2790Sstevel@tonic-gate 280*7574SJan.Pechanec@Sun.COM - The sshd server process (the one that will become a monitor) 281*7574SJan.Pechanec@Sun.COM forks a child process before the key exchange starts. The reason 282*7574SJan.Pechanec@Sun.COM for it is that if we forked after that we would end up using 283*7574SJan.Pechanec@Sun.COM PKCS#11 sessions initialized in the monitor unless 284*7574SJan.Pechanec@Sun.COM UseOpenSSLEngine was explicitly set to 'no'. Using any existing 285*7574SJan.Pechanec@Sun.COM PKCS#11 sessions or object handles over fork is what the PKCS#11 286*7574SJan.Pechanec@Sun.COM standard explicitly prohibits. To solve that, we would have to 287*7574SJan.Pechanec@Sun.COM rekey before fork and then newly initialize the engine in the 288*7574SJan.Pechanec@Sun.COM child, together with the new crypto contexts initialized with the 289*7574SJan.Pechanec@Sun.COM keys produced by the key re-exchange. And, that wouldn't help in 290*7574SJan.Pechanec@Sun.COM situations where the client does not support rekeying which also 291*7574SJan.Pechanec@Sun.COM includes the whole protocol version 1. The pre-fork solution is 292*7574SJan.Pechanec@Sun.COM simpler and also much faster. So, the key exchange and 293*7574SJan.Pechanec@Sun.COM authentication is fully done in the child server process while 294*7574SJan.Pechanec@Sun.COM the monitor waits aside to read the authentication context that 295*7574SJan.Pechanec@Sun.COM is needed for further operation. The child drops privileges after 296*7574SJan.Pechanec@Sun.COM the authentication finishes. 297*7574SJan.Pechanec@Sun.COM 298*7574SJan.Pechanec@Sun.COM With the ssh client, the situation is slightly more complicated. 299*7574SJan.Pechanec@Sun.COM Given the fact that the user can request to go to the background 300*7574SJan.Pechanec@Sun.COM during the connection using the ~& sequence we must be prepared 301*7574SJan.Pechanec@Sun.COM to rekey before forking, to reinitialize the engine in the child 302*7574SJan.Pechanec@Sun.COM after that, and then set the new crypto contexts with the new 303*7574SJan.Pechanec@Sun.COM keys. If the server we are communicating with does not support 304*7574SJan.Pechanec@Sun.COM rekeying we will not use the engine at all. We expect this 305*7574SJan.Pechanec@Sun.COM situation to be extremely rare and will not offer any workaround 306*7574SJan.Pechanec@Sun.COM for that. This also includes the protocol version 1. However, 307*7574SJan.Pechanec@Sun.COM this version is already considered obsolete and should not be used 308*7574SJan.Pechanec@Sun.COM if possible. 3090Sstevel@tonic-gate 3100Sstevel@tonic-gate6. Comparison of the OpenSSH and SUNWssh PrivSep Models 3110Sstevel@tonic-gate 3120Sstevel@tonic-gate The OpenSSH server involves three processes which we will term 3130Sstevel@tonic-gate "pre-session," "session" and "monitor." 3140Sstevel@tonic-gate 3150Sstevel@tonic-gate The OpenSSH pre-session process implements: 3160Sstevel@tonic-gate 3170Sstevel@tonic-gate - the ssh version string exchange 3180Sstevel@tonic-gate - the ssh message encoding/decoding 3190Sstevel@tonic-gate - most of the initial key exchange protocols 3200Sstevel@tonic-gate - transport protection 3210Sstevel@tonic-gate - part of the user authentication protocols 3220Sstevel@tonic-gate 3230Sstevel@tonic-gate The OpenSSH session process implements: 3240Sstevel@tonic-gate 3250Sstevel@tonic-gate - the ssh message encoding/decoding 3260Sstevel@tonic-gate - transport protection 3270Sstevel@tonic-gate - most of the re-keying protocols 3280Sstevel@tonic-gate - the session protocols 3290Sstevel@tonic-gate 3300Sstevel@tonic-gate The OpenSSH monitor process implements: 3310Sstevel@tonic-gate 3320Sstevel@tonic-gate - the ssh message encoding/decoding 3330Sstevel@tonic-gate - parts of the key exchange and re-key protocols (primarily signing 3340Sstevel@tonic-gate of server replies with host private keys) 3350Sstevel@tonic-gate - most of the user authentication protocols, specifically: 3360Sstevel@tonic-gate 3370Sstevel@tonic-gate - evaluation of ~/.ssh/authorized_keys (for pubkey userauth) 3380Sstevel@tonic-gate - evaluation of known hosts files (for hostbased userauth) 3390Sstevel@tonic-gate - evaluation of .shosts/.rhosts files (for hostbased userauth) 3400Sstevel@tonic-gate - verification of signatures w/ public keys (pubkey, hostbased) 3410Sstevel@tonic-gate - PAM API calls, conversation function 3420Sstevel@tonic-gate - GSS-API calls 3430Sstevel@tonic-gate 3440Sstevel@tonic-gate Note that any vulnerabilities in the parsing of authorized_keys, 3450Sstevel@tonic-gate known hosts and .shosts/rhosts files are as exploitable in the 3460Sstevel@tonic-gate monitor as in a server w/o privilege separation. 3470Sstevel@tonic-gate 3480Sstevel@tonic-gate Similarly for any vulnerabilities in PAM modules and GSS-API 3490Sstevel@tonic-gate mechanisms. 3500Sstevel@tonic-gate 3510Sstevel@tonic-gate The SUNWssh server involves two processes which we will term 3520Sstevel@tonic-gate "session" and "monitor." 3530Sstevel@tonic-gate 3540Sstevel@tonic-gate The SUNWssh monitor process implements: 3550Sstevel@tonic-gate 3560Sstevel@tonic-gate - the ssh version string exchange 3570Sstevel@tonic-gate - the ssh message encoding/decoding 3580Sstevel@tonic-gate - transport protection 3590Sstevel@tonic-gate - all of the key exchange and re-key protocols 3600Sstevel@tonic-gate - all of the user authentication protocols 3610Sstevel@tonic-gate 3620Sstevel@tonic-gate The SUNWssh session process implements: 3630Sstevel@tonic-gate 3640Sstevel@tonic-gate - the ssh message encoding/decoding 3650Sstevel@tonic-gate - transport protection 3660Sstevel@tonic-gate - the session protocols 3670Sstevel@tonic-gate 3680Sstevel@tonic-gate Obviously all of these processes also implement their side of the 3690Sstevel@tonic-gate monitor protocols. 3700Sstevel@tonic-gate 3710Sstevel@tonic-gate The OpenSSH 3.5p1 monitor protocol, on Solaris, has approximately 20 3720Sstevel@tonic-gate monitor request and corresponding response messages. 3730Sstevel@tonic-gate 374*7574SJan.Pechanec@Sun.COM The SUNWssh monitor protocol has 5 monitor request and response 3750Sstevel@tonic-gate messages; additionally, the monitor processes standard re-key 3760Sstevel@tonic-gate messages (but note: the monitor and the session process IPC is 3770Sstevel@tonic-gate completely unencrypted), which amounts to about 14 more messages 3780Sstevel@tonic-gate altogether. 3790Sstevel@tonic-gate 3800Sstevel@tonic-gate Much of the OpenSSH monitor protocol is a variation of the 3810Sstevel@tonic-gate on-the-wire ssh protocols, with some contents re-packaging. We 3820Sstevel@tonic-gate believe this does not afford the monitor much additional, if any 3830Sstevel@tonic-gate protection from attacks in the key exchange and user authentication 3840Sstevel@tonic-gate protocols. 3850Sstevel@tonic-gate 3860Sstevel@tonic-gate The re-packaging that is done in the OpenSSH monitor protocol is 3870Sstevel@tonic-gate risky business. By separating the act of signing some blob of data 3880Sstevel@tonic-gate from computing that blob of data one can create an oracle; this is 3890Sstevel@tonic-gate exactly what happened in the OpenSSH case. 3900Sstevel@tonic-gate 3910Sstevel@tonic-gate As you can see in the next section, the SUNWssh privilege separation 3920Sstevel@tonic-gate could evolve somewhat in the OpenSSH direction by saving the monitor 3930Sstevel@tonic-gate all transport protection work, but we cannot save the monitor much, 3940Sstevel@tonic-gate if any work relating to authentication or key exchange. 3950Sstevel@tonic-gate 3960Sstevel@tonic-gate 3970Sstevel@tonic-gate7. Future Directions 3980Sstevel@tonic-gate 3990Sstevel@tonic-gate The SUNWssh server privilege separation implementation could stand 4000Sstevel@tonic-gate several improvements. 4010Sstevel@tonic-gate 4020Sstevel@tonic-gate The first improvement would be to have a single system-wide monitor. 4030Sstevel@tonic-gate This would reduce resource consumption. The work needed to 4040Sstevel@tonic-gate implement such an enhancement is very similar to the work needed to 4050Sstevel@tonic-gate produce an SSH API and library, and it is not trivial. If this is 4060Sstevel@tonic-gate not done then at least dropping PRIV_PROC_SETID and instead setting 4070Sstevel@tonic-gate the saved-set-user-id in the monitor to that of the logged in user 4080Sstevel@tonic-gate would be nice. 4090Sstevel@tonic-gate 4100Sstevel@tonic-gate The second enhancement would be to add a "none" host key algorithm 4110Sstevel@tonic-gate to SSHv2 and a corresponding option in SUNWssh to disallow re-keying 4120Sstevel@tonic-gate with any other host key algorithm. This would allow customers to 4130Sstevel@tonic-gate configure their server and monitor so that no re-key protocol 4140Sstevel@tonic-gate messages need be processed by the monitor. 4150Sstevel@tonic-gate 4160Sstevel@tonic-gate A third enhancement would be to enhance the GSS-API mechanisms to 4170Sstevel@tonic-gate require fewer privileges. In practice this means overhauling the 4180Sstevel@tonic-gate Kerberos V mechanism's replay cache. This would allow the monitor 4190Sstevel@tonic-gate to run with fewer privileges. 4200Sstevel@tonic-gate 4210Sstevel@tonic-gate Further, even without improving the Kerberos V mechanism's replay 4220Sstevel@tonic-gate cache it should be possible to drop at least PRIV_PROC_FORK/EXEC/ 4230Sstevel@tonic-gate SESSION. 4240Sstevel@tonic-gate 4250Sstevel@tonic-gate A fourth enhancement would to have the unprivileged process handle 4260Sstevel@tonic-gate all transport protection and proxy to the monitor all key exchange 4270Sstevel@tonic-gate and user authentication protocol messages. This is a variation on 4280Sstevel@tonic-gate the OpenSSH model, but without the re-packaging of ssh message 4290Sstevel@tonic-gate contents seen there. After authentication succeeds the monitor 4300Sstevel@tonic-gate could either change the unprivileged process' credentials (as can be 4310Sstevel@tonic-gate done with ppriv(1) or the unprivileged process would, as in OpenSSH, 4320Sstevel@tonic-gate pass the session keys/IVs/keystate to the monitor which would then 4330Sstevel@tonic-gate pass them to a new process, the session process, that would then run 4340Sstevel@tonic-gate as the logged in user. 4350Sstevel@tonic-gate 4360Sstevel@tonic-gate 4370Sstevel@tonic-gate8. Guide to the AltPrivSep Source Code 4380Sstevel@tonic-gate 4390Sstevel@tonic-gate 4400Sstevel@tonic-gate First, a brief introduction to the SUNWssh/OpenSSH source code. 4410Sstevel@tonic-gate 4420Sstevel@tonic-gate The source code is organized as follows: 4430Sstevel@tonic-gate 4440Sstevel@tonic-gate $SRC/cmd/ssh/etc/ 4450Sstevel@tonic-gate | 4460Sstevel@tonic-gate +-> config files 4470Sstevel@tonic-gate 4480Sstevel@tonic-gate $SRC/cmd/ssh/include/ 4490Sstevel@tonic-gate | 4500Sstevel@tonic-gate +-> header files (note: none are installed/shipped) 4510Sstevel@tonic-gate 4520Sstevel@tonic-gate $SRC/cmd/ssh/libopenbsd-compat/common/ 4530Sstevel@tonic-gate | 4540Sstevel@tonic-gate +-> misc. portability source code 4550Sstevel@tonic-gate 4560Sstevel@tonic-gate $SRC/cmd/ssh/libssh/common/ 4570Sstevel@tonic-gate | 4580Sstevel@tonic-gate +-> implementation of encoding, transport protection, 4590Sstevel@tonic-gate various wrappers around cryptography, the key exchange 4600Sstevel@tonic-gate and host authentication protocols, the session 4610Sstevel@tonic-gate protocols, and misc. other code 4620Sstevel@tonic-gate 4630Sstevel@tonic-gate cipher.c 4640Sstevel@tonic-gate mac.c 4650Sstevel@tonic-gate compress.c 4660Sstevel@tonic-gate packet.c 4670Sstevel@tonic-gate | 4680Sstevel@tonic-gate +-> transport protocol 4690Sstevel@tonic-gate 4700Sstevel@tonic-gate buffer.c 4710Sstevel@tonic-gate bufaux.c 4720Sstevel@tonic-gate | 4730Sstevel@tonic-gate +-> encoding 4740Sstevel@tonic-gate 4750Sstevel@tonic-gate channels.c 4760Sstevel@tonic-gate nchan.c 4770Sstevel@tonic-gate | 4780Sstevel@tonic-gate +-> session protocol 4790Sstevel@tonic-gate 4800Sstevel@tonic-gate kex.c 4810Sstevel@tonic-gate kexdh.c 4820Sstevel@tonic-gate kexgex.c 4830Sstevel@tonic-gate | 4840Sstevel@tonic-gate +-> key exchange/re-key code common to ssh and sshd 4850Sstevel@tonic-gate 4860Sstevel@tonic-gate kexdhs.c 4870Sstevel@tonic-gate kexgexs.c 4880Sstevel@tonic-gate kexgsss.c 4890Sstevel@tonic-gate | 4900Sstevel@tonic-gate +-> key exchange/re-key code (server only) 4910Sstevel@tonic-gate 4920Sstevel@tonic-gate kexdhc.c 4930Sstevel@tonic-gate kexgexc.c 4940Sstevel@tonic-gate kexgssc.c 4950Sstevel@tonic-gate | 4960Sstevel@tonic-gate +-> key exchange/re-key code (client only) 4970Sstevel@tonic-gate 4980Sstevel@tonic-gate dh.c 4990Sstevel@tonic-gate rsa.c 5000Sstevel@tonic-gate mpaux.c 5010Sstevel@tonic-gate ssh-rsa.c 5020Sstevel@tonic-gate ssh-dss.c 5030Sstevel@tonic-gate ssh-gss.c 5040Sstevel@tonic-gate | 5050Sstevel@tonic-gate +-> crypto wrappers/utilities 5060Sstevel@tonic-gate 5070Sstevel@tonic-gate log.c 5080Sstevel@tonic-gate | 5090Sstevel@tonic-gate +-> logging, including debug logging, on stderr or 5100Sstevel@tonic-gate syslog 5110Sstevel@tonic-gate 5120Sstevel@tonic-gate 5130Sstevel@tonic-gate $SRC/cmd/ssh/ssh/ 5140Sstevel@tonic-gate | 5150Sstevel@tonic-gate +-> ssh(1) 5160Sstevel@tonic-gate 5170Sstevel@tonic-gate $SRC/cmd/ssh/sshd/ 5180Sstevel@tonic-gate | 5190Sstevel@tonic-gate +-> sshd(1M), including auditing, implementation of user 5200Sstevel@tonic-gate authentication and the OpenSSH and SUNWssh monitors 5210Sstevel@tonic-gate 5220Sstevel@tonic-gate sshd.c 5230Sstevel@tonic-gate | 5240Sstevel@tonic-gate +-> main() 5250Sstevel@tonic-gate 5260Sstevel@tonic-gate auth*.c 5270Sstevel@tonic-gate | 5280Sstevel@tonic-gate +-> user authentication 5290Sstevel@tonic-gate 5300Sstevel@tonic-gate serverloop.c 5310Sstevel@tonic-gate session.c 5320Sstevel@tonic-gate | 5330Sstevel@tonic-gate +-> session protocols 5340Sstevel@tonic-gate 5350Sstevel@tonic-gate bsmaudit.[ch] 5360Sstevel@tonic-gate sshlogin.c 5370Sstevel@tonic-gate loginrec.c 5380Sstevel@tonic-gate | 5390Sstevel@tonic-gate +-> auditing and record-keeping 5400Sstevel@tonic-gate 5410Sstevel@tonic-gate $SRC/cmd/ssh/<misc commands>/ 5420Sstevel@tonic-gate | 5430Sstevel@tonic-gate +-> scp, sftp, sftp-server, ssh-agent, ssh-add, ... 5440Sstevel@tonic-gate 5450Sstevel@tonic-gate 5460Sstevel@tonic-gate The SUNWssh altprivsep adds two new source files: 5470Sstevel@tonic-gate 5480Sstevel@tonic-gate $SRC/cmd/ssh/include/altprivsep.h 5490Sstevel@tonic-gate $SRC/cmd/ssh/sshd/altprivsep.c 5500Sstevel@tonic-gate | 5510Sstevel@tonic-gate +-> monitor start routine, altprivsep_packet_*() routines 5520Sstevel@tonic-gate for communication with the monitor, routines to help 5530Sstevel@tonic-gate with key exchanges, service procedures for the monitor, 5540Sstevel@tonic-gate etc... 5550Sstevel@tonic-gate 5560Sstevel@tonic-gate and modifies the following: 5570Sstevel@tonic-gate 5580Sstevel@tonic-gate $SRC/cmd/ssh/include/config.h 5590Sstevel@tonic-gate | 5600Sstevel@tonic-gate +> adds cpp define "ALTPRIVSEP" 5610Sstevel@tonic-gate 5620Sstevel@tonic-gate $SRC/cmd/ssh/include/ssh2.h 5630Sstevel@tonic-gate | 5640Sstevel@tonic-gate +-> adds private message type "SSH2_PRIV_MSG_ALTPRIVSEP" (254) 5650Sstevel@tonic-gate 5660Sstevel@tonic-gate $SRC/cmd/ssh/include/packet.h 5670Sstevel@tonic-gate | 5680Sstevel@tonic-gate +-> adds prototypes for several simple utility functions, 5690Sstevel@tonic-gate some of which are specifically meant to avoid having to 5700Sstevel@tonic-gate link altprivsep.c into ssh(1) 5710Sstevel@tonic-gate 5720Sstevel@tonic-gate $SRC/cmd/ssh/libssh/common/kex.c 5730Sstevel@tonic-gate $SRC/cmd/ssh/libssh/common/packet.c 5740Sstevel@tonic-gate | 5750Sstevel@tonic-gate +-> implements the hooks needed to proxy re-key messages 5760Sstevel@tonic-gate to/from the monitor 5770Sstevel@tonic-gate 5780Sstevel@tonic-gate $SRC/cmd/ssh/sshd/Makefile 5790Sstevel@tonic-gate | 5800Sstevel@tonic-gate +-> adds altprivsep.o to list of objects linked into sshd(1M) 5810Sstevel@tonic-gate 5820Sstevel@tonic-gate $SRC/cmd/ssh/sshd/serverloop.c 5830Sstevel@tonic-gate | 5840Sstevel@tonic-gate +-> adds an event loop for the monitor 5850Sstevel@tonic-gate modifies the usual event loops for SSHv2 5860Sstevel@tonic-gate 5870Sstevel@tonic-gate $SRC/cmd/ssh/sshd/session.c 5880Sstevel@tonic-gate | 5890Sstevel@tonic-gate +-> modifies do_login() and session_pty_cleanup2() to call 5900Sstevel@tonic-gate altprivsep_record_login/logout() instead of 5910Sstevel@tonic-gate record_login/logout(). 5920Sstevel@tonic-gate 5930Sstevel@tonic-gate modifies do_exec_pty() so that the server waits for the 5940Sstevel@tonic-gate call to altprivsep_record_login() in child process to 5950Sstevel@tonic-gate complete before returning so that the server and the 5960Sstevel@tonic-gate child processes do not compete for monitor IPC I/O. 5970Sstevel@tonic-gate 5980Sstevel@tonic-gate $SRC/cmd/ssh/include/log.h 5990Sstevel@tonic-gate $SRC/cmd/ssh/libssh/common/log.c 6000Sstevel@tonic-gate | 6010Sstevel@tonic-gate +-> adds an internal interface, set_log_txt_prefix() so that 6020Sstevel@tonic-gate the monitor's debug and log messages get prefixed with a 6030Sstevel@tonic-gate string ("monitor ") that indicates they are from the 6040Sstevel@tonic-gate monitor 6050Sstevel@tonic-gate 6060Sstevel@tonic-gate $SRC/cmd/ssh/sshd/sshd.c 6070Sstevel@tonic-gate | 6080Sstevel@tonic-gate +-> modifies the body of code that follows the user 6090Sstevel@tonic-gate authentication phase of the ssh protocols so as to start 6100Sstevel@tonic-gate the monitor and move the relevant code into the monitor 6110Sstevel@tonic-gate or session processes as appropriate while dropping 6120Sstevel@tonic-gate privileges and access to privileged resources in the 6130Sstevel@tonic-gate session process 6140Sstevel@tonic-gate 6150Sstevel@tonic-gate The monitor uses the packet.h interfaces to communicate with the 6160Sstevel@tonic-gate session process as though it were its ssh client peer, but always 6170Sstevel@tonic-gate uses the "none" cipher, mac and compression algorithms and installs 6180Sstevel@tonic-gate even handlers only for the relevant key exchange messages and the 6190Sstevel@tonic-gate private monitor message used for the other monitor services. 6200Sstevel@tonic-gate 6210Sstevel@tonic-gate The monitor serves the following services: 6220Sstevel@tonic-gate 6230Sstevel@tonic-gate - APS_MSG_NEWKEYS_REQ -> used to obtain keys/IVs after re-keys 6240Sstevel@tonic-gate - APS_MSG_RECORD_LOGIN -> used to update utmpx/wtmpx 6250Sstevel@tonic-gate - APS_MSG_RECORD_LOGOUT -> used to update utmpx/wtmpx 6260Sstevel@tonic-gate 6270Sstevel@tonic-gate The session and monitor processes communicate over a pipe. 6280Sstevel@tonic-gate 6290Sstevel@tonic-gate All monitor IPC I/O from the session process is blocking (though the 6300Sstevel@tonic-gate pipe is set to non-blocking I/O). The monitor protocol is entirely 6310Sstevel@tonic-gate synchronous and relies on the re-key protocols being entirely 6320Sstevel@tonic-gate synchronous also (which they are, unlike the session protocols). 6330Sstevel@tonic-gate 6340Sstevel@tonic-gate The kex.c and packet.c files are minimally modified, primarily to 6350Sstevel@tonic-gate prevent the monitor from handling SSH_MSG_NEWKEYS messages as a 6360Sstevel@tonic-gate normal ssh server should, instead letting the session process 6370Sstevel@tonic-gate process SSH_MSG_NEWKEYS messages by requesting the new keys 6380Sstevel@tonic-gate negotiated with client from the monitor. 6390Sstevel@tonic-gate 6400Sstevel@tonic-gate Note that for SSHv1 no on-the-wire messages are processed by the 6410Sstevel@tonic-gate monitor after authentication. In fact, the monitor thinks it's 6425562Sjp161948 running SSHv2, even if the on-the-wire protocol is v1. 6430Sstevel@tonic-gate 6440Sstevel@tonic-gate 6450Sstevel@tonic-gateA. References 6460Sstevel@tonic-gate 6470Sstevel@tonic-gate The IETF SECSH Working Group: 6480Sstevel@tonic-gate 6490Sstevel@tonic-gate http://www.ietf.org/html.charters/secsh-charter.html 6500Sstevel@tonic-gate 6510Sstevel@tonic-gate The SSHv2 architecture, assigned numbers: 6520Sstevel@tonic-gate 6530Sstevel@tonic-gate http://www.ietf.org/internet-drafts/draft-ietf-secsh-architecture-16.txt 6540Sstevel@tonic-gate http://www.ietf.org/internet-drafts/draft-ietf-secsh-assignednumbers-06.txt 6550Sstevel@tonic-gate 6560Sstevel@tonic-gate New cipher modes for SSHv2: 6570Sstevel@tonic-gate 6580Sstevel@tonic-gate http://www.ietf.org/internet-drafts/draft-ietf-secsh-newmodes-02.txt 6590Sstevel@tonic-gate 6600Sstevel@tonic-gate The SSHv2 "transport," including initial key exchange and re-key 6610Sstevel@tonic-gate protocols, but excluding negotiable DH group size and GSS-API-based 6620Sstevel@tonic-gate key exchange: 6630Sstevel@tonic-gate 6640Sstevel@tonic-gate http://www.ietf.org/internet-drafts/draft-ietf-secsh-transport-18.txt 6650Sstevel@tonic-gate 6660Sstevel@tonic-gate Additional key exchange protocols for SSHv2: 6670Sstevel@tonic-gate 6680Sstevel@tonic-gate http://www.ietf.org/internet-drafts/draft-ietf-secsh-gsskeyex-08.txt 6690Sstevel@tonic-gate http://www.ietf.org/internet-drafts/draft-ietf-secsh-dh-group-exchange-04.txt 6700Sstevel@tonic-gate 6710Sstevel@tonic-gate Base user authentication spec for SSHv2 (includes none, password, 6720Sstevel@tonic-gate pubkey and hostbased user authentication): 6730Sstevel@tonic-gate 6740Sstevel@tonic-gate http://www.ietf.org/internet-drafts/draft-ietf-secsh-userauth-21.txt 6750Sstevel@tonic-gate 6760Sstevel@tonic-gate SSHv2 user authentication using PAM-style prompting: 6770Sstevel@tonic-gate 6780Sstevel@tonic-gate http://www.ietf.org/internet-drafts/draft-ietf-secsh-auth-kbdinteract-06.txt 6790Sstevel@tonic-gate 6800Sstevel@tonic-gate SSHv2 user authentication using the GSS-API: 6810Sstevel@tonic-gate 6820Sstevel@tonic-gate http://www.ietf.org/internet-drafts/draft-ietf-secsh-gsskeyex-08.txt 6830Sstevel@tonic-gate 6840Sstevel@tonic-gate SSHv2 "session" protocol (i.e., the protocol used for pty sessions, 6850Sstevel@tonic-gate port forwarding, agent forwarding, X display forwarding, etc...): 6860Sstevel@tonic-gate 6870Sstevel@tonic-gate http://www.ietf.org/internet-drafts/draft-ietf-secsh-connect-19.txt 688