1. Home
  2. Linux
  3. Linux Privilege Escalation Techniques

Linux Privilege Escalation Techniques

Linux privilege escalation remains prevalent despite defenses. This in-depth guide examines common vectors like exploit SUID binaries, kernel bugs, container escapes, password cracks, misconfigurations services for unauthorized privilege access, and supply chain compromises. Learn adversary tactics and mitigations for Linux escalation hardening.

Sections on this page

Privilege escalation refers to tactics that allow adversaries to gain unauthorized access to resources, functions and sensitive data that exceed what they are authorized to interact with on a system.

Perhaps you’ve heard of intruders exploiting vulnerabilities to escalate from a normal user account to administrator or root privileges. This enables far more devastating attacks, not only interacting with protected files and directories, but also loading kernel modules, tampering with execution paths, and masking malicious activity through logs.

Escalation techniques are becoming increasingly commonplace and advanced due to Linux’s expanding footprint across servers, devices, containers and cloud infrastructure. Legacy systems with unpatched local privilege escalation (LPE) flaws pose particular risk as they pile up exponentially across enterprises. Distributions differ substantially in the speed that critical updates reach production systems, so patch latencies impact exposure.

In this comprehensive field guide, we’ll cover the most prevalent Linux privilege escalation vectors including:

  • Hijacking flawed SUID executables
  • Kernel exploitation
  • Container breakouts
  • Password brute forcing
  • Misconfigured services
  • Shell and scripting subtleties

Equipped with insight into attackers’ tactics, you’ll learn how to harden systems and combat intrusion attempts. Let’s break down each major technique, their impact vectors, and key mitigations in depth.

Abusing SUID Executables

The setuid bit or SUID applied to executables is designed to temporarily escalate privileges for specific actions. This overrides the default Unix access model to enable regular users to accomplish administrative tasks.

But misconfigurations can enable adversaries to abuse these binaries for unauthorized persistent access. Executables like vim, bash, python that spawn shells or interpreters are common targets.

Dynamic Libraries & $LD_PRELOAD

Injecting shared object libraries is a classic attack. By loading a custom .so file with elevation-friendly code into a SUID process’s execution, adversaries can orchestrate arbitrary actions well beyond intended permissions.

The LD_PRELOAD path variable simplifies this vector enormously. Many SUID executables allow configuring dynamic link library load order – enabling injected libs to override intended functions executed by the process. This key environment variable can point to adversary controlled files, triggering the injection automatically.

Consider this example escalating privileges through vim’s SUID bit to spawn a shell:

$ sudo -l # Check for vim SUID permissions
$ gcc -shared -fPIC -o exploit.so exploit.c -ldl # Compile injection .so 
$ LD_PRELOAD=./exploit.so vim # Run vim with library load 
# vim executes exploit code inheriting its permissions!

By hijacking libraries that applications depend on, adversaries can achieve execution of arbitrary code within the context of the higher privileged process.

Path Prefixes & Symlinks

If developers aren’t careful, directly modifying path variables that find executables can enable similar trouble. Linux inherits directories to search for binaries from environment variables like $PATH. Prepending custom script folders can lead the privileged process to unexpectedly invoke attacker controlled logic instead!

$ export PATH=/tmp:$PATH
$ echo 'int main() { setuid(0); system("/bin/sh"); }' > /tmp/vim
$ chmod +x /tmp/vim 
$ vim # Executes adversary vim binary!
# Spawns root shell thanks to fake vim dropping privileges.

Symbolic link pointing to protected resources combined with careful filename selections can also achieve swaps. Fooling the execution order checks filenames first before validation:

$ ln -s /usr/bin/vim ./links/vim
$ chmod +s ./links/vim # Set SUID bit
$ ./links/vim -c ':!/bin/sh' # Execute vim but with shell spawn command
# Breaks out of links/vim to gain root shell

While simple, these techniques continue to find real-world use due to difficulty both development teams and administrators face in fully locking down writable paths. Runtime dependencies wind up spread across scores of directories. Identifying the full chain is essential.

Sudobits applied to dangerous interpreters remains highly problematic: Python, Perl, php and others continue to enable unintended breakouts.

Mitigations

Securing SUID executables remains challenging given complexity of dependencies and legitimate dynamic needs. But several principles dramatically reduce attack surface:

  • Don’t SUID root – Use the most minimal privilege elevation required rather than blanket root access. Granularity here prevents wide impact if one component is compromised.
  • Statically link binaries – Removing reliance on unpredictable libraries makes runtime manipulation far more difficult. This trades continuous security maintenance for deployment flexibility however.
  • Check executable sanity – Cryptographic hash/validate critical binaries before execution rather than assume filesystem integrity checking alone suffices. Remediations like Tripwire enact continuous verification.
  • Enforce restrictive permissions – across execution paths and libraries, limiting any unwarranted modifications. While Duombreaking remains possible, it raises the bar.

While imperfect, these principles limit attack surface. Applying least privilege access controls makes escalation opportunities sparse. But as the next section shows, determined intruders have other tricks ready when SUID avenues narrow!

Kernel Exploitation

The kernel operates as the central broker of all system resources. Compromise it, and adversaries seize the highest level of control possible. Modern defenses made reliable userspace attacks vastly more difficult in environments with sanely configured SUID binaries, motivating intruders toward coveted kernel targets.

We’ll cover the most common kernel attack vectors that, if vulnerable, provide pathways to complete system compromise:

Memory Safety Bugs

Various types like stack/heap overflows or use after frees may enable arbitrary code execution. The vmsplice() exploit [CVE-2016-5195] shocked IT administrators by enabling root access via a small userspace program barely larger than a tweet!

By carefully manipulating data passed ultimately to the kernel, attackers turned a single bug into total control. This remains possible due to the massive C codebase still underpinning most general purpose operating system kernels. Memory corruption and confusion weaknesses continue to be found via fuzzing and code audits – an inherent risk.

While automation endeavor to prevent entire classes like buffer overflows, with millions of lines of kernel code vulnerable conditions still slip in. Determined adversaries specifically target the stateful infrastructure for such flaws. Successfully exploiting even a single condition can decisively break through confinement barriers.

Race Conditions

Timing inconsistencies during execution can cause logic flaws allowing unintended operations. Take [CVE-2017-1000364] where a race while updating setuid programs could lead to tampering with what should be protected binaries. This gap between checking state and acting on state enabled attackers to win the race.

Another class timing attack is the [TOCTOU] (time of check, time of use) bug where verifying then acting on files can be exploited if an adversary alters the filesystem object between access attempts. Carefully coordinated actions insert malicious payloads between validation and usage stages.

Information Leaks

Data only visible to the kernel accidentally getting exposed unintentionally has enabled attacks against assumed isolated environments. Hardware speculation side channels including [Meltdown] and [Spectre] CPU vulnerabilities enabled adversaries to access what should have been protected memory by indirectly observing fast cached responses to unauthorized memory accesses.

Container escapes frequently rely on tricking processes like runC or Docker daemon into somehow exposing host files, environment variables, credentials or other useful information that can enable pivots to full host compromise. Any visibility past intended data severely weakens security boundaries.

Mitigations

Vigilance around patching, compiler enhancements like stack canaries, restricting modules, and stronger isolation via virtualization solutions can make kernel escalation far more difficult.

Security-focused distributions like [Qubes OS] and [Tails Linux] limit attack surface dramatically by isolating components, minimizing drivers and services, sandboxing execution and other techniques to raise assurance. Containment may be an organization’s preference if directly exploiting kernel bugs proves too costly or unavailable to their intrusion capabilities.

Carefully delegating privileges across execution contexts, integrity protecting access to credentials, and monitoring for anomaly chains that could indicate compromise reach across mitigation disciplines. Developing intuition for how systems fail inspires more robust configurations.

Container Breakout Tactics

Containers and orchestrators like Docker pose an interesting puzzle for intruders. The technology isolates processes into user space instances, preventing visibility or access to host devices, ports and files. This enables portable application deployment across environments.

But the intended security boundaries have been successfully defeated many times to achieve full host compromise. Common breakout vectors include:

Misconfigured Mappings

Attackers check if any privileged containers exist which map dangerous host paths, socket connections, insecure storage mounts, or access to device nodes that could enable escapes.

Overly permissive interfaces between host and container should be avoided. Validate restrictions are sane rather than implicitly trust containers won’t escape. Some organizations merely check containers against a baseline configuration but don’t adapt to runtime threats.

Kernel Exploits

Reusing reliable kernel escalations like [CVE-2016-5195] has successfully jumped from containerized applications directly into the host system. This demonstrates the fiction of containers as a security boundary – they remain dependent on the kernel’s integrity at the end of the day.

Ensuring your kernels are always updated, ideally using a specialized container hardened distro like RancherOS, is critical to limiting this breakout path. Containers themselves can help in accelerating patching by serving immutable infrastructure.

Memory Leaks

Tricking processes like runC or Docker daemon into exposing host files, environment variables, credentials or secrets is a coveted technique to pivot to the underlying system. Carefully analyzing communication channels that bridge containers to the host OS can find cracks like hard-coded passwords in defaults.

The runC shared memory bug enabled container to host privilege escalation by leaking file descriptors granting access to resources beyond intended permissions.

Restricting memory access via seccomp, pledging policies and related defenses mitigate risks once flaws surface until vendors can patch formally. Unfortunately, attacks move faster than traditional software update processes in many enterprise environments.

Containers remain extremely useful technologies so long as security teams understand their limitations and layer sensible hardening to minimizebreaks. Avoid blindly trusting these isolation mechanisms without extensive penetration testing against your specific deployment’s posture.

Cronjob Manipulation

The cron daemon allows both administrators and general users to schedule periodic job execution. Configuration files in /etc/cron.* on most Linux variants orchestrate this scheduled task functionality. While quite useful for automation, cron and command substitutions within crontab leave an avenue for intruders to escalate.

If adversaries make their way into lower privileged user contexts such as via phishing password theft or exploiting weak web apps, poking around cron gives plenty of opportunity. Path variables can once again be abused similar to SUID tricks to inject arbitrary logic into root processes. Tampering with an admin’s existing crontab scripts also regularly goes unnoticed if integrity checks aren’t in place.

Developers sometimes dangerously tie Cron to web application functionality presuming only trusted users have access. Remote command execution exposure can arise by allowing HTTP inputs to invoke admins’ high privilege scheduled jobs. Sensitive cfg files may also hide within webroot exposing secrets upon discovery.

Regular cron output mailing to a monitored administrator address provides sage visibility. Modern defenses like pamd_cron and cron_hardening add safeguards assuming some non root access gets attained either via mistakes or malice.

This hardening guide covers helpful measures including:

  • Restricting cron access and making crons editable only via sudo
  • Creating separate cron-specific user profiles with limited shells
  • Wrapping jobs with scripts that explicitly drop privileges before taking actions
  • Pointing job output to protected logs monitored for anomalies
  • Encrypting file stored in cron directories at rest
  • Enforcing limited access control lists (ACLs) on cron directories

Well constructed containers will also restrict cron and task scheduling by default. Never presume a container stays fully sealed at all times.

Brute Forcing Credentials

Cracking weak, reused or default passwords remains reliable for escalation. The /etc/passwd and /etc/shadow files contain credential validation hashes accessible once lower level shell access gets obtained.

Admin users frequently authenticate across servers and workstations without using SSH keys or two factor authentication. Password reuse or trivial selection gets exploited. Compromise on one system enables lateral pivots trying the same secrets elsewhere.

John the Ripper or Hashcat leverage GPUs to target cryptographically weak cipher variants at dizzying speeds. Misconfigurations of the shadow password security model parameters also make attacks exponentially easier:

/etc/login.defs 

PASS_MAX_DAYS 99999 # Allow incredibly long intervals between change
PASS_MIN_DAYS 0 # Zero day minimum before reset
MAX_MEMBERS -1 # Remove limit on attempts before lockout
ENCRYPT_METHOD DES # Trivial to crack standard

/etc/pam.d/common-password

sha512 # Modern adaptive hash count minimums removed

Such policies enable brute forcing on cracker rigs. Best practice hardening increases entropy dramatically against cracks through smarter models and enforcement:

/etc/login.defs 

PASS_MAX_DAYS 90 # Reasonably frequent cycles  
PASS_MIN_DAYS 14 # Prevent immediate recycling
MAX_MEMBERS 3 # Small threshold to trigger lockouts
ENCRYPT_METHOD SHA512 # Modern adaptive hash 

/etc/pam.d/common-password

sha512 minlen=14 maxrepeat=3 reject_username enforce_for_root # Significantly enhanced configuration

Designed to increase cost on crackers through iterations tuned over time against GPU capabilities, unique salts preventing rainbow tables, strict complexity standards, delays between allowable changes, and profile lockouts.

Well constructed Active Directory domains on the Windows side centralize authentication and authorization with deep protections against offline attacks. Limiting Linux to single system auth opens exposure to crackers. Integrating Linux identity into AD or PKI infrastructure better secures credentials.

For securing standalone Linux credentials beyond built-in shadow features:

  • Enforce 2 factor authentication (FIDO U2F) for administrators and limit password fallback mechanisms
  • Monitor brute force attempts across systems with centralized logging intelligence
  • Change default login ports and security banners to slow discovery
  • Employ IP whitelisting for remote access
  • Use ephemeral boot partitions to wipe keys/hashes after each cycle

Detecting Misconfigurations

Basic information leakage and permissions misconfigurations surprisingly catch even sophisticated operators off guard given the frequency of oversights. Quick wins through probing for common lapses provides intruders macro visibility into target environments.

Unmonitored services like Redis may have no authentication enabled at all or default to dangerous visibility. Debug modes leaking system stats may be functional but never deactivated after development. Unprotected memories or caches store plaintext credentials and session tokens ready for plundering.

File systems meant to be isolated expose through inadvertent bridging.snr developers expect adversaries to discover subtle seams across disparate systems. But systemically faulty security architecture creates a web of enticing trinkets once an initial foothold emerges.

Careful attention identifying vectors usable by lower privileged users during red teaming exercises uncovers way more than expected in even modern environments. Chaining just a couple lapses together can snowball access rapidly especially with orchestration tooling automating checks.

Discovery tactics Include:

  • Check running process nodes, owners and binaries across ports to identify vulnerable versions
  • Probe likely config, cache and variable locations for secrets
  • Brute force files that may expose access if permissions allow
  • Test SUID/SGID bits for unsafe circumvention pathways
  • Invoke error messages that can leak system details not intended
  • Attempt common container escape vectors based on orchestrator
  • Headers/Stack traces signaling tech versions vulnerable to latest exploits

Combining scripted vulnerability scanners that perform extensive version fingerprinting and environment enumeration alongside manual probing unearths doors. Persistence me chanisms left by predecessors may lurk as well across startup flows.

Carelessness breathes opportunity. Defenders must instead internalize and automate securing fundamentals.

Supply Chain Compromises

While the above vector focus on operational configuration risks, code compromises occurring prior to production deployment accounts for many breaches nowadays. Nearly every organization relies on scores of third party open source components riddled with vulnerabilities sparse security teams scramble to track.

Attempting to validate integrity dynamically proves notoriously tricky given complexity of build pipelines, testing lags, developer skills etc. Static analysis tries bolting on security but suffers false positives/negatives especially with interpretable languages.

Adversaries now compromise upstream open source repositories, inject malware during builds or redirects, counterfeit package managers, exploit lack of hashes or compromise distributor accounts. High privilege intrusion points get planted for future activation long before sysadmins can lockdown externally sourced components.

Mitigating risks requires substantially more investment validating supply chain security rather than purely focusing on enterprise perimeter protections and vulnerability management which fail catching pre-embedded access mechanisms. Practices like:

  • Multi-party code reviews on OSS libraries
  • CICD pipeline instrumentation at all artifact transit stages
  • Comparing versions across central/decentral package registries
  • Reproducible builds verifying integrity from diverse compile sources
  • Debugging striping and related anti-analysis obfuscations
  • Hardware verified boot protections against tampered runtimes

Move towards more integrity-focused development and infrastructure operations. Holistic analysis of privilege paths – not only operational controls but also continuously validating platform integrity – helps transform tactical intrusion impacts into mere annoyances rather than catastrophes.

Closing Thoughts

This comprehensive exploration demonstrates Linux privilege escalation’s blend of art, science and outmaneuvering across configurations, services and bespoke application code. No perfect ‘always stay secured’ panacea exists given software’s continual introduction of new attack surface through layers of dependencies and runtimes.

Related Articles
Are you an aspiring software engineer or computer science student looking to sharpen your data structures and algorithms (DSA) skills....
Descriptive statistics is an essential tool for understanding and communicating the characteristics of a dataset. It allows us to condense....
It's essential for developers to stay informed about the most popular and influential programming languages that will dominate the industry.....
Software engineering is a dynamic and rapidly evolving field that requires a unique set of skills and knowledge. While theoretical....
A tuple is an ordered, immutable collection of elements in Python. It is defined using parentheses () and can contain elements of....
In Java, an Iterator is an object that enables traversing through a collection, obtaining or removing elements. An Iterator is....

This website is using cookies.

We use them to give the best experience. If you continue using our website, we will assume you are happy to receive all cookies on this website.