File Permissions and Ownership¶
Every file has an owner, a group, and three sets of permissions: owner, group, everyone else. The Linux flaws in this area are the same as NTFS flaws on Windows: a file everyone can write, a secret everyone can read, or a system file owned by a user.
Read them¶
ls -l /etc/shadow
stat -c '%a %U:%G %n' /etc/shadow
stat -c %a prints the mode as three digits: owner, group, other. Each digit is read (4) + write (2) + execute (1). 640 is owner read/write, group read, others nothing.
Files that must be right¶
| File | Mode | Owner | Why |
|---|---|---|---|
/etc/passwd, /etc/passwd- |
644 | root:root | Readable by all (programs need it), writable only by root (CIS 7.1.1, 7.1.2) |
/etc/shadow, /etc/shadow- |
640 | root:shadow | Password hashes; "other" must be 0 (7.1.5, 7.1.6) |
/etc/gshadow, /etc/gshadow- |
640 | root:shadow | Group passwords (7.1.7, 7.1.8) |
/etc/group, /etc/group- |
644 | root:root | (7.1.3, 7.1.4) |
/etc/shells |
644 | root:root | The list of valid shells (7.1.9) |
/etc/security/opasswd |
600 | root:root | Password history (7.1.10) |
/etc/sudoers |
440 | root:root | sudo refuses to run if this is wrong |
/etc/sudoers.d/* |
440 | root:root | Same |
/etc/ssh/sshd_config |
600 | root:root | |
/etc/ssh/ssh_host_*_key |
600 | root:root | Private host keys |
/etc/crontab, /etc/cron.* |
600 / 700 | root:root | A user who can write a cron file runs code as root |
/boot/grub/grub.cfg |
600 | root:root | Contains the GRUB password hash |
/etc/ssl/private/* |
600 | root:root | TLS private keys (vsftpd, Apache, nginx) |
/var/log/* |
640 or 600 | root:adm | Logs are for administrators |
/root |
700 | root:root | |
/home/* |
750 | user:user | A user's home is not world-readable ("other" digit 0) |
/var/lib/mysql |
750 | mysql:mysql | Database files; "other" digit 0 |
/tmp, /var/tmp |
1777 | root:root | The leading 1 is the sticky bit: users can only delete their own files |
sudo chmod 644 /etc/passwd /etc/passwd- /etc/group /etc/group- /etc/shells; sudo chown root:root /etc/passwd /etc/passwd- /etc/group /etc/group- /etc/shells
sudo chmod 640 /etc/shadow /etc/shadow- /etc/gshadow /etc/gshadow-; sudo chown root:shadow /etc/shadow /etc/shadow- /etc/gshadow /etc/gshadow-
sudo chmod 600 /etc/security/opasswd 2>/dev/null
sudo chmod 440 /etc/sudoers; sudo chmod 440 /etc/sudoers.d/*
sudo chmod 600 /etc/ssh/sshd_config /etc/ssh/ssh_host_*_key /boot/grub/grub.cfg
sudo chmod 700 /root
sudo chmod 750 /home/*
System commands and libraries¶
The STIG spells out what CIS leaves implied (UBTU-22-232010 to 232075): every directory that holds system commands (/bin, /sbin, /usr/bin, /usr/sbin, /usr/local/bin, /usr/local/sbin) and every library directory (/lib, /lib64, /usr/lib) is mode 755 or tighter and owned by root:root, and so is every file inside them. A writable /usr/bin/sudo or /lib/x86_64-linux-gnu/libc.so.6 is root for whoever can write it.
sudo find -L /bin /sbin /usr/bin /usr/sbin /usr/local/bin /usr/local/sbin /lib /lib64 /usr/lib -perm /022 -type f 2>/dev/null
sudo find -L /bin /sbin /usr/bin /usr/sbin /usr/local/bin /usr/local/sbin /lib /lib64 /usr/lib ! -user root 2>/dev/null
sudo find -L /bin /sbin /usr/bin /usr/sbin /usr/local/bin /usr/local/sbin /lib /lib64 /usr/lib ! -group root 2>/dev/null
All three print nothing on a clean system. Fix a hit with sudo chmod go-w file; sudo chown root:root file. A few packages legitimately install files owned by a system account (_apt, messagebus); the STIG allows those, and they'll be the only lines the second command prints on a clean system.
The log and journal areas have their own expected owners (UBTU-22-232025 to 232140): /var/log is 755 root:syslog, /var/log/syslog is 640 syslog:adm, /var/log/journal and its files are owned by root:systemd-journal, and /usr/bin/journalctl is root:root mode 740 so only administrators read the journal.
sudo chmod 755 /var/log; sudo chown root:syslog /var/log
sudo chmod 640 /var/log/syslog; sudo chown syslog:adm /var/log/syslog
sudo chown -R root:systemd-journal /var/log/journal
sudo chmod 740 /usr/bin/journalctl
Find the wrong ones¶
sudo find / -xdev -type f -perm -0002 -not -path '/proc/*' 2>/dev/null # world-writable files
sudo find / -xdev -type d -perm -0002 -not -perm -1000 2>/dev/null # world-writable dirs without sticky bit
sudo find / -xdev \( -nouser -o -nogroup \) 2>/dev/null # owned by a deleted user
sudo find / -xdev -perm -4000 -type f 2>/dev/null # setuid
find /home -maxdepth 1 -mindepth 1 -type d -perm /007 # home dirs readable by others
World-writable files under /etc, /usr, /bin, or /lib are the emergency: anyone can change what root runs (CIS 7.1.11). Files with no owner (7.1.12) belonged to a deleted account and are reassigned or removed: sudo chown root:root file. The setuid review is 7.1.13. The setuid list has a known set (sudo, passwd, su, mount, umount, chsh, chfn, newgrp, gpasswd, pkexec, fusermount3, ssh-keysign, chrome-sandbox); anything else is suspect.
Ownership¶
sudo chown root:root /etc/passwd /etc/group /etc/sudoers
sudo chown -R alice:alice /home/alice
sudo chown root:root /usr/bin/sudo && sudo chmod 4755 /usr/bin/sudo
A system file owned by a normal user means that user can edit it. ls -l file | awk '{print $3 $4}' prints rootroot for a correct one.
Verify¶
stat -c '%a %U:%G %n' /etc/passwd /etc/shadow /etc/sudoers /etc/ssh/sshd_config /root /home/*
sudo find / -xdev -type f -perm -0002 -not -path '/proc/*' 2>/dev/null | wc -l # 0
Example¶
stat -c '%a %U:%G' /etc/shadow prints 644 root:root: every user can read the hashes. chmod 640; chown root:shadow. The world-writable find lists /etc/sudoers.d/ops and /usr/local/bin/backup.sh (which root's cron runs). chmod 440 the first, chmod 755; chown root:root the second, and read the script to see whether anyone already edited it. /home/bob is 777; chmod 750.
Try it¶
chmod 666 /etc/shadowon a practice image, find it withstat, fix it.- Run the world-writable
findand read every result before fixing any.
Build it¶
A perms.sh that runs stat -c '%a %U:%G %n' on the files in the table and prints any that differ from the expected mode and owner listed in a file you write.