Patrick
December 20, 2019, 11:20am
21
I want to add a usability feature.
As user user
.
stat -c "%n %a %U %G" /bin/su
/bin/su 755 root root
which su
/bin/su
I.e. su
is still executable by user user
even though it has suid removed. This is bad because su
fails open, i.e. in weird ways. It does not report “missing suid”. What I preferred:
sudo chmod o-x /bin/su
stat -c "%n %a %U %G" /bin/su
/bin/su 754 root root
which su
su
bash: /bin/su: Permission denied
Now user user
cannot execute su
anymore. It is failing closed.
1 Like
Patrick
December 20, 2019, 11:31am
22
This is the script output as of now.
run: dpkg-statoverride --add --update root root 0755 /home
run: dpkg-statoverride --add --update user user 0700 /home/user
run: dpkg-statoverride --add --update root root 0700 /root
run: dpkg-statoverride --add --update root root 0700 /boot
run: dpkg-statoverride --add --update root root 0600 /etc/permission-hardening.d
INFO: fso: ‘/usr/local/etc/permission-hardening.d’ - does not exist. This is likely normal.
INFO: set-user-id found - file_name: ‘/bin/fusermount’ | existing_mode: ‘4755’ | new_mode: ‘755’
run: dpkg-statoverride --add --update root root 755 /bin/fusermount
INFO: set-user-id found - file_name: ‘/bin/su’ | existing_mode: ‘4755’ | new_mode: ‘755’
run: dpkg-statoverride --add --update root root 755 /bin/su
INFO: set-user-id found - file_name: ‘/bin/ntfs-3g’ | existing_mode: ‘4755’ | new_mode: ‘755’
run: dpkg-statoverride --add --update root root 755 /bin/ntfs-3g
INFO: set-user-id found - file_name: ‘/usr/bin/sudo’ | existing_mode: ‘4755’ | new_mode: ‘755’
run: dpkg-statoverride --add --update root root 755 /usr/bin/sudo
INFO: set-user-id found - file_name: ‘/usr/bin/chsh’ | existing_mode: ‘4755’ | new_mode: ‘755’
run: dpkg-statoverride --add --update root root 755 /usr/bin/chsh
INFO: set-group-id found - file_name: ‘/usr/bin/crontab’ | existing_mode: ‘2755’ | new_mode: ‘755’
run: dpkg-statoverride --remove /usr/bin/crontab
run: dpkg-statoverride --add --update root crontab 755 /usr/bin/crontab
INFO: set-user-id found - file_name: ‘/usr/bin/chfn’ | existing_mode: ‘4755’ | new_mode: ‘755’
run: dpkg-statoverride --add --update root root 755 /usr/bin/chfn
INFO: set-group-id found - file_name: ‘/usr/bin/ssh-agent’ | existing_mode: ‘2755’ | new_mode: ‘755’
run: dpkg-statoverride --add --update root ssh 755 /usr/bin/ssh-agent
INFO: set-user-id found - file_name: ‘/usr/bin/newuidmap’ | existing_mode: ‘4755’ | new_mode: ‘755’
run: dpkg-statoverride --add --update root root 755 /usr/bin/newuidmap
INFO: set-user-id found - file_name: ‘/usr/bin/pkexec.security-misc-orig’ | existing_mode: ‘4755’ | new_mode: ‘755’
run: dpkg-statoverride --add --update root root 755 /usr/bin/pkexec.security-misc-orig
INFO: set-user-id found - file_name: ‘/usr/bin/bwrap’ | existing_mode: ‘4755’ | new_mode: ‘755’
run: dpkg-statoverride --add --update root root 755 /usr/bin/bwrap
INFO: set-group-id found - file_name: ‘/usr/bin/chage’ | existing_mode: ‘2755’ | new_mode: ‘755’
run: dpkg-statoverride --add --update root shadow 755 /usr/bin/chage
INFO: fso: ‘/usr/local/bin/’ - does not exist. This is likely normal.
INFO: set-user-id found - file_name: ‘/sbin/mount.nfs’ | existing_mode: ‘4755’ | new_mode: ‘755’
run: dpkg-statoverride --add --update root root 755 /sbin/mount.nfs
INFO: fso: ‘/usr/local/sbin/’ - does not exist. This is likely normal.
INFO: set-user-id found - file_name: ‘/usr/lib/policykit-1/polkit-agent-helper-1’ | existing_mode: ‘4755’ | new_mode: ‘755’
run: dpkg-statoverride --add --update root root 755 /usr/lib/policykit-1/polkit-agent-helper-1
INFO: set-user-id found - file_name: ‘/usr/lib/eject/dmcrypt-get-device’ | existing_mode: ‘4755’ | new_mode: ‘755’
run: dpkg-statoverride --add --update root root 755 /usr/lib/eject/dmcrypt-get-device
INFO: set-user-id set-group-id found - file_name: ‘/usr/lib/virtualbox/VBoxNetDHCP’ | existing_mode: ‘6755’ | new_mode: ‘755’
run: dpkg-statoverride --add --update root root 755 /usr/lib/virtualbox/VBoxNetDHCP
INFO: set-user-id set-group-id found - file_name: ‘/usr/lib/virtualbox/VBoxNetNAT’ | existing_mode: ‘6755’ | new_mode: ‘755’
run: dpkg-statoverride --add --update root root 755 /usr/lib/virtualbox/VBoxNetNAT
INFO: set-user-id set-group-id found - file_name: ‘/usr/lib/virtualbox/VBoxHeadless’ | existing_mode: ‘6755’ | new_mode: ‘755’
run: dpkg-statoverride --add --update root root 755 /usr/lib/virtualbox/VBoxHeadless
INFO: set-user-id found - file_name: ‘/usr/lib/x86_64-linux-gnu/lxc/lxc-user-nic’ | existing_mode: ‘4755’ | new_mode: ‘755’
run: dpkg-statoverride --add --update root root 755 /usr/lib/x86_64-linux-gnu/lxc/lxc-user-nic
INFO: set-user-id found - file_name: ‘/usr/lib/dbus-1.0/dbus-daemon-launch-helper’ | existing_mode: ‘4754’ | new_mode: ‘754’
run: dpkg-statoverride --remove /usr/lib/dbus-1.0/dbus-daemon-launch-helper
run: dpkg-statoverride --add --update root messagebus 754 /usr/lib/dbus-1.0/dbus-daemon-launch-helper
INFO: set-user-id found - file_name: ‘/usr/lib/kde4/libexec/fileshareset’ | existing_mode: ‘4755’ | new_mode: ‘755’
run: dpkg-statoverride --add --update root root 755 /usr/lib/kde4/libexec/fileshareset
INFO: set-group-id found - file_name: ‘/usr/lib/kde4/libexec/kdesud’ | existing_mode: ‘2755’ | new_mode: ‘755’
run: dpkg-statoverride --add --update root nogroup 755 /usr/lib/kde4/libexec/kdesud
INFO: set-user-id found - file_name: ‘/usr/lib/chromium/chrome-sandbox’ | existing_mode: ‘4755’ | new_mode: ‘755’
run: dpkg-statoverride --add --update root root 755 /usr/lib/chromium/chrome-sandbox
INFO: set-user-id found - file_name: ‘/usr/lib/qubes/qfile-unpacker’ | existing_mode: ‘4755’ | new_mode: ‘755’
run: dpkg-statoverride --add --update root root 755 /usr/lib/qubes/qfile-unpacker
INFO: set-group-id found - file_name: ‘/usr/lib/evolution/camel-lock-helper-1.2’ | existing_mode: ‘2755’ | new_mode: ‘755’
run: dpkg-statoverride --add --update root mail 755 /usr/lib/evolution/camel-lock-helper-1.2
INFO: fso: ‘/usr/lib64/’ - does not exist. This is likely normal.
INFO: fso: ‘/usr/local/lib/’ - does not exist. This is likely normal.
INFO: fso: ‘/usr/local/lib32/’ - does not exist. This is likely normal.
INFO: fso: ‘/usr/local/lib64/’ - does not exist. This is likely normal.
run: dpkg-statoverride --add --update root root 4755 /usr/bin/sudo
run: dpkg-statoverride --add --update root root 4755 /usr/bin/bwrap
run: dpkg-statoverride --add --update root root 4755 /usr/lib/policykit-1/polkit-agent-helper-1
INFO: fso: ‘/usr/lib/spice-gtk/spice-client-glib-usb-acl-helper’ - does not exist. This is likely normal.
run: dpkg-statoverride --add --update root utmp 2755 /usr/lib/x86_64-linux-gnu/utempter/utempter
new_mode is either 755
or 754
. I.e. has still execution permission for others
or group
.
For config entries stating nosuid
only: Would it be a good idea to hardcode / change newmode
of these to 744
? I.e. to remove exeution permission for others
and `group?
if [ "$new_mode" = "755" ]; then
new_mode=744
fi
if [ "$new_mode" = "754" ]; then
new_mode=744
fi
if [ "$new_mode" = "745" ]; then
new_mode=744
fi
I guess the question is:
Are there suid or guid binaries which are still useful if suid / guid has been removed from these?
1 Like
Patrick
December 20, 2019, 12:05pm
23
Could you please review if it is sane to remove suid / guid from the following binaries? @madaidan
run: dpkg-statoverride --add --update root root 755 /bin/fusermount
run: dpkg-statoverride --add --update root root 755 /bin/su
run: dpkg-statoverride --add --update root root 755 /bin/ntfs-3g
run: dpkg-statoverride --add --update root root 755 /usr/bin/sudo
run: dpkg-statoverride --add --update root root 755 /usr/bin/chsh
run: dpkg-statoverride --remove /usr/bin/crontab
run: dpkg-statoverride --add --update root crontab 755 /usr/bin/crontab
run: dpkg-statoverride --add --update root root 755 /usr/bin/chfn
run: dpkg-statoverride --add --update root ssh 755 /usr/bin/ssh-agent
run: dpkg-statoverride --add --update root root 755 /usr/bin/newuidmap
run: dpkg-statoverride --add --update root root 755 /usr/bin/pkexec.security-misc-orig
run: dpkg-statoverride --add --update root shadow 755 /usr/bin/chage
run: dpkg-statoverride --add --update root root 755 /sbin/mount.nfs
run: dpkg-statoverride --add --update root root 755 /usr/lib/policykit-1/polkit-agent-helper-1
run: dpkg-statoverride --add --update root root 755 /usr/lib/eject/dmcrypt-get-device
run: dpkg-statoverride --add --update root root 755 /usr/lib/virtualbox/VBoxNetDHCP
run: dpkg-statoverride --add --update root root 755 /usr/lib/virtualbox/VBoxNetNAT
run: dpkg-statoverride --add --update root root 755 /usr/lib/virtualbox/VBoxHeadless
run: dpkg-statoverride --add --update root root 755 /usr/lib/x86_64-linux-gnu/lxc/lxc-user-nic
run: dpkg-statoverride --add --update root messagebus 754 /usr/lib/dbus-1.0/dbus-daemon-launch-helper
run: dpkg-statoverride --add --update root root 755 /usr/lib/kde4/libexec/fileshareset
run: dpkg-statoverride --add --update root nogroup 755 /usr/lib/kde4/libexec/kdesud
run: dpkg-statoverride --add --update root root 755 /usr/lib/chromium/chrome-sandbox
run: dpkg-statoverride --add --update root root 755 /usr/lib/qubes/qfile-unpacker
run: dpkg-statoverride --add --update root mail 755 /usr/lib/evolution/camel-lock-helper-1.2
run: dpkg-statoverride --add --update root root 4755 /usr/lib/policykit-1/polkit-agent-helper-1
run: dpkg-statoverride --add --update root utmp 2755 /usr/lib/x86_64-linux-gnu/utempter/utempter
Does the suid default whitelist need to be expanded?
Specifically, let’s not break chromium and virtualbox.
1 Like
Patrick
December 20, 2019, 12:58pm
24
Found some issue.
Dec 20 07:54:47 disp3633 permission-hardening[26043]: + seq -w 000 4777
Dec 20 07:54:47 disp3633 permission-hardening[26043]: + grep -qw 2755
Dec 20 07:54:47 disp3633 permission-hardening[26043]: seq: write error: Broken pipe
Need to use a better regex here.
Another issue.
user@disp3633:~$ sudoedit /usr/lib/security-misc/permission-hardening
sudoedit: /usr/bin/sudoedit must be owned by uid 0 and have the setuid bit set
user@disp3633:~$ sudo test
sudo: /usr/bin/sudo must be owned by uid 0 and have the setuid bit set
That is because there is a significant time gap between suid removal from /usr/bin
and re-adding the whitelist of /usr/bin/sudo
. Therefore we need to implement the whitelist another way. Not by first removing suid and then re-adding. Better to not modify file permissions of sudo
(and other white listed ones) at all. Otherwise this can cause a lot bugs which are timing dependent (when other scripts use sudo
).
1 Like
Patrick
December 20, 2019, 1:03pm
25
Found some issue.
Dec 20 07:54:47 disp3633 permission-hardening[26043]: + seq -w 000 4777
Dec 20 07:54:47 disp3633 permission-hardening[26043]: + grep -qw 2755
Dec 20 07:54:47 disp3633 permission-hardening[26043]: seq: write error: Broken pipe
Need to use a better regex here.
Not perfect but functional.
committed 01:02PM - 20 Dec 19 UTC
no longer use seq due to issue
https://forums.whonix.org/t/permission-hardening… /8655/13
1 Like
Patrick
December 20, 2019, 1:59pm
27
fso: /lib/
usr/lib/security-misc/permission-hardening: line 19: /usr/bin/stat: Argument list too long
Can reproduce manually too.
shopt -s globstar
stat -c “%n %a %U %G” /lib/**
> bash: /usr/bin/stat: Argument list too long
We are hitting ARG_MAX
getconf ARG_MAX
more info:
"Argument list too long": Beyond Arguments and Limitations | Linux Journal
How can I prevent arguments to `xargs` from being prefixed with spaces? - Unix & Linux Stack Exchange said xargs
can split it up.
Will use
done < <( find "${fso_without_trailing_slash}/" -print0 | xargs -I{} -0 stat -c "%n %a %U %G" {} )
to fix it.
That does not work. It will “forget” to process some files.
find /usr/bin | wc -l
1149
Added a counter.
INFO: fso_to_process: ‘/usr/bin/’ | counter: ‘575’
1 Like
Patrick
December 20, 2019, 2:50pm
29
sudo /usr/lib/security-misc/permission-hardening
sudo: /usr/bin/sudo must be owned by uid 0 and have the setuid bit set
On Qubes there is also /bin/sudo
and /bin/brwap
. Fixed.
committed 02:48PM - 20 Dec 19 UTC
1 Like
Patrick
December 20, 2019, 3:28pm
30
Found a way to crazy speed up things. Using find
with -perm /u=s,g=s
. Will add.
1 Like
Btw I make no claim that my code style is superior in any form but it is easier to grasp by my participial biased brain. Hope that is ok.
It’s fine. Do what you want. You’re better than me at writing bash scripts anyway.
I.e. su
is still executable by user user
even though it has suid removed.
You can just add another rule for su
:
/bin/su 0700 root root
Would it be a good idea to hardcode / change newmode
of these to 744
? I.e. to remove exeution permission for others
and `group?
What’s the point of reading binaries if it can’t even be executed? Maybe just give a mode of 700
.
Could you please review if it is sane to remove suid / guid from the following binaries?
It’s fine to remove it from most of them but whitelist sudo, virtualbox, polkit, dbus and chromium. Chromium only needs suid if unprivileged user namespaces are disabled which Debian does by default.
1 Like
Btw, I noticed in the script you refer to setgid as “guid”. It’s not “guid” but “sgid”. GUID is different and may cause confusion.
1 Like
Patrick
December 20, 2019, 5:03pm
33
Could you please review if it is sane to remove suid / guid from the following binaries?
It’s fine to remove it from most of them but whitelist sudo, virtualbox, polkit, dbus and chromium. Chromium only needs suid if unprivileged user namespaces are disabled which Debian does by default.
VirtualBox has “plenty”. 6
at the moment.
In future, more/less might be added or paths might change. In that case, I would like to avoid hunting down bugs due to that.
Any reason not to add a nosuid whitelist matching feature? Could match for /virtualbox/
.
I don’t see how such a matching feature could be abused. Threat model:
Any suid / sgid can only be abused by non-root as root does no longer need to escalate to root. Only only root (apt) and superroot can write to these folders anyhow. Therefore I see now way to create binaries which would match such names to gain access to a suid / sgid to be spared from suid removal. Well, there are ways, but those capable to to write to these folders do not need to bother with suid / sgid anymore.
Btw, I noticed in the script you refer to setgid as “guid”. It’s not “guid” but “sgid”. GUID is different and may cause confusion.
Fixed in git master.
1 Like
VirtualBox has “plenty”. 6 at the moment.
Are any of these actually used? Is there any breakage from removing their SUID bits? If not, then we can just ignore them.
I doubt VboxNetDHCP would be used seeing as Whonix doesn’t even use DHCP at all.
Could match for /virtualbox/
.
Would be better to match for /usr/lib/virtualbox/
in case some random directory that just happens to have the name “virtualbox” gets whitelisted.
1 Like
Patrick
December 20, 2019, 5:39pm
35
set-user-id set-group-id found - file_name: ‘/usr/lib/xorg/Xorg.wrap’
Needed?
At first sight looks important. But Debian / systemd might not use / need it.
Are any of these actually used? Is there any breakage from removing their SUID bits? If not, then we can just ignore them.
Not yet tested. Can’t find anything online what these are used for. Testing this can be future work.
I doubt VboxNetDHCP would be used seeing as Whonix doesn’t even use DHCP at all.
security-misc isn’t just used by Whonix. I don’t want to break VirtualBox (hosts) for those who install security-misc or Kicksecure.
Would be better to match for /usr/lib/virtualbox/
in case some random directory that just happens to have the name “virtualbox” gets whitelisted.
Will add.
1 Like
No, Debian and many other linux distros use Xorg rootless by default so there’s no need for the suid wrapper unless the user themselves has configured X to run as root for whatever reason (which is a security risk due to X’s large attack surface).
1 Like
We can use this to remove capabilities of some unneeded binaries too by using the none
capability rule.
getcap -r / 2>/dev/null
/usr/lib/x86_64-linux-gnu/gstreamer1.0/grstreamer-1.0/gst-ptp-helper = cap_net_bind_service,cap_net_admin+ep
/bin/ping = cap_net_raw+ep
I think we should remove the capabilities of /bin/ping
since it doesn’t work with Tor anyway.
1 Like
We can add Whonix specific things such as ping capability removal to anon-apps-config package as a drop- snippet.
Pull requests welcome.
1 Like
Patrick
December 21, 2019, 7:34am
40
This is now in the developers repository. Enabling it will be easy.
sudo systemctl enable permission-hardening.service
It might be enabled by default one day (similar to Restrict Hardware Information to Root - Testers Wanted! ) but it needs a fair amount of testing as I am running into many issues here.
We’ll also need some way to record changes and to undo these.
Breaks whonix-firewall.
Dec 21 06:43:54 host enable-firewall[351]: iptables/1.8.2 Failed to initialize nft: Protocol not supported
1 Like