Skip to content

Linux Enumeration

After getting a shell on a Linux host (usually low-privilege), the first job is understanding where you are before trying to escalate. Who you are, what permissions you hold, what runs, what’s misconfigured, and what credentials are lying around. Orderly enumeration almost always reveals the escalation vector; firing exploits blindly is noisy and unnecessary.

who am I and what can I do? → what’s locally exploitable? → what else do I reach (network/credentials)?

id ; whoami ; groups # user, UID/GID, groups (docker? sudo? adm?)
sudo -l # what I can run as root (key! see lin-sudo)
cat /etc/passwd # system users (valid shells)
cat /etc/group # groups (interesting memberships)
history ; cat ~/.bash_history # prior commands (sometimes credentials)

Juicy groups: sudo, wheel, docker (=root, see Container and Docker Escapes), lxd, adm (logs), disk.

uname -a # kernel and architecture (for kernel exploits, see lin-kernel)
cat /etc/os-release # distro and version
hostname ; cat /etc/hosts

Cross-reference the kernel version with known exploits (Dirty COW, Dirty Pipe, PwnKit…).

ps aux --forest # processes and as whom they run (root with weak binaries?)
ss -tulpn # listening ports (internal services, pivoting)
systemctl list-units --type=service
cat /etc/crontab ; ls -la /etc/cron.* # tasks (writable scripts? see lin-cron)
cat /etc/fstab # mounts (NFS, disks)

Permissions and interesting files (privesc vectors)

Section titled “Permissions and interesting files (privesc vectors)”
# SUID/SGID binaries (see lin-suid)
find / -perm -4000 -type f 2>/dev/null
find / -perm -2000 -type f 2>/dev/null
# capabilities (see lin-caps)
getcap -r / 2>/dev/null
# world-writable files/directories
find / -writable -type d 2>/dev/null
find / -perm -o+w -type f 2>/dev/null
# config files with credentials
grep -riE 'password|secret|api_key' /etc /var/www /opt 2>/dev/null
cat ~/.ssh/id_rsa ~/.ssh/authorized_keys 2>/dev/null # SSH keys
cat ~/.aws/credentials ~/.config/* 2>/dev/null
find / -name "*.conf" -o -name "*.env" 2>/dev/null | xargs grep -l pass 2>/dev/null
cat /var/www/html/wp-config.php /var/www/*/config* 2>/dev/null # web configs
mysql/psql history, .netrc, .git-credentials
ip a ; ip route ; arp -a # interfaces, routes, neighbors (other subnets? see net-pivot)
ss -tulpn # internal services not exposed outside
linpeas.sh # the reference all-in-one enumerator (flags everything in colors)
LinEnum.sh / linux-smart-enumeration (lse.sh)
pspy # spy on processes/cron without being root (see what root launches)

linpeas is almost mandatory: it automates all the above and highlights likely vectors. pspy is gold for seeing root cron/processes without privileges.

Reduce enumerability and vectors: least privilege (no unnecessary SUID/sudo), no credentials in files/configs (use managed secrets), strict permissions, execution logging (auditd), kernel and packages up to date, and EDR that detects linpeas/pspy execution and post-exploitation recon chains.

  • id, sudo -l, groups (docker/lxd/sudo/adm)
  • Kernel and distro → map kernel exploits (Linux Kernel Exploits)
  • SUID/SGID and capabilities (SUID/SGID Binaries, Linux Capabilities)
  • Cron and services with writable scripts/binaries (Cron Jobs and Timers)
  • World-writable files/directories
  • Credentials in configs, histories, SSH/AWS keys
  • Network: other reachable subnets (pivoting)
  • Run linpeas + pspy to miss nothing