[graphical gui] Whonix Setup Wizard / Anon Connection Wizard - Technical Discussion

Another anon-connection-wizard “full Tor controller” thought. Not realistic short term.

  • do not write to any Tor config files (except for DisableNetwork 1 by default shipped by the package to prevent Tor networking without anon-connection-wizard interaction)
  • talk only to Tor using Tor control protocol
  • Tor started by anon-connection-wizard rather than directly systemd (but therefore perhaps some anon-connection-wizard component being started by systemd)
  • config stored inside anon-connection-wizard database
1 Like

This is for Qubes users who don’t sudo apt-get autoremoveafter upgrade to Whonix 14 as suggested.

Please review.

https://github.com/Whonix/whonix-setup-wizard/commit/a269bbc616487e57e2ad092f517c0ccc7aa3fed0

1 Like

Hi Patrick!

I am not sure what is the relationship between sudo apt-get autoremove and the commit?

Tested on both Debian Stretch and Fedora 26 in Qubes, using the Tor from their default package manager.

user@latest-Tor:~$ ls -l /var/run/tor/
total 8
srw-rw---- 1 debian-tor debian-tor  0 Jan 29 18:26 control
-rw-r----- 1 debian-tor debian-tor 32 Jan 29 18:26 control.authcookie
srw-rw-rw- 1 debian-tor debian-tor  0 Jan 29 18:26 socks
-rw-r--r-- 1 debian-tor debian-tor  5 Jan 29 18:26 tor.pid

Then set DisableNetwork to 1 and start Tor without systemd:

user@latest-Tor:~$ sudo /usr/bin/tor --runasdaemon 0 --defaults-torrc /usr/share/tor/ -f /etc/tor/torrc
Jan 29 18:28:02.477 [notice] Tor 0.2.9.14 (git-a211f886ad759cab) running on Linux with Libevent 2.0.21-stable, OpenSSL 1.1.0f and Zlib 1.2.8.
Jan 29 18:28:02.477 [notice] Tor can't help you if you use it wrong! Learn how to be safe at https://www.torproject.org/download/download#warning
Jan 29 18:28:02.477 [notice] Read configuration file "/etc/tor/torrc".
Jan 29 18:28:02.480 [notice] DisableNetwork is set. Tor will not make or accept non-control network connections. Shutting down all existing connections.
Jan 29 18:28:02.000 [notice] Parsing GEOIP IPv4 file /usr/share/tor/geoip.
Jan 29 18:28:02.000 [notice] Parsing GEOIP IPv6 file /usr/share/tor/geoip6.
Jan 29 18:28:02.000 [warn] You are running Tor as root. You don't need to, and you probably shouldn't.
Jan 29 18:28:02.000 [notice] Bootstrapped 0%: Starting
Jan 29 18:28:02.000 [notice] Delaying directory fetches: DisableNetwork is set.

ls -l /var/run/tor/ again and control socket still exist.
Then restart Tor using systemd and control socket disappear:

user@latest-Tor:~$ systemctl restart tor@default.service 
user@latest-Tor:~$ ls -l /var/run/tor/
total 8
-rw-r----- 1 debian-tor debian-tor 32 Jan 29 18:29 control.authcookie
-rw-r--r-- 1 debian-tor debian-tor  5 Jan 29 18:29 tor.pid

I think this indicates this is not a Tor bug, maybe something related to systemd.

When DisableNetwork is set back to 0, the /var/run/tor/control will not be generated when executing:
sudo /usr/bin/tor --runasdaemon 0 --defaults-torrc /usr/share/tor/defaults-torrc -f /etc/tor/torrc

Not sure if this is the intended behaviors.

Can you reproduce this on a non-Qubes Whonix? @Patrick

iry:

Hi Patrick!

I am not sure what is the relationship between sudo apt-get autoremove and the commit?

These users not auto removing whonix-setup-wizard would continue to have
whonix-setup-wizard installed in Whonix-Workstation, which would result
in autostart of whonixcheck at every reboot. (Issue described above as
blocker.)

1 Like

acw is now security vulnerable with showing Tor bootstrap messages. We must make sure acw won’t aid in exploitation of the gateway.

If a Tor malfunction could lead to make Tor show weird messages as bootstrap status, these would be shown during bootstrap status. And Qt is parsing these for formatting.

Therefore we shouldn’t show Tor bootstrap messages verbatim as Tor is telling us. These need to be parsed and sanatized before shown in gui. Only static messages should be shown. (Possible to have sanazited variables such as digits of the length of three for bootstrap percent as reported by Tor.)

This is a good chance to translate all bootstrap status messages by Tor into user understandable speech.

As a stopgap, do you think you could make it show only the percentage and no bootstrap messages by Tor (until these are properly parsed, sanatized and translated to static strings)?

2 Likes

Patrick Schleizer:

As a stopgap, do you think you could make it show only the percentage
and no bootstrap messages by Tor (until these are properly parsed,
sanatized and translated to static strings)?

Hi Patrick! I just tested it and it can be done by changing one single
line. However:

If a Tor malfunction could lead to make Tor show weird messages as bootstrap status, these would be shown during bootstrap status. And Qt is parsing these for formatting.

My understanding is Whonix or whatever platform relies on using a
trusted Tor. If Tor itself has malfunction, or if the malfunction is
added to Tor by getting the root privilege and acting as debian-tor user
in Whonix-GW, then much more effective and simpler attack can be launched.

Please educate me if I misunderstand something. Thank you so much!

1 Like

True, if the malfunction means an exploited Tor client, then it’s game over.

But if a minor malfunction where for example a Tor relay can influence the bootstrap message by Tor to contain weird output, then such a small malfunction shouldn’t be able exploit a gui application showing that message.

2 Likes

But if a minor malfunction where for example a Tor relay can influence the bootstrap message by Tor to contain weird output, then such a small malfunction shouldn’t be able exploit a gui application showing that message.

Thank you for the explanation, Patrick!

I am not sure how hard/realistic such an attack will be due to the lack of knowledge on how Tor is paring the communication with Tor relay. But if it is a realistic one, we should definitely support it.

It seems to be something quiet simple to implement but maybe hard to maintain,

Right now:

bootstrap_status = self.tor_controller.get_info("status/bootstrap-phase")
bootstrap_percent = int(re.match('.* PROGRESS=([0-9]+).*', bootstrap_status).group(1))
bootstrap_phase = re.search(r'SUMMARY=(.*)', bootstrap_status).group(1)

Solution: change bootstrap_phase with a hardcoded string for each percentage.

New problem: Have to keep up with what Tor development on what the string is on each phase.

1 Like

Let’s go with this one for now. Can be improved in later releases.

The strings aren’t great for verbatim showing to the user anyhow. Somehow I also doubt that these strings change often. But indeed, for new strings (unknown at time of development) we need a static fallback message.

1 Like

Patrick Schleizer:

Let’s go with this one for now. Can be improved in later releases.

The strings aren’t great for verbatim showing to the user anyhow. Somehow I also doubt that these strings change often. But indeed, for new strings (unknown at time of development) we need a static fallback message.

I will do a pull request hopefully in 24 hours. :slight_smile:

1 Like

Done:

This implementation will prepare the bootstrap phase info for being translated.

It will also mitigate the vulnerability described in: http://forums.dds6qkxpwdeubwucdiaord2xgbbeyds25rbsgr73tbfpqpt4a6vjwsyd.onion/t/graphical-gui-whonix-setup-wizard-anon-connection-wizard-technical-discussion/650/540

However, I choose not to prevent the weird SUMMARY= from showing up when an attacker manipulates both TAG= and SUMMARY=. Because:

  1. The implementation will be consistent with the Tor launcher doc:

If Tor Launcher cannot map the TAG to a localized string, it displays the SUMMARY text instead otherwise, the SUMMARY field is not used).

  1. When such an attack is performed, we need to stay alert of it somehow.

What I am wondering is if such an alert should be exposed to daily user. Or should we simply keep it in a log?

3 Likes

Finally, this has been workarounded.

It turns out for unknown reason, when DisableNetwork set to 1, a simple systmctl restart tor@defautl.service is not enough. We have to do an additional systemctl reload tor@default.service.

I can reproduce this using systemd weird behaviors on both Debian and Fedora. Is this something we should report to BTS, @Patrick ?

3 Likes

Since now we can make sure that Tor control socket will open no matter what value DisableNetwork is.

The only reason for us to still write it to a file is to make Tor auto-connect to the network or not:

  • when value is 1, start Tor process but prevent Tor from connecting to the Network.
  • when value is 0, start Tor process and let Tor connect to the Network.

Therefore, we may actually set a box in anon-connection-wizard saying “After reboot, I want to start anon-connection-wizard again before connecting to the Tor network” or “After reboot, I want to connect to the Tor network with current set without being asked by anon-connection-wizard”


Currently, we use systemctl stop --no-pager tor@default.service to stop Tor process. However, do you think it will be better that we still keep Tor process but simply prevent Tor from connecting to the Network by talk to Tor control protocal?

What will happen?


Tor started by anon-connection-wizard rather than directly systemd (but therefore perhaps some anon-connection-wizard component being started by systemd)

It seems without systemd, control port will still be missing for unknown reason. For now, we may keep it and let it make sure Tor’s control socket is always open?

Yes, that would be great!

+            if bootstrap_tag in self.tag_phase:
+                bootstrap_phase = self.tag_phase[bootstrap_tag]
+            else:
+                # Only use SUMMARY= as phase info when the TAG= is not in the dictionary
+                bootstrap_phase = re.search(r'SUMMARY=(.*)', bootstrap_status).group(1)

This needs improvement. An unknown tag and re.search(r'SUMMARY=(.*)', bootstrap_status).group(1) is actually what we try to secure against here. So in that case, it should be a static message “unknown status” or something more useful. The real output could still be written to console and/or a lot so developers can add it for a later version (or notice when something did actually went wrong with Tor).

+        '''The TAG to phase mapping is mainly according to:
+        https://gitweb.torproject.org/tor-launcher.git/tree/src/chrome/locale/en/torlauncher.properties
+        '''
+        self.tag_phase = {'starting': 'Starting',

This is great!

iry:

What I am wondering is if such an alert should be exposed to daily user.

In Whonix I was always for exposing such messages. The reasoning behind
it being: Otherwise often we developers never have a chance to learn
about such corner cases (or attacks) and to do anything about them.

However the way to expose these information can be tailored with the
needs of the user in mind, i.e. usability. It’s not worth showing such
messages upfront and verbatim. A big popup with the strange message only
wouldn’t be great for the user. Of course a unknown bootstrap message
shouldn’t stop the user from enabling Tor.

Something like this…? “Unknown bootstrap message. In most cases this
is harmless. Please report this.” And then instructions how to
copy/paste this information from logs?

Or should we simply keep it in a log?

Log also.

Console output also is always good since fewest users are running gui
applications from console. More something advanced users and developers
are doing.

Patrick Schleizer:

This needs improvement. An unknown tag and re.search(r'SUMMARY=(.*)', bootstrap_status).group(1) is actually what we try to secure against here. So in that case, it should be a static message “unknown status” or something more useful. The real output could still be written to console and/or a lot so developers can add it for a later version (or notice when something did actually went wrong with Tor).

Thank you, Patrick! :slight_smile:

Done:

1 Like

Patrick Schleizer:

iry:

What I am wondering is if such an alert should be exposed to daily user.

In Whonix I was always for exposing such messages. The reasoning behind
it being: Otherwise often we developers never have a chance to learn
about such corner cases (or attacks) and to do anything about them.

I agree!

However the way to expose these information can be tailored with the
needs of the user in mind, i.e. usability. It’s not worth showing such
messages upfront and verbatim. A big popup with the strange message only
wouldn’t be great for the user. Of course a unknown bootstrap message
shouldn’t stop the user from enabling Tor.

Something like this…? “Unknown bootstrap message. In most cases this
is harmless. Please report this.” And then instructions how to
copy/paste this information from logs?

Sounds great. anon-connection-wizard definitely should have a log
module. Also, in terms of copy and paste the log, we may take the
Tor-launcher’s approach as an example.

Console output also is always good since fewest users are running gui
applications from console. More something advanced users and developers
are doing.

I agree. The log module should write to both log file and stdout/stderr.

1 Like

One global workaround in Debian, which is not anon-connection-wizard specific, is to put this line in the [Service] section of /lib/systemd/system/tor@default.service :

ExecStartPost=/bin/kill -HUP ${MAINPID}

Just asked for more input: [tor-dev] No Control Socket when DisableNetwork 1

I will wait for a while to see if this workaround is okay or not.

2 Likes