Re: [Tails-dev] active probing vs. AdvGoalTracking [Was: [RF…

Delete this message

Reply to this message
Author: anonym
Date:  
To: The Tails public development discussion list
Subject: Re: [Tails-dev] active probing vs. AdvGoalTracking [Was: [RFC] Design (and prototype) for MAC spoofing in Tails]
21/11/13 13:50, intrigeri wrote:
> Hi,
>
> anonym wrote (21 Nov 2013 05:58:37 GMT) :
>> Ah, I didn't connect the dots before. What you mean is that, with
>> persistent NM-connections, the list of ssids/bssids/whatever probed for
>> can be used as a fingerprint.
>
> Right.
>
>> I haven't looked into NM's code yet, but I promise to do so soon, cause
>> I certainly get your point. I've at least updated the blueprint to
>> reflect this (see the "Active probe fingerprinting" section).
>
> Great.


I've done some investigating of NetworkManager (and wpa_supplicant) and
this is what I've gathered. We cannot fully disable active scanning; no
matter what we do, some Probe Requests will be sent, however, all is
still good:

* If NM sets scan_ssid=0 in wpa_supplicant, then only broadcast Probe
Requests are sent, so no known SSIDs are disclosed. Hurray, that's
what we want! Broadcasts are actually useful so it's good we don't
have to disable them.

* If NM sends scan_ssid=1, then directed Probe Requests are sent to
some number of known SSIDS in addition to the broadcast.

It remains to decide whether we want to always set scan_ssid=0, or only
do it when MAC spoofing is enabled. Always doing it may leak that we are
using Tails if the device supports active scanning (supposedly "many" do
not according to wpa_supplicant, but that statement may be out-dated):
first we start Tails without MAC spoofing enabled, and then we reboot
with another OS that has some saved connections. In the first instance
no directed active probes are witnessed from the MAC address, but in the
seconds some are. This is a pretty weak leak, though, since the first
case may be interpreted as a using different profile/OS instead of Tails.

To always set scan_ssid=0 is of course much easier to implement.
Otherwise we'll have to add a NetworkManager.conf option, I suppose,
which after an initial investigation looks non-trivial. Also scan_ssid=0
is the default in wpa_supplicant and supposedly works quite well even
for hidden networks (one can instead use ap_scan=2, which NM will set
automatically when needed) so it shouldn't add much problems. In fact,
after some bug searching it seems there are more issues with hidden
networks with the other method. :)

I feel inclined to go the simple path: we always set scan_ssid=0.

Thoughts?

# How to completely disable directed Probe Requests (but not broadcasts)

It should be noted that I haven't yet verified that any of the below
solutions work. I've built some squeeze debs with the solution below and
will try it one of these days.

## NM in squeeze (0.8.1-6+squeeze2)

We always set scan_ssid=0.

diff --git a/src/supplicant-manager/nm-supplicant-config.c
b/src/supplicant-manager/nm-supplicant-config.c
index b516de5..89de45d 100644
--- a/src/supplicant-manager/nm-supplicant-config.c
+++ b/src/supplicant-manager/nm-supplicant-config.c
@@ -402,13 +402,11 @@ nm_supplicant_config_add_setting_wireless
(NMSupplicantConfig * self,
                }
        }


-       /* Except for Ad-Hoc networks, request that the driver probe for the
-        * specific SSID we want to associate with.
-        */
-       if (!is_adhoc) {
-               if (!nm_supplicant_config_add_option (self, "scan_ssid",
"1", -1, FALSE))
-                       return FALSE;
-       }
+       /* We don't want to broadcast any SSIDs since they can be used to
+        * fingerprint individual Tails users based on peristently stored
+        * NM connections. */
+       if (!nm_supplicant_config_add_option (self, "scan_ssid", "0",
-1, FALSE))
+               return FALSE;


        id = nm_setting_wireless_get_bssid (setting);
        if (id && id->len) {


## NM in wheezy (0.9.4.0-10)

Same as in squeeze (modulo line numbering).

diff --git a/src/supplicant-manager/nm-supplicant-config.c
b/src/supplicant-manager/nm-supplicant-config.c
index a8e4ab9..76c582e 100644
--- a/src/supplicant-manager/nm-supplicant-config.c
+++ b/src/supplicant-manager/nm-supplicant-config.c
@@ -412,13 +412,11 @@ nm_supplicant_config_add_setting_wireless
(NMSupplicantConfig * self,
                }
        }


-       /* Except for Ad-Hoc networks, request that the driver probe for the
-        * specific SSID we want to associate with.
-        */
-       if (!is_adhoc) {
-               if (!nm_supplicant_config_add_option (self, "scan_ssid",
"1", -1, FALSE))
-                       return FALSE;
-       }
+       /* We don't want to broadcast any SSIDs since they can be used to
+        * fingerprint individual Tails users based on peristently stored
+        * NM connections. */
+       if (!nm_supplicant_config_add_option (self, "scan_ssid", "0",
-1, FALSE))
+               return FALSE;


        id = nm_setting_wireless_get_bssid (setting);
        if (id && id->len) {


## Upstream NM's git (as of commit 90782cf, 0.9.9.0 development)

Nowadays NM actually tries to limit the privacy implications of active
scanning by allowing at most five SSIDs from stored connections to be
used for directed Probe Requests. That's not good enough, obvioudly, so
we instead set the maximum to 0, which yields the same result as
scan_ssid=0. [We could also set the maximum to 1, since NM assumes that
wpa_supplicant will use one itself for the broadcast, so NM will only do
stuff with >=2.]

diff --git a/src/supplicant-manager/nm-supplicant-interface.c
b/src/supplicant-manager/nm-supplicant-interface.c
index 4063085..6d03568 100644
--- a/src/supplicant-manager/nm-supplicant-interface.c
+++ b/src/supplicant-manager/nm-supplicant-interface.c
@@ -411,38 +411,11 @@ static void
 parse_capabilities (NMSupplicantInterface *self, GHashTable *props)
 {
        NMSupplicantInterfacePrivate *priv =
NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
-       GValue *value;
-       gboolean have_active = FALSE, have_ssid = FALSE;
-
-       g_return_if_fail (props != NULL);
-
-       value = g_hash_table_lookup (props, "Scan");
-       if (value && G_VALUE_HOLDS (value, G_TYPE_STRV)) {
-               const char **vals = g_value_get_boxed (value);
-               const char **iter = vals;
-
-               while (iter && *iter && (!have_active || !have_ssid)) {
-                       if (g_strcmp0 (*iter, "active") == 0)
-                               have_active = TRUE;
-                       else if (g_strcmp0 (*iter, "ssid") == 0)
-                               have_ssid = TRUE;
-                       iter++;
-               }
-       }


-       value = g_hash_table_lookup (props, "MaxScanSSID");
-       if (value && G_VALUE_HOLDS (value, G_TYPE_INT)) {
-               /* We need active scan and SSID probe capabilities to
care about MaxScanSSIDs */
-               if (have_active && have_ssid) {
-                       /* wpa_supplicant's WPAS_MAX_SCAN_SSIDS value is
16, but for speed
-                        * and to ensure we don't disclose too many
SSIDs from the hidden
-                        * list, we'll limit to 5.
-                        */
-                       priv->max_scan_ssids = CLAMP (g_value_get_int
(value), 0, 5);
-                       nm_log_info (LOGD_SUPPLICANT, "(%s) supports %d
scan SSIDs",
-                                    priv->dev, priv->max_scan_ssids);
-               }
-       }
+       /* We don't want to broadcast any SSIDs since they can be used to
+        * fingerprint individual Tails users based on peristently stored
+        * NM connections. */
+       priv->max_scan_ssids = 0;
 }


static void