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

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

Btw the proper way would be a drop-in in folder /lib/systemd/system/tor@default.service.d. Examples in Whonix source code. For example here:

https://github.com/Whonix/anon-gw-anonymizer-config/tree/master/lib/systemd/system/tor%40default.service.d

Attempting first get this fixed upstream is the proper and clean way to go! :slight_smile:

1 Like

Thank you for the instructions, Patrick!

I don’t know how long it will take to get it fixed so here is the workaround:
https://github.com/Whonix/anon-gw-anonymizer-config/pull/9

If no response is received for a while, I will report it to BTS.

2 Likes

iry:

I don’t know how long it will take to get it fixed so here is the workaround:
https://github.com/Whonix/anon-gw-anonymizer-config/pull/9

On the second thought we should be careful with this. If not absolutely
required for Whonix 14, leaving it out. This could introduce some unique
bugs.

First of all, we have to see what upstream thinks about this and how
they go about fixing it. Then if possible and needed, we can add their
fix in Whonix earlier than their fix flows down to Whonix.

1 Like

I agree. It seems only anon-connection-wizard and swdate is using systemd to start Tor so it is not a big problem I guess:

user@host:~/Whonix/packages$ mygrep -r -i "systemctl.*restart tor"
sdwdate/usr/lib/sdwdate/suspend-post:      systemctl --no-pager restart tor@default
anon-connection-wizard/usr/lib/python3/dist-packages/anon_connection_wizard/tor_status.py:    command = 'systemctl --no-pager restart tor@default
1 Like

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

1 Like
1 Like

Great catch!

Thank you so much, Patrick!

1 Like

From Whonix VirtualBox 14.0.0.6.6 - Testers Wanted! - #15 by TechieMike

Any idea what might cause calling kdesudo without any arguments?

Tried to safeguard against it, but not sure I managed.

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

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

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

1 Like
user@host:~/Whonix$ mygrep -r -i "command = 'kdesudo"
packages/whonix-repository/usr/lib/whonix-repository/whonix-repository-wizard:    command = 'kdesudo %s' % (whonix_repository_wizard)
packages/anon-connection-wizard/usr/lib/anon-connection-wizard/anon-connection-wizard:    command = 'kdesudo {}'.format(anon_connection_wizard)
packages/whonix-setup-wizard/usr/lib/whonix-setup-wizard/whonixsetup_check_for_start:   command = 'kdesudo {} setup'.format(whonix_setup_wizard)
packages/whonix-setup-wizard/usr/lib/whonix-setup-wizard/whonix-setup-wizard-setup:command = 'kdesudo {} setup'.format(whonix_setup_wizard)

I guess the only possible commands cause this problem are these two:

packages/whonix-repository/usr/lib/whonix-repository/whonix-repository-wizard:    command = 'kdesudo %s' % (whonix_repository_wizard)
packages/anon-connection-wizard/usr/lib/anon-connection-wizard/anon-connection-wizard:    command = 'kdesudo {}'.format(anon_connection_wizard)

My guess is variables whonix_repository_wizard and/or anon_connection_wizard are not referenced, making the kdesudo called without arguments.

When seeing the code:

whonix_repository_wizard = distutils.spawn.find_executable("whonix-repository-wizard")
if not whonix_repository_wizard == "":
    command = 'kdesudo {}'.format(whonix_repository_wizard)
    call(command, shell=True)

distutils.spawn.find_executable will return None when executable not found; however, None != "".

distutils.spawn.find_executable should be replaced by shutil.which anyway since the former one is not well-documented and widely used.

I will do some pull requests to fix it.

1 Like

https://github.com/Whonix/whonix-repository/pull/1

1 Like