nuvious / pam-duress

A Pluggable Authentication Module (PAM) which allows the establishment of alternate passwords that can be used to perform actions to clear sensitive data, notify IT/Security staff, close off sensitive network connections, etc if a user is coerced into giving a threat actor a password.
GNU Lesser General Public License v3.0
1.33k stars 39 forks source link

Store duress password in unix crypt format #14

Closed rechner closed 3 months ago

rechner commented 3 years ago

https://github.com/nuvious/pam-duress/blob/30d7065e173d6062384387af10e74e8c1c138d48/src/duress.c#L193

Using the modular crypt(3) format from glibc instead of specifying a hash, will make this a bit more future-proof, storing passwords the same way as standard password authentication.

Artoria2e5 commented 3 years ago

The thing about the crypt format is that it’s not exactly open to having a salt that long — in this case the whole script. I guess storing the hash of the script there instead is an option; explicitly listing it will allow for knowing whether it’s the password or the script that’s wrong (related to #20, maybe?).

nuvious commented 3 years ago

The thing about the crypt format is that it’s not exactly open to having a salt that long — in this case the whole script. I guess storing the hash of the script there instead is an option; explicitly listing it will allow for knowing whether it’s the password or the script that’s wrong (related to #20, maybe?).

Yup, for the use of crypt I would likely use the hash of the file as the salt as you described. The main interest in using crypt instead of digital signing is it allows me to associate passwords directly with scripts. Permission controls that only allows scripts to run if they have 500, 540, and 550 permissions are the next layer of reasonable protection. I am planning on either implementing group controls to limit what accounts can execute ~/.duress scripts and/or implementing conventional RSA signatures to ensure validation of scripts. However that's a low priority due to existing permission controls required for the module to execute scripts as well as the validity checking involved with the script being incorporated into the salt of the password (so you need a valid script and proper password for the script to be executed).

nuvious commented 3 years ago

One implementation discussion point; to maintain compatibility with MacOS, the current implementation may be preferable. From what I can see crypt() has mixed support for algorithms across BSD and Mac with only DES and BSDi being available in MacOS's implementation (their man page for crypt apparently hasn't been updated since the 1994 version they got from BSD and explicitly point to DES as the encryption standard). FreeBSD/NetBSD/OpenBSD also have no support for SHA 256/512. Given that I think it would be better to stick to the current implementation since openssl libraries are commonly available for all flavors of unix agnostic to their crypt implementation.

https://en.wikipedia.org/wiki/Crypt_(C)

Artoria2e5 commented 3 years ago

From what I can see crypt() has mixed support for algorithms across BSD and Mac

Yeah. I think the argument for using MCF would be the ability to switch to other hash algos without breaking the format. The actual implementation will be likely independent of the libc with things like libxcrypt being used on some platforms.

nuvious commented 3 years ago

From what I can see crypt() has mixed support for algorithms across BSD and Mac

Yeah. I think the argument for using MCF would be the ability to switch to other hash algos without breaking the format. The actual implementation will be likely independent of the libc with things like libxcrypt being used on some platforms.

That sounds like the right path then. Definitely would like to leverage a common standard and this looks more appropriate than openssl and proprietary storage mechanisms at least at first glance.

nuvious commented 3 months ago

I reviewed this a bit more and decided to close it without modifying the current convention. Per @Artoria2e5, with the script being consumed as the salt the hash both acts as a means to verify the password and ensure the integrity of the script in one step. I may explore libxcrypt in the future but would be a bit of an overhaul I don't have bandwidth for at the moment (but will make time to review anyone willing to offer an implementation as a PR). Right now the implementation satisfies the needs for the secure hash as well as script integrity protection to satisfy #20.