Skip to content

Commit

Permalink
Execute commands directly using execv (#24)
Browse files Browse the repository at this point in the history
* Execute commands directly using execv

There is no reason to start an intermediate shell.

* Updated version/changelog.
Unrelated to PR but done for testing
this and future PR's, suspended
default redirect to /dev/null for debug builds.
Unrelated to PR; spell checker pass on markdown docs.

Co-authored-by: David Cheeseman <[email protected]>
  • Loading branch information
juergenhoetzel and nuvious authored Aug 29, 2021
1 parent 1b9420b commit 3659e50
Show file tree
Hide file tree
Showing 5 changed files with 18 additions and 13 deletions.
6 changes: 5 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,13 @@
- Removed unnecessary casts for malloc calls.
- Created dbg_log wrapper function to clean up DEBUG compile flag use.
- 1.1.3
- Fixed privilege esclation issue #16 [reported by wowaname](https://news.ycombinator.com/item?id=28276200) from Hacker News.
- Fixed privilege escalation issue #16 [reported by wowaname](https://news.ycombinator.com/item?id=28276200) from Hacker News.
- Redirected output of all scripts/binaries to /dev/null by convention.
- 1.1.4
- Memory leak resolved by [Jürgen Hötzel on github](https://github.com/juergenhoetzel).
- 1.1.5
- Makefile improvements by [Prateek Ganguli on github](https://github.com/pganguli). Debug build path now added.
- 1.1.6
- Removal of unnecessary intermediate shell.
- Debug builds will not redirect output of stderr and stdout to /dev/null by default to support testing/debugging.

12 changes: 7 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# 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.
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 arbitrary 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 functionality could be used to allow someone pressed to give a password under coercion 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 notification 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.
This is transparent to the person coercing 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).

Expand Down Expand Up @@ -33,13 +33,15 @@ make clean
### Debug Build

```bash
# Debug build provides detailed output to syslog.
# Debug build provides detailed output to syslog.\
sudo make uninstall
make clean
make debug
sudo make install
```

**NOTE**: In debug builds script output IS NOT redirected to /dev/null by default; in non-debug builds it is.

## Configuration

Configuration of the duress module is split into two different configuration directories. After installation, you'll need to manually create both of them.
Expand Down Expand Up @@ -94,7 +96,7 @@ auth requisite pam_deny.so
- 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.
- The pam_unix.o module first checks standard username and password, but since the duress password is not the users actual password it fails resulting in a default behavior of 'ignore' per the configuration.
- PAM then applies the username/password to pam_duress.so which:
- Enumerates files in /etc/duress.d/
- Checks for files that have matching .sha256 extensions
Expand Down
2 changes: 1 addition & 1 deletion docs/examples/Pushover.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ sudo chmod 400 /etc/duress.d/pushover.sh.sha256

This will produce a pushover.sh.sha256 file. The has is not the direct hash of the file but rather the hash of the password salted with the sha256 hash of the file.

You can then distribute this global configuration's password to new users you can simply give them the password. Before local configurations are run a password provided to the duress module will be checked against the hashes of the scripts in /etc/duress.d. If the password matches the script wil be run with root priviledges.
You can then distribute this global configuration's password to new users you can simply give them the password. Before local configurations are run a password provided to the duress module will be checked against the hashes of the scripts in /etc/duress.d. If the password matches the script wil be run with root privileges.

**SECURITY NOTE:** If a person who is granted one of these shared passwords leaves the group/organization/etc, you should immediately re-sign the script. This is in keeping with the best practices of using organizational duress-words; they must be kept secret and need-to-know and if someone leaves the group, they don't need to know anymore so change it.

Expand Down
9 changes: 4 additions & 5 deletions src/duress.c
Original file line number Diff line number Diff line change
Expand Up @@ -237,14 +237,13 @@ pid_t run_shell_as(const char *pam_user, const char *run_as_user, char *script)

switch (pid) {
case 0: {
#ifndef DEBUG
/* Redirect sderr and sdout to /dev/null */
int fd = open("/dev/null", O_WRONLY | O_CREAT, 0666);
dup2(fd, STDOUT_FILENO);
dup2(fd, STDERR_FILENO);
#endif //DEBUG

/* craft the command line arguments to execute the script */
char *argv[] = { SHELL_CMD, "-c", script, NULL };

/* get user information struct */
struct passwd *run_as_pw = getpwnam(run_as_user);

Expand All @@ -270,8 +269,8 @@ pid_t run_shell_as(const char *pam_user, const char *run_as_user, char *script)
goto child_failed;
}

/* execute the shell command */
execv(SHELL_CMD, argv);
/* execute the command */
execv(script, NULL);

child_failed:
dbg_log(LOG_ERR, "Could not run script %s, %d.\n", script, errno);
Expand Down
2 changes: 1 addition & 1 deletion src/version.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@

#define VERS_MAJOR 1
#define VERS_MINOR 1
#define VERS_REVISION 5
#define VERS_REVISION 6

#endif

0 comments on commit 3659e50

Please sign in to comment.