aboutsummaryrefslogtreecommitdiff
path: root/README.md
diff options
context:
space:
mode:
Diffstat (limited to 'README.md')
-rw-r--r--README.md127
1 files changed, 127 insertions, 0 deletions
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..dec9818
--- /dev/null
+++ b/README.md
@@ -0,0 +1,127 @@
+# SecDesk
+
+An attempt to port Windows *secure desktop* to Linux.
+
+## Background
+
+On Windows, every window belongs to a [desktop](https://learn.microsoft.com/en-us/windows/win32/winstation/desktops),
+and processes can (?) read the input of other windows, unless they are privileged (?).
+
+Winlogon and UAC consent protects user inputs (e.g. passwords) from being stolen by 1) running as `NT Authority\SYSTEM`
+, and running on the secure desktop, which is a separate desktop from the users'. This way, user processes cannot read
+inputs.
+
+macOS should (?) has a similar security measurement, but I am not sure.
+
+On Unix, X11 does not have such a protection, and user processes are free to read any other process's input. This
+includes your lock screen (e.g. `i3lock(1)`) or terminal (running `sudo(1)`).
+
+Wayland fixes this issue by implementing a security control, while X11 users are left unprotected.
+
+This proof-of-concept project aims at porting the secure desktop concept on Windows to Unix.
+
+## Threat model
+
+This project is aimed at preventing malware running as the unprivileged user to capture or hijack the input of
+sensitive dialogues. It assumes that the operating system (kernel, libraries, binaries, daemons, and everything
+privileged) is trusted.
+
+## Basic idea
+
+Without modifying the kernel, the easiest approach is to use virtual terminals. While most current Unix operating
+systems has virtual terminal support, this project is mainly focused on Linux due to the author's familiarity. Porting
+it to other Unix could be possible.
+
+Linux has multiple virtual terminals (defined in `MAX_NR_CONSOLES`), and each one can run a text terminal or GUI. The
+kernel provides text terminals: programs read and write to `/dev/ttyN`, and the kernel handles input and outputs from
+the keyboard and to the screen. Display servers can use framebuffer or DRM, as well as `/dev/input/`, to draw their own
+graphics.
+
+Popular implementations of display servers, like Xorg or wayland compositors using `seatd` are all using DRM and
+`/dev/input`.
+
+Each virtual terminal is independent of each other, and users may switch from one to another using `Ctrl + Alt + Fx` or
+`VT_ACTIVATE` ioctl.
+
+Each virtual terminal is isolated from each other. For the text terminals, `/dev/ttyN` has the default permission of
+`0620 root:tty`, and privileged display servers holding `/dev/input/*` does not pass keystrokes to user processes after
+switching to other virtual terminals (Xorg will keep these files open, while `seated` will close them).
+This is ideal for implementing a secure desktop on Linux.
+
+The approach is to start a separate display server (e.g. Xorg) on a free (unused) virtual terminal, switch to it, read
+sensitive data, switch back, and close the virtual terminal. This guarantees that unprivileged processes have no way to
+hijack the password dialogue, with the limitation that the password dialogue must be trusted and ran by root.
+For example, a dedicated X server coule be started using:
+
+```shell
+Xorg -background none :$NEW_DISPLAY vt$NEW_VT -nolisten tcp
+# Setup XAuth, so only root can connect.
+```
+
+Then, start a password dialogue:
+
+```shell
+DISPLAY=:$NEW_DISPLAY /usr/lib/ssh/x11-ssh-askpass
+```
+
+This would be the simplest form of a secure desktop.
+
+## Implementation
+
+To make the startup process faster, more portable, and simpler, I wrote this PoC that uses the text terminal instead of
+a display server. It is not a *desktop* in terms of the Windows secure desktop, but it satisfies the requirement of
+securely reading sensitive data.
+
+This PoC makes uses of various TTY and Console related ioctl (see `ioctl_console(2)` and `ioctl_tty(2)`), and it uses
+codes from [kbd](http://kbd-project.org/). How this PoC works is obvious:
+
+1. Open the TTY of the current process.
+2. Find an open virtual terminal (`VT_OPENQRY`) and open it.
+3. Make the virtual terminal the controlling terminal (`setsid(2)` and `TIOCSCTTY`).
+4. Read / write as usual using the file descriptor from step 2.
+5. Switch to it or switch back using `VT_ACTIVATE` and `VT_WAITACTIVATE`.
+
+## SAK
+
+Although the above process can safely read passwords, one more security measure must be taken into consideration: the
+user must know the authenticity of the password dialogue. That is, a user process may create a full-screen window to
+mimic the password dialogue in order to obtain the password.
+
+Windows mitigates this issue by having a SAK (Secure attention key), which is `Ctrl + Alt + Delete`. The NT kernel
+directly handles this key combo, and it notifies winlogon to show a privileged screen (either login screen or the
+security options page). Users can trust the page is authentic because no other programs shall capture the key combo.
+Moreover, domain administrators can enable the Require Ctrl Alt Del on Logon group policy to train users that they must
+press the SAK before login to ensure the authenticity of the login screen.
+
+However, this feature is missing on most current Unix operating systems. Linux is the only known Unix operating system
+to have a SAK, and it is less known and has little use. On Linux, the SAK is `SysRq + K`. The kernel will kill all
+processes (including the display server) in the current virtual terminal, so the service manager will restart the login
+prompt (either the display manger or getty), and it is authentic. This behaviour makes SAK on Linux very limited, as
+most users do not want their desktop programs to be killed just for logging in.
+
+This project took the advantage of the Linux SAK by forking a child to display the message `Press SysRq + K to continue`
+on the new virtual terminal and wait for it to be killed by `SIGKILL`. Although race condition could happen after
+`waitpid(2)` and `TIOCSCTTY`, it is still safe because the `/dev/ttyN` file does not allow non-root processes to write.
+
+## In the future
+
+This project is far from perfect: its authentication UI / UX is naive, and it requires running as root to open the TTY.
+In the future, I will make it an AskPass / PolKit agent, where unprivileged user can run use it to securely authenticate
+themselves. I will also fix the behaviour when running from environments like SSH (pts) or serial, where virtual
+terminals do not exist. In these environments, it should simply use the current terminal and inform the user that the
+terminal is insecure, which is what Windows RDP does regarding remote UAC consent.
+
+## Build and run
+
+```shell
+mkdir build
+cd build
+cmake ..
+sudo ./secdesktop password test # mode prompt
+```
+
+The code is ugly: it is written in 4 hours. I will try to make it pretty.
+
+## License
+
+WTFPL \ No newline at end of file