FOG 1.5.10 and earlier - NFS Privilege Escalation Vulnerability
-
Hello all,
There was a vulnerability brought to attention of a privelege escalation in how FOG has previously used NFS.
The specific vulnerability was using options “no_root_squash” and “insecure” as definitions of the exports file.
The
insecure
option effectively allowed any system on non-priveleged ports (anything > 1024 which we defaulted to for NFS) had root level access to the filesystem.The
no_root_squash
allowed a client system to mount the NFS share and if a client UID matched the UID of the server the files would be created as that user (say client had user named bob with UID 1000, and server had user named admin with UID 1000, NFS on the server would show “admin” created the file). It also allowedroot
(UID 0) on a clients machine to create files - scripts and all - as root on the server.If I understand the depth, once that client root level created a file that contained code to escalate privilege, anyone could mount the NFS share and use that bad acting file to elevate as root on the server system.
Luckily this had a relatively easy fix and this fix has been implemented to dev-branch and working-1.6 from an installer standpoint.
Since I don’t know when a “full” release will be made I am outlining the steps you should/will need to take to correct the issue in the meantime.
Here’s a diff of the master to include these changes in an automated fashion if you feel comfortable doing this:
diff --git a/lib/common/functions.sh b/lib/common/functions.sh index b20b0e482..44f8657f5 100755 --- a/lib/common/functions.sh +++ b/lib/common/functions.sh @@ -1357,7 +1357,9 @@ configureNFS() { echo "Skipped" else mv -fv "${nfsconfig}" "${nfsconfig}.${timestamp}" >>$error_log 2>&1 - echo -e "$storageLocation *(ro,sync,no_wdelay,no_subtree_check,insecure_locks,no_root_squash,insecure,fsid=0)\n$storageLocation/dev *(rw,async,no_wdelay,no_subtree_check,no_root_squash,insecure,fsid=1)" > "$nfsconfig" + userId=$(id -u $username) + groupId=$(id -g $username) + echo -e "$storageLocation *(ro,sync,no_wdelay,no_subtree_check,insecure_locks,all_squash,anonuid=${userId},anongid=${groupId},fsid=0)\n$storageLocation/dev *(rw,async,no_wdelay,no_subtree_check,all_squash,anonuid=${userId},anongid=${groupId},fsid=1)" > "$nfsconfig" diffconfig "${nfsconfig}" errorStat $? dots "Setting up and starting RPCBind" @@ -1569,8 +1571,8 @@ configureStorage() { else (head -1 "$storageLocationCapture/postinitscripts/fog.postinit" | grep -q '^#!/bin/bash') || sed -i '1i#!/bin/bash' "$storageLocationCapture/postinitscripts/fog.postinit" >/dev/null 2>&1 fi - chmod -R 777 $storageLocation $storageLocationCapture >>$error_log 2>&1 - chown -R $username $storageLocation $storageLocationCapture >>$error_log 2>&1 + chmod -R 775 $storageLocation $storageLocationCapture >>$error_log 2>&1 + chown -R $username:$username $storageLocation $storageLocationCapture >>$error_log 2>&1 errorStat $? } clearScreen() {
Steps:
(If you rerun the installer please re-perform these steps to ensure things are as secure as possible)- Get your fogproject user’s user and group ids:
echo "UserID: "$(id -u fogproject); echo "GroupID: "$(id -g fogproject)
- Note these down and edit your systems export file (usually located in
/etc/exports
)
Remove theno_root_squash
and replace withall_squash
in both instances
Remove theinsecure,
from both instances - Add:
anonuid=<UserID>,anongid=<GroupID>
to both instances
Please replace <UserID> with the actual userID returned, and <GroupID> with the actual groupID returned.
You should end up with an exports that looks like:
/images *(ro,sync,no_wdelay,no_subtree_check,insecure_locks,all_squash,anonuid=1001,anongid=1001,fsid=0) /images/dev *(rw,async,no_wdelay,no_subtree_check,all_squash,anonuid=1001,anongid=1001,fsid=1)
- Change filesystem permissions of /images to at least
chmod -R 775 /images
(Not necessary, but useful for an extra bit of security) - Change owner ship of /images to fogproject/fogproject
chown -R fogproject:fogproject /images
- Restart nfsd:
systemctl restart nfsd
- Test.
This should address the vulnerabilty. While it won’t prevent a “bad actor” from placing a new file on your system the max level of that escalation could only be that of your fogproject user.
I know this isn’t a good way to start a Monday, but when is a good time when it comes to security issues?
Hopefully this will help and is simple enough to work in the mean time. Those who don’t mind, please use dev-branch for simplicity as it should address this in a more autonomous method.
Thank you all in advance!
Particularly, thank you Christophe Hugueny (Advens) @IronBlackBird
- Get your fogproject user’s user and group ids:
-