Linux Fundamentals

Users, Groups & sudo

/etc/passwd, /etc/shadow, groups, and how sudo is configured - and misconfigured.

Medium 18 minuserssudoshadow

Every action on a Linux system is performed by a user - and the most consequential question in security is always: "what user am I, and what can I do?" This lesson is the foundation for understanding identity, authentication, and privilege on Linux.

This Is Sensitive System Knowledge

The files and commands covered here - /etc/shadow, password hashes, sudo configuration - are the beating heart of Linux access control. Learn this to build secure systems and perform authorized security assessments. Accessing these files or accounts without authorization is illegal.

Who Am I? - The Identity Commands

Before anything else, establish your identity on a system:

kali@vr4cs: ~
 

id is the richest of these. It shows:

  • uid - numeric user ID and username
  • gid - primary group ID and name
  • groups - all groups the user belongs to

Notice 27(sudo) in the groups - that means this user can run sudo. This is the first thing an attacker confirms after gaining a shell, and the first thing an auditor checks when reviewing a user account.

Post-Exploitation Reflex

The moment you get a shell - in a CTF, a lab, or an authorized pentest - your first three commands should be: whoami, id, and sudo -l. These three tell you everything about what you can immediately do.

/etc/passwd - The User Database

/etc/passwd is readable by every user on the system. It contains one entry per user account:

username:password:UID:GID:comment:home_dir:shell
kali@vr4cs: ~
 

Key fields to understand:

FieldMeaningSecurity note
usernameLogin name
xPassword fieldx means hash is in /etc/shadow. Empty field means no password needed!
UIDUser ID numberUID 0 = root. Any account with UID 0 is root-equivalent
GIDPrimary group ID
commentGECOS fieldOften contains full name - useful for OSINT
home_dirHome directory path
shellLogin shell/usr/sbin/nologin = service account, can't get interactive shell

What attackers look for in /etc/passwd:

  • UID 0 accounts other than root (hidden backdoor users)
  • Service accounts (www-data, svc-backup) with /bin/bash shells
  • The password field being empty (no x) - immediate login without password
  • Users with interesting home directories or shells
# Find all accounts with UID 0
awk -F: '($3 == 0) {print}' /etc/passwd
 
# Find all accounts that can get an interactive shell
grep -v "nologin\|false" /etc/passwd

/etc/shadow - Where Password Hashes Live

/etc/shadow stores the actual password hashes. Only root can read it (permissions: 640, owned by root:shadow on Debian/Kali):

kali@vr4cs: ~
 

The format is: username:hash:last_changed:min_age:max_age:warn:inactive:expire

Hash formats - know these:

PrefixAlgorithmCrackability
$1$MD5Very fast to crack - obsolete
$5$SHA-256Faster than SHA-512
$6$SHA-512Slow enough to be acceptable
$y$yescryptModern, memory-hard, hard to crack
$2b$bcryptStrong, widely used
!Account lockedNo password login possible
*No loginService account, no login

Hash Format Tells You the Cracking Difficulty

If you gain access to /etc/shadow in an authorized engagement, the hash format immediately tells you how viable password cracking is. $1$ (MD5) hashes can be cracked at billions of attempts per second on a GPU. $y$ (yescrypt) is designed to be memory-hard and significantly more resistant. In a pentest report, old hash formats ($1$, $5$) are a finding - the OS or PAM configuration should use yescrypt or bcrypt.

An interesting scenario: if you find /etc/shadow readable by your unprivileged user, that's a critical misconfiguration. Extract the hashes and crack them with john or hashcat.

/etc/group - Group Membership

/etc/group maps group names to GIDs and lists members:

groupname:password:GID:member1,member2,member3
kali@vr4cs: ~
 

High-value groups from an attacker's perspective:

GroupWhy it matters
sudoMembers can run commands as root via sudo
dockerDocker group is essentially root - can mount host filesystem into containers
wheelSame as sudo on Red Hat-based systems
admCan read log files in /var/log
shadowCan read /etc/shadow
lxdLXD containers - another root escalation vector

If your user is in the docker group, you have root:

docker run -v /:/mnt --rm -it alpine chroot /mnt sh
# You now have a root shell with access to the entire host filesystem

Switching Users - su

su (substitute user) opens a shell as a different user:

su alice            # switch to alice (needs alice's password)
su -                # switch to root with full login environment
su - alice          # switch to alice with full login environment
su -c "command" alice   # run one command as alice

The - (or -l) flag sources the target user's shell config files (.bashrc, .profile), sets the HOME directory correctly, and resets the environment. Always use su - rather than just su when switching to root.

kali@vr4cs: ~
 

Managing Users - useradd, usermod, userdel, passwd

These are system administration commands. You need root to run them:

# Create a new user
useradd -m -s /bin/bash -c "Alice Smith" alice
# -m: create home directory
# -s: set shell
# -c: comment/full name
 
# Set or change a password
passwd alice
 
# Modify an existing user
usermod -aG sudo alice          # add alice to sudo group
usermod -aG docker,developers alice   # add to multiple groups
usermod -L alice                # lock account (add ! to shadow)
usermod -U alice                # unlock account
 
# Delete a user
userdel alice                   # delete user but keep home dir
userdel -r alice                # delete user AND home directory

usermod -aG - The -a Matters

When adding a user to a group with usermod -G, always include -a (append). Without it, usermod -G sudo alice would replace all of Alice's group memberships with just sudo, potentially removing her from other groups she needs.

sudo - Controlled Privilege Escalation

sudo (superuser do) lets authorized users run specific commands as root (or another user). It's the standard, auditable way to grant administrative access without sharing the root password.

kali@vr4cs: ~
 

sudo -l - The Attacker's Favorite Command

sudo -l lists what the current user is allowed to run via sudo. This is always checked during privilege escalation:

kali@vr4cs: ~
 

That second example shows a misconfigured sudo policy:

  • NOPASSWD means no password prompt
  • vim /var/www/html/* - the * is a glob, not a restriction. You can run sudo vim /var/www/html/../../etc/sudoers and overwrite /etc/sudoers. Or use :!/bin/bash inside vim to get root.
  • Even the systemctl restart nginx entry is potentially exploitable if the nginx service file is writable.

/etc/sudoers - The sudo Configuration File

Never edit /etc/sudoers directly with a text editor - always use visudo, which validates syntax before saving (a broken sudoers file can lock everyone out of sudo):

sudo visudo

The syntax:

# Format: WHO WHERE=(AS_WHOM) [NOPASSWD:] COMMANDS
kali    ALL=(ALL:ALL) ALL          # full sudo access
alice   ALL=(root) /bin/systemctl  # alice can only restart services
bob     ALL=(ALL) NOPASSWD: /usr/bin/git  # bob can run git as root, no password
%sudo   ALL=(ALL:ALL) ALL          # % means group: everyone in sudo group

Common dangerous sudo misconfigurations:

MisconfigurationWhy it's dangerous
(ALL) NOPASSWD: ALLComplete root access without even a password
(root) /usr/bin/vimvim can spawn shell commands - trivial escalation
(root) /bin/bashDirect root shell
(root) /usr/bin/python3Python can exec('/bin/bash')
(root) /usr/bin/findfind can execute commands with -exec
(root) /usr/bin/gitgit hooks can run arbitrary commands
Any command with * globGlob may allow unintended path traversal
/etc/sudoers.d/ writableCreate a new policy file granting yourself root
# If sudo lets you run python:
sudo python3 -c "import os; os.system('/bin/bash')"
 
# If sudo lets you run find:
sudo find / -exec /bin/bash -i \; -maxdepth 0 2>/dev/null
 
# If sudo lets you run vim with any path:
sudo vim /legitimate/path/../../etc/sudoers

sudoers.d - The Include Directory

Modern systems also read /etc/sudoers.d/*.conf files. These are included by the main sudoers file. If this directory is world-writable (misconfiguration), any user can drop a file there granting themselves root. Check with ls -la /etc/sudoers.d/.

Key Takeaways

  • whoami, id, and groups reveal your identity and group memberships. id is the most complete - it shows all UIDs, GIDs, and supplementary groups.
  • /etc/passwd is world-readable: contains usernames, UIDs, home directories, and shells. Password field containing x means hash is in shadow. Empty password field = no password required.
  • /etc/shadow contains password hashes (root-only). Hash format reveals cracking difficulty - $1$ (MD5) is weak, $y$ (yescrypt) is modern and strong.
  • /etc/group maps groups to members. Membership in sudo, docker, or lxd effectively grants root.
  • su - switches to another user with a full login environment. sudo runs commands with elevated privileges with auditing.
  • sudo -l is always one of the first commands in privilege escalation research. It reveals what you can run as root, and many policies are misconfigured in exploitable ways.
  • Always edit /etc/sudoers with visudo - never with a regular text editor.