diff options
Diffstat (limited to 'README.md')
-rw-r--r-- | README.md | 127 |
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 |