Enumerating and Exploiting NFS

James Patrick
5 min readMay 13, 2021

NFS-Common

It is important to have this package installed on any machine that uses NFS, either as client or server. It includes programs such as: lockd, statd, showmount, nfsstat, gssd, idmapd and mount.nfs. Primarily, we are concerned with “showmount” and “mount.nfs” as these are going to be most useful to us when it comes to extracting information from the NFS share. If you’d like more information about this package, feel free to read: https://packages.ubuntu.com/xenial/nfs-common. You can install nfs-common using “sudo apt install nfs-common”, it is part of the default repositories for most Linux distributions such as Kali.

The first step of enumeration is to conduct a port scan, to find out as much information as you can about the services, open ports and operating system of the target machine. You can go as in-depth as you like on this, however, I suggest using nmap with the -A and -p- tags.

Mounting NFS shares

Your client’s system needs a directory where all the content shared by the host server in the export folder can be accessed. You can create
this folder anywhere on your system. Once you’ve created this mount point, you can use the “mount” command to connect the NFS share to the mount point on your machine like so:

sudo mount -t nfs IP:share /tmp/mount/ -nolock

Let’s break this down:

sudo = Run as root
mount = Execute the mount command
-t nfs = type of device to mount, then specifying that it’s NFS
IP:share = The IP Address of the NFS server, and the name of the share we wish to mount
-nolock = Specifies not to use NLM locking

Performing a port scan of the target we see the NFS service we are looking for:

Now use the below command to list the NFS shares:

/usr/sbin/showmount -e [IP]

We get a list of NFS shares on this box:

Now we will create a local directory to mount the share to:

mkdir /tmp/mount

Then, use the mount command we broke down earlier to mount the NFS share to your local machine:

sudo mount -t nfs IP:share /tmp/mount/ -nolock

When we change to the mount directory and list the contents we see the below folder:

When browsing that folder we see a .ssh folder which could be used to get us remote access to the server:

Browsing the .ssh directory we see a file named ID_RSA which will be very useful to us:

We will copy this file locally and change the permissions:

chmod 600 id_rsa

We will then us this file to attempt to ssh into the box:

ssh -i id_rsa cappacino@<ip>

If you have a low privilege shell on any machine and you found that a machine has an NFS share you might be able to use that to escalate privileges, depending on how it is configured.

root_squash

By default, on NFS shares- Root Squashing is enabled, and prevents anyone connecting to the NFS share from having root access to the NFS volume. Remote root users are assigned a user “nfsnobody” when connected, which has the least local privileges. Not what we want. However, if this is turned off, it can allow the creation of SUID bit files, allowing a remote user root access to the connected system.

So, what are files with the SUID bit set? Essentially, this means that the file or files can be run with the permissions of the file(s) owner/group. In this case, as the super-user. We can leverage this to get a shell with these privileges!

This sounds complicated, but really- provided you’re familiar with how SUID files work, it’s fairly easy to understand. We’re able to upload files to the NFS share, and control the permissions of these files. We can set the permissions of whatever we upload, in this case a bash shell executable. We can then log in through SSH, as we did in the previous task- and execute this executable to gain a root shell!

Due to compatibility reasons, we’ll use a standard Ubuntu Server 18.04 bash executable, the same as the server’s- as we know from our nmap scan. You can download it here.

If this is still hard to follow, here’s a step by step of the actions we’re taking, and how they all tie together to allow us to gain a root shell:

NFS Access ->

Gain Low Privilege Shell ->

Upload Bash Executable to the NFS share ->

Set SUID Permissions Through NFS Due To Misconfigured Root Squash ->

Login through SSH ->

Execute SUID Bit Bash Executable ->

ROOT ACCESS!

First, change directory to the mount point on your machine, where the NFS share should still be mounted, and then into the user’s home directory.

Download the bash executable to your Downloads directory. Then use “cp ~/Downloads/bash” to copy the bash executable to the NFS share. The copied bash shell must be owned by a root user, you can set this using “sudo chown root bash”

Now, we’re going to add the SUID bit permission to the bash executable we just copied to the share using:

sudo chmod +s bash

Download the bash executable to your Downloads directory. Then use “cp ~/Downloads/bash .” to copy the bash executable to the NFS share. The copied bash shell must be owned by a root user, you can set this using “sudo chown root bash”

Now, ssh into the machine as the user. List the directory to make sure the bash executable is there. Now, the moment of truth. Lets run it with “./bash -p”. The -p persists the permissions, so that it can run as root with SUID- as otherwise bash will sometimes drop the permissions.

Verify we have root:

Get the flag!

--

--