Privacy improving suggestions for ObscureKeystrokeTiming

58 views
Skip to first unread message

pro...@riseup.net

unread,
Sep 6, 2023, 2:59:57 PM9/6/23
to openssh-...@mindrot.org
Hi, Whonix OS privacy dev here. I had a discussion concerning the new
ObscureKeystrokeTiming feature with a prominent researcher and author of
the mouse and keyboard biometrics obfuscation tool called Kloak. While
it's exciting to see keystroke obfuscation measures [1] start to become
more prevalent mainstream, the current implementation of using a 50Hz
fixed packet timing has the potential to create fingerprinting risks for
hosts. Reason being, not all computer clocks have the exact same
precision. Some may oscillate slightly faster or slower because of the
physical discrepancies of clock crystals. A network adversary monitoring
connections on the clearnet could potentially link future ones of the
same host even if routed through an anonymity network like Tor.

Advanced attacks where attackers run loads on onion services that
influence CPU activity and clock skew in predictable ways [2] may be
possibly used to deanonymize them.

We would suggest drawing the padding packet intervals from some other
distribution instead of firing these off on a fixed timer. Basically, do
what kloak does but at the network layer.


[0] https://github.com/vmonaco/kloak
[1] http://undeadly.org/cgi?action=article;sid=20230829051257
[2] https://murdoch.is/talks/ccs06hotornot.pdf
_______________________________________________
openssh-unix-dev mailing list
openssh-...@mindrot.org
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev

Damien Miller

unread,
Sep 7, 2023, 12:49:23 AM9/7/23
to pro...@riseup.net, openssh-...@mindrot.org
On Wed, 6 Sep 2023, pro...@riseup.net wrote:

> Hi, Whonix OS privacy dev here. I had a discussion concerning the new
> ObscureKeystrokeTiming feature with a prominent researcher and author of the
> mouse and keyboard biometrics obfuscation tool called Kloak. While it's
> exciting to see keystroke obfuscation measures [1] start to become more
> prevalent mainstream, the current implementation of using a 50Hz fixed packet
> timing has the potential to create fingerprinting risks for hosts. Reason
> being, not all computer clocks have the exact same precision. Some may
> oscillate slightly faster or slower because of the physical discrepancies of
> clock crystals. A network adversary monitoring connections on the clearnet
> could potentially link future ones of the same host even if routed through an
> anonymity network like Tor.
>
> Advanced attacks where attackers run loads on onion services that influence
> CPU activity and clock skew in predictable ways [2] may be possibly used to
> deanonymize them.
>
> We would suggest drawing the padding packet intervals from some other
> distribution instead of firing these off on a fixed timer. Basically, do what
> kloak does but at the network layer.

Yeah, making the intervals a bit uncertain seems like a reasonable idea.
This gives them 10% jitter.

diff --git a/clientloop.c b/clientloop.c
index b461917..73cdd09 100644
--- a/clientloop.c
+++ b/clientloop.c
@@ -109,6 +109,9 @@
/* Permitted RSA signature algorithms for UpdateHostkeys proofs */
#define HOSTKEY_PROOF_RSA_ALGS "rsa-sha2-512,rsa-sha2-256"

+/* Uncertainty (in percent) of keystroke timing intervals */
+#define SSH_KEYSTROKE_TIMING_FUZZ 10
+
/* import options */
extern Options options;

@@ -519,6 +522,33 @@ send_chaff(struct ssh *ssh)
return 1;
}

+/* Sets the next interval to send a keystroke or chaff packet */
+static void
+set_next_interval(const struct timespec *now, struct timespec *next_interval,
+ u_int interval_ms, u_int interval_fuzz_pct)
+{
+ struct timespec tmp;
+ long long interval_ns, fuzz_ns;
+
+ interval_ns = interval_ms * (1000LL * 1000);
+ fuzz_ns = (interval_ns * interval_fuzz_pct) / 100;
+ /* Center fuzz around requested interval */
+ if (fuzz_ns > INT_MAX)
+ fuzz_ns = INT_MAX;
+ if (fuzz_ns > interval_ns) {
+ /* Shouldn't happen */
+ fatal_f("internal error: fuzz %u%% %lldns > interval %lldns",
+ interval_fuzz_pct, fuzz_ns, interval_ns);
+ }
+ interval_ns -= fuzz_ns / 2;
+ interval_ns += arc4random_uniform(fuzz_ns);
+
+ tmp.tv_sec = interval_ns / (1000 * 1000 * 1000);
+ tmp.tv_nsec = interval_ns % (1000 * 1000 * 1000);
+
+ timespecadd(now, &tmp, next_interval);
+}
+
/*
* Performs keystroke timing obfuscation. Returns non-zero if the
* output fd should be polled.
@@ -586,8 +616,9 @@ obfuscate_keystroke_timing(struct ssh *ssh, struct timespec *timeout,
options.obscure_keystroke_timing_interval);
just_started = had_keystroke = active = 1;
nchaff = 0;
- ms_to_timespec(&tmp, options.obscure_keystroke_timing_interval);
- timespecadd(&now, &tmp, &next_interval);
+ set_next_interval(&now, &next_interval,
+ options.obscure_keystroke_timing_interval,
+ SSH_KEYSTROKE_TIMING_FUZZ);
}

/* Don't hold off if obfuscation inactive */
@@ -620,8 +651,9 @@ obfuscate_keystroke_timing(struct ssh *ssh, struct timespec *timeout,
n = (n < 0) ? 1 : n + 1;

/* Advance to the next interval */
- ms_to_timespec(&tmp, options.obscure_keystroke_timing_interval * n);
- timespecadd(&now, &tmp, &next_interval);
+ set_next_interval(&now, &next_interval,
+ options.obscure_keystroke_timing_interval * n,
+ SSH_KEYSTROKE_TIMING_FUZZ);
return 1;

Damien Miller

unread,
Sep 9, 2023, 11:35:03 PM9/9/23
to pro...@riseup.net, openssh-...@mindrot.org
On Thu, 7 Sep 2023, Damien Miller wrote:

> Yeah, making the intervals a bit uncertain seems like a reasonable idea.
> This gives them 10% jitter.

FYI We committed something similar to this
Reply all
Reply to author
Forward
0 new messages