Ctrl+Alt+Del (three-finger salute) action

Ctrl+Alt+Del (sometimes called the “three-finger salute”):

On Windows, the three-finger does something useful. Noways, shows a menu:

  • Lock
  • Switch user
  • Sign out
  • Change a password
  • Task manager
  • Cancel

On Qubes, simply activates the screen lock.

On Kicksecure, we could also provide similar options such as:

  • Task manager
  • Lock
  • Regular shutdown
  • Emergency shutdown
1 Like

Please see my thread 1147 about this.

My question is what route should be the go to?

Set a local shortcuts config for user and sysmaint? Downside would be these keyboard shortcuts would not populate if user uses sysmaint to create more users. Unless there is something specific to xfce4’s xconf for globally setting shortcuts it seems like the only route is dconf?

My idea was to use the existing emerg-shutdown framework (which monitors for a “panic” key combo already) to also act as the Ctrl+Alt+Delete handler. That would make it work anywhere in the system, and could also (if handled carefully) prevent malware running as a local user from being able to interfere with the key handler and associated features.

1 Like

What about other default shortcuts like super key for whisker menu for easy searching for applications like “windows task bar”. Many distros already set super key for application menu like Ubuntu and Mint.

These cannot be referenced by number. Difficult to find. I had to click on your profile and check all created forum threads.

This:
Kicksecure distro specific keyboard shortcuts

Had a conversation about how this could work with Patrick, this is my current set of ideas/plans after that conversation.

We have the emerg-shutdown background process now, which among other things monitors all keystrokes on the system by grabbing the /dev/input/event* devices on startup. This is done so that if the user presses a panic key combination (user configurable, the default is yet to be determined, see Emergency key press shutdown sequence), the system can be immediately and forcibly shut down, without any possibility of malicious interference or accidental overriding. That same mechanism could be used in theory to listen for any key combination though, allowing us to define keyboard shortcuts that talk to a privileged component of the system (similar to the Secure Attention Key in other operating systems). Another advantage of this is that it’s not possible for malware to access this interface unless it is running as root, because emulated input mechanisms allow communicating with the display server, not the kernel’s evdev driver. Injecting key events into the kernel’s evdev subsystem requires using uinput, which requires root privileges to access, thus unprivileged malware can’t send keystroke combinations in order to trigger whatever privileged actions are configured here.

Since shortcuts configured in emerg-shutdown require either root privileges or physical access to the machine to trigger, this makes it seem like the perfect place to implement a Ctrl+Alt+Delete handler. The question then becomes, what should this handler do?

There are two possible directions we could take this. One is the simple route - register the salute in emerg-shutdown, and send a DBus message to whatever user session is on an active TTY in response. Those messages would then instruct an agent running as the user to do something like start a task manager or lock the screen. This would be useful, but it would only be marginally better than just defining a keyboard shortcut in the user session. It wouldn’t allow the user to kill applications that are running as root or as a different user (something they may have a legitimate reason to do even in a user session), and it wouldn’t prevent anything “going wrong” in the user session (a malicious or runaway process, for instance) from being able to interfere with the salute’s functionality in some way.

The other, more complex route, would be to switch to an “emergency session” of sorts, moving the user to an unused TTY and launching a graphical session in that TTY where they can do things as root or another privileged user. This is far more powerful, and possibly far more secure if done right.

The more complex solution is unsafe under X11 because of the world-writable UNIX sockets created by X11, exposing attack surface that could result in exploitable escalation of privilege vulnerabilities. Under Wayland however, the display server’s socket is generally under /run/user/UID, which has strict permissions to prevent access by other users, so as long as the kernel’s permission subsystem holds up, this shouldn’t be an issue. We can thus run a separate Wayland server as a privileged user (such as sysmaint) alongside an unprivileged and untrusted user session, without as much fear of vulnerabilities. (If running a full Wayland server sounds like too much risk, we could also use a raw framebuffer. Qt supports rendering directly to a framebuffer, it’s very slow at least under a virtual machine, but it works. I think this is overkill though, and it will also make it hard to work with multiple programs at once, which would almost certainly be desirable.)

One danger of an emergency UI such as this is that it’s not impossible for a malicious application to prevent the user from escaping to the emergency session. The emergency session would simply run in a TTY (since that’s the only feature Linux has for this sort of thing), and it would be fairly trivial for malware running as a user in a graphical session to simply force the user back to the original TTY, using a console file descriptor. (One can switch the active TTY to any other TTY if they have write access to any one TTY. In other words, if the user is logged in graphically and thus /dev/tty7 is writable by them, malware running as that user can open /dev/tty7 and then switch the user to any desired TTY.) To prevent this, one solution would be to SIGSTOP potentially malicious processes, specifically those which run as a logged-in user. This cannot be done to every process in the system though, since:

  • PID 1 cannot be SIGSTOP’d (I tried, the signal was silently ignored)
  • A SIGSTOP’d program can be SIGKILL’d without receiving a SIGCONT first
  • systemd’s watchdog mechanism can and probably will restart a service that is SIGSTOP’d as a result

However, “freezing” all logged-in user accounts should still be feasible in theory. This would prevent any running malware from doing anything while the user is in the emergency session, thus it would be unable to force the user to a different TTY. Any malware on the system that wasn’t running as a logged-in user would have to be running as root or be able to elevate its privileges to that of a logged-in user in order to gain access to a console and thus change TTYs.

One thing that is still uncertain about SIGSTOP is how it behaves when dealing with stuck kernel threads. If a thread calls into the kernel and then gets stuck there (such as can happen when dealing with flaky I/O devices), it cannot be SIGKILL’d or SIGSTOP’d. What’s unclear is whether the process’s other threads can be SIGKILL’d or SIGSTOP’d in this situation. If the answer is “yes”, then using SIGSTOP should be an effective freezing mechanism, but if the answer is “no”, then malware may be able to circumvent a SIGSTOP by launching a thread that then does something to get stuck in the kernel. Getting a thread stuck in kernel mode is hard though (I believe it should be impossible without either buggy hardware, a buggy kernel, or root access, and even with root access you’d have to do something convoluted like set up a VM with an NFS share, mount the NFS share on the host, kill the VM abruptly, and then attempt I/O on the mounted share edit: just tried something like this, even this doesn’t result in a stuck kernel thread, Creating controllable D state (uninterruptible sleep) processes has better instructions for getting a process stuck in a kernel thread), so this might not be an issue.

Another difficulty is that we most likely are not going to go through a display manager., As a result, the “session” we will end up in will be rather limited and things that one might expect to work (like systemd user units, DBus, some xdg-related things, etc.) probably won’t work. Thus the functionality within the emergency session will need to be limited to cope with this. (This will also prevent us from simply switching to a sysmaint session when the salute is registered - the sysmaint session has features that depend on a full login session running. It most likely will not behave itself well if it doesn’t have all of the infrastructure usually set up by a display manager working right. We also can’t just switch to the sysmaint session because some of the features of the sysmaint session, like software updates, are not things that can be safely done when booted into a user session. Even if they work now, they won’t work once we implement Verified Boot.)

Obviously, some form of authorization will be needed in order to access the features of this emergency session. Otherwise any attacker with physical access to the system could use this to take the system over entirely. It shouldn’t be too difficult to implement an authorization prompt of some sort to make this work. Because of the need for authorization, the graphical session MUST NOT run as root, since then any arbitrary code execution vulnerability in a used graphical toolkit or Wayland compositor could allow an attacker with physical access to gain unauthorized root access. The sysmaint account would be ideal to use instead, since then if the user has set a password, they will have to provide it in order to run any privileged operations.

2 Likes

On the topic of a secure attention key, someone in 2016 posted a really nice overview of attack scenarios where a SAK is very useful: SAK/SAS - Secure attention key sequence on Linux | Ars OpenForum Quoting the post:

It’s not about a machine we don’t trust; that’s a separate but valid concern. It’s about a computer that multiple people have access to, e.g. libraries, computer labs, workplaces. Many people may be allowed on that machine, but each having their own accounts and passwords.

Attack type number 1:
Attacker logs into his account and starts up a full-screen program that looks and acts identical to the login screen. (Program designed to collect the username/password data and store it or send it somewhere, then shows a fictitious error screen or simply logs out or reboots or hangs so that someone forces a restart.)
Victim finds an apparently unused workstation. Logs in. Game over.

Attack type number 2:
Victim logs in, starts up some programs, opens some files, then locks the screen and goes for a coffee break.
Attacker hard-resets the machine, logs in and runs a similar program that looks/behaves like the screenlocker instead.
Victim returns and attempts to unlock the screen. Game over.

Attack type number 3:
Victim forgets to lock screen on going to the john. (When you gotta go…)
Attacker runs fake screenlocker on the Victim’s own acct.
Victim returns and either forgot that he didn’t lock it or figures it timed out from inactivity. Unlocks screen. Game over. (program simply terminates itself putting him back at his desktop after having sent the password over the internet and deleting its tracks)
Some compromise existed already, since Victim failed to lock, but this attack provides stealthy expansion of that gap, allowing future log on, not just a one time access, and also gives you any sudo privileges the account has.

Having a SAK that users are trained to ALWAYS enter before passwords eliminates the risk.

One of the features Windows has bound to the three finger salute is triggering the lock screen or login screen to function (the screen displays even before that, but the SAK signals it to prompt for the password), which conveniently solves all of these issues. To implement something like this on Linux, we could probably do something like this:

  • The screen locker itself doesn’t accept a password, it simply listens for a privileged process to give it an “unlock the screen” signal and unlocks the screen upon receipt of that signal.
  • Pressing Ctrl+Alt+Del causes emerg-shutdown (which probably needs renamed at this point) to freeze all user accounts on the system, send the user to an unused TTY, and display a greetd+wlgreet window. The user can then log in with their user name and password.
  • The script that runs on login signals emerg-shutdown to unfreeze the system, then looks to see if the user is already logged in (and if so, on which TTY). If the user is already logged in, the script instructs emerg-shutdown to unlock that user’s TTY, then it switches to that user’s TTY and is done. If the user is not already logged in, a new login is created.

This mitigates all three attack scenarios. As for how to implement this and the emergency session at the same time, we just need emerg-shutdown to be able to tell whether or not the active TTY is locked (this can be done most likely with the help of the custom screen locker). If the TTY is locked, the salute will trigger a login/unlock action like described above, otherwise it will trigger an emergency session like described earlier.

1 Like

Based on some quick testing using the fsfreeze technique described in an earlier shared link, it looks like it is not possible to immunize a process to SIGKILL or SIGSTOP by using a stuck thread.

# Set up
mkdir stickyfs
fallocate -l 8M sticky.img
mkfs.ext4 sticky.img
sudo mount sticky.img stickyfs
sudo chmod 777 stickyfs

# Write a simple multithreaded C program that will get one thread stuck
cat <<EOF > test.c
#include <pthread.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>

void *sticky_func(void *arg) {
  const char *stuckstr = "I'm stuck, help!\n";
  int stuckfd = open("stickyfs/sticky.txt", O_RDWR | O_CREAT);
  write(stuckfd, stuckstr, strlen(stuckstr));
}

int main() {
  pthread_t sticky;
  pthread_create(&sticky, NULL, sticky_func, NULL);
  int i = 0;
  while (1) {
    printf("%d\n", i++);
  }
}
EOF

gcc test.c

# Lock the stickyfs filesystem
sudo fsfreeze -f stickyfs

# Run the newly created application
./a.out

# Numbers will scroll down the screen indicating that the process is doing something. Open another terminal to do other work in.

# Look at the contents of stickyfs, verify sticky.txt does not exist there
ls stickyfs

# Find the PID of the sticky process
pgrep a.out

# SIGSTOP it
kill -s SIGSTOP PID

# Observe the numbers stop scrolling down the screen
# Resume the process
kill -s SIGCONT PID

# Observe the numbers start scrolling again
# Kill the process with SIGKILL
kill -s SIGKILL PID

# Observe the numbers stop scroling, but the process does not fully exit, confirming that it is stuck in a kernel thread
# Unfreeze the stickyfs dir
sudo fsfreeze -u stickyfs

# Observe the process exits now

So it looks like SIGSTOP is usable here. Even though the stuck thread isn’t responding to the signals, the unstuck threads that could actually be dangerous are still affected by those signals.

1 Like

Sure? This contradicts what we’re currently writing in chapter Console Login Attacks.

Another advantage of this might be that misbehaving processes (such as clogging up all CPU due to a bug) would stop doing that so the user has system resources available to investigate this and to terminate misbehaving processes.

1 Like

I don’t believe so. That documentation explicitly warns that one way to be able to switch virtual terminals is to:

…be running under a user account that has logged in at a virtual terminal already. In this … instance, software running as the logged-in user could switch to a different virtual terminal, but it would not be able to attempt to login at that terminal. That would require read/write access to the virtual terminal that was switched to. Virtual terminals that have a login prompt are only able to be read from and written to by root or a person with physical access to the machine.

The reason this is a problem in the context of a SAK is that even if we switch to a TTY presenting an authentic login screen, malware could immediately switch us back to the TTY it was on a second ago and display a fake login screen. It’s not a danger when it comes to logging into other accounts, it is a problem when it comes to stealing user data.

(Worthy of note, once we switch to Wayland, the compositor will almost certainly run as a user other than root, and thus the TTY it runs on will have its permissions set to a non-root user. Thus this issue will start affecting graphical sessions as well, not just text-only VT logins. I think though that’s a small price to pay, especially since there’s a mitigation.)