Skip to content

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

  1. chmod 666 /etc/shadow on a practice image, find it with stat, fix it.
  2. Run the world-writable find and 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.

Next

Firefox