Chapter 12: Common Attack Paths and Defensive Strategies

Updated

October 31, 2026

Chapter 12: Common Attack Paths and Defensive Strategies

To defend a Linux system effectively, an engineer must think like an adversary. When an attacker gains an initial foothold on a host—whether via a compromised web application, a leaked SSH credential, or an unprivileged container process—they execute a predictable series of offensive maneuvers designed to escalate privileges to root, establish long-term persistence, and move laterally across the infrastructure.

This chapter dissects the primary attack vectors observed in modern Linux breaches and provides concrete, verifiable defensive countermeasures to detect and neutralize them.

Local Privilege Escalation Vectors

Local Privilege Escalation (LPE) is the process of converting an unprivileged user shell (e.g., www-data or UID 1000) into superuser authority (UID 0 / root).

┌────────────────────────────────────────────────────────────────────────┐
│                        ANATOMY OF A LINUX LPE ATTACK                   │
│                                                                        │
│   Initial Foothold: Unprivileged Shell (UID 1001)                      │
│          │                                                             │
│          ├─► SUID Abuse / GTFOBins (find, vim, bash, nmap)             │
│          ├─► Sudo Misconfigurations (NOPASSWD, wildcards)               │
│          ├─► Path Hijacking & Writable Cron Scripts                    │
│          ├─► Kernel Memory Exploitation (Dirty Pipe, unshare LPE)      │
│          └─► Container Escape (Privileged flags, docker.sock)          │
│          │                                                             │
│          ▼                                                             │
│   Root Compromise Achieved (UID 0)                                     │
│          │                                                             │
│          ├─► Establish Persistence (/etc/cron*, SSH authorized_keys)   │
│          └─► Lateral Movement (Extract cloud credentials, pivot)       │
└────────────────────────────────────────────────────────────────────────┘

The Threat of SUID Binaries and GTFOBins

The GTFOBins project catalogs standard Unix binaries that can be leveraged to bypass security restrictions or spawn root shells when configured with the SUID bit or granted via sudo.

Common dangerous examples: - find with SUID: bash /usr/bin/find . -exec /bin/sh -p \; -quit - vim with SUID: bash /usr/bin/vim -c ':py3 import os; os.execl("/bin/sh", "sh", "-pc", "reset; exec sh -p")' - base64 or awk: Used to read arbitrary protected files (such as /etc/shadow) even without spawning a shell: bash /usr/bin/base64 "/etc/shadow" | base64 --decode

Defensive Countermeasure

  1. Remove the SUID bit from all non-essential binaries:

    sudo chmod u-s /usr/bin/find /usr/bin/vim /usr/bin/awk
  2. Mount partitions hosting user-writable data (/home, /tmp, /var/tmp) with the nosuid option.

Sudo Misconfiguration and Abuse

Granting sudo privileges without understanding binary functionality is a leading cause of privilege escalation:

Insecure Sudo Wildcards

# DANGEROUS: Sudoers rule intended to allow restarting a service
operator ALL=(ALL) /bin/systemctl restart *

An attacker exploits this wildcard by supplying flags that spawn interactive pagers:

sudo /bin/systemctl restart myapp --plain --no-pager
# Or abuses systemctl to run an arbitrary unit or shell

Dangerous Environmental Variables (env_keep)

If /etc/sudoers preserves dynamic library paths:

# CRITICAL VULNERABILITY:
Defaults env_keep += "LD_PRELOAD LD_LIBRARY_PATH"

An attacker compiles a malicious .so shared library and executes any harmless allowed sudo command (e.g., sudo /bin/ls), causing the dynamic linker to execute their root exploit payload before ls even begins.

Defensive Countermeasure

  • Always enforce Defaults env_reset and Defaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin".
  • Never use LD_PRELOAD in env_keep.
  • Restrict commands to explicit executable paths and use sudoedit for file modifications.

Insecure File Permissions and Paths

1. Insecure $PATH and Relative Path Execution

If a privileged script or cron job includes relative paths or world-writable directories in its $PATH:

# Insecure script executed by root cron:
PATH=/tmp:/usr/local/bin:/usr/bin
check_status.sh

An attacker writes an executable named check_status.sh inside /tmp. When root’s cron runs, the attacker’s script executes with full root authority.

2. World-Writable System Scripts and Service Definitions

If a systemd unit or startup script has write permissions accessible to group or others:

# Check for insecure permissions on systemd services
find /etc/systemd/system/ /lib/systemd/system/ -type f -perm -002 -ls

An unprivileged user simply appends a reverse shell line (ExecStartPre=/bin/bash -c '...') into the service file and waits for the next reboot or service restart.

Malicious Services and Scheduled Tasks

Adversaries establish persistence by scheduling recurring tasks:

  • Cron Hooks: Inspect /etc/crontab, /etc/cron.*, and user spools under /var/spool/cron/crontabs/:

    # Audit all user crontabs
    for user in $(cut -f1 -d: /etc/passwd); do sudo crontab -u $user -l 2>/dev/null; done
  • Systemd Timers: Modern attacks favor systemd timer units over cron because they are less commonly monitored by legacy security tools:

    # List all active system timers and their associated triggers
    systemctl list-timers --all
  • Udev Rule Injection: Malicious udev rules placed in /etc/udev/rules.d/ execute arbitrary commands whenever a specific virtual device is triggered.

Kernel Vulnerabilities and Local Exploits

When configuration flaws do not exist, attackers turn to kernel zero-day or N-day vulnerabilities.

Classic Kernel Exploits

  • Dirty COW (CVE-2016-5195): A race condition in the kernel’s copy-on-write (COW) memory subsystem allowed unprivileged users to write to read-only memory mappings, enabling them to overwrite /etc/passwd.
  • Dirty Pipe (CVE-2022-0847): A flaw in the Linux kernel pipe implementation allowed unprivileged users to overwrite data in arbitrary page cache pages, hijacking SUID binaries or /etc/shadow.

Restricting Unprivileged User Namespaces

Many recent kernel vulnerabilities exist in network protocol implementations or legacy filesystems that are only reachable because unprivileged users can create new user and network namespaces (unshare -U -n). Mitigate this attack vector:

# /etc/sysctl.d/99-disable-userns.conf
# On Debian/Ubuntu systems:
kernel.unprivileged_userns_clone = 0

# Restrict user namespaces to root only
user.max_user_namespaces = 0

Container Escapes and Namespace Abuse

As established in Chapter 11, container escapes exploit shared kernel primitives:

  • Abusing Host Mounts: Mounting / or /etc into a container allows modifying the host /etc/shadow or /etc/cron.d/.
  • Capability Abuse (CAP_SYS_ADMIN): An unprivileged container granted CAP_SYS_ADMIN can mount cgroups, inject a release_agent script, and force the host kernel to execute arbitrary commands on the host.

Defensive Countermeasure

  • Always drop all capabilities and whitelist only what is strictly necessary (--cap-drop=ALL --cap-add=NET_BIND_SERVICE).
  • Enforce Read-Only root filesystems (--read-only).
  • Deploy seccomp and AppArmor profiles to block unshare, clone with user namespaces, and mount.

Persistence Mechanisms and Lateral Movement

Once root is achieved, adversaries guarantee future access:

  1. SSH Key Injection: Adding a malicious public key to /root/.ssh/authorized_keys or appending to system-wide authorized keys files.
  2. PAM Backdoors: Replacing pam_unix.so with a trojanized version that accepts a master backdoor passphrase for any account.
  3. Shell Initialization Poisoning: Appending malicious alias commands or reverse shells into /etc/bash.bashrc or /etc/profile.
  4. Lateral Movement via Cloud Metadata: Attackers curl http://169.254.169.254 to steal temporary STS tokens and pivot to the AWS/GCP/Azure cloud control plane.

Continuous Verification Checklist

# Audit SSH authorized keys across all user home directories
sudo find /root /home -name "authorized_keys" -exec ls -la {} +

# Check integrity of core PAM modules against distribution packages
sudo dpkg --verify libpam-modules    # On Debian/Ubuntu
sudo rpm -V pam                      # On RHEL/CentOS