Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!swrinde!mips!carbon!stanford.edu!ATHENA.MIT.EDU!tytso From: tytso@ATHENA.MIT.EDU (Theodore Ts'o) Newsgroups: comp.protocols.kerberos Subject: Re: Verifying passwords without getting new tickets Message-ID: <9105170222.AA01914@tsx-11.MIT.EDU> Date: 17 May 91 02:22:45 GMT References: <1991May16.213433.28223@ncsu.edu> Sender: news@shelby.stanford.edu (USENET News System) Reply-To: tytso@athena.mit.edu Organization: Internet-USENET Gateway at Stanford University Lines: 71 Date: 16 May 91 21:34:33 GMT From: kctreima@eos.ncsu.edu (Kenneth C. Treimann) Organization: North Carolina State University Sender: owner-comp-protocols-kerberos@shelby.Stanford.EDU Reply-To: kctreima@eos.ncsu.edu (Kenneth C. Treimann) Hello, I'm new to this newsgroup, so be patient with me. Is there a way to verify a userid and password without getting a new ticket-granting-ticket? All I want to do is pass a name to a function, make sure that Kerberos knows the principal, prompt for the password, verify it, and return a yes or no type answer (or k_errno). I do NOT want to use krb_get_pw_in_tkt, because it replaces the existing tickets, and then I have to do another call to krb_get_pw_in_tkt to get a new ticket-granting-ticket for the user who was already logged in (unfortunately, this is what my program does now). DANGER WILL ROBINSON!!!!! If your site is relying on Kerberos to check passwords as you've described, your site has a huge large security hole. What you're doing is *NOT* sufficient for verifying a userid and password, even if you get a new ticket-granting-ticket. So the short answer is no --- getting a ticket-granting-ticket isn't even sufficient by itself. Consider the following scenario: you write a "ksu" program which prompts for a username and password and tries to get a ticket-granting-ticket to verify the password. Then if that username is in an access control list, it gives you a root shell. This program is vulnerable to attack in the following method: the attacker runs the ksu program, and enters a username which he knows is in the access control list. He then floods the port that ksu is using with faked-up replies which appear to come from the KDC, but which are really a fake set of credentials encrypted in a password of the attcker's choosing. The attacker then types the password which he choose, and the ksu program (having gotten one of the fake replies from the KDC) decrypts the reply using the password and gets something which looks like valid credentials, and so the ksu program will give the attack a root shell. This security "hole" comes from the misuse and misunderstanding of what it means to be able to successfully obtain a ticket granting ticket. Obviously, as the above scenario shows, merely obtaining a ticket granting ticket does not prove anything about the user's authenticity. You can only say something about the user's authenticity if you can successfully use those tickets to obtain service from a server. You see, in the above scenario, the fake "tickets" are useless because the attacker does not have any of the secrets known by the KDC. Thus, the first time anyone tried to use those tickets, they would be known to be fakes. The problem with the "ksu" program as designed above is that it never tried to use the ticket-granting-ticket. It merely assumed that possession of something which looked like a ticket-granting-ticket was good enough give someone a root shell. Kerberos was not designed to verify passwords; it was designed to authenticate clients to servers across a network. Anyone trying to use Kerberos for the first purpose has really voided their warranty..... There is one safe way of using Kerberos to verify passwords, but it requires that the program have access to a service key. (For example, the rcmd.hostname service key in /etc/srvtab.) The way to check if a password is valid is as follows: 1) request ticket-granting-tickets. 2) try to decrypt the ticket-granting tickets with the user's password. If it fails, error out. 3) Using the ticket-granting-tickets obtained in step 2, obtain credentials for rcmd.hostname. 4) Using the key for rcmd.hostname found in /etc/srvtab, verify that the session key stored in the rcmd.hostname ticket matches the session key in the credentials. If and only if all four steps are successful can you assume that the password is valid. - Ted