Feature #15053

Use PAM to increase SHA-512 password rounds

Added by cypherpunks 2017-12-14 02:52:48 . Updated 2019-03-07 12:18:08 .

Status:
Confirmed
Priority:
Low
Assignee:
cypherpunks
Category:
Target version:
Start date:
2017-12-14
Due date:
% Done:

0%

Feature Branch:
Type of work:
Research
Blueprint:

Starter:
0
Affected tool:
Deliverable for:

Description

The pam_unix module is responsible for managing Linux’s shadow passwords. By default, it does a single, salted SHA-512 hash on the administrator password, when one is set. It is well known that passwords should never be stored using a single cryptographic hash because of its speed. The recommended solution is to use a KDF like bcrypt or PBKDF2. However, glibc’s crypt(3) does not support either of these. Linux PAM gets around this by using multiple rounds of a hash to strengthen the password, but it is not enabled by default. It can be done by modifying the /etc/pam.d/system-auth file. For example:

--- /etc/pam.d/system-auth
+++ /etc/pam.d/system-auth
@@ -7 +7 @@
-password   required    pam_unix.so try_first_pass use_authtok nullok sha512 shadow
+password   required    pam_unix.so try_first_pass use_authtok nullok sha512 shadow rounds=1000000

Adding the rounds argument increases the number of hash iterations used by default when hashing a password. This results in the shadow file containing an extra field specifying the number of rounds. This is completely transparent to the user, and greatly increases the work factor required to crack the password. Tails should utilize this to further protect users against an adversary able to obtain this file, whether through physical access or through LPE.

The number of rounds determines how long it will take to generate the password hash. On a single Haswell i7 mobile core @ 2.80GHz, it takes slightly over half a second to perform one million SHA-512 rounds using PAM. Older processors may take longer. The number of rounds can be reduced if this proves to be an issue.


Subtasks


History

#1 Updated by cacahuatl 2017-12-14 23:11:42

> By default, it does a single, salted SHA-512 hash on the administrator password

This isn’t true, the default is 5000 rounds. See login.defs(5) under SHA_CRYPT_MIN_ROUNDS and /etc/login.def.

> Tails should utilize this to further protect users against an adversary able to obtain this file, whether through physical access or through LPE.

There are no passwords on Tails by default, unless you choose to set up an administrator password at the greeter. Even so, picking a strong password will always provide more protection than adding extra rounds of hashing will. You cannot simply add more rounds of hashing to make “hunter2” a strong password.

To defeat a local attacker guessing passwords at a login prompt, you’d be better served by setting FAIL_DELAY in /etc/login.defs to add a delay to every failed login attempt, while allowing normal users to login quickly. Anyone with the /etc/shadow file is already root and even if they weren’t, under the average use case gives them absolutely nothing of value for privilege escalation since there are no passwords.

#2 Updated by cypherpunks 2017-12-15 01:16:56

login.defs(5) is for systems that are not using PAM and is ignored otherwise (try upping the rounds in it and setting a new password - naturally no effect when PAM is in use). I don’t know if PAM uses the same default, but whether or not it does, 5000 is quite low now days.

I know that Tails does not use passwords by default, so this is only intended for the “administrator” password. While it would be nice if no one ever re-used passwords, the sad truth is that the administrator password itself, is likely valuable information to some attackers, regardless of whether or not they are already root.

#3 Updated by cacahuatl 2017-12-16 15:40:45

>5000 is quite low now days.

Again, adding more rounds will not make a weak password any stronger. A single round of salted SHA512 with a strong password will always provide more protection than a weak password and more rounds of SHA512.

>the sad truth is that the administrator password itself, is likely valuable information to some attackers, regardless of whether or not they are already root.

If the attacker is already root, they probably have a lot of easier ways to get this password. e.g. persisting by patching the Tails USB, running a software keylogger for the session and waiting for the user to type it, volatile memory forensics, etc.

I think this is a change that brings little advantage to an already risky use case, which would be better served by users picking strong, unique passphrases.

There is no shortcut to password security through more hashing.

#4 Updated by cypherpunks 2017-12-17 05:00:16

cacahuatl wrote:
> >5000 is quite low now days.
>
> Again, adding more rounds will not make a weak password any stronger. A single round of salted SHA512 with a strong password will always provide more protection than a weak password and more rounds of SHA512.

Strong passwords and slow KDFs are not mutually exclusive, and no trade-off is required.

A slow KDF doesn’t increase the shannon entropy present in the password, but it can be the difference between a password being cheap to crack and being completely impractical. A bad password that takes an hour to crack would instead take more than a hundred years on the same hardware. A password that takes a day to crack would instead take almost three millennia.

Take an adversary with the capability and willingness to perform a sustained attack against a single salted hash for ten years. If a sufficient password is defined as one which can hold up under these conditions, then without a slow KDF, a user must select a password which, at minimum, can hold up for ten years. With a slow KDF with a work multiplication factor of a million, the minimum requirement is one which can withstand such an attack for only six minutes. This means that a slow KDF is of limited effectiveness for protecting passwords that can stand up for less than six minutes, and is unnecessary for passwords which can already stand up for ten years. This is a large subset of users who’s passwords can be made effective.

> If the attacker is already root, they probably have a lot of easier ways to get this password. e.g. persisting by patching the Tails USB, running a software keylogger for the session and waiting for the user to type it, volatile memory forensics, etc.

A local attacker is not the only attacker in Tails’ threat model. As Tails does not boot with intel_iommu=on, it is vulnerable to evil busmastering, which is (usually) passive. Reading out memory is a lot easier than trying to hook and inject malicious handlers into the IDT. Tails’ threat model clearly includes physical attackers who cannot necessarily resort to keylogging, given that it takes effort to remove secrets from memory at reboot (see section 2.1.2 and 2.7.1 from the PELD specification).

> I think this is a change that brings little advantage to an already risky use case, which would be better served by users picking strong, unique passphrases.
>
> There is no shortcut to password security through more hashing.

I am aware of no methods to convince all Tails users to increase their password strength by six orders of magnitude. If people always picked strong passwords in the first place, we could just use MD5 for everything. :)


Some facts to be aware of:

  • The PELD threat model includes actors who gain unauthorized access but cannot rely on user interaction.
  • Users cannot be guaranteed to use passwords of ideal strength, and may share it across services.
  • Slow KDFs can increase a subset of passwords’ effectiveness to the point where attacks become infeasible.
  • Using PAM for a slow KDF is simple, easy to maintain, takes minimal configuration, and results in no UX issues.

These should all be either indisputable facts (e.g. adversarial assumptions from section 2.2 of PELD), or universally agreeable (e.g. the mathematical properties of a slow KDF). From that, it follows that this is proposal is a net positive change. While I agree with you in that it is not a universal solution to the issue of weak passwords and password reuse, I disagree that it does not provide a tangible benefit in the scope of the PELD threat model.

#5 Updated by cacahuatl 2017-12-17 18:43:07

The password is worthless if it’s unique to Tails, I.E., it’s not shared.

>2.1.2 Protection from data recovery after shutdown

The password is only stored in RAM, it is wiped after shutdown. That is covered.

>2.7.1 Memory recovery attacks

Hashing the password more times doesn’t prevent memory recovery attacks.

If the threat is that the password, once recovered, would be revealing to the users identity then using a unique password, no matter how strong, is an easy solution that requires no maintenance of patches by the Tails developers.

If your claim is true, that Tails users use weak passphrases, then more rounds in SHA512, bcrypt or pbkdf2 is infact no longer considered sufficient, see for example this recent paper https://www.cs.purdue.edu/homes/jblocki/papers/SP18EconomicsOfOfflinePasswordCracking.pdf

#6 Updated by intrigeri 2017-12-24 10:57:48

  • Status changed from New to Confirmed
  • Assignee set to cypherpunks
  • Priority changed from Normal to Low
  • Type of work changed from Code to Research

It looks like everyone here now agrees that the proposed change aims at protecting other/future reuse of the same, suboptimal password. It would improve the safety of a minority of Tails users, in quite specific cases. This does not mean we should not care, but let’s be clear that we won’t get anything more than that out of it.

I agree with cacahuatl that an adversary who got access to /etc/shadow has other means to get the plain password than reversing this hash. Now, whether these other attack vectors are doable / cheaper or not greatly depends on the situation, so it would not feel absurd to me to take steps in order to ensure that cracking /etc/shadow is never the weakest link.

Next steps for whoever wants to make this happen, seem to be:

  1. find out if there’s already been discussions about this in PAM upstream or in Debian: before we propose to change the default, we have to understand the rationale for the current state of things
  2. find out what’s the current default number of rounds if none is specified: is it 1?
  3. research what number of rounds would be good as the new (possibly per-platform?) default; this requires benchmarking various numbers of diverse hardware and defining a maximum acceptable delay for this operation

This does not seem Tails-specific to me so IMO whatever change we think would make sense should be applied in Debian, or even preferably in PAM upstream. The above steps are needed regardless of whether the change is proposed in Tails or upstream. Proposing these changes upstream will generate more (expert) feedback than discussing this here only, e.g. we might be told about issues with the proposal that we had not thought of ourselves. And then we won’t have to maintain a delta against Debian.

#7 Updated by cypherpunks 2018-06-04 05:11:46

intrigeri wrote:
> I agree with cacahuatl that an adversary who got access to /etc/shadow has other means to get the plain password than reversing this hash. Now, whether these other attack vectors are doable / cheaper or not greatly depends on the situation, so it would not feel absurd to me to take steps in order to ensure that cracking /etc/shadow is never the weakest link.

I wouldn’t say that’s true. You are assuming that all attackers are active and can mount attacks that require user involvement. In reality, the more likely threat model is someone’s laptop is ripped out of their hands, rooted (easy to do with the current splash screen setup by crashing the DE and entering a new root password), and the password hashes taken and attacked in order to gain plausible passwords for other services which the victim may be using. This has happened in the wild (not specifically for Tails).

> Next steps for whoever wants to make this happen, seem to be:
>
> # find out if there’s already been discussions about this in PAM upstream or in Debian: before we propose to change the default, we have to understand the rationale for the current state of things

Debian would not accept it upstream because Debian is designed to work on far more resource-constrained systems than Tails could ever work on. They did add a way for individual distros to tweak it, which is the PAM settings I have proposed to change. If you asked them to change their defaults, they would tell you that their defaults work on everything from supercomputers to embedded devices (Tails is neither and has a much more narrow spectrum of potential devices), and that your distro should change the defaults on their own. It’s being very picky to not only ask that Debian provide a configuration option, but also change to the defaults that would be ideal for laptops but would break embedded devices that could not even run Tor.

> # find out what’s the current default number of rounds if none is specified: is it 1?

I think it’s either 1 or 5000. I can’t recall. Both of those are far, far too low for modern standards (10,000 was the recommended minimum some time ago).

> # research what number of rounds would be good as the new (possibly per-platform?) default; this requires benchmarking various numbers of diverse hardware and defining a maximum acceptable delay for this operation

It would not be hard to do that. Even 50,000 rounds would be extremely quick even on the oldest Tails systems. It would not need to be per-platform unless you want to introduce additional complexity (would be nice to have a program benchmark how many hashes can be done in one second, then set that number of hashes as the default, but is unnecessary).

> This does not seem Tails-specific to me so IMO whatever change we think would make sense should be applied in Debian, or even preferably in PAM upstream. The above steps are needed regardless of whether the change is proposed in Tails or upstream. Proposing these changes upstream will generate more (expert) feedback than discussing this here only, e.g. we might be told about issues with the proposal that we had not thought of ourselves. And then we won’t have to maintain a delta against Debian.

It is extremely Tails-specific for reasons outlined above. Debian is designed to run on a far broader spectrum of devices. Tails will not ever run on machines with less than 128 MiB of memory or on routers with MIPS processors that will struggle with more than a few thousand iterations. The delta for changing the configuration is extremely small since Debian already provides a configuration option to tweak this. I see it as no different from doing what Tails is currently doing for numerous other configuration files.

#8 Updated by intrigeri 2018-06-04 06:01:42

> Debian would not accept it upstream because Debian is designed to work on far more resource-constrained systems than Tails could ever work on.

It’s true that Debian supports slow architectures but having architecture-specific settings is feasible and sometimes done in practice. So e.g. whatever setting would be good enough for Tails could be made the default in Debian on amd64.

#9 Updated by cypherpunks 2018-06-05 00:46:33

intrigeri wrote:
> > Debian would not accept it upstream because Debian is designed to work on far more resource-constrained systems than Tails could ever work on.
>
> It’s true that Debian supports slow architectures but having architecture-specific settings is feasible and sometimes done in practice. So e.g. whatever setting would be good enough for Tails could be made the default in Debian on amd64.

That still wouldn’t work because there are embedded x86-64 devices that could not ever run Tails and would be too weak to support Debian’s defaults. They would not accept such a change because they are extremely conservative in that sense. How is this different from changing sysctl settings? I mean the vm.mmap_rnd_bits was increased without any push to make it the default in Debian, even though arguably it would be fine on all architectures.

#10 Updated by intrigeri 2018-06-05 07:52:04

> That still wouldn’t work because there are embedded x86-64 devices that could not ever run Tails and would be too weak to support Debian’s defaults. They would not accept such a change because they are extremely conservative in that sense.

I feel that we’re speculating here. I’m sure both of us could find examples and counter-examples either way, but the reality is that it’s the maintainers’ call, and each might feel differently, so we won’t know for sure unless someone tries.

> How is this different from changing sysctl settings? I mean the vm.mmap_rnd_bits was increased without any push to make it the default in Debian, even though arguably it would be fine on all architectures.

Indeed, that’s blurry and there’s a fine line between what is worth diverging for and what should be done upstream. In the case at hand I feel the marginal benefit of the proposed change outweighs the marginal cost of implementing + QA’ing + maintaining it. Others might feel differently.

#11 Updated by cypherpunks 2018-06-06 02:34:05

intrigeri wrote:
> > How is this different from changing sysctl settings? I mean the vm.mmap_rnd_bits was increased without any push to make it the default in Debian, even though arguably it would be fine on all architectures.
>
> Indeed, that’s blurry and there’s a fine line between what is worth diverging for and what should be done upstream. In the case at hand I feel the marginal benefit of the proposed change outweighs the marginal cost of implementing + QA’ing + maintaining it. Others might feel differently.

I’m not aware of what possible implementation, QA, or maintenance costs there would be. It’s among the most trivial possible changes to PAM configuration. For implementation, it takes adding a single line to a configuration file, as outlined in the ticket. QA is unnecessary because it has already been done by the PAM authors. There are no extant bugs and it works as intended on the literally billions of devices that rely on it. And maintenance is not required unless the PAM syntax changes (it won’t), in which case we would have a lot more problems than we have now.

If this change required a heavy configuration update or adding our own PAM modules, I would completely agree. However this is not the case. Using, say, 100k iterations would not slow down even the slowest of devices. We could quibble over the perfect optimal value that is as large as feasibly possible while still just barely being tolerable for the slowest devices, but I don’t see that as necessary. Using an officially-recommended value (the 2016 “absolute minimum” from NIST is 10,000 iterations). It would be easy to do the math to get a high value that still takes a fraction of a second on the slowest hardware that will ever run Tails.

#12 Updated by intrigeri 2018-06-06 06:57:34

> I’m not aware of what possible implementation, QA, or maintenance costs there would be.

I understand this might not be very visible from your vantage point, but as someone who’s been maintaining Tails since 10 years, I can tell you these costs definitely exist. I’m pretty sure that debating this further won’t lead us anywhere interesting.

Next step: find out which number of iterations would work smoothly on the oldest hardware that can run a modern amd64 Debian, which is actually quite close (modulo RAM) to the oldest hardware that can run Tails. This should be tested in Tails in the Greeter, with sudo, the screen locker, and at least one app that uses polkit to get admin credentials. Once this data is gathered it can back a proposal brought to the maintainers of src:pam in Debian, ideally with a patch attached.

#13 Updated by cypherpunks 2018-06-07 03:59:15

I just asked a Debian developer who said they would not make the changes upstream because there are Debian systems with thousands of simultaneous users where PAM authentication may be automated, where a mere 500ms of authentication time could bring down the whole server. I don’t think I’ll be able to convince them otherwise.

#14 Updated by intrigeri 2018-06-07 05:52:07

> I just asked a Debian developer […]

Thanks for trying.

(And IMO next steps remain the same as the ones I’ve suggested in my previous comment.)

#15 Updated by cypherpunks 2018-06-07 13:17:49

intrigeri wrote:
> > I just asked a Debian developer […]
>
> Thanks for trying.
>
> (And IMO next steps remain the same as the ones I’ve suggested in my previous comment.)

Testing it on Greeter, sudo, etc? That I can do (though I thought it would have been part of the automated test suite to test those components, but I can do it anyway). I just can’t get it upstream in Debian unless their views change.

#16 Updated by intrigeri 2018-06-10 16:55:08

>> (And IMO next steps remain the same as the ones I’ve suggested in my previous comment.)

> Testing it on Greeter, sudo, etc?

Yes.

> That I can do

Great. What matters is also measuring :)

> (though I thought it would have been part of the automated test suite to test those components, but I can do it anyway).

The automated test suite does exercise these components but it won’t help us “find out which number of iterations would work smoothly on […] the oldest hardware that can run Tails”.

#17 Updated by Anonymous 2018-08-16 12:59:21

Ping?

#18 Updated by cypherpunks 2019-03-07 12:18:08

I’ve tested various round settings on a system with SMP disabled and which was underclocked to 400 MHz (or so). I did not find any performance issue with secure PAM settings, although the UI was almost unusably slow regardless (indicating that it was just barely capable of running Tails).