Abusing Hardlinks Via NFS

If you’ve been doing network pentesting for a while, you’ll no doubt be aware that there are plenty of ways to configure NFS insecurely.  Here are a few examples:

  • If you export /home and allow read-write access: Attackers can read everyone’s home directories, alter them and probably log in as any user.
  • If an attacker has a non-priv logon and write access to an NFS share he can impersonate any non-root user… unless you set the nosuid or noexec mount option on the exported file system.
  • If an attacker has a non-priv logon and write access to an NFS share he can create device files and perform raw read/writes to disks, kmem, etc… unless you set the nodev mount option on the exported file system.

Another technique just occured to me that I don’t recall hearing about before: Under some conditions an attacker could create hardlinks to gain read/write access to files outsite of the exported directory.  The rest of this post discusses this attack in more detail.

What’s A Hardlink?

According to wikipedia a hardlink is:

“… a reference, or pointer, to physical data on a storage volume. On most file systems, all named files are hard links. The name associated with the file is simply a label that refers the operating system to the actual data. As such, more than one name can be associated with the same data. Though called by different names, any changes made will affect the actual data, regardless of how the file is called at a later time. Hard links can only refer to data that exists on the same file system. ”

Any user can create a hardlink using the “ln” command (I’m using Linux.  Other Unixes are similar, though):

$ ln /etc/passwd password-hardlink
$ ls -l passwd-hardlink
-rw-r--r-- 4 root root 2854 Aug  9 13:18 passwd-hardlink

You just need write access to the place you’re writing the link and to and to be able to traverse the parent directories of the target file – you don’t need read access to the target file.

How do Hardlinks Help Me Access Files During A Pentest?

The following conditions need to be met for the “hardlink” technique to work:

  • You’ve got write access to an NFS share
  • You’ve got a non-priv logon for the NFS server that can write to the NFS share
  • You want to read/write a file that is not in the NFS exported directory.  The target file (probably) needs to be read/writable by a non-root user because root_squash is normally turned on.  NB: If the target file is on the NFS export, simple UID/GID manipulation will get you what you need – you don’t need the “hardlink” attack.
  • You’ve found that the nosuid and nodev options are being used (if they aren’t, then there are better attacks than this one you could use).

We’ll illustrate te technique with an example:

  • Log into the target system using your non-priv account and identify a file that you want to read/write but can’t.  Remember that you can’t pick /etc/shadow because you a need a file that’s read/writable by a non-root user (NFS’s root_squash option means that root’s files are safe).  By way of an example, image you’ve found the file /etc/apache2/site-htpasswd and would like to read it.
$ ls -l /etc/apache2/site-htpasswd
-rw------- 1 apache apache 123 Jul  9 20:02 /etc/apache2/site-htpasswd
  •  While you’re still logged in, locate the NFS exported directory and write a hardlink in there to the target file.
$ cd /some/exported/dir/
$ ln /etc/apache2/site-htpasswd myhardlink
$ ls -l  myhardlink
-rw------- 1 apache apache 123 Jul  9 20:02 myhardlink
  • Finally, access the hardlink via the NFS share.  In this case we’ll need to lie to the NFS server about our UID.  We’ll use nfsshell, but you could just mount the NFS share normally and create a local account with the appropriate UID.
$ sudo nfs
nfs> host 10.0.0.1
Using a privileged port (1021)
Open 10.0.0.1 (10.0.0.1) TCP
nfs> mount /some/exported/dir/
Using a privileged port (1020)
Mount `/some/expored/dir/', TCP, transfer size 8192 bytes.
nfs> ls -l
drwxr-xr-x1002     1024     0         1  Aug 16 23:34  .
drwxr-xr-x  0     1024     0         1  Aug 16 23:31  ..
-rw-------   80    123     0         1 Jul  9 20:02 myhardlink
nfs> uid 80
nfs> get myhardlink
myhardlink? y
nfs>

Limitations

You have to be able to traverse the parent directories of target file (i.e. have +x permission on the parent dirs) in order to create the hardlink.  This attack will therefore not allow you to read files in other user’s home directories if the home directories have 700 permissions.

You can only read files on the same partition as the NFS-exported directory.  There’s no problem if the there is only one partition in use – as is common on Linux installations.  If, however /home was a separate partition, you wouldn’t be able to create hardlinks to /var/log/messages for example as the target file is on a different parition.

/dev is a separate file system, so you cannot do raw read/writes to disk devices even though they’re often read/writable by the “disk” group or similar.

If root_squash in enabled (it normally is), you won’t be able to access files that are only accessible by the root user.  If root_squash is not enabled, though, you should be able to easily read/write to /etc/shadow and /etc/passwd.


Leave a Reply