-
Notifications
You must be signed in to change notification settings - Fork 3
5_2_1 PrivEsc Client, no_root_squash enabled
Clients should always use the nodev
and nosuid
mount options when mounting an NFS export.
If one of these options is omitted, it is possible to escalate privileges on the client if an attacker is able to upload files to the export as root which requires the no_root_squash
option to be enabled on the server.
This attack is well-known and has been used many times. A modified version of it does not even require the no_root_squash
option to be set.
- Server side: An export has the option `no_root_squash set.
- Client side: The export is mounted without the
nosuid
ornodev
option, the attack is possible if at least one of these two options is missing. - Attacker: The attacker must either have root access on a(nother) client or has to be able to send manipulated traffic to the NFS server.
There are two versions of this attack depending on which of the two options has been omitted when the export was mounted on the client.
To perform this attack, use the machine where you have root privileges to upload a setuid
binary to the NFS server and allow everyone to execute it.
You can then simply execute the file on the other clients and get root access.
The typical code for a setuid
binary that starts a shell looks like this.
#include <unistd.h>
#include <stdlib.h>
int main(void) {
setuid(0);
setgid(0);
system("sh");
}
It can be compiled, given the correct permissions and tested using the following command. At the end you should get a root shell.
gcc -o setuid setuid.c && sudo chown root:root setuid && sudo chmod 6755 setuid && ./setuid
You can now upload this file to the NFS export and run it on the client to get root access.
A detailed description of the attack can be found here.
If the export was mounted with nosuid
but without the nodev
option, the process is more complicated.
The background behind this version of the attack is that the NFS protocol also supports block and character devices files.
They contain a major and minor number which are used to identify a device on a machine.
If these special files are accessed via NFS, their major and minor numbers are transferred to the client which means that they will always refer to the devices on the client, not those on the server.
In order to prevent users on the client machine from accessing these device files, NFS exports should be mounted with the nodev
option enabled.
For security reasons only NFS clients with root privileges can create devices files in exports. The attack is therefore not possible if no_root_squash
is not enabled.
To perform the attack, use the machine where you have root access to create a block device in the export which has the same major and minor number as the operating system drive of the client where you want to escalate privileges. Make the device accessible to everyone and log in to the client. You can now use this file to access raw data on the hard drive while bypassing all security checks of the operating system.
If the client uses an ext
file system, you can use debugfs
to interact with the disk.
WARNING: This attack is only useful for reading files that can only be read by root. Writing directly to the disk can corrupt the file system, lead to data loss and make the system unbootable especially if the disk is modified while it is mounted. Be extremely careful and only use this method for writing on a machine with no important data and which you can recover if it fails to boot. While testing this attack, creating a file or overwriting /etc/shadow
on the operating system partition using debugfs resulted in a corrupted file system.
You can use the mount
command to find out on which device the operating system is installed.
If you want to see the major and minor of a specific device you can run ls -l /dev/NAME
on the target. For example, you might get the following result:
$ ls -l /dev/sd*
brw-rw---- 1 root disk 8, 0 May 27 13:56 /dev/sda
brw-rw---- 1 root disk 8, 1 May 27 13:56 /dev/sda1
brw-rw---- 1 root disk 8, 2 May 27 13:56 /dev/sda2
In this case the operating system is installed on the ext
partition on /dev/sda2
which has the major id 8 and minor id 2.
debugfs
requires a device file that refers to the ext partition, not the entire disk.
In the output of ls
you can also see that the disks are accessible to a group called disk
which does not matter now but will be relevant for another attack.
On the attacker machine you can now create a device file called priv_esc_sda2
in the export and make it accessible to anyone.
$ sudo mknod priv_esc_sda2 b 8 2
$ sudo chmod 666 priv_esc_sda2
You can then access the disk on the client using debugfs
by simply running debugfs priv_esc_sda2
.
This will start an interactive session where you can use familiar commands like cd
, ls
and cat
to perform read operations on the file system.
The debugfs
binary might not be in your path as an unprivileged user because it is located in the sbin
directory, so you may have to use the full path /usr/sbin/debugfs
to run it.
You can also use debugfs
to write data to the disk, however this is not useful in practice because it may cause data corruption.
WARNING: The following commands resulted in a corrupted file system, but after rebooting and running e2fsck
the content of /etc/shadow
was overwritten. More work would be needed to find a corruption-free way to modify data on a mounted disk, as debugfs
was not designed for this use case.
When you are in debugfs
, you can use cat /etc/shadow
to read /etc/shadow
. You can copy the content to a new file and edit it. To overwrite the file, run rm /etc/shadow
and write <PATH_TO_THE_FILE> /etc/shadow
.
In order to determine which version of the attack you can use, run the mount
command on the client and check the line that contains the NFS export.
Consider the following example.
$ mount
...
192.168.247.129:/nfs_test on /mnt/nfs_export type nfs (rw,nosuid,relatime,vers=3,rsize=262144,wsize=262144,...)
...
In this example, the nosuid
option is enabled but the nodev
option isn't which means that only the second version of this attack is going to work.
If the export is mounted with neither of the two options, the first version of the attack is much easier and safer.