Sam Britt
Sam Britt

Reputation: 410

Why is `sudo` Slow When Password is Incorrect?

When I enter my password for superuser privileges or to log in to my Linux box, if I enter it correctly, it returns immediately, granting me access. However, if I make some typo, there is a long wait before it tells me my password is incorrect. Usually, I realize that I messed up long before the computer does.

Why is this the case? As I understand it, user passwords are encrypted and stored in /etc/shadow, so it seems like my input should just be encrypted and compared to what is in that file for my username---which would take roughly the same time whether I enter the correct password or not. Is there some algorithmic reason, like it has to check in a bunch of extra places before it can confirm that it is incorrect? Or maybe the system knows it's an incorrect password quickly, but has to do a lot of work to keep track of incorrect login attempts. Or maybe it's just trying to punish me for screwing up.

Upvotes: 15

Views: 1743

Answers (5)

Timmmm
Timmmm

Reputation: 96801

Ok I did some research and it turns it... there is no reason!

I believe how sudo works is:

  1. It loads libpam.so. libpam.so is just an ordinary library. No special permissions.
  2. It asks libpam, "is the password for the current user correct?".
  3. If libpam says "yes" then it runs the command as root (sudo is SUID so it can do that).

The delay is inserted by libpam. It's actually super super complicated how the delay is calculated - it's even randomised slightly. Some of the code is 25 years old so it's a bit hard to follow. I think the delay is triggered in pam_authenticate() where there's this code:

_pam_await_timer(pamh, retval);   /* if unsuccessful then wait now */

And the actual delay is somehow set by calls to pam_fail_delay(). That page has some helpful information including rationale:

It is often possible to attack an authentication scheme by exploiting the time it takes the scheme to deny access to an applicant user. In cases of short timeouts, it may prove possible to attempt a brute force dictionary attack -- with an automated process, the attacker tries all possible passwords to gain access to the system. In other cases, where individual failures can take measurable amounts of time (indicating the nature of the failure), an attacker can obtain useful information about the authentication process. These latter attacks make use of procedural delays that constitute a covert channel of useful information.

On my RHEL 8 system the delay is set using the fail delay PAM plugin. If you edit /etc/pam.d/system-auth then you see this line:

auth        required                                     pam_faildelay.so delay=2000000

Comment it out and the delays disappear! According to the docs this is a common config for local authentication and there's also password-auth for remote auth, so it should be 100% safe to remove this delay.

Some stuck-in-the-muds are probably screaming BuT lOcAl DiCtIoNaRy AtTaCkS!!1! at me right now. Don't listen to their squeals.

Recall how I said libpam.so is an ordinary library. It isn't SUID, so how does it actually check your password (since /etc/shadow is a thing now it can't just see the hash). The answer is it calls a helper binary that IS SUID. That is called unix_chckpwd, and it's probably on your PATH. If you run it it checks if stdin is a TTY and does some silly security theatre:

❯ unix_chkpwd 
This binary is not designed for running in this way
-- the system administrator has been informed

There's a 10 second wait at the end for literally no reason but to annoy you. I'm not joking:

sleep(10);  /* this should discourage/annoy the user */

Anyway, a thought that might be niggling at you now is "so if PAM is responsible for the delay and it's just a normal non-SUID library, how does it securely store access attempt times, and e.g. do exponential delays?"

Well... it doesn't. Don't want to wait for sudo's delay? You can just run a new instance of sudo. But you don't even need that because unix_chkpwd has this comment:

    /*
     * we establish that this program is running with non-tty stdin.
     * this is to discourage casual use. It does *NOT* prevent an
     * intruder from repeatedly running this program to determine the
     * password of the current user (brute force attack, but one for
     * which the attacker must already have gained access to the user's
     * account).
     */

The delay is 100% security theatre. It does nothing to stop local dictionary attacks.

I mean even if it did, if you have access to a local user's account it's trivial to get their password without cracking it.

So what have we learned?

  1. There's no point to sudo's delay.
  2. The security architecture of PAM is crazy.
  3. PAM itself is stateless so it actually can't do exponential delays. I client of PAM (e.g. sshd) could though.

So finally, why does this delay exist if it is totally pointless? My guess is a) it make people feel secure (look at all the replies in this question saying it improves security), and b) it does make sense for remote password-based authentication, so I guess they added the feature for that and then nobody bothered to turn it off for sudo?


Edit:

Some time after writing that I looked into fixing it properly. It turns out to be quite difficult. I wasn't totally right about libpam being stateless - there is a stateful plugin: pam_faillock which locks an account after N consecutive failed logins. But it's quite complicated, so I decided that the simplest solution would be to just lower the default 2 second delay to something less annoying: 0.5 seconds.

Way less annoying and doesn't really affect brute forcing (if 2s is insecure then 0.5s definitely is too). Here's the PR but it's been waiting almost 2 years now so I wouldn't hold your breath.

Upvotes: 3

Xeoncross
Xeoncross

Reputation: 57244

Console or SSH Login is slow too. Anything that requires a password is "slowed-down" to stop brute-force attacks.

Upvotes: 0

Jonathan Leffler
Jonathan Leffler

Reputation: 754480

The slow response from sudo when you enter an erroneous password is so that if you are mounting a crude brute force 'try and guess the password' attack with sudo, you are slowed down every time you guess wrong, so that the attack takes longer. Those who are using it legitimately have no cause for complaint. If you make a typo every once in a while, you won't mind. If you really can't type your own password, it might be time to change it to something (secure) that you can type.

Upvotes: 0

aelguindy
aelguindy

Reputation: 3711

I am not sure if this question is relevant here.. I am also not sure of the correctness of my answer but I think it's for security. Making it n times slower would mean that a bruteforce attack would take n times longer.

Upvotes: 0

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 726809

This is done totally on purpose: the reason for that is to make it impossible to guess a password using a dictionary attack.

Fast turn-around is crucial for a dictionary attack. Slowing down on incorrect passwords is a way to slow the attack to a crawl, making it impossible to execute in a meaningful time interval.

Upvotes: 10

Related Questions