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.

Overview

Intro

The PAM Duress is a module designed to allow users to generate 'duress' passwords that when used in place of their normal password will execute abritrary scripts.

This functionality could be used to allow someone pressed to give a password under coersion to provide a password that grants access but in the background runs scripts to clean up sensitive data, close connections to other networks to limit lateral movement, and/or to send off a notifcation or alert (potentially one with detailed information like location, visible wifi hotspots, a picture from the camera, a link to a stream from the microphone, etc). You could even spawn a process to remove the pam_duress module so the threat actor won't be able to see if the duress module was available.

This is transparent to the person coersing the password from the user as the duress password will grant authentication and drop to the user's shell.

Duress scripts can be generated on an individual user basis or generated globally. Users can also re-use global duress passwords to sign their own duress scripts (rare instance where this could actually be useful from a security perspective).

Contributions to this project are more than welcome; refer to our guidance on making contributions here.

Requirements

# Ubuntu/Debian dependencies
sudo apt-get install build-essential libpam0g-dev libssl-dev

Build

make
sudo make install
make clean
# make uninstall

Configuration

Configuration of the duress module is split into two different configuration directories. After installation, you'll need to manually create both of them.

mkdir -p ~/.duress # Local duress scripts/binaries.
mkdir -p /etc/duress.d  # Global Duress scripts/binaries.

After creating the directories you can create scripts, compile binaries, etc and put them in these directories. To assign a password to execute a particular script you use the duress_sign to create a combination password hash and integrity hash for the script.

$> duress_sign ~/.duress/delete_workspace.sh
Password: 
Confirm: 
Reading /home/user/.duress/delete_workspace.sh, 33...
Done
6B8B621EFB8050B83AAC734D56BF9165DC55D709CBAD530C6241E8A352587B3F
$> chmod -R 500 ~/.duress
$> ls -al ~/.duress/
drwxr-xr-x 2 user user 4096 Aug 20 15:15 .
drwxr-xr-x 8 user user 4096 Aug 20 15:11 ..
-r-x------ 1 user user   33 Aug 20 15:11 delete_workspace.sh
-r-x------ 1 user user   32 Aug 20 21:49 delete_workspace.sh.sha256

NOTE: Scripts will only execute with permission masks of 500, 540, 550, 700 or 750

NOTE: User generated duress scripts are only run when they attempt to log in AND use a duress password that one of their scripts is signed with. If user Jill signs their scripts with the same password as a global script, when they use it the global scripts will run, followed by Jill's duress scripts, but Bob, Jane, or Dan's scripts will not be run even if they also re-used the same duress scripts.

PAM Configuration

Modify /etc/pam.d/common-auth from the following defaults:

auth    [success=1 default=ignore]      pam_unix.so

auth    requisite                       pam_deny.so

To the below:

# Example /etc/pam.d/common-auth
auth    [success=2 default=ignore]      pam_unix.so
auth    [success=1 default=ignore]      pam_duress.o

auth    requisite                       pam_deny.so

Order of Operations Normal Password

  • User enters their standard username and password.
  • pam_unix.o confirms them and returns PAM_SUCESS and skips 2 past pam_deny.o.

Order of Operations Duress Password

  • The pam_unix.o module first checks standard username and password, but since the duress password is not the users actuall password it fails resulting in a default behavior of 'ignore' per the configuration.
  • PAM then applies the username/password to pam_duress.o which:
    • Enumerates files in /etc/duress.d/
    • Checks for files that have matching .sha256 extensions
    • Hashes the provided password salted with the sha256 hash of the file and compares it with the one stored in the .sha256 extension file
    • If the hashes match, the script is executed via:
      • export PAMUSER=[USERNAME]; /bin/sh [FILE]
      • NOTE: PAMUSER is set so global duress scripts can specify the account flagging durress.
    • Process is repeated for all files in ~/.duress/ for the user attempting to log in.
    • Finally if ANY script is run, PAM_SUCCESS is return. Otherwise PAM_IGNORE is returned.
  • If PAM_SUCESS is returned PAM will skip 1 and move past pam_deny.o to continue the pam module processes, eventually dropping to an authenticated shell. Otherwise the default 'ignore' behavior is honored moving to pam_deny.o, resulting in a failed authentication.

Simple Flow Diagram

Testing

It is easy to do a quick test to ensure the duress module is working properly.

$> mkdir -p ~/.duress
$> echo 'echo "Hello World"' > ~/.duress/hello.sh
$> duress_sign ~/.duress/hello.sh
Password: # Enter a duress password that is NOT your actual password.
Confirm: 
$> chmod 500 ~/.duress/hello.sh
$> chmod 400 ~/.duress/hello.sh.sha256
$> sudo pam_test $USER
Credentials accepted.
Password: # Enter the password you signed the hello.sh script with.
Hello World # This output is from the duress script...
Account is valid. # ...and we still got a valid authentication.
Authenticated
$> sudo pam_test $USER
Credentials accepted.
Password: # Now enter your actual password.
Account is valid. # Note, Hello World doesn't print.
Authenticated

Exmample Implementations

Comments
  • How to make it work on arch linux

    How to make it work on arch linux

    I have trouble configuring duress on arch linux. First of all I am not even sure if using /etc/pam.d/system-auth is ok since there is no common-auth. The default content of system-auth is:

    #%PAM-1.0
    
    auth       required                    pam_faillock.so      preauth
    # Optionally use requisite above if you do not want to prompt for the password
    # on locked accounts.
    -auth      [success=2 default=ignore]  pam_systemd_home.so
    auth       [success=1 default=bad]     pam_unix.so          try_first_pass nullok
    auth       [default=die]               pam_faillock.so      authfail
    auth       optional                    pam_permit.so
    auth       required                    pam_env.so
    auth       required                    pam_faillock.so      authsucc
    # If you drop the above call to pam_faillock.so the lock will be done also
    # on non-consecutive authentication failures.
    
    -account   [success=1 default=ignore]  pam_systemd_home.so
    account    required                    pam_unix.so
    account    optional                    pam_permit.so
    account    required                    pam_time.so
    
    -password  [success=1 default=ignore]  pam_systemd_home.so
    password   required                    pam_unix.so          try_first_pass nullok shadow sha512
    password   optional                    pam_permit.so
    
    -session   optional                    pam_systemd_home.so
    session    required                    pam_limits.so
    session    required                    pam_unix.so
    session    optional                    pam_permit.so
    

    I have tried replacing

    -auth      [success=2 default=ignore]  pam_systemd_home.so
    auth       [success=1 default=bad]     pam_unix.so          try_first_pass nullok
    auth       [default=die]               pam_faillock.so      authfail
    auth       optional                    pam_permit.so
    

    with

    -auth      [success=3 default=ignore]  pam_systemd_home.so
    auth       [success=2 default=bad]     pam_unix.so          try_first_pass nullok
    auth       [success=1 default=ignore]  pam_duress.so
    auth       [default=die]               pam_faillock.so      authfail
    auth       optional                    pam_permit.so
    

    When I run a test with regular password I get:

    ~ $ sudo pam_test $USER                                                                                                                                             [master]
    [sudo] password for dusan:
    Credentials accepted.
    Not Authenticated
    

    And when I use a pass I've set for a script I just get "sorry, try again" and pass prompt

    opened by DusanLesan 14
  • [#34] Clean memory leaks

    [#34] Clean memory leaks

    Summary: There are some memory leaks in the code that have been squashed and some additional checks are written to handle if malloc fails. Issue: #34 Test:

    $ pam_test $USER
    Credentials accepted.
    Password: 
    Hello World
    Account is valid.
    Authenticated
    

    Valgrind Results:

    $ 2>&1 valgrind pam_test $USER > /dev/null | tail -n 14 | head -n 9
    ==44655== HEAP SUMMARY:
    ==44655==     in use at exit: 5,089 bytes in 15 blocks
    ==44655==   total heap usage: 5,716 allocs, 5,701 frees, 1,261,870 bytes allocated
    ==44655== 
    ==44655== LEAK SUMMARY:
    ==44655==    definitely lost: 0 bytes in 0 blocks
    ==44655==    indirectly lost: 0 bytes in 0 blocks
    ==44655==      possibly lost: 0 bytes in 0 blocks
    ==44655==    still reachable: 5,089 bytes in 15 blocks
    
    opened by zakuArbor 6
  • Privilege escalation vulnerability.

    Privilege escalation vulnerability.

    The initial implementation does not run user scripts as the target user; nor checks to see if the script being run is owned by the user; only if it's readable and executable by the "owner". Then all scripts are run as root, even the local ones. This could allow and attacker to use a non-privileged account to execute root level commands if the PAM Duress module is employed.

    Repro steps: image

    opened by nuvious 5
  • Example Code May Not Work On Fresh Ubuntu Systems

    Example Code May Not Work On Fresh Ubuntu Systems

    I installed a new image of Ubuntu to test the project and kept encountering an error where the code would not execute:

    Jun 24 01:38:49 zaku pam_test: File is valid.
    Jun 24 01:38:49 zaku pam_test: Processing /etc/duress.d.
    Jun 24 01:38:49 zaku pam_test: Could not open directory /etc/duress.d, No such file or directory.
    Jun 24 01:38:49 zaku pam_test: Executing /home/zaku/.duress/hello.sh.
    Jun 24 01:38:49 zaku pam_test: Could not run script /home/zaku/.duress/hello.sh, Exec format error.
    

    I resolved the issue by specifying on top of the shell script that it's a shell script

    echo -e '#!/bin/sh\necho "Hello World"'
    #!/bin/sh
    echo "Hello World"
    

    This is what we want to indicate that this is a shell script

    opened by zakuArbor 2
  • Missing Free Call for duress_hash in is_valid_duress_file

    Missing Free Call for duress_hash in is_valid_duress_file

    https://github.com/nuvious/pam-duress/blob/04e607f9ab674c8dbbf27ea8bb59158178a72f69/src/duress.c#L141

    I was skimming the code and noticed you forgot to free duress_hash in the function is_valid_duress_file since sha_256_sum allocates memory in the heap, it should be freed before calling return

    opened by zakuArbor 2
  • Duress password does not unlock keyring

    Duress password does not unlock keyring

    After logging in with a duress password, the keyring notification window pops up and says the login password no longre matches the keyring password and asks for the password

    opened by joshbowyer 2
  • I would like to translate this for macOS

    I would like to translate this for macOS

    Hey :-)

    Does anyone, especially the author have tried or has some opinion if this will work for macOS?, I have to study the differences when it comes to how PAM operates in each of this systems tho.

    Thanks!

    opened by federico22285 1
  • Related projects

    Related projects

    Hi,

    I will leave it here, maybe someone will find this useful:

    https://github.com/pampanic/pam_panic https://github.com/x13a/pam-party https://github.com/nekohasekai/lockup https://github.com/x13a/Duress

    Feel free to close it. Have a good day.

    opened by x13a 1
  • Some PAM config files looking very different from the example

    Some PAM config files looking very different from the example

    I was interested in testing this package out on openSUSE so I managed (I think) to put in OBS in a very bare bones way. (https://build.opensuse.org/package/show/home:lilfroggy/pam-duress). It seems to install properly, however my pam config file doesn't really seem to have the same syntax as the one in the example and also says it won't except any modifications to it:

    /etc/pam.d/common-auth:

    #%PAM-1.0
    #
    # This file is autogenerated by pam-config. All manual
    # changes will be overwritten!
    #
    # The pam-config configuration files can be used as template
    # for an own PAM configuration not managed by pam-config:
    #
    # for i in account auth password session; do \
    #      rm -f common-$i; sed '/^#.*/d' common-$i-pc > common-$i; \
    # done
    #
    # Afterwards common-{account, auth, password, session} can be
    # adjusted. Never edit or delete common-*-pc files!
    #
    # WARNING: changes done by pam-config afterwards are not
    # visible to the PAM stack anymore!
    #
    # WARNING: self managed PAM configuration files are not supported,
    # will not see required adjustments by pam-config and can become
    # insecure or break system functionality through system updates!
    #
    #
    # Authentication-related modules common to all services
    #
    # This file is included from other service-specific PAM config files,
    # and should contain a list of the authentication modules that define
    # the central authentication scheme for use on the system
    # (e.g., /etc/shadow, LDAP, Kerberos, etc.). The default is to use the
    # traditional Unix authentication mechanisms.
    #
    auth	required	pam_env.so	
    auth	optional	pam_gnome_keyring.so
    auth	required	pam_unix.so	try_first_pass
    

    Any ideas on how to make it work with such a setup?

    opened by ghost 1
  • pam_test does not function properly in Arch

    pam_test does not function properly in Arch

    Issu #29 uncovered an issue with Arch where pam_test would return authentication failures while ssh localhost and sudo su - USER was triggering the appropriate scripts. Determine if/why the pam_test isn't function in Arch and/or determine if it's worth trying to maintain that tester vs advising users to use ssh localhost or sudo su - USER to test properly.

    opened by nuvious 1
  • /etc/duress.d scripts should run after ~/.duress scripts

    /etc/duress.d scripts should run after ~/.duress scripts

    /etc/duress.d scripts should be run after ~/.duress script to allow for a script to be implemented that removes pam-duress itself as a cleanup action. In the current implementation one would have to write a delayed-action script to remove pam-duress system-wide which if misconfigured may allow an attacker to see the modules presence after the attacker has dropped to a user shell.

    opened by nuvious 1
  • Script not running on arch linux

    Script not running on arch linux

    I have set up pam_duress, but when a duress password is used it doesn't seem to run the script and just logs in without doing anything.

    blecc@toweringboi ~$ cat ~/.duress/hello.sh 
    #!/bin/sh
    echo "Hello World"
    
    blecc@toweringboi ~$ duress_sign ~/.duress/hello.sh 
    Password:  # 1234
    Confirm:  # 1234
    Reading .duress/hello.sh, 30...
    Done
    818034A48A634AEACAB6753A80E2160D42EE25C44791A083D5F8727E2B3D7A99
    blecc@toweringboi ~$ chmod 400 ~/.duress/hello.sh.sha256 
    blecc@toweringboi ~$ ls -l ~/.duress/
    total 8
    -r-x------ 1 blecc blecc 30 Sep 30 16:48 hello.sh
    -r-------- 1 blecc blecc 32 Sep 30 16:51 hello.sh.sha256
    blecc@toweringboi ~$ ssh blecc@localhost
    blecc@localhost's password:  # 1234
    < no hello world >
    Last login: Fri Sep 30 16:46:36 2022 from ::1 
    blecc@toweringboi ~$ 
    

    Using an incorrect (non-duress) password still fails to log in at all, but no input causes the script to actually run. I have tried putting the script in /etc/duress.d instead of ~/.duress and using a non-outputting check (eg touching a file in /tmp/) with the same result.

    opened by bleck9999 10
  • How can I get it working on gentoo?

    How can I get it working on gentoo?

    Hello, first of all can I just say thank you for this project as it has worked well on other systems. However, on my gentoo install I am running into a few problems. Firstly, the system-auth vs common-auth issue, I followed the guidance for arch users however I do not know if it has worked for reasons I will state later Next, the library was placed in /lib/security and was not being detected. I moved it to /lib64/security and su stopped spitting out an error saying it could not find the library However, it still did not work. I attempted to log the PAM while ssh'ing in with and without my duress password. The only difference between the two was this line: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=::1 user=max This suggests pam_duress.so is not even being loaded so that's why I believe that the system-auth might not be valid I am not knowledgeable at all with PAM so im sure there is an easy answer that I am just missing. Any help is appreciated! Max

    opened by max12mx13 1
  • not work on Linux Mint 20.2

    not work on Linux Mint 20.2

    When trying to enter a "password under duress", we return to the password entry window. If you enter a regular password, authentication is normal.

    In the same time:

    sudo pam_test $ USER
    Credentials accepted.
    Password:
    Account is valid.
    Authenticated
    

    Configuration /etc/pam.d/common-auth

    auth    [success=2 default=ignore]      pam_unix.so nullok
    auth    [success=1 default=ignore]      pam_duress.so nullok
    auth    requisite                       pam_deny.so
    auth    required                        pam_permit.so
    auth    optional        pam_ecryptfs.so unwrap
    auth    optional                        pam_cap.so
    

    `

    opened by bug0000 0
  • Feature request: Protect the duress script itself

    Feature request: Protect the duress script itself

    Hi there,

    I think there are chances that a duress password could be the utmost simple one, which means it could be a dictionary word or easily being brute force and guessed it out. An adversary could also use PII or related information from the victim, to potentially guess what is the password(either the correct one or the duress code).

    SHA256 is great, and it does the job on checksum, but not when it comes to the case that we should also protect the duress script itself.

    I suggest introducing an option to add cryptographically signed duress script, ideally would be PGP signed, on top of the sha256 hashed script. So that the user can always know if the file has been tampered with, and failover to the sha256 hashed script if the validation failed.

    Regards, Ivan

    opened by lifehome 4
  • Make ~/.duress directory a toggleable feature.

    Make ~/.duress directory a toggleable feature.

    Some admins may not trust their users to create duress scripts and want full control to only have the ones in /etc/duress.d run when duress password is used. Modify the module such that it reads in a configuration file /etc/duress.conf to see if the administrator wants to enable ~/.duress for users and create a group that controls which users have their ~/.duress files parsed during login.

    opened by nuvious 0
Owner
null
This is a proof-of-concept of a modern C web-framework that compiles to WASM and is used for building user interfaces.

DanCing Web ?? ?? (DCW) Getting Started Dancing Web is now distributed with the Tarantella Package Manager — a tool I've made to simplify setup of pro

Danilo Chiarlone 3 Sep 11, 2021
Pion Network Library (Boost licensed open source)

Pion Network Library C++ framework for building lightweight HTTP interfaces Project Home: https://github.com/splunk/pion Retrieving the code git clone

Splunk GitHub 293 Nov 17, 2022
fix vmprotect import function used unicorn-engine.

Vm2Import fix vmprotect import function used unicorn-engine. it can repair functions such as call [module.function] or jmp [module.function] or reg(mo

共产主义接班人 79 Dec 24, 2022
The application framework for developer module of EdgeGallery platform

crane-framework crane-framework将可复用的计算和软件功能抽象成插件,APP开发者面向使用插件进行MEC APP开发。这样屏蔽了和MEC平台交互的细节,实现MCE APP和MEC平台的松耦合。而且插件框架基础能力可裁剪,按需提供最小的APP系统。 特性介绍 为了方便开发者

EdgeGallery 21 Aug 30, 2021
A gazebo actor plugin that utilizes the map of the environment and graph search methods to generate random actor trajectories that don't pass through walls, furniture, etc.

Gazebo-Map-Actor-Plugin A gazebo actor plugin that utilizes the map of the environment and graph search methods to generate random actor trajectories

Yasin Sonmez 11 Dec 23, 2022
anthemtotheego 402 Dec 26, 2022
Program that can be used for rating user passwords.

Rate_My_Password Program that can be used for rating user passwords. The criteria for rating passwords are: • Has a length of at least 8 characters •

Sabri 1 Dec 28, 2021
An embedded CAN bus sniffer which is able to monitor any of the vehicle internal CAN bus and perform some action by triggering new CAN messages.

An embedded CAN bus sniffer which is able to monitor any of the vehicle internal CAN bus and perform some action by triggering new CAN messages. In this way certain vehicle functionality can be triggered by responding to custom steering wheel button events, or use the vehicle virtual cockpit to display OBD-PIDs values instead of relying on an external display to present new information to the user

null 18 Dec 28, 2022
Extracting clear-text passwords from VeraCrypt.exe using API Hooking

VeraCryptThief VeraCryptThief by itself is a standalone DLL that when injected in the VeraCrypt.exe process, will perform API hooking via Detours, ext

snovvcrash 193 Aug 15, 2022
Cobalt Strike is a commercial, full-featured, remote access tool that bills itself as "adversary simulation software designed to execute targeted attacks and emulate the post-exploitation actions of advanced threat actors".

COBALT STRIKE 4.4 Cobalt Strike is a commercial, full-featured, remote access tool that bills itself as "adversary simulation software designed to exe

Trewis [work] Scotch 104 Aug 21, 2022
ESP32 + GitHub Actions + Husarnet. A boilerplate project for ESP32 allowing in-field firmware update using GitHub Actions workflow.

esp32-internet-ota ESP32 + GitHub Actions + Husarnet. A boilerplate project for ESP32 allowing in-field firmware update using GitHub Actions workflow.

Husarnet 31 Sep 22, 2022
Hidden Eye is an all in one tool that can be used to perform a variety of online attacks on user accounts

Hidden Eye is an all in one tool that can be used to perform a variety of online attacks on user accounts. It’s well loaded, therefore it can be used as keylogger (keystroke logging), phishing tool, information collector, social engineering tool, etc.

Muhammad Qazi 0 Jun 24, 2022
✔️The smallest header-only GUI library(4 KLOC) for all platforms

Welcome to GUI-lite The smallest header-only GUI library (4 KLOC) for all platforms. 中文 Lightweight ✂️ Small: 4,000+ lines of C++ code, zero dependenc

null 6.6k Jan 8, 2023
Stock exchange simulator made in Swing using Java with logic backend in C++ giving it faster load time and better data control

StockSimulator Stock exchange simulator made in Swing using Java with logic backend in C++ giving it faster load time and better data control Features

Dušan Todorović 0 Mar 1, 2022
King Hamlet is a simple tool, which allows you to perform a Process Ghosting Attack

KingHamlet Process Ghosting Tool - 64 bits Only! King Hamlet is a simple tool, which allows you to perform a Process Ghosting Attack

null 149 Dec 27, 2022
By controlling the frequency at which the output Pins of MSP430 are turned off and on, we can make music.

By controlling the frequency at which the output Pins of MSP430 are turned off and on, we can make music.

Premkumar Vincent 1 Nov 9, 2021
HIBA is a system built on top of regular OpenSSH certificate-based authentication that allows to manage flexible authorization of principals on pools of target hosts without the need to push customized authorized_users files periodically.

HIBA is a system built on top of regular OpenSSH certificate-based authentication that allows to manage flexible authorization of principals on pools of target hosts without the need to push customized authorized_users files periodically.

Google 333 Dec 31, 2022
A different way of calling the notify function on the ps4 for homebrew development.

PS4-Notify A different way of calling the notify function on the ps4 for homebrew development. Calling the new Notify void Notify(char* IconURI, char*

Greg 24 Dec 20, 2022
pluggable tool to convert an unrolled TritonAST to LLVM-IR, optimize it and get back to TritonAST

it is fork from https://github.com/fvrmatteo/TritonASTLLVMIRTranslator *WARNINGS: tested only linux(ubuntu 20.04) and only llvm and clang version 10*

pr4gasm 5 Jun 10, 2022