{{Header}} {{#seo: |description=Deanonymization using user keystrokes, keystroke deanonymization, keystroke fingerprinting and defenses. |image=Keystroke.png }} {{web_related}} [[File:Keystroke.png|thumb]] {{intro| Deanonymization using user keystrokes, keystroke deanonymization, keystroke fingerprinting and defenses. }} = Keystroke Dynamics = Keystroke biometric algorithms have advanced to the point where it is viable to fingerprint users based on soft biometric traits. This is a privacy risk because masking spatial information -- such as the IP address via Tor -- is insufficient to anonymize users. https://github.com/vmonaco/keystroke-obfuscation Users can be uniquely fingerprinted based on: https://en.wikipedia.org/wiki/Keystroke_dynamics * Typing speed. * Exactly when each key is located and pressed (seek time), how long it is held down before release (hold time), and when the next key is pressed (flight time). * How long the breaks/pauses are in typing. * How many errors are made and the most common errors produced. * How errors are corrected during the drafting of material. * The type of local keyboard that is being used. * Whether they are likely right or left-handed. * Rapidity of letter sequencing indicating the user's likely native language. * [[Keyboard Layout]] as the placement of the keys on the keyboard leads to different key seek times and typing mistakes. A unique neural algorithm generates a primary pattern for future comparison. It is thought that most individuals produce keystrokes that are as unique as handwriting or signatures. This technique is imperfect; typing styles can vary during the day and between different days depending on the user's emotional state and energy level. Unless protective steps are taken to obfuscate the time intervals between key press and release events, it is likely most users can be deanonymized based on their keystroke manner and rhythm biometrics. Adversaries are likely to have samples of clearnet keystroke fingerprinting which they can compare with "anonymous" Tor samples. Typing on the most popular keyboard layout which is probably en-US might help mitigation however a more effective way is the following. At a minimum users should not type into browsers with Javascript enabled, since this opens up this deanonymization vector. Text should be written in an offline text editor and then copied and pasted into the web interface when it is complete. In addition, users must also disguise their linguistic style to combat [[Surfing_Posting_Blogging#Stylometry|stylometric analysis]] and be aware of [[Surfing_Posting_Blogging#Mouse_Fingerprinting|mouse tracking techniques]] available to adversaries. = Defenses = == Kloak == Kloak is an input device anonymization tool. It includes mitigations for keystroke fingerprinting as well as for masking unique user mouse movement behavior.https://github.com/vmonaco/kloak/pull/38https://github.com/vmonaco/kloak/pull/50#issuecomment-1657250132https://arxiv.org/pdf/2101.09087.pdf * [[Non-Qubes-Whonix|{{non_q_project_name_short}}]] supported by default. * [[Qubes|{{q_project_name_long}}]] Unavailable. * https://github.com/vmonaco/kloak/pull/50 stalled For previous tickets on this issue, see [https://forum.qubes-os.org/t/tutorial-how-to-use-kloak-with-usb-keyboards/14134 this]. * https://github.com/QubesOS/qubes-issues/issues/2558 * https://github.com/QubesOS/qubes-issues/issues/1850 * Using /dev/input/event0 in Qubes VMs [https://forums.whonix.org/t/current-state-of-kloak/5605/6 will not work since not a keyboard device]. * https://github.com/QubesOS/qubes-issues/issues/9771 * https://github.com/QubesOS/qubes-issues/issues/9775 Kloak is installed in {{non_q_project_name_long}} {{project_name_workstation_long}} by default. We recommend [[Packages for Debian Hosts|installing kloak on the host]] too so it remains effective in event of a {{project_name_workstation_short}} VM compromise. If you need to access accounts (for example banking) that enforce keystroke biometrics, then it may be a good idea to just limit installation to {{project_name_long}} VMs. Kloak has the added benefit of foiling attacks that identify search queries in encrypted network traffic using information leaked through autocomplete suggestions of search engines. [https://vmonaco.com/papers/Feasibility%20of%20a%20Keystroke%20Timing%20Attack%20on%20Search%20Engines%20with%20Autocomplete.pdf Feasibility of a Keystroke Timing Attack on Search Engines with Autocomplete] https://www.usenix.org/sites/default/files/conference/protected-files/sec19_slides_monaco.pdf === Rescue Keys === Kloak by default recognizes a "rescue key" sequence, which will terminate the kloak process. The default rescue key sequence is KEY_LEFTSHIFT + KEY_RIGHTSHIFT + KEY_ESC (i.e. left shift + right shift + escape). Depending on how kloak is run: * '''A)''' daemon: If you are running kloak as a systemd service (the default), this will ''restart'' kloak (as systemd will automatically re-launch it after it terminates). * '''B)''' manual: If you are running kloak in a terminal, this will ''terminate'' kloak, which then will be no longer anonymizing keyboard and mouse actions. ==== Rescue Keys Customization ==== Kloak rescue keys may be customized by using the -k option, which takes a comma-separated list of key codes as an argument. The full list of supported key codes can be seen at [https://github.com/Whonix/kloak/blob/master/src/keycodes.c keycodes.c]. For instance, to run kloak with the rescue key set to KEY_LEFTSHIFT + KEY_ESC, run: '''1.''' Stop background kloak process first. {{CodeSelect|code= sudo systemctl stop kloak }} '''2.''' Run kloak in terminal. {{CodeSelect|code= sudo kloak -k KEY_LEFTSHIFT,KEY_ESC }} '''3.''' Terminate with Ctrl+C or rescue key sequence when done. '''4.''' Restart background kloak process. {{CodeSelect|code= sudo systemctl start kloak }} '''5.''' Persistent configuration change. To make this change permanent, see [[Keystroke_Deanonymization#Setting_persistent_kloak_settings|setting persistent kloak settings]]. '''6.''' Done. ==== Disabling rescue keys ==== Some users have reported that they are unable to use certain keyboard shortcuts on account of the rescue key functionality. To disable the rescue key feature entirely, you may use the -p option. Be warned that this will prevent you from terminating or restarting kloak using the rescue key sequence! To run kloak with the rescue key feature disabled: '''1.''' Stop background kloak process first. {{CodeSelect|code= sudo systemctl stop kloak }} '''2.''' Run kloak in terminal. {{CodeSelect|code= sudo kloak -p }} '''3.''' Terminate with Ctrl+C when done. '''4.''' Restart background kloak process. {{CodeSelect|code= sudo systemctl start kloak }} '''5.''' Persistent configuration change. To make this change permanent, see [[Keystroke_Deanonymization#Setting_persistent_kloak_settings|setting persistent kloak settings]]. '''6.''' Done. === Kloak Debug Mode === If you are experiencing problems with kloak, generating debug logs can be useful for determining what's going wrong. {{mbox |icon=fa-solid fa-exclamation cs-red |addToClass=cs-yellow-light |text= Warning: * Only enable in case of issues when needing a log file for debugging or sharing with a trusted user. * Kloak acts as a keylogger when running in verbose mode! Logs contain detailed info of all keystrokes and mouse movements made while kloak is running. Sharing kloak logs with another individual reveals key logs, mouse activity logs, and keyboard/mouse biometrics to the receiving user. Do not do anything sensitive while kloak is generating debug logs! Under no circumstances should you share a kloak log with any user you do not fully trust! Do not publicize kloak logs, transmit them over an insecure channel, or store them online unencrypted! }} Kloak provides a -v option that is useful in these scenarios. Due to the volume of data kloak produces during logging, it is recommended that you run kloak in a terminal when gathering logs. To run kloak in verbose mode, run the following commands: '''1.''' Stop background kloak process first {{CodeSelect|code= sudo systemctl stop kloak }} '''2.''' Run kloak in terminal {{CodeSelect|code= sudo kloak -v }} '''3.''' Gather logs, then terminate with Ctrl+C or rescue key sequence. '''4.''' Restart background kloak process {{CodeSelect|code= sudo systemctl start kloak }} '''5.''' Persistent configuration change. To make this change permanent, see [[Keystroke_Deanonymization#Setting_persistent_kloak_settings|setting persistent kloak settings]]. '''6.''' Done. === Setting persistent kloak settings === Notes: * Kloak's verbose mode can be enabled as a persistent setting by following these instructions. However, verbose mode generates copious amounts of data, which may consume large amounts of disk space or cause wear-and-tear on the disks. Enabling verbose mode as a persistent setting is not recommended. If you use kloak as a systemd service and wish to use some of its options, you may do so by adding a configuration file for kloak. To do this: '''1.''' {{Open with root rights|filename= /lib/systemd/system/kloak.service.d/50_user.conf }} '''2.''' Paste. Note: Replace <options> with the options you wish to pass to kloak. {{CodeSelect|code= [Service] ExecStart=/usr/sbin/kloak }} '''3.''' Save and exit. '''4.''' Reload systemd manager configuration. {{CodeSelect|code= sudo systemctl daemon-reload }} '''5.''' Restart kloak. {{CodeSelect|code= sudo systemctl restart kloak }} '''6.''' Done. Kloak will now run with custom options. === View kloak journal log === If you want to look at any info kloak may have output since starting it, you may do so by checking the journal logs. To do this, run: {{CodeSelect|code= sudo journalctl -u kloak {{!}} cat }} === xrdp === {{quotation |quote= Looked into what would be necessary to make kloak work over xrdp. Sadly this does not seem possible, as xrdp acts as its own X server (to my awareness) and thus intercepting and delaying keystrokes would require kloak to somehow intercept the keystrokes at the layer between the X server and the applications. I looked ways of doing this but failed to find them - there are ways of logging keystrokes at the X server level, but my research failed to find a way to block keystrokes or otherwise keep them from being delivered to applications for the purpose of delaying them. This issue affects any use of kloak over a remote desktop session - unless the remote desktop application creates uinput devices on the remote machine and then feeds user input into them, kloak will not be able to intercept them. Recommendation - xrdp users should run kloak on the client machine to obfuscate their typing patterns on the client. This will then naturally obfuscate them on the remote machine as well. |context=ArrayBolt3 }} === Stop Kloak === It is usually not required to stop kloak unless for testing, debugging. Stop clock until restart or reboot. {{CodeSelect|code= sudo systemctl stop kloak }} === Start Kloak === It is usually not required to start kloak as it is running by default. Start kloak. {{CodeSelect|code= sudo systemctl restart kloak }} === Kloak Status === {{CodeSelect|code= sudo systemctl status kloak }} == Qubes Event Buffering == {{mbox |type = notice |image = [[File:Ambox_notice.png|40px|alt=Info]] |text = This feature is only available in Qubes OS R4.3 and later. At the time of this writing, Qubes OS R4.3 has not yet been released. Use of the pre-release builds is not recommended for inexperienced users or users with high security requirements. This is a feature built into Qubes OS. It is not a part of Whonix itself, and can be used with any Qubes OS virtual machine except for full desktop StandaloneVMs. }} Qubes OS is incompatible with Kloak, due to the fact that most VMs in Qubes OS do not use evdev to receive input. To provide the same benefits as Kloak despite these limitations, Qubes OS R4.3 provides a feature known as "event buffering". Whereas kloak would run within each individual VM, intercepting and buffering evdev input events, Qubes event buffering runs on dom0, catching X11 input events intended for a particular VM and buffering them before sending them to the VM. Qubes event buffering uses the same underlying algorithms as kloak, and should be similarly effective. To enable event buffering for a particular VM: '''1:''' Determine the VM you want to enable event buffering on. We will use whonix-workstation-17-dvm as our example here. '''2:''' Open a terminal in dom0. '''3:''' Run: {{CodeSelect|code= qvm-features whonix-workstation-17-dvm gui-events-max-delay 200 }} This will enable event buffering on whonix-workstation-17-dvm, with a maximum buffer time of 200ms. If you want a longer buffer time, specify a larger number as the last argument. '''4:''' This setting does not take effect on currently running VMs. If whonix-workstation-17-dvm or any DispVMs based on it are running, shut them down. '''5:''' Done. Event buffering is now enabled for whonix-workstation-17-dev. You should notice a delay in typing when you launch the VM next. = Limitations = == Kloak and Qubes Event Buffering == Both kloak and Qubes event buffering have some limitations users MUST be aware of before relying on them for security: * '''Mouse events are cloaked, but not as well as keyboard events.''' Pointing devices (mice, touchpads, trackballs, etc.) produce a very large number of events when the pointer is being moved by the user. Both kloak and Qubes event buffering use a scheduling system that queues events as they arrive, and tries to ensure no event is delayed longer than the set maximum delay value. Because pointing devices flood the queue with events when the pointer is moved, this usually results in almost all of the events involved in a pointer movement being delayed for exactly the maximum delay time. This gets rid of almost all anonymizing jitter, and may allow an adversary to fingerprint and identify the user via mouse movements even if kloak or event buffering is being used. * '''Typing may be substantially more difficult.''' Because kloak and event buffering both queue, delay, and release keystrokes at semi-randomly chosen times, typing is not as easy when using kloak. Lag is usually noticeable and unpredictable. Shorter maximum delay times can improve usability, but only at the cost of providing less anonymity. * '''Biometric software can tell that you're using kloak.''' When using kloak, one's typing rhythm will appear very unnatural and strange to biometric software, which is a pretty clear indicator that one is using kloak or software similar to it. Kloak makes no attempt to mask its use. It only is able to make all kloak and kloak-alike users look similar to each other. This is similar to the limitations of Tor - one cannot tell which Tor user is accessing a resource, but they can tell very easily that the resource is being accessed over Tor. * '''Legitimate uses of biometric software will break.''' If you use software that uses keystroke biometrics to identify you, it will almost certainly fail to identify you if you are using kloak. This may require you to temporarily disable kloak before using certain services. == Kloak only == The following limitations apply only to kloak, not to Qubes event buffering: * '''Kloak only works if the system uses the evdev input driver.''' Almost all modern Linux distributions use evdev by default for input devices. Qubes OS is a notable exception - it uses its own virtual input device, which the X server in each qube reads from. Kloak is not capable of intercepting events from non-evdev-based input devices. * '''Kloak does not intercept events that are fed directly to the system's display server without going through an input device driver.''' Any form of emulated input cannot be intercepted by kloak. Remote desktop software frequently uses emulated input for obvious reasons. Another common class of software that makes use of emulated input is Keyboard-Video-Mouse (KVM) software such as Barrier, Synergy, and Input Leap. If you need kloak to provide anonymity in these scenarios, you '''must''' run kloak on the machine that the physical keyboard and mouse are attached to. This will obfuscate the movements the host machine sees, and therefore obfuscate the movements that are sent to other machines via emulated input. == Qubes event buffering only == The following limitations apply only to Qubes event buffering, not kloak: * '''Event buffering is not available in any version of Qubes R4.2 or earlier.''' It will be present in Qubes R4.3.0 and later. * '''There is no easy way to enable or configure event buffering.''' The only way to enable and configure event buffering is using the qvm-features command in a dom0 terminal. A configuration feature event buffering may be added to Qube Manager in the future. * '''Event buffering is not enabled by default on Qubes-Whonix-Workstation.''' It must be explicitly enabled by the end user. This is expected to be fixed. See [https://github.com/QubesOS/qubes-issues/issues/9771 Enable X11 event buffering in Whonix by default]. = Defense Testing = You can test that kloak actually works by trying a keystroke test website. https://vmonaco.com/device-fingerprinting/ is a good choice as it is free, open source, and requires no personal data or signup process to use. The code is visible at https://github.com/vmonaco/device-fingerprinting. To use the test: * Ensure kloak is not running. * Open the website. * Move the mouse around and click on random locations on the page. You will see a graph labeled "mousemove" start to update. As the mouse moves, the graph should eventually show a few (oftentimes only one) orange-marked spikes that act as a fingerprint for your device. * Click inside the text area and type for some amount of time. A graph labeled "keydown" should show one or more prominent orange-marked spikes after a bit of typing. * Start kloak. then refresh the page. * Move the mouse around again. The graph will act erratically and fail to obtain an orange-marked spike for very long. * Click inside the text area and type for some amount of time. The graph should act erratically similar to the mouse graph. * By default, the website uses event.timeStamp as a time source for fingerprint extraction. If desired, repeat the above steps with the other time sources (Date.now(), performance.now(), and Web Worker). A device or biometric fingerprint can be obtained quickly and with high certainty when kloak is not used. The tests done with kloak enabled show that kloak obfuscated typing behavior, making it difficult to authenticate or identify a particular user. Note that websites that observe typing behavior will likely see users running kloak as being distinctly different from other users (due to the randomized, unnatural typing rhythms and mouse movements). This is similar to how Tor users can be detected separately from internet users who do not use Tor, but telling individual Tor users from each other is very difficult. As more users use kloak, the anonymity set will increase. Other potential tests (not recommended): * https://www.typingdna.com/demo-sametext.html * https://github.com/topics/keystroke-dynamics * [https://forums.whonix.org/t/current-state-of-kloak/5605/60 forum discussion] Previously KeyTrac was recommended for testing kloak. However, the KeyTrac demo is no longer available. When KeyTrac did exist, the following results were obtained by training and testing KeyTrac with and without kloak: {{Box|text= '''Train normal, test normal''' trial 1: 94% accuracy identified trial 2: 92% accuracy trial 3: 94% .. '''Train normal, test kloak''' trial 1: 18% trial 2: 15% trial 3: 19% '''Train kloak, test kloak''' trial 1: 40% trial 2: 42% trial 3 36% }} Without kloak users can be identified with very high certainty. The second set of tests show that kloak definitely obfuscates typing behavior, making it difficult to authenticate or identify a particular user. Third set: users running kloak may look "similar" to other users running kloak. That is, it might be possible to identify kloak users from non-kloak users. These results are similar to the results obtained using vmonaco's device fingerprinting test. References: * [[Surfing_Posting_Blogging#Mouse_Fingerprinting|Mouse Fingerprinting]] * https://github.com/vmonaco/keystroke-obfuscation * https://github.com/vmonaco/keystroke-obfuscation/issues/1#issuecomment-268598887 * https://github.com/vmonaco/kloak * https://github.com/vmonaco/kloak/issues/7#issuecomment-893817507 * https://twitter.com/{{project_name_short}}/status/1111053743905226752 * https://t.co/QcKyLppZBr * https://forums.whonix.org/t/current-state-of-kloak/5605 * https://phabricator.whonix.org/T583 * https://forums.whonix.org/t/device-fingerprinting-with-peripheral-timestamps-mouse-fingerprinting/12114 = Potential future development research = * Do X11 or Wayland provide hooks that would allow intercepting input events as read by the Wayland compositor or X server, before those events are sent directly to applications? This would allow kloak to work even with setups that don't use evdev. * Could a "toggle" feature be added to kloak to allow temporarily enabling and disabling it without having to stop the kloak service entirely? This would be useful for users who have high anonymity requirements, but also have to use systems that use keystroke biometrics as a legitimate method of authentication. * Can mouse events be obfuscated better? It might be possible to randomly select times at which to deliver mouse events, then deliver all queued mouse events at once at those selected times, with intermediate events "squashed" together so that the mouse simply jumps to the position it would have ended up in had all mouse events been processed normally. If this is done, mouse events should probably be handled in a separate queue from keyboard events. = See Also = * [https://raw.githubusercontent.com/vmonaco/vmonaco.github.io/master/papers/Device%20Fingerprinting%20with%20Peripheral%20Timestamps.pdf Device Fingerprinting with Peripheral Timestamps] * [[stylometry|Stylometry]] * [[Surfing_Posting_Blogging|Surfing Posting Blogging]] = References = {{reflist|close=1}} {{Footer}} [[Category:Documentation]]