Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature Request: Anti-Keystroke Fingerprinting Tool #1850

Closed
HulaHoopWhonix opened this issue Mar 17, 2016 · 12 comments
Closed

Feature Request: Anti-Keystroke Fingerprinting Tool #1850

HulaHoopWhonix opened this issue Mar 17, 2016 · 12 comments
Labels
C: gui-virtualization C: Whonix This issue impacts Qubes-Whonix help wanted This issue will probably not get done in a timely fashion without help from community contributors. P: default Priority: default. Default priority for new issues, to be replaced given sufficient information. privacy This issue pertains to data or information privacy through technological means.

Comments

@HulaHoopWhonix
Copy link

Keystroke fingerprinting works by measuring how long keys are pressed and the time between presses. Its very high accuracy poses a serious threat to anonymous users.[1]

This tracking technology has been deployed by major advertisers (Google, Facebook), banks and massive online courses. Its also happening at a massive scale because just using an interactive JS application in presence of a network adversary that records all traffic allows them to construct biometric models for virtually everyone (think Google suggestions) even if the website does not record these biometric stats itself.[2] They have this data from everyone's clearnet browsing and by comparing this to data exiting the Tor network they will unmask users.

As a countermeasure security researcher Paul Moore created a prototype Chrome plugin known as KeyboardPrivacy. It works by caching keystrokes and introducing a random delay before passing them on to a webpage.[3] Unfortunately there is no source code available for the add-on and the planned Firefox version has not surfaced so far. There are hints that the author wants to create a closed hardware solution that implements this which does not help our cause.

A very much needed project would be to write a program that mimics the functionality of the this add-on but on the display server / OS level. Ideally the solution would be compatible with Wayland for the upcoming transition in the near future.

[1] http://arstechnica.com/security/2015/07/how-the-way-you-type-can-shatter-anonymity-even-on-tor/

[2] http://ieeexplore.ieee.org/xpls/abs_all.jsp?arnumber=7358795

[3] https://archive.is/vCvWb

@adrelanos
Copy link
Member

adrelanos commented Mar 17, 2016

Confirmed. This affects anonymity / Whonix.

A very much needed project would be to write a program that mimics the functionality of the this add-on but on the display server / OS level. Ideally the solution would be compatible with Wayland for the upcoming transition in the near future.

Sounds like a great solution. Unfortunately this is outside my abilities. Help welcome!

@rootkovska
Copy link
Member

Looks like this could be a simple modification to Qubes GUI daemon. Of course would have to be opt-in enabled for select VMs only.

@andrewdavidwong andrewdavidwong added enhancement help wanted This issue will probably not get done in a timely fashion without help from community contributors. C: gui-virtualization privacy This issue pertains to data or information privacy through technological means. labels Apr 6, 2016
@andrewdavidwong andrewdavidwong added this to the Far in the future milestone Jun 7, 2016
andrewdavidwong added a commit that referenced this issue Jun 7, 2016
@sdffgh
Copy link

sdffgh commented Jul 28, 2016

Unfortunately there is no source code available for the add-on

There is! Chrome Extensions are just are zip files with some added metadata. If we unzip the extension's crx file, all the relevant code is a few lines in js/input.js.

See Tim's comment on https://paul.reviews/behavioral-profiling-the-password-you-cant-change/#comment-2165097313 where he includes a paste of the source code, the discussions below on the choices, and Paul's comment "If you strip away the fundamentals required to make a chrome extension, the code is just 13 lines long".

There is no license mentioned. One of you who knows more about licenses and legality can better decide how to proceed. If it's legal, maybe we could just reconstruct Paul's technique that he described publicly without looking at his code. The javascript basically just adds random delays and other implementation details are only meant to delay the js thread to disrupt timing of keystroke-initiated browser events, but that is unnessary if the delays are introduced outside the VM, and therefore outside the browser. In that case it is sufficient to just add random delays to keystroke times. The tests to confirm that this works against the bank fingerprinting demo are also very simple and can be reproduced if we're not sure that the new code has the same effectiveness as Paul's.

@adrelanos
Copy link
Member

Related:

@iacore
Copy link

iacore commented Jul 7, 2022

A simpler solution to this is to block tracking scripts using an ad blocker, and visit Facebook in separate VM (or don't visit at all).

Maybe running kloak in dom0 as sudo will work.

@adrelanos
Copy link
Member

A simpler solution to this is to block tracking scripts using an ad blocker, and visit Facebook in separate VM (or don't visit at all).

Blocking is a denylist approach and will always be a game of whack-a-mole and miss some things. Hence not a reliable approach. And not limited to facebook. I don't know if facebook does this. Could happen anyhwere.

Maybe running kloak in dom0 as sudo will work.

That would work but the kloak would needlessly apply to dom0 and all other VMs too. Since kloak might cause some (and currently even some nasty bugs such as vmonaco/kloak#31) I wouldn't recommend it.

@adrelanos
Copy link
Member

Quote #2558

kloak (anti keystroke deanonymization tool) currently cannot be used inside Qubes.

quote @marmarek:

Hmm, I was under impression it expect X server input device, not not Linux kernel input device. Qubes GUI agent do not expose the later. It shouldn't be hard to change that, but still it is some code change. Namely, rewrite this function (feed /dev/uinput instead of X input device).

@andrewdavidwong
Copy link
Member

@bluesteal: Please note that the issue tracker (qubes-issues) is not intended to be a place for fielding questions. Instead, we have other venues meant for asking questions, asking for help, and having discussions. (By contrast, the issue tracker is more of a technical tool intended to support our developers in their work.) Thank you for your understanding!

@ArrayBolt3
Copy link

It looks like this is just about ready to make work - I was able to get Kloak up-and-running inside a Whonix Workstation VM under Qubes R4.2 by doing the following:

  • Launch a terminal in the whonix-workstation-17 template.
  • In whonix-workstation-17, install xserver-xorg-input-evdev (this is required for the evdev-based keyboard input to work, if you don't do this your keyboard will be entirely non-functional within the VM)
  • In whonix-workstation-17, install kloak.
  • In dom0, run qvm-service whonix-workstation-17-dvm gui-agent-virtual-input-device on to enable the evdev-based input driver.
  • Shut down whonix-workstation-17 and wait for it to fully shut down.
  • Launch a DispVM from whonix-workstation-17-dvm.
  • Open XFCE Terminal in the new DispVM.
  • Ensure you can type.
  • Run sudo systemctl stop kloak && sudo /usr/sbin/kloak -d250 & and ensure kloak starts properly.
  • Type a bit in the terminal, you should notice significant lag and randomized timing as what you type appears on the screen.

The primary issue at this point is that we need xserver-xorg-input-evdev to be installed within Whonix Workstation in order to safely fix #8534. Otherwise the keyboard will become unusable in Whonix. This has to be done first, then the other ticket can be solved. Doing this will require a bit of orchestration. I think qubes-core-admin's API can be used for this, by making it so that the evdev input service is only enabled on Whonix Workstation VMs that advertise support for it, and that support is only advertised within Whonix Workstation if the evdev driver is present. But I'm not entirely sure that works, and am also slightly at a loss as to how I should test it.

Any thoughts?

marmarek added a commit to QubesOS/qubes-gui-daemon that referenced this issue Nov 18, 2024
* origin/pr/149:
  Add event buffering for cloaking user input patterns
  Replace magic quotes with normal quotes in parse_vm_config
  Typo fix, change "canot" to "cannot"

Pull request description:

# Goal

Implement the functionality of [kloak](https://github.com/Whonix/kloak) (a tool designed to hide biometric behavior patterns in keystrokes and mouse movements) in qubes-gui-daemon. This PR will implement the functionality requested in QubesOS/qubes-issues#1850 and fleshed out further in QubesOS/qubes-issues#8541. It will also close QubesOS/qubes-issues#8534 as it will no longer be necessary.

# TODOs

* Test rigorously on Qubes R4.3 (an earlier iteration of the code has been smoke-tested on Qubes R4.2, this hasn't been tested at all on R4.3 yet)

# Fixed TODOs:

* Figure out why the domU window occasionally freezes until another input event is sent - we aren't buffering info coming from domU to dom0 so why this is happening is a mystery to me, and something for later investigation. (Solved, #149 (comment))
* Potentially change how events are treated (do some events have to operate in pairs for best results?). (Lots of X events are now not buffered in the latest implementation. Only ones that look valuable to buffer are buffered.)
* Make the delay duration user-configurable (right now it's hardcoded to 150 milliseconds). (Implemented.)
* Allow configuring event delay duration for individual VMs buffering (right now it is applied equally to all VMs). (Implemented.)
* Get the configuration code working and test it. (Solved, this ended up requiring a change to [core-admin-client](https://forum.qubes-os.org/t/cannot-change-qubes-gui-daemon-settings-using-qvm-features/29345/3) which I will be submitting as a separate PR.)
* Ensure all new code adheres to Qubes OS standards (didn't have time to finish that up) (should be done now)

# Rationale

Kloak, the inspiration for this PR, is a user input buffering and obfuscation tool. It intercepts keyboard and mouse events at the evdev layer, holds them in a queue for release at a later scheduled time, then releases them to the applications they were intended for periodically. By adding random noise into the user's input patterns, kloak aims to make otherwise recognizable patterns in user behavior (such as keystroke rhythm and mouse movement patterns) too erratic to be used as a method of identifying the user. This is potentially very useful especially for Whonix Workstation domUs, as it denies an adversary access to a remarkably effective biometric fingerprinting mechanism they could otherwise access without specialized tools.

Kloak is currently able to operate directly in Qubes domUs if (and only if!) `gui-agent-virtual-input-device` is enabled for the domU in question. Even in these instances, only keyboard events are anonymized, and additionally the domU must have an evdev X driver installed. This is less than ideal from a functionality standpoint, and as @DemiMarie has explained in QubesOS/qubes-issues#8541 it will eventually stop working entirely. There's also the possibility of malware compromise in the domU resulting in the deanonymization of the user. For these reasons, enabling the use of evdev in domUs and running kloak in the domU is not a good solution.

The other obvious option is to run kloak directly in dom0. This has several disadvantages:

* kloak can now potentially wreak havoc on the user's ability to use their computer. If a bug in kloak locks up the keyboard, or the user does something inadvisable like setting a 20-second event delay, regaining control of the system could be difficult or impossible without doing a hard reset (or worse, booting an external USB in order to chroot into dom0 and disable kloak).
* Application of kloak's functionality becomes all-or-nothing - you either anonymize all keyboard and mouse input everywhere, or you anonymize none of it. This could make management of dom0 annoying with larger delay times, and it could prevent the user from making use of applications or websites that require input pattern telemetry to function (such as some bank websites).
* kloak's configuration options similarly apply globally. One might want a comfortable delay of only 25ms in a domU they expect to be safe, but wish to use an extremely long one like 1000ms in a domU they believe is compromised and actively exfiltrating data. With kloak running directly in dom0, this is impossible.

This PR implements a third option - *inserting the functionality of kloak directly into qubes-gui-daemon.* kloak upstream never needs to be involved, only the functionality of it must be. This functionality I have termed "event buffering", and as this implementation works with X server events I have called it "event buffering", or "ebuf" for short (which is the term used for it in the code). Previously I had called this "X event buffering" and used "xbuf" for short, but as @3hhh pointed out that name would become inaccurate when this is ported to Wayland, so I changed it to "ebuf" so as to make the name be display server agnostic.

By working inside the GUI daemon, the following advantages are gained:

* No evdev support needed at all, we can work with X events instead.
* The amount of additional code needed is smaller.
* Per-VM application and configuration of event buffering is now possible - some VMs can use a small, comfortable delay, others can use a very long one, and others can skip delays entirely.
* Even if something goes very wrong and buffering prevents the user from inputting anything into any Qube, the user retains control of dom0 and can recover their system from there.
* A compromised domU with event buffering enabled will be less likely to leak valuable biometric info to the malware within the VM.

# How it works

Most of the code should be fairly self-explanatory. In a nutshell, we use a tail queue to store a list of delayed, scheduled X events. As events come from dom0 to a domU, they are captured, scheduled for release at a later time, and thrown into the queue. Events in the queue are regularly checked to see if their scheduled release time has arrived, and those events are released when appropriate. The scheduler inserts some random noise into the delays, making it difficult to uniquely identify the user's typing and mouse movement/usage patterns.

By default, event buffering is disabled and all events are passed through without buffering. To enable it, one must use `qvm-features` to set `gui-ebuf-max-delay` to a value greater than 0. It is worth noting that 0 is interpreted not as a "don't add any delay when buffering events", but rather it is interpreted as "don't buffer events at all". This configuration feature **does not work** without the `ebuf_max_events` setting being added to the list of GUI daemon configuration settings in qubes-core-admin-client. The pull request for that is at QubesOS/qubes-core-admin-client#309.

This PR needs more testing (especially on Qubes R4.3), but it is solid enough that I feel comfortable asking for a review on it. Thanks for your help!
@ArrayBolt3
Copy link

@HulaHoopWhonix, @marmarek I believe this can be closed now, as event buffering is now merged into Qubes R4.3. Whonix does need changes to take advantage of this, but the feature itself is here. Does it need to be exposed in some part of the user interface?

@andrewdavidwong
Copy link
Member

Closing as completed. If anyone believes this issue is not yet completed, or if anyone is still affected by this issue, please leave a comment saying so, and we'll be happy to reopen it. Thank you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C: gui-virtualization C: Whonix This issue impacts Qubes-Whonix help wanted This issue will probably not get done in a timely fashion without help from community contributors. P: default Priority: default. Default priority for new issues, to be replaced given sufficient information. privacy This issue pertains to data or information privacy through technological means.
Projects
None yet
Development

No branches or pull requests

8 participants
@adrelanos @HulaHoopWhonix @rootkovska @andrewdavidwong @sdffgh @iacore @ArrayBolt3 and others