Skip to main content
Synced from an Obsidian vault

For graph and advanced features, download the full Intel Codex Vault and open it in Obsidian.

Linux Pentesting SOP (Authorized)

Authorized environments only. Read Legal & Ethics and OPSEC Plan before any engagement. This SOP covers defensive assessment, hardening validation, and non-destructive privilege-escalation enumeration.


Table of Contents

  1. Engagement Setup
  2. Information Gathering (Read-Only)
  3. Configuration Review
  4. Privilege Escalation Vectors (Non-Destructive Checks)
  5. Logging & Monitoring Review
  6. Network Security
  7. Automated Enumeration Tools
  8. Common Misconfigurations Checklist
  9. Evidence Collection
  10. Reporting
  11. Safety & Legal
  12. Tools Reference
  13. Common Pitfalls
  14. Reference Resources

Pre-Engagement & Authorization

Linux LPE work is inherently destabilizing — kernel exploits panic boxes, container escapes cross trust boundaries, and persistence primitives outlive the engagement window. Pin specifics in writing before any tool from §7 runs against an in-scope host. The "Pre-Engagement" checklist inside §1 below covers engagement kickoff; this section adds the Linux-specific abuse-surface authorization an LPE engagement actually needs.

Authorization Checklist

  • Kernel-exploit detonation scope — explicit per-CVE authorization for any LPE PoC binary (PwnKit / DirtyPipe / GameOver(lay) / Looney Tunables / nf_tables UAF / Leaky Vessels), tied to a captured uname -a + distro snapshot taken at engagement start. Public PoCs on production are out-of-scope by default.
  • Container escape boundary — explicit host-vs-guest authorization. runc Leaky Vessels (CVE-2024-21626), cgroup release_agent escape, Docker / containerd / podman socket abuse, and Kubernetes service-account-token use all cross the container/host boundary; if the host is out of scope, escape PoCs stop at proof-of-namespace-break.
  • /etc/passwd / /etc/shadow modification scope — read-only enumeration is in scope; write access (adding a UID 0 row, exfiltrating /etc/shadow for offline cracking) requires written sign-off and a backup snapshot.
  • Sudo / sudoedit policy abuse — capturing sudo -l output is enumeration; chaining NOPASSWD entries via GTFOBins or detonating CVE-2023-22809 / CVE-2021-3156 is exploitation and must be named in the SoW.
  • SUID binary modification — auditing the existing SUID set is in scope; creating new SUID bits (chmod +s …) or modifying baseline SUID binaries requires explicit permission plus a documented revert step.
  • NFS / SMB / CIFS share write authorizationshowmount -e and no_root_squash flag-grep are read-only; writing a SUID payload to a no_root_squash export needs sign-off from the share owner, not just the host owner.
  • systemd unit / cron / timer write authorization — dropping a .service, .timer, .socket, lingering ~/.config/systemd/user/ unit, or /etc/cron.*/ file creates persistence and must be named, time-boxed, and registered for cleanup.
  • Jurisdictional + safe-harbor framing — see Legal & Ethics (canonical) for CFAA / Computer Misuse Act framing; bug-bounty engagements: confirm the program's safe-harbor language covers Linux LPE explicitly (some VDPs scope to web-only).

Lab Environment Requirements

  • Distro + kernel version-matched lab VM. Kernel CVE PoCs are pinned at the patch level — Ubuntu 22.04 with kernel 5.15.0-67 is not the same target as 5.15.0-101 even though both report 5.15.0 to uname -r. Snapshot the target's cat /etc/os-release, uname -a, ldd --version, sudo --version, pkexec --version, and runc --version before staging the lab.
  • Throwaway VM snapshot before any kernel-exploit detonation. Public LPE PoCs panic the kernel on near-miss versions or leave the box unbootable; reproduce in a snapshotted VM, never on the live target.
  • Container runtime version-matched for Leaky Vessels (CVE-2024-21626) testing. runc, containerd, and the Docker engine bundle runc independently — Docker 25.0.2 / containerd 1.7.13 / runc 1.1.12 are the patched baseline; match the target's bundled set exactly in the lab.
  • Capability-aware lab container. Validate container-escape primitives in a lab container that mirrors the in-scope target's --cap-add / --privileged / --security-opt / mount set; capability differences silently change which primitives work.
  • GTFOBins coverage spot-check pre-engagement. Before reporting a sudo / SUID / capability finding as exploitable, verify the binary appears on GTFOBins with the relevant primitive — many baseline binaries look exploitable but lack a public escalation gadget.
  • Operator-side OPSEC. No curl … | sh from a target you do not control (see §7 note); download to a throwaway path, sha256sum, inspect, then run. Tool artifacts (LinPEAS output, pspy logs, captured /etc/shadow) are sensitive — store, transport, and destroy per OPSEC Plan.

Disclosure-Ready Posture

  • Baseline before touching anything. At engagement start capture: linpeas.sh -a > linpeas.baseline.out, lse.sh -l 2 -i > lse.baseline.out, sudo -l > sudo-policy.baseline.out, getcap -r / 2>/dev/null > caps.baseline.out, full find / -perm -4000 -ls > suid.baseline.out SUID inventory. The disclosure delta (what you changed) is meaningless without the baseline.
  • Activity timeline. Run pspy and/or auditd (where authorized) for the duration of active testing so the sysadmin can correlate test activity to alerts post-engagement; capture journalctl -u auditd --since "<engagement-start ISO-8601>" at hand-off.
  • Do NOT wipe history in scope unless explicitly authorized. ~/.bash_history, ~/.zsh_history, lastb, journald, and /var/log/auth.log are evidence — wiping them is itself a finding that must be disclosed. Use a dedicated operator account or unset HISTFILE rather than scrubbing after the fact.
  • Sudoers + capability state snapshot. Sudoers (mode 440 root-owned) and file capabilities change rarely, but the sudo -l policy and getcap -r / output that were in effect during the test must be in the report — otherwise reproducibility is lost when sysadmins later tighten the rules.
  • Container runtime + image digest snapshot. Record docker info --format '{{.RuncVersion}}', image digest (docker inspect --format '{{.Image}}' &lt;ctr&gt;), and kubectl version so findings tie back to a reproducible runtime build.
  • Evidence pack + final report routing. Stage evidence per the Collection Log hash-and-timestamp pattern referenced in §9 below; final disclosure pack (executive summary, technical detail, IOC defanging, remediation timeline) follows Reporting / Packaging / Disclosure.

1. Engagement Setup

Pre-Engagement

  • Obtain written authorization (signed Rules of Engagement)
  • Define scope: hosts, subnets, services, user accounts
  • Set time windows and blackout periods
  • Establish emergency contacts and escalation path
  • Agree on change control procedures
  • Confirm backup/restore process exists

Objectives (Examples)

  • Identify misconfigurations enabling unauthorized access or privilege escalation
  • Validate hardening baseline compliance (CIS, STIG, etc.)
  • Test privilege separation and access controls
  • Evaluate logging/monitoring efficacy

2. Information Gathering (Read-Only)

System Identification

# OS version and kernel
uname -a
cat /etc/os-release
cat /etc/*-release
hostnamectl

# Kernel version (for known vuln research)
uname -r

User & Group Enumeration

# List all users
cat /etc/passwd
cut -d: -f1 /etc/passwd

# Users with login shells
grep -v "/nologin\|/false" /etc/passwd

# Check for UID 0 (root-equivalent) accounts
awk -F: '$3 == 0 {print $1}' /etc/passwd

# Group memberships
cat /etc/group
groups &lt;username&gt;

# Sudo access
sudo -l
cat /etc/sudoers
ls -la /etc/sudoers.d/

# Recently modified user accounts
ls -lat /home/

Running Services & Network

# Active services
systemctl list-units --type=service --state=running
ps aux

# Network listeners
ss -tulnp
netstat -tulnp

# Firewall status
sudo iptables -L -n -v
sudo ufw status verbose
sudo firewall-cmd --list-all

# Check for unusual binds (0.0.0.0 vs localhost)
ss -tulnp | grep "0.0.0.0"

Installed Packages

# Debian/Ubuntu
dpkg -l
apt list --installed

# RHEL/CentOS
rpm -qa
yum list installed

# Check for outdated packages
apt list --upgradable # Debian/Ubuntu
yum check-update # RHEL/CentOS

# Look for unnecessary packages (compilers, dev tools on prod)
dpkg -l | grep -E "gcc|g\+\+|build-essential|python-dev"

3. Configuration Review

File & Directory Permissions

Sensitive files to check:

# SSH configuration
ls -la /etc/ssh/sshd_config
cat /etc/ssh/sshd_config | grep -E "PermitRootLogin|PasswordAuthentication|PubkeyAuthentication|PermitEmptyPasswords"

# Shadow file (should be 600 or 640)
ls -la /etc/shadow

# Sudoers (should be 440)
ls -la /etc/sudoers
ls -la /etc/sudoers.d/

# Cron files
ls -la /etc/cron*
ls -la /var/spool/cron/crontabs/

# World-writable files (dangerous)
find / -type f -perm -002 -ls 2>/dev/null

# World-writable directories
find / -type d -perm -002 -ls 2>/dev/null

# SUID/SGID binaries (privilege escalation vectors)
find / -type f \( -perm -4000 -o -perm -2000 \) -ls 2>/dev/null

# Files owned by users but writable by others
find / -type f -perm -o+w -ls 2>/dev/null

SSH Hardening Checks

# Show effective sshd config (resolves Match/Include blocks)
sudo sshd -T 2>/dev/null | grep -Ei "permitroot|passwordauth|permitempty|kbdinteract|maxauth|kex|ciphers|macs|allowusers|allowgroups|x11|tcpforward|gatewayports|allowagent|clientalive"

# Per-directive checks (raw config; does not honor Match)
grep -Ei "^PermitRootLogin" /etc/ssh/sshd_config # expected: no (or prohibit-password if using key-only root mgmt)
grep -Ei "^PasswordAuthentication" /etc/ssh/sshd_config # expected: no when keys are mandatory
grep -Ei "^KbdInteractiveAuthentication|^ChallengeResponseAuthentication" /etc/ssh/sshd_config # expected: no
grep -Ei "^PermitEmptyPasswords" /etc/ssh/sshd_config # expected: no
grep -Ei "^MaxAuthTries" /etc/ssh/sshd_config # expected: <= 4
grep -Ei "^LoginGraceTime" /etc/ssh/sshd_config # expected: 60 or less
grep -Ei "^X11Forwarding" /etc/ssh/sshd_config # expected: no unless required
grep -Ei "^AllowAgentForwarding" /etc/ssh/sshd_config # expected: no unless required
grep -Ei "^AllowTcpForwarding" /etc/ssh/sshd_config # expected: no unless required
grep -Ei "^GatewayPorts" /etc/ssh/sshd_config # expected: no
grep -Ei "^Allow(Users|Groups)|^Deny(Users|Groups)" /etc/ssh/sshd_config # principle of least access

# Algorithm strength (Mozilla "Modern" / "Intermediate" baselines)
grep -Ei "^KexAlgorithms|^Ciphers|^MACs|^HostKeyAlgorithms|^PubkeyAcceptedAlgorithms" /etc/ssh/sshd_config

# NOTE: SSH protocol 1 was removed from OpenSSH 7.6 (Oct 2017). The legacy
# "Protocol 2" directive is unparsed in modern sshd; do not rely on its absence.

# External audit (recommended; --policy=mozilla_modern or --policy=mozilla_intermediate)
ssh-audit &lt;target_host&gt; # github.com/jtesta/ssh-audit

# Inventory authorized_keys (per-user, including root and service accounts)
sudo find / -xdev -name "authorized_keys*" -ls 2>/dev/null
# Inspect specific files only after scoping; printing keys to stdout is logged

Sudo Policy Review

# Check sudoers for NOPASSWD (dangerous)
sudo grep NOPASSWD /etc/sudoers /etc/sudoers.d/*

# Check for overly permissive sudo (ALL=(ALL) ALL)
sudo grep "ALL=(ALL)" /etc/sudoers /etc/sudoers.d/*

# Users in sudo/wheel group
getent group sudo
getent group wheel

Service Configuration

# Apache (Debian path /etc/apache2 ; RHEL path /etc/httpd)
grep -RIE "Indexes|ServerTokens|ServerSignature|TraceEnable" /etc/apache2/ /etc/httpd/ 2>/dev/null
# Expected: -Indexes, ServerTokens Prod, ServerSignature Off, TraceEnable Off

# Nginx
grep -RIE "server_tokens|autoindex|ssl_protocols|ssl_ciphers" /etc/nginx/ 2>/dev/null
# Expected: server_tokens off; autoindex off; TLS 1.2/1.3 only

# Check running services on unexpected ports (anything not on loopback)
ss -tulnp | awk 'NR==1 || ($5 !~ /^127\./ && $5 !~ /^\[::1\]/)'

# Check for credentials in config files (skip binary matches and avoid /proc)
sudo grep -RIin --exclude-dir={proc,sys} -E "password|passwd|secret|api[_-]?key|token" /etc/ 2>/dev/null | head -50

4. Privilege Escalation Vectors (Non-Destructive Checks)

PATH Hijacking

# Check PATH for writable directories
echo $PATH | tr ':' '\n' | while read dir; do ls -ld "$dir" 2>/dev/null; done

# Check if current directory (.) is in PATH (dangerous)
echo $PATH | grep -E "^\.:|:\.:|\.$"

Writable Scripts/Binaries in Privileged Locations

# Check if user can write to system binaries
find /usr/bin /usr/sbin /bin /sbin -writable 2>/dev/null

# Check for writable scripts called by root cron
cat /etc/crontab
ls -la /etc/cron.d/
ls -la /etc/cron.daily/

Kernel & userland LPE (Version Check Only)

Only enumerate. Do not run public exploit binaries on production hosts — many are noisy, panic-prone, or backdoored. If exploitation is in scope, copy the host kernel/glibc/sudo/polkit versions into a sandbox and reproduce there.

# Distribution + kernel + relevant userland (sudo, glibc, polkit, runc)
cat /etc/os-release
uname -a # kernel version + build
ldd --version | head -1 # glibc
sudo --version | head -1 # sudo
pkexec --version 2>/dev/null # polkit
runc --version 2>/dev/null # container runtime

# Auditing tools (read-only, heuristic)
linux-exploit-suggester.sh # github.com/The-Z-Labs/linux-exploit-suggester
linux-exploit-suggester-2.pl # github.com/jondonas/linux-exploit-suggester-2

# Installed kernels (multi-kernel hosts may boot a stale image)
dpkg -l | grep -E "^ii\s+linux-image" # Debian/Ubuntu
rpm -qa | grep -E "^kernel-" # RHEL/Fedora

Recent illustrative LPE primitives (verify each against the running kernel/userland — most distros ship patches):

CVEComponentTrigger surfaceQuick check
CVE-2021-4034 (PwnKit)polkit pkexecSUID pkexec + crafted argv/envls -l $(which pkexec) ; pkexec --version (polkit < 0.120 likely vuln)
CVE-2022-0847 (DirtyPipe)Linux kernel 5.8–5.16.xsplice() into pipe, write to read-only fileuname -r in vulnerable range
CVE-2023-2640 / CVE-2023-32629 (GameOver(lay))Ubuntu OverlayFSUbuntu-shipped OverlayFS patcheslsb_release -a Ubuntu + kernel 5.4–6.5 ; `mount
CVE-2023-4911 (Looney Tunables)glibc ld.so GLIBC_TUNABLESBuffer overflow when SUID binary processes envldd --version (glibc 2.34–2.38 unpatched)
CVE-2023-22809 (sudoedit env-var)sudo 1.8.0–1.9.12p1EDITOR/VISUAL/SUDO_EDITOR argv injectionsudo --version ; sudo -l shows sudoedit rule
CVE-2021-3156 (Baron Samedit)sudo 1.8.2–1.9.5p1Heap overflow via sudoedit -s argvsudo --version ; reproduce only in sandbox
CVE-2023-32233Linux kernel nf_tables ≤ 6.3.1Anonymous-set UAFuname -r + `lsmod
CVE-2024-1086Linux kernel nf_tables 5.14–6.7.1UAF via nft_verdict_inituname -r + `lsmod
CVE-2024-21626 (Leaky Vessels)runc ≤ 1.1.11FD leak → host filesystem in containerrunc --version ; container engines bundle runc — check Docker/containerd build

[verify 2026-04-25] Each row's "fixed in" version differs per distro back-port. Cross-check with the vendor security tracker (https://ubuntu.com/security/cves, https://access.redhat.com/security/cve/&lt;id&gt;, https://security-tracker.debian.org/tracker/&lt;id&gt;).

Capabilities (Linux File Capabilities)

# File capabilities across the entire mounted filesystem
getcap -r / 2>/dev/null

# Capabilities of the current process / shell / a target PID
capsh --print
getpcaps $$
getpcaps &lt;pid&gt;

# Per-thread capabilities (CapEff/CapPrm/CapBnd as bitmaps — decode with capsh)
grep ^Cap /proc/self/status
capsh --decode=$(awk '/^CapEff/{print $2}' /proc/self/status)

Dangerous capabilities (single-cap → root) — most have a documented GTFOBins-style escalation path; cross-reference GTFOBins → Capabilities:

CapabilityWhy it's root-equivalent
cap_setuid / cap_setgidDirect UID/GID change inside scripted interpreters that hold the cap
cap_dac_overrideBypass file read/write/execute permission checks (read /etc/shadow)
cap_dac_read_searchBypass file read + directory search checks
cap_chown / cap_fownerRe-own arbitrary files (chown root:root + chmod +s)
cap_sys_adminEffectively root: mount, BPF, kernel module ops, namespace setup
cap_sys_ptraceAttach to root processes; inject shellcode
cap_sys_moduleLoad kernel modules (drop a malicious .ko)
cap_net_admin + cap_net_rawNetwork reconfiguration, raw sockets, ARP/DNS poisoning
cap_sys_chroot + writable host pathsCombine with mount tricks to escape
cap_bpf (kernel ≥ 5.8)Load BPF programs without cap_sys_admin

T1548.001 (SUID/SGID), T1574.012 (Linux File and Directory Permissions Modification — capabilities subset).

Container & runtime escape (If Applicable)

# Am I in a container?  (any of the following is a strong signal)
ls -la /.dockerenv /.containerenv 2>/dev/null
grep -E "docker|kubepods|containerd|lxc|crio" /proc/1/cgroup /proc/self/cgroup 2>/dev/null
grep -qE "container=" /proc/1/environ && echo "systemd-nspawn/podman"
cat /proc/1/sched | head -1 # PID 1 not "init"/"systemd" → container

# What kind? (orchestrator hints)
mount | grep -E "overlay|aufs|fuse-overlayfs"
ls /var/run/secrets/kubernetes.io/serviceaccount/ 2>/dev/null # K8s pod
env | grep -E "KUBERNETES_|HOSTNAME|HOST_IP"
# === Docker socket mounted into container (host control plane exposed) ===
ls -la /var/run/docker.sock /run/docker.sock 2>/dev/null
# If readable, the container can drive the host's Docker daemon and request
# a new container with the host root mounted — equivalent to root on host.
# Equivalent for containerd / nerdctl / podman sockets:
ls -la /run/containerd/containerd.sock /run/podman/podman.sock 2>/dev/null

# === User in `docker` group (host) ===
id ; groups | grep -qw docker && echo "docker group → root-equivalent on host"

# === Privileged or over-capabilitied containers ===
# Inside container: check own capability set
capsh --print | grep -E "cap_sys_admin|cap_sys_module|cap_sys_ptrace|cap_dac_read_search"
# CAP_SYS_ADMIN + writable cgroup v1 → release_agent escape (legacy primitive)

# === runc / Leaky Vessels (CVE-2024-21626) ===
runc --version 2>/dev/null
docker info --format '{{.RuncVersion}}' 2>/dev/null
# runc ≤ 1.1.11 → FD leak escape; Docker engines bundle runc — patched in
# Docker 25.0.2 / containerd 1.7.13 / runc 1.1.12. Verify host build.

# === Kubernetes pod context ===
SA=/var/run/secrets/kubernetes.io/serviceaccount
[ -d "$SA" ] && { cat "$SA/namespace"; head -c40 "$SA/token"; echo; cat "$SA/ca.crt" | head -2; }
# With token + API server reachable: `kubectl auth can-i --list` (requires kubectl in image
# or curl-able API). Look for: pods/exec, secrets, nodes/proxy, clusterrolebindings.

T1611 (Escape to Host), T1610 (Deploy Container), T1613 (Container and Resource Discovery).

Sudo policy & sudo CVE surface

# Effective sudo policy for current user (-n returns non-zero if a password is needed → still informative)
sudo -n -l 2>&1 || sudo -l

# Look for sudoers entries that map to GTFOBins escalation
sudo -l | grep -E "NOPASSWD|\(ALL\)|\(root\)|sudoedit"

# sudo binary version (compare against CVEs in the LPE table above)
sudo --version | head -1

# Sudoers files referenced (read-only — these are mode 440 root-owned)
sudo cat /etc/sudoers /etc/sudoers.d/* 2>/dev/null | grep -vE "^\s*#|^\s*$"

# Quick GTFOBins lookup for any binary in your sudo policy:
# https://gtfobins.github.io/#&lt;binary&gt;+sudo

Polkit / pkexec

pkexec --version 2>/dev/null              # PwnKit fixed in polkit 0.120 / distro back-ports
ls -l $(command -v pkexec) # SUID root — present on most desktop installs
pkaction | head -20 # registered actions (look for org.freedesktop.policykit.exec)
ls /etc/polkit-1/rules.d/ /usr/share/polkit-1/actions/ 2>/dev/null

systemd unit & timer abuse

# Writable units (override files in /etc/systemd are loaded with priority over /lib/systemd)
sudo find /etc/systemd /lib/systemd /run/systemd -type f \( -name "*.service" -o -name "*.timer" -o -name "*.socket" \) -writable 2>/dev/null

# Enumerate timers — alternative scheduler to cron
systemctl list-timers --all --no-pager
systemctl list-unit-files --type=service --state=enabled --no-pager

# User-level (lingering) units run as that user when enabled with `loginctl enable-linger`
ls -la ~/.config/systemd/user/ 2>/dev/null
loginctl list-users

NFS Shares (Privilege Escalation)

# Check for NFS exports
cat /etc/exports 2>/dev/null
showmount -e &lt;server&gt; 2>/dev/null

# Look for no_root_squash (mount as remote root, drop SUID shell, exec as local user)
grep -E "no_root_squash|no_all_squash|insecure" /etc/exports 2>/dev/null

5. Logging & Monitoring Review

Check Logging Status

# Syslog/rsyslog status
systemctl status rsyslog
systemctl status syslog-ng

# Auth log (login attempts, sudo usage)
tail -100 /var/log/auth.log # Debian/Ubuntu
tail -100 /var/log/secure # RHEL/CentOS

# Check for log rotation
cat /etc/logrotate.conf
ls /etc/logrotate.d/

# Check log permissions (should not be world-readable)
ls -la /var/log/

Audit Daemon (auditd)

# Check if auditd is running
systemctl status auditd

# Review audit rules
auditctl -l

# Check for monitoring of sensitive files
auditctl -l | grep -E "/etc/passwd|/etc/shadow|/etc/sudoers"

Failed Login Attempts

# Check for brute force attempts
grep "Failed password" /var/log/auth.log | tail -50

# Count failed logins by IP
grep "Failed password" /var/log/auth.log | awk '{print $(NF-3)}' | sort | uniq -c | sort -rn

6. Network Security

Firewall Configuration

# Check firewall status
sudo iptables -L -v -n
sudo ufw status verbose
sudo firewall-cmd --list-all

# Look for overly permissive rules (ACCEPT all, 0.0.0.0/0)
sudo iptables -L -v -n | grep "ACCEPT.*0.0.0.0/0"

Exposed Services

# Check what's listening externally (not just localhost)
ss -tulnp | grep -v "127.0.0.1"

# Scan from external perspective (if authorized)
nmap -sV -p- &lt;target_ip&gt;

7. Automated Enumeration Tools

Always download to disk and inspect before piping curl | sh on a target you do not control. The snippets below assume an authorized lab.

LinPEAS (PEASS-ng) — primary

# Canonical org is now peass-ng/PEASS-ng (carlospolop/PEASS-ng redirects)
curl -fL -o /tmp/linpeas.sh https://github.com/peass-ng/PEASS-ng/releases/latest/download/linpeas.sh
sha256sum /tmp/linpeas.sh # record hash in evidence
chmod +x /tmp/linpeas.sh
/tmp/linpeas.sh -a > /tmp/linpeas.out # -a = "all checks"; redirect for evidence

# Useful flags: -s (superfast/stealth), -e (extra), -P &lt;password&gt; (sudo password for sudo -l checks),
# -o &lt;list&gt; (only specific section codes), -n (skip network calls)

Linux Smart Enumeration (LSE) — secondary, color-graded

curl -fL -o /tmp/lse.sh https://github.com/diego-treitos/linux-smart-enumeration/releases/latest/download/lse.sh
chmod +x /tmp/lse.sh
/tmp/lse.sh -l 2 -i > /tmp/lse.out # -l 2 = full verbosity, -i = non-interactive

linux-exploit-suggester(-2) — kernel-CVE heuristics (read-only)

# v1 (The-Z-Labs / mzet)
curl -fL -o /tmp/les.sh https://raw.githubusercontent.com/The-Z-Labs/linux-exploit-suggester/master/linux-exploit-suggester.sh
chmod +x /tmp/les.sh && /tmp/les.sh

# v2 (jondonas) — Perl rewrite, smaller signature DB, useful as cross-check
curl -fL -o /tmp/les2.pl https://raw.githubusercontent.com/jondonas/linux-exploit-suggester-2/master/linux-exploit-suggester-2.pl
perl /tmp/les2.pl -k $(uname -r)

LinEnum (legacy)

# rebootuser/LinEnum — kept for parity with old playbooks but no releases published and
# essentially unmaintained for years; LinPEAS / LSE supersede it. Use only if both refuse to run.
curl -fL https://raw.githubusercontent.com/rebootuser/LinEnum/master/LinEnum.sh -o /tmp/LinEnum.sh && bash /tmp/LinEnum.sh

pspy — process snooping without root

# Reveals cron/systemd-driven root processes and their argv (file watch via inotify)
curl -fL -o /tmp/pspy https://github.com/DominicBreuker/pspy/releases/latest/download/pspy64
chmod +x /tmp/pspy && /tmp/pspy -pf -i 1000

Note: Review tool output manually; automated scanners generate false positives, miss context, and (especially LinEnum / older LES rule packs) flag CVEs that the running kernel has back-ported patches for. Treat findings as leads, not verdicts.


8. Common Misconfigurations Checklist

Authentication & SSH

  • Root login via SSH enabled (PermitRootLogin yes)
  • Password authentication enabled when keys should be used
  • PermitEmptyPasswords yes or KbdInteractiveAuthentication yes left on
  • Weak SSH KEX/Cipher/MAC (e.g. diffie-hellman-group1, arcfour, MD5/SHA-1 MACs) — confirm with ssh-audit
  • Authorized keys present in unexpected accounts (root, service users, decommissioned employees)

Authorization

  • Users in sudoers with NOPASSWD, or (ALL) ALL for non-admins
  • Sudoers rule maps to a binary listed on GTFOBins (vi, find, awk, less, python, tar, nmap interactive mode, …)
  • sudo / sudoedit / polkit version still vulnerable to CVE-2021-3156, CVE-2023-22809, CVE-2021-4034

Filesystem permissions

  • World-writable files / directories in system paths (/etc, /usr, /opt, /srv)
  • SUID/SGID binaries outside the distro's expected baseline (compare with a known-good install)
  • Files with dangerous capabilities (cap_setuid+ep, cap_dac_read_search+ep, cap_sys_admin+ep)
  • Weak permissions on /etc/shadow, /etc/sudoers, /etc/sudoers.d/*, ~/.ssh/authorized_keys

Scheduled execution

  • Writable cron jobs / /etc/cron.d/* / /etc/cron.{hourly,daily,weekly,monthly}/*
  • Writable systemd .service / .timer / .socket units (especially under /etc/systemd/system/)
  • PATH wildcards or relative paths in root-executed scripts

Network & services

  • Firewall disabled or overly permissive (ACCEPT … 0.0.0.0/0)
  • Unnecessary services running (FTP, Telnet, rsh, rlogin, tftp, NFSv2/3 without Kerberos)
  • Internal services (databases, Redis, Elasticsearch, Memcached) bound to 0.0.0.0 instead of loopback
  • Default credentials in config files / committed .env / ~/.aws/credentials readable by group

Containers & runtime

  • User in docker group (root-equivalent on host)
  • Mounted Docker / containerd / podman socket inside a container
  • Privileged container (--privileged) or container holding CAP_SYS_ADMIN/CAP_SYS_MODULE
  • runc < 1.1.12 / Docker < 25.0.2 / containerd < 1.7.13 (CVE-2024-21626 Leaky Vessels)
  • Kubernetes pod with cluster-admin SA token, or hostPath/hostNetwork/hostPID exposed

Storage

  • NFS exports with no_root_squash / insecure
  • World-readable backups (/var/backups, /root/*.bak, mysqldumps with passwords inline)

Logging & visibility

  • No central logging (rsyslog/journald → SIEM forwarder absent)
  • auditd not running or no rules covering /etc/passwd, /etc/shadow, /etc/sudoers
  • Log files world-readable (history of usernames, source IPs)

Patch posture

  • Kernel / glibc / sudo / polkit / OpenSSL / OpenSSH severely out of date
  • Unattended upgrades disabled on internet-facing hosts

9. Evidence Collection

For each finding, document:

  • Exact command used
  • Full output (sanitize sensitive data)
  • Timestamp (UTC)
  • Affected hosts/files
  • Screenshot if GUI-based

File structure:

/Evidence/{engagement_id}/Linux/
├── enumeration/
│ ├── 20251005_uname_output.txt
│ ├── 20251005_ps_aux.txt
│ └── 20251005_netstat.txt
├── configs/
│ ├── 20251005_sshd_config.txt
│ ├── 20251005_sudoers.txt
│ └── 20251005_iptables.txt
├── permissions/
│ ├── 20251005_suid_binaries.txt
│ └── 20251005_world_writable.txt
└── screenshots/
└── 20251005_linpeas_output.png

Hash all files:

sha256sum *.txt > evidence_hashes.txt

10. Reporting

Finding Format

Title: SSH Root Login Enabled
Severity: High
Affected Hosts: server01.example.com, server02.example.com
Description: SSH daemon permits direct root login (PermitRootLogin yes)
Impact: Attackers can brute-force or use leaked credentials to gain root access
Evidence: /etc/ssh/sshd_config line 32
Remediation:
1. Edit /etc/ssh/sshd_config
2. Set: PermitRootLogin no
3. Restart SSH: systemctl restart sshd
4. Test SSH access with non-root user + sudo
Verification: Re-check config and test login attempts as root (should fail)

Remediation Priorities

  1. Critical: Root SSH, SUID exploits, kernel vulnerabilities
  2. High: Sudo NOPASSWD, world-writable system files, exposed services
  3. Medium: Weak logging, outdated packages, firewall gaps
  4. Low: Informational findings, hardening recommendations

  • Read-only first: Prefer enumeration over exploitation
  • No destructive actions without explicit approval (e.g., kernel exploits, DoS, fork bombs, kernel module loads)
  • No public exploit binaries on production: stage in a sandbox built from the host's distro / kernel / glibc / sudo / polkit / runc versions
  • Coordinate with sysadmins before running intensive scans
  • Stop immediately if you cause instability or user impact
  • Document everything for audit trail and legal defensibility (see Collection Log for chain-of-custody)
  • Respect scope: Do not pivot beyond authorized hosts; cloud workloads, managed-K8s control planes, and shared hypervisors are usually out-of-scope by default
  • Refer to Legal & Ethics (canonical) and OPSEC Plan for engagement-wide rules — this SOP does not re-derive them

12. Tools Reference

Enumeration & privilege-escalation discovery

ToolPurposeInstall / Link
linpeas.shPrimary automated LPE enumeration (PEASS-ng)github.com/peass-ng/PEASS-ng
lse.shColor-graded LPE enumeration (verbosity 0–2)github.com/diego-treitos/linux-smart-enumeration
linux-exploit-suggesterKernel-CVE heuristic auditor (v1)github.com/The-Z-Labs/linux-exploit-suggester
linux-exploit-suggester-2Kernel-CVE heuristic auditor (v2, Perl)github.com/jondonas/linux-exploit-suggester-2
LinEnum.shLegacy Linux enumeration script (largely unmaintained — fall back only)github.com/rebootuser/LinEnum
pspyMonitor processes / file events without rootgithub.com/DominicBreuker/pspy
GTFOBinsSUID / sudo / capabilities escalation databasegtfobins.github.io

Auditing & hardening baselines

ToolPurposeInstall / Link
lynisHost security auditapt install lynis ; dnf install lynis ; latest from github.com/CISOfy/lynis
chkrootkit / rkhunterRootkit signature scannersapt install chkrootkit rkhunter
debsecan / dnf updateinfoOutstanding security advisories per hostapt install debsecan ; dnf updateinfo list security
ssh-auditSSH server policy + algorithm auditgithub.com/jtesta/ssh-audit ; pip install ssh-audit
OpenSCAP / oscapCIS / STIG compliance scanapt install libopenscap8 ; dnf install openscap-scanner scap-security-guide
auditd + auditctl / aureportKernel audit-rule enforcement & queryBundled with most distros

Capability / process / kernel introspection

ToolPurposeInstall / Link
getcap / setcap / capsh / getpcapsFile + process capability inspectionlibcap2-bin (Debian) / libcap (RHEL)
bpftrace / bpftopLive tracing (read-only when run as root)apt install bpftrace
auditd ruleset templatesAnomaly-detection baselinesgithub.com/Neo23x0/auditd

Container & Kubernetes

ToolPurposeInstall / Link
deepceDocker container enumeration & escape primitives auditgithub.com/stealthcopter/deepce
kube-hunterKubernetes attack-surface discoverygithub.com/aquasecurity/kube-hunter
kubeauditK8s manifest / cluster security auditgithub.com/Shopify/kubeaudit
peiratesK8s post-exploitation toolkit (offensive)github.com/inguardians/peirates
amicontainedIdentify container runtime + capability setgithub.com/genuinetools/amicontained

13. Common Pitfalls

  • ❌ Running public exploit code on production (panic risk, backdoored PoCs)
  • ❌ Forgetting to sanitize sensitive data in reports (passwords, keys, tokens, JWTs from /var/run/secrets/...)
  • ❌ Not checking scope before scanning (out-of-scope hosts, shared K8s nodes, hypervisor)
  • ❌ Relying only on automated tools (miss context-specific issues; no scanner reads policy intent)
  • ❌ Not documenting commands/timestamps (breaks evidence chain — see Collection Log)
  • ❌ Ignoring false positives from tools (verify manually; LinEnum / older LES rules over-flag back-ported kernels)
  • ❌ Assuming all SUID binaries are exploitable (check GTFOBins first; Linux ignores the SUID bit on shell scripts)
  • ❌ Treating CAP_*-marked binaries as benign because they aren't SUID (capabilities bypass the SUID check)
  • ❌ Inside a container, attacking the host without first verifying you actually escaped the namespace (cat /proc/1/cgroup, readlink /proc/1/root)
  • ❌ Piping curl … | sh from a target you do not control; always download, hash, and inspect first
  • ❌ Failing to check kernel back-ports — Ubuntu/RHEL frequently patch a CVE without changing the upstream uname -r minor version

14. Reference Resources

Comprehensive Knowledge Bases

Enumeration & Scanning Tools

Hardening & Security Benchmarks

Exploit Databases

Kernel Exploitation Resources

  • Kernel Exploit Development - 0x00sec.org
    • Forum with kernel exploitation tutorials
  • Linux Kernel Security - kernsec.org/wiki
    • Kernel security subsystem documentation
  • Dirty COW (CVE-2016-5195) - dirtycow.ninja
    • Famous kernel exploit example and documentation

Docker & Container Security

Vendor security trackers (kernel + userland CVE back-ports)

Notable LPE write-ups (illustrative, not exhaustive)

SSH & Authentication Resources

Post-Exploitation & Persistence

Cheat Sheets & Quick References

Logging & Monitoring

Practice Platforms

Books & Courses

  • Linux Basics for Hackers by OccupyTheWeb
  • SANS SEC504: Hacker Tools, Techniques, and Incident Handling
  • Offensive Security PWK (OSCP)
  • HackerSploit Linux Privilege Escalation - youtube.com/hackersploit

Community & Forums


Engagement governance:

  • Legal & Ethics - Authorization, scope, evidence handling, jurisdictional rules (canonical)
  • OPSEC Plan - Operator and infrastructure OPSEC during the engagement
  • Collection Log - Evidence chain-of-custody pattern referenced by §9 above

Analysis:

Pentesting & Security:


Version: 1.1 · Last Updated: 2026-04-25 · Review Frequency: Quarterly (medium-rot tooling SOP — kernel/userland CVE landscape and PEASS-ng release cadence drive churn)