Date: Sat, 1 Jul 2000 01:11:09 -0400 From: "Richard E. Silverman" <slade@SHORE.NET> Subject: Kerberos security vulnerability in SSH-1.2.27 To: BUGTRAQ@SECURITYFOCUS.COM I am writing to report a security bug in SSH 1.2.27. SOFTWARE AFFECTED: SSH 1.2.27 with Kerberos authentication support compiled in (i.e. "configure --with-kerberos5"). I have contacted SSH Communicators Security (http://www.ssh.com) about this, and they have just released ssh-1.2.28, which fixes this problem. OPERATING SYSTEMS: all those supported by the SSH release (many flavors of Unix) SYNOPSIS: When logging in a user, sshd sets the user's KRB5CCNAME environment variable to the value "none". If the user subsequently makes use of Kerberos in that login session (e.g. does a kinit), Kerberos tickets will be stored in a file named "none" in the current directory. This is inappropriate and presents significant risk of disclosure of the user's Kerberos tickets, via insecure file-sharing protocols such as NFS or SMB, or other methods. It is important to note that this bug occurs regardless of whether Kerberos authentication is actually being used for the current session; merely compiling in Kerberos support is sufficient to cause the problem. DETAILS: Kerberos tickets are sensitive information, and stealing them may allow an attacker to impersonate the legitimate user for the lifetime of the ticket. The ticket cache is normally kept on the local host in a directory set aside for such usage, e.g. /tmp. Placing the Kerberos ticket cache in the current directory is a serious problem. For example: * Upon login, the current directory the user's home directory, often an NFS-mounted filesystem. This means that tickets may be sent in the clear over the network via NFS. * Since the pathname ("none") is relative, tickets may be placed in unpredictable locations, depending on the user's actions. Even though Kerberos sets the protections of the ticket cache file restrictively, in this situation they might be placed, say, in a directory with an inherited ACL which gives read access to someone else, or on a removable medium. The problem is especially bad because the user may never notice it. As long as he or she stays in the same directory with the cache file, Kerberos will operate normally. Only careful reading of the output of klist, for example, will reveal the change. QUICK FIX: Change this: [sshd.c:4296] if (ticket) child_set_env(&env, &envsize, "KRB5CCNAME", ticket); to this: if (ticket && strcmp("none",ticket)) child_set_env(&env, &envsize, "KRB5CCNAME", ticket); FIX EXPLANATION: This bug arises from confusion in the source code about the value of this variable: [sshd.c:547] char *ticket = "none\0"; This variable holds file pathname to be used on the remote side for the ticket cache, if a forwarded Kerberos TGT has been obtained. There appears to be some inconsistency about how to interpret the value of this variable. In some places, the SSH source compares *ticket to the string "none" to determine whether a forwarded ticket is available; e.g.: [sshd.c:2691] #ifdef KERBEROS /* If you forwarded a ticket you get one shot for proper authentication. */ /* If tgt was passed unlink file */ if (ticket){ if (strcmp(ticket,"none")) /* ticket -> FILE:path */ unlink(ticket + 5); else ticket = NULL; } #endif /* KERBEROS */ But, setting and testing the pointer against the NULL value is also used. In particular, here: [sshd.c:4296] if (ticket) child_set_env(&env, &envsize, "KRB5CCNAME", ticket); It is possible for this line to be reached with the ticket variable still pointing to the string "none", which causes the problem. - Richard Silverman slade@shore.net