Privilege Escalation Theory: Formal Models of Least Privilege Violations
"The principle of least privilege states that every program and every user of the system should operate using the least set of privileges necessary to complete the job." — Jerome H. Saltzer and Michael D. Schroeder, "The Protection of Information in Computer Systems," Proceedings of the IEEE, 1975
Abstract
Privilege escalation sits at the intersection of formal access control theory and practical exploitation. It is not merely a collection of techniques: it is the empirical refutation of a formal guarantee. Every successful escalation demonstrates that the system's privilege model failed to satisfy the safety property defined by Harrison, Ruzzo, and Ullman in 1976, that a subject reached a rights set the designers intended to be unreachable. This article develops privilege escalation from first principles, tracing the theoretical lineage from the HRU access control matrix through Bell-LaPadula, Biba, and Clark-Wilson to the lattice-based information flow models that underpin modern mandatory access control. It then maps those formal structures onto real vulnerability classes, showing how CVE-2021-4034, CVE-2024-1086, and CVE-2022-0492 each violate specific formal properties. A graph-theoretic framework for modelling escalation chains as bounded reachability problems over privilege state spaces is introduced, along with a complete Python implementation of BFS-based chain discovery. The article concludes with an analysis of the commercial privileged access management (PAM) market and the open research problems that remain unsolved despite decades of theoretical progress.
1. Introduction
"The Windows UAC bypass we published in CVE-2024-6769 is architecturally interesting because it doesn't exploit a memory corruption bug at all. It exploits a logical inconsistency in how the kernel maps drive letters to NT object paths. The formal model was violated, not the memory model." — Fortra Security Research, January 2025
The history of privilege escalation research is a history of formal guarantees failing contact with implementation. Access control theory, beginning with the foundational work of Bell and LaPadula in the early 1970s, attempted to reduce the privilege problem to a mathematical question: given an initial state of the protection system, can a subject ever acquire a right it was not initially granted? Harrison, Ruzzo, and Ullman answered this question in 1976 with a decidability result both elegant and devastating: the general safety problem for protection systems is undecidable [1]. No algorithm can determine, for an arbitrary access control system, whether a given right can be leaked to an unauthorized subject. The consequence is that every access control system that aims to provide formal safety guarantees must restrict itself to a decidable fragment of the general model.
Practitioners absorbed a different lesson from the same literature: if perfect formal safety is impossible, then every deployed system has an escalation surface waiting to be found. The question shifts from "is this system safe?" to "how far can an attacker traverse the privilege lattice from a given initial position?" This reframing from a static decision problem to a dynamic traversal problem is the conceptual move that organizes modern privilege escalation research. The attacker's goal is not to satisfy a formal property; it is to find a path through the system's state space that terminates at a state with elevated rights, specifically at the root or SYSTEM privilege level that controls the machine outright.
The practical stakes are considerable. The PAM market was valued at $3.46 billion in 2024 and is projected to reach $16.49 billion by 2032, growing at a compound annual growth rate of 21.8% [2]. CyberArk, the dominant vendor, acquired Venafi for $1.54 billion in October 2024 and Zilla Security for $175 million in 2025, reflecting the market's conviction that privileged access is the primary perimeter in modern enterprise security [3]. BeyondTrust reported annual recurring revenue exceeding $400 million in the same period, driven by demand for just-in-time privilege and session recording capabilities [4]. This investment reflects a recognition that privilege escalation is not a solved problem and that the theoretical models underlying access control systems are imperfectly instantiated in every operating system, hypervisor, and cloud control plane deployed at scale today.
This article proceeds in eight sections. Section 2 develops the formal theory of access control, from the access matrix model through the major safety-oriented extensions. Section 3 presents the mathematical framework for privilege escalation as a graph problem. Section 4 examines the Linux kernel privilege surface in detail. Section 5 covers Windows-specific escalation primitives. Section 6 provides the Python implementation of escalation chain discovery. Section 7 analyses the commercial and strategic landscape. Section 8 states open problems.
2. Formal Models of Access Control
2.1 The Access Matrix Model
The access matrix model, introduced by Lampson in 1971 and formalized by Graham and Denning in 1972, defines access control in terms of a matrix $M$ where rows index subjects (processes, users), columns index objects (files, devices, memory segments), and each cell $M[s, o]$ contains the set of rights that subject $s$ holds over object $o$ [5]. The model is deceptively simple: a subject may perform an operation on an object if and only if the corresponding right appears in the appropriate matrix cell. The access matrix is the abstract specification against which all concrete access control mechanisms, capability lists, access control lists, security labels, are evaluated.
The critical question the matrix model leaves open is what happens when rights change. A static matrix with a fixed set of subjects, objects, and rights is easy to reason about. Real systems are not static: processes create files, fork new processes, and transfer rights between subjects. The Harrison-Ruzzo-Ullman (HRU) model, published in the Communications of the ACM in 1976, extends the access matrix with a set of commands that can modify the matrix, and asks whether a given right $r$ can ever appear in a cell $M[s, o]$ where it was not initially present [1]. Formally, the safety problem asks:
$$\text{SAFE}(Q_0, r) = \exists \text{ sequence of commands } c_1, \ldots, c_n \text{ such that } Q_0 \xrightarrow{c_1} Q_1 \xrightarrow{c_2} \cdots \xrightarrow{c_n} Q_n \text{ and } r \in Q_n[s, o] \tag{1}$$
where $Q_0$ is the initial protection state, $Q_i$ denotes the state after applying the $i$-th command, and the final state $Q_n$ contains the right $r$ in a cell where it did not appear initially. Harrison, Ruzzo, and Ullman proved that this problem is undecidable in general: there is no algorithm that, given an arbitrary HRU system and initial state, can determine whether the safety property holds [1]. The proof reduces the halting problem to the safety problem, showing that a Turing machine can be simulated within the HRU command language.
The undecidability result has direct implications for privilege escalation. If no algorithm can decide whether a right can be leaked in an arbitrary HRU system, then no static analysis tool can guarantee that a deployed access control system is leak-free. Every deployed system is, from a theoretical standpoint, an untested hypothesis about the reachability of its privilege states. The security community's response has been to restrict the model: decidable subclasses of HRU exist where commands can only add rights or only delete rights, and these fragments admit polynomial-time safety algorithms [1]. But real operating systems are not decidable fragments. They implement the full expressive power of the HRU model and more, including operations that the original HRU paper did not anticipate, such as namespace manipulation, cgroup lifecycle management, and kernel memory layout choices exposed via /proc.
2.2 Bell-LaPadula and Mandatory Confidentiality
The Bell-LaPadula (BLP) model, developed by David Bell and Leonard LaPadula for the MITRE Corporation under US Air Force sponsorship in 1973 and formalized through 1976, introduces mandatory access control (MAC) via security labels [6]. Every subject and object is assigned a security level from a linearly ordered set (e.g., Unclassified, Confidential, Secret, Top Secret), and access is governed by two core properties. The simple security property (no read up) states:
$$\text{SSP}: \forall (s, o) \in \text{read-access}, \; \lambda(s) \geq \lambda(o) \tag{2}$$
where $\lambda$ denotes the security level function and $\geq$ is the dominance relation on the security lattice. A subject may read an object only if its clearance level dominates the object's classification. The star property (no write down) states:
$$\star\text{-property}: \forall (s, o) \in \text{write-access}, \; \lambda(o) \geq \lambda(s) \tag{3}$$
A subject may write to an object only if the object's classification dominates the subject's current level. Together, these properties prevent information from flowing from higher to lower classification levels, formally guaranteeing confidentiality under the model's assumptions. The BLP model was enormously influential: it underlies SELinux type enforcement, the mandatory integrity control (MIC) in Windows Vista and later, and the security context framework in the Linux Security Modules (LSM) API.
From an attacker's perspective, BLP defines a target precisely. The goal of a privilege escalation attack is to create a subject that violates one of these two properties: a subject that can read objects at a higher level than its label permits, or a subject that can write to objects at a lower level, thereby contaminating lower-clearance data with higher-clearance information. The Dirty COW vulnerability, CVE-2016-5195, is a textbook violation of the star property: a process running at user level (low integrity) was able to write to a copy-on-write memory mapping of /etc/passwd (high integrity), violating the write-down prohibition [7]. The race condition in the kernel's memory management subsystem allowed the user-level process to dirty a page that it should have had no write access to, effectively breaking the mandatory integrity guarantee.
2.3 Biba and Clark-Wilson: Integrity Models
The Bell-LaPadula model addresses confidentiality but is silent on integrity. The Biba integrity model, published by Kenneth Biba in 1977, applies the dual logic: subjects may not read objects of lower integrity (no read down, preventing contamination of high-integrity subjects by low-integrity data) and may not write to objects of higher integrity (no write up, preventing corruption of high-integrity objects by low-integrity subjects) [8]. The formal structure mirrors BLP with integrity levels replacing security levels. Biba's model is the theoretical foundation for Windows MIC, which assigns integrity levels (Low, Medium, High, System) to processes and objects and uses them to enforce write restrictions between process trust tiers.
The Clark-Wilson model, published by David Clark and David Wilson in 1987, takes a more pragmatic approach to integrity by focusing on well-formed transactions and separation of duty [9]. Rather than a lattice of labels, Clark-Wilson defines constrained data items (CDIs) that may only be modified through transformation procedures (TPs) that are explicitly certified to preserve integrity invariants. Access control is enforced by integrity verification procedures (IVPs) that can audit the state of CDIs. Clark-Wilson is closer to how application-layer integrity is actually implemented in enterprise systems: database transactions with foreign key constraints, signed software packages that may only be installed through trusted package managers, and configuration management systems that mediate all write operations to infrastructure state. Most application-layer privilege escalation attacks violate Clark-Wilson rather than Biba: they find a transformation procedure that, through a logical flaw rather than a label violation, allows an uncertified modification of a CDI.
2.4 Denning's Lattice Model and Information Flow
Dorothy Denning's lattice model of secure information flow, published in the Communications of the ACM in 1976, provides the most general theoretical treatment of the confidentiality problem by focusing on information flow rather than access control [10]. The model defines a lattice $(SC, \leq, \oplus)$ where $SC$ is a set of security classes, $\leq$ is a partial order on classes, and $\oplus$ is a least upper bound operation. Information is permitted to flow from class $A$ to class $B$ only if $A \leq B$. The lattice structure allows the model to handle compound classes (e.g., a file that is both "Secret" and "Personnel") naturally through the join operation.
Denning's lattice model is the theoretical backbone of modern taint tracking and information flow control (IFC) systems. Tools such as taintgrind (a Valgrind plugin), FlowDroid for Android, and the JOANA framework for Java all implement variants of the Denning model to detect illicit information flows in programs. From an exploitation perspective, the lattice model explains why covert channels are theoretically unavoidable in any system where a high-privilege subject and a low-privilege subject share any resource, even one as indirect as CPU cache timing or network packet scheduling. Covert channel attacks such as Flush+Reload and Prime+Probe exploit information flows that are completely invisible to the access matrix but violate the lattice order: information flows from a high-security process to a low-security observer through a shared cache line, without any direct read or write access to protected objects [11].
3. Privilege Escalation as a Graph Problem
3.1 Privilege State Spaces
A privilege state is a pair $(\Sigma, \Phi)$ where $\Sigma$ is a security principal (a process, user, or service account) and $\Phi$ is a set of rights held by that principal at a given moment. A privilege escalation transition is a function $T: (\Sigma, \Phi) \to (\Sigma, \Phi')$ where the new rights set $\Phi'$ is a strict superset of the original:
$$\exists T: \Phi'(\sigma) \supsetneq \Phi(\sigma) \tag{4}$$
This captures the essential property of escalation: the subject gains rights it did not previously hold, without those rights being legitimately granted through the system's intended access control mechanisms. An escalation transition exploits a vulnerability, a misconfiguration, or a logical flaw in a transformation procedure (in the Clark-Wilson sense) to produce a state transition that the access control model prohibits but the implementation permits.
An escalation chain is a finite sequence of such transitions:
$$(\Sigma, \Phi_0) \xrightarrow{T_1} (\Sigma, \Phi_1) \xrightarrow{T_2} \cdots \xrightarrow{T_k} (\Sigma, \Phi_k) \tag{5}$$
where $\Phi_0$ is the attacker's initial rights (e.g., the rights of a web application process running as www-data) and $\Phi_k$ is the target rights set (e.g., {read, write, exec, setuid} corresponding to root). Each transition $T_i$ is an individual exploit, misconfiguration abuse, or privilege abuse technique. The chain-finding problem is: given an initial state $(\Sigma, \Phi_0)$, a set of available transitions $\mathcal{T}$, and a target rights set $\Phi^*$, find all finite sequences of transitions from $\mathcal{T}$ that lead from $\Phi_0$ to a state containing $\Phi^*$. This is a bounded reachability problem over the directed graph $(V, E)$ where $V$ is the set of reachable privilege states and $E$ is the set of applicable transitions.
3.2 Complexity of Chain Finding
The chain-finding problem, as stated above, is NP-hard in the general case when transitions can be composed arbitrarily and the state space is exponential in the number of rights. In practice, two restrictions make it tractable. First, the number of distinct rights in any real system is bounded: Linux has approximately 40 capability bits (CAP_NET_ADMIN, CAP_SYS_PTRACE, etc.), and the Windows privilege set enumerates about 35 named privileges. Second, the depth of exploitable chains is empirically small: the vast majority of real escalation paths have depth 1 or 2, with chains of depth 3 or more being exceptional and typically involving a combination of a kernel exploit, a container escape, and a lateral movement step.
For bounded depth $d$, BFS over the state space runs in time $O(|\mathcal{T}|^d \cdot |V|)$, which is manageable for $d \leq 5$ and state spaces of the size encountered in real systems. The key implementation challenge is not computational complexity but state representation: the set of applicable transitions depends not only on the current rights set but on environmental conditions such as kernel version, installed packages, sudo rules, world-writable directories, and SUID binaries present on the filesystem. A complete escalation chain discovery tool must combine the graph-theoretic framework with host enumeration to build the set of applicable transitions from the live system state.
3.3 Time-of-Check to Time-of-Use: Probabilistic Escalation
A distinct but related escalation class involves TOCTOU (time-of-check to time-of-use) races, where the attacker exploits the window between a privilege check and the privileged operation it guards. The probability that an attacker wins a TOCTOU race in a single attempt depends on the size of the race window $\delta$ relative to the total operation period $T$:
$$P(\text{win in } n \text{ attempts}) = 1 - \left(1 - \frac{\delta}{T}\right)^n \tag{6}$$
For typical kernel TOCTOU vulnerabilities, $\delta/T$ is on the order of $10^{-3}$ to $10^{-2}$, meaning the attacker needs on the order of 100 to 1,000 attempts to achieve a win probability exceeding 63%. CVE-2016-5195 (Dirty COW) used this exact structure: the race window was small but the attacker could trigger the write operation in a tight loop. Sophisticated exploits for CVE-2016-5195 achieved reliable exploitation within seconds on typical hardware by running the racing thread at realtime priority to maximise $\delta/T$ [7]. The formula in Equation (6) also explains why TOCTOU mitigations based on reducing the race window are insufficient: the attacker can compensate for a smaller $\delta$ by increasing $n$, and the asymptotic win probability remains 1 as long as $\delta > 0$.
4. The Linux Kernel Privilege Surface
4.1 Capabilities, Namespaces, and the Kernel Attack Surface
The Linux kernel's privilege model evolved significantly from the simple root/non-root binary of early UNIX. POSIX capabilities, introduced in Linux 2.2 and stabilized in the kernel from version 2.6.24 onward, divide the monolithic root privilege into approximately 40 discrete capability bits that can be independently granted and revoked [12]. A process with CAP_NET_ADMIN can configure network interfaces but cannot read arbitrary files; a process with CAP_SYS_PTRACE can attach to other processes but cannot load kernel modules. This decomposition was intended to implement the principle of least privilege at the kernel level, giving system daemons only the capabilities they require.
Linux namespaces, introduced incrementally from kernel version 3.8 onward, further segment the privilege model by allowing processes to have isolated views of system resources: PID namespaces give processes a private process ID space, network namespaces give them private network stacks, and user namespaces give unprivileged processes a private UID space in which they can be "root" without being root in the host namespace. User namespaces have been a persistent source of privilege escalation vulnerabilities because they allow unprivileged processes to invoke kernel subsystems with elevated privileges within the namespace scope, and the boundary between namespace-scoped and host-scoped privileges has been repeatedly violated.
CVE-2022-0492, a Linux kernel vulnerability disclosed in March 2022, exploited a logic error in the cgroup release agent mechanism [13]. The cgroup (control group) subsystem allows processes to set a release agent, a program executed as root when a control group becomes empty. An unprivileged process inside a user namespace could create a cgroup hierarchy and configure a release agent without the kernel validating whether the namespace boundary was properly enforced. The result was that a process running as www-data inside a container could cause the host kernel to execute an arbitrary binary as root by creating and immediately emptying a cgroup. Containment tools including certain configurations of runc were affected, and the fix required tightening the capability checks guarding cgroup release agent writes to verify namespace crossing rather than simply checking for the CAP_SYS_ADMIN capability, which was available inside the user namespace.
4.2 PwnKit and SUID Binary Exploitation
CVE-2021-4034, disclosed by Qualys Research Labs in January 2022 and immediately dubbed PwnKit, affected pkexec, the SUID-root binary that is part of the PolicyKit (polkit) suite installed by default on virtually all Linux distributions [14]. The vulnerability was a memory corruption issue: pkexec incorrectly handled the case where argv[0] was null (as produced by calling execve with an empty argument vector), leading to an out-of-bounds write that could be exploited to overwrite environment variables and ultimately hijack the execution flow of the SUID binary. The Qualys proof-of-concept achieved reliable local privilege escalation to root in under a second on Ubuntu, Debian, Fedora, and CentOS, covering the overwhelming majority of enterprise Linux deployments.
PwnKit's longevity is remarkable from a formal standpoint. The vulnerability was introduced in May 2009 when the affected code path was first committed, meaning it was present and exploitable for approximately 12 years before disclosure. Every privilege escalation during that window that used this vector was a violation of the BLP star property: the pkexec binary, running with SUID-root effective UID, was written to by a low-integrity process through a memory corruption primitive that bypassed all label checks. The kernel's virtual memory subsystem is not subject to MAC enforcement; the LSM hooks that implement SELinux and AppArmor labels operate at the system call level, not at the level of CPU memory instructions. A memory corruption that redirects execution before or after an LSM hook can therefore bypass MAC enforcement entirely, which is why memory safety remains the most critical precondition for MAC effectiveness.
4.3 The "Flipping Pages" Exploit: CVE-2024-1086
CVE-2024-1086, published in January 2024, affects the nf_tables Netfilter subsystem in Linux kernels from 5.14 through 6.6 [15]. The vulnerability is a use-after-free in the nft_verdict_init function, exploitable to achieve arbitrary kernel read/write and ultimately a full privilege escalation to root. The exploit published by Notselwyn in March 2024, named "Flipping Pages," achieved a 99.4% success rate in testing across kernels from 5.14 to 6.6 on standard hardware. This reliability figure is exceptional for a kernel use-after-free and reflects sophisticated heap grooming techniques combined with a careful exploitation strategy that avoids triggering memory safety mitigations such as SMAP and SMEP.
The Flipping Pages exploit is theoretically significant because it demonstrates the gap between formal MAC guarantees and practical kernel security. A system running SELinux in enforcing mode, with a carefully crafted type enforcement policy that should prevent any transition to a privileged security context, is fully compromised by this vulnerability because the exploit operates below the level at which SELinux hooks fire. The kernel's integrity model, which includes SMEP (Supervisor Mode Execution Prevention) and SMAP (Supervisor Mode Access Prevention) as hardware-enforced boundaries between user and kernel address spaces, is bypassed through a controlled corruption of kernel data structures rather than direct code injection. The formal guarantee offered by SELinux's type enforcement is not violated in any formally auditable sense; the exploit simply reaches around the label system by operating at the level of raw kernel memory management, which the label system does not protect.
5. Windows Privilege Escalation Primitives
5.1 Windows Token Architecture and UAC
The Windows access control architecture is built around security tokens, which are kernel objects attached to every process and thread that record the security context, including user identity, group memberships, and privileges [16]. A token contains a list of LUID (locally unique identifier) privilege entries, each of which can be enabled, disabled, or removed. The privilege escalation problem on Windows typically reduces to one of three questions: can the attacker impersonate a higher-privileged token, can the attacker enable a disabled privilege in their current token, or can the attacker inject code into a higher-privileged process whose token will then be used for subsequent operations?
User Account Control (UAC), introduced in Windows Vista, creates a filtered token for administrative users that has most administrative privileges disabled by default, requiring explicit elevation via a UAC consent prompt. UAC is not a security boundary in the Windows security model (Microsoft's own documentation acknowledges this), meaning that a vulnerability that bypasses UAC without any user interaction is classified as a privilege escalation from medium to high integrity but not as a security boundary violation in the sense that would entitle it to the highest severity classification. CVE-2024-6769, disclosed by Fortra in January 2025, exploits a logical inconsistency in how Windows maps drive letters in the NT object namespace [17]. By creating a junction from a user-controlled directory to a system directory through a specific sequence of namespace operations, an attacker can cause a medium-integrity process to write to a location that a high-integrity process will subsequently execute, achieving UAC bypass without any UAC dialog being shown. The vulnerability is not a memory corruption; it is a violation of the Clark-Wilson model's requirement that CDIs (in this case, executable system files) be modifiable only through certified transformation procedures.
5.2 SeImpersonatePrivilege and Token Impersonation
The SeImpersonatePrivilege privilege, present in the tokens of all service accounts by default on Windows, allows a process to impersonate any user that presents it with a token. The class of exploits known as "potato" attacks (Hot Potato, Rotten Potato, Juicy Potato, Sweet Potato, and their successors) exploit various mechanisms to coerce a high-privileged process, typically the SYSTEM account running a COM server, to authenticate to a named pipe or socket controlled by the attacker [18]. The authentication protocol (typically NTLM) causes the high-privileged process to present its token to the attacker's server, and the attacker can then use ImpersonateNamedPipeClient or equivalent APIs to obtain an impersonation token for SYSTEM. From there, CreateProcessWithTokenW or CreateProcessAsUserW can spawn a new process running as SYSTEM.
"Juicy Potato has been patched more times than I can count and there's still a working variant every six months. The fundamental issue is that COM servers run as SYSTEM by default and NTLM coercion is a 30-year-old design decision." — @splinter_code, X/Twitter, March 2024
The persistence of potato-class exploits reflects a structural property of the Windows COM architecture: it was designed in the early 1990s without a threat model that anticipated the case where service accounts running as SYSTEM would be used to host components callable from less-privileged contexts. The CLSID-based instantiation mechanism, which allows clients to activate COM servers by specifying a class identifier, predates the security model refinements that Windows Vista introduced. Sweet Potato (2022) and PrintSpoofer (CVE-2020-1048) demonstrate that even after extensive patching of specific CLSID-based coercion paths, new coercion primitives continue to be discovered because the underlying architecture has not changed.
5.3 ADCS and Active Directory Certificate Abuse
The "Certified Pre-Owned" research by Will Schroeder (@harmj0y) and Lee Christensen published in 2021 documented eight escalation techniques (ESC1 through ESC8) against Active Directory Certificate Services (ADCS), the PKI infrastructure embedded in most enterprise Windows domains [19]. The most widely exploited technique, ESC1, arises when a certificate template allows the Subject Alternative Name (SAN) field to be specified by the requester and the resulting certificate can be used for Kerberos authentication. An attacker with enrollment rights on such a template can request a certificate claiming to be any domain user, including a Domain Admin, and then authenticate as that user using the certificate. The template misconfiguration is not a software vulnerability but a configuration error that violates the principle that transformation procedures (certificate issuance) must validate the identity claims they certify.
The scale of ESC1 exposure in enterprise environments was staggering when first disclosed. Assessments by multiple penetration testing firms found that a majority of large Active Directory environments had at least one ESC1-vulnerable template, and tools such as Certify by SpecterOps made the enumeration and exploitation of these templates trivial for any authenticated domain user. The attack requires no elevated privileges to initiate: an account with basic domain authentication and enrollment rights on the vulnerable template is sufficient to escalate to Domain Admin. BloodHound, the attack path visualization tool developed by @_wald0 (Andy Robbins) and collaborators, was extended to enumerate ADCS paths after the Certified Pre-Owned research, making the attack graph for ADCS abuse auditable in the same framework used for Kerberoasting and ACL abuse paths.
6. Tooling and Implementation
6.1 Enumeration Tools and the PEASS-ng Ecosystem
Privilege escalation enumeration tools automate the collection of system state that informs the applicable transition set $\mathcal{T}$ in the graph model from Section 3. The PEASS-ng suite (Privilege Escalation Awesome Scripts Suite, Next Generation), maintained by Carlos Polop and available at github.com/carlospolop/PEASS-ng with over 19,800 GitHub stars, includes linPEAS for Linux and macOS and winPEAS for Windows [20]. Both tools enumerate kernel version, installed packages, SUID/SGID binaries, world-writable directories and files, cron jobs running as root, sudo rules, SUID capabilities, interesting files in home directories, and network services listening on local ports. The output is color-coded by severity, with red indicating high-confidence escalation paths.
GTFOBins (gtfobins.github.io), maintained by Emilio Pinna and Andrea Cardaci, catalogs Unix binaries that can be exploited to bypass local security restrictions [21]. Each entry documents how the binary can be used to read files, write files, spawn shells, or perform other privileged operations outside its intended use. The GTFOBins dataset is effectively a manually curated transition set for the graph model: each entry specifies a precondition (the binary must be SUID, or available via sudo without a password) and the resulting privilege gain (shell as the binary's owner, or as root if SUID). LOLBAS (Living Off The Land Binaries, Scripts and Libraries, lolbas-project.github.io) performs the equivalent function for Windows, cataloging signed Microsoft binaries that can execute, download, or bypass application control policies [22].
6.2 BloodHound and Attack Path Visualization
BloodHound, originally published by @_wald0, @CptJesus (Rohan Vazarkar), and @harmj0y at DEF CON 24 in 2016, models Active Directory as a directed graph and finds privilege escalation paths using cypher queries over a Neo4j database [23]. The tool collects data on user accounts, computer objects, group memberships, ACL entries, session data, and Group Policy Objects via the SharpHound collector, then visualizes shortest paths to Domain Admin from any starting node. BloodHound Community Edition (released 2023) and BloodHound Enterprise (commercial) extended the original tool with continuous collection, historical trend analysis, and tier-zero asset identification.
"BloodHound changed the game because it made attack path analysis a first-class operation rather than something a senior consultant did in their head. Now every junior pen tester can find a path to DA in 20 minutes that would have taken an experienced consultant hours to discover manually." — @CptJesus, SANS Threat Hunting Summit, 2022
The graph-theoretic framework underlying BloodHound is directly related to the formal model in Section 3. Each node in the BloodHound graph corresponds to a privilege state (a security principal with its current effective rights), and each edge corresponds to a transition: HasSession edges allow token theft via credential dumping, GenericWrite edges on user objects allow targeted Kerberoasting or password reset, WriteDacl edges allow ACL manipulation to grant arbitrary additional rights. The Cypher query MATCH p=shortestPath((u:User {name:"TARGET"})-[*1..]->(c:Computer {name:"DC01.DOMAIN.COM"})) RETURN p implements exactly the bounded reachability search from Equation (5), finding the shortest escalation chain from a given user to a domain controller.
6.3 Python Implementation: BFS-Based Escalation Chain Discovery
The following implementation performs BFS over the privilege state space to enumerate all escalation chains from an initial state to a target rights set, within a configurable depth bound. It models the transitions from the CVEs and techniques discussed in previous sections.
from __future__ import annotations
from dataclasses import dataclass, field
from typing import FrozenSet, List, Optional
from collections import deque
@dataclass(frozen=True)
class PrivilegeState:
"""Immutable snapshot of a principal's current rights."""
subject: str
rights: FrozenSet[str]
def has(self, right: str) -> bool:
return right in self.rights
def has_all(self, required: FrozenSet[str]) -> bool:
return required.issubset(self.rights)
def escalated_over(self, baseline: "PrivilegeState") -> bool:
"""True if this state has strictly more rights than baseline (Eq. 4)."""
return self.rights > baseline.rights
def __repr__(self) -> str:
return f"PrivilegeState({self.subject!r}, {sorted(self.rights)})"
@dataclass
class EscalationTransition:
"""A single exploitable step in a privilege escalation chain."""
name: str
cve: str
requires: FrozenSet[str] # rights the current state must include
grants: FrozenSet[str] # rights added by this transition
technique: str
def applicable(self, state: PrivilegeState) -> bool:
"""True if the transition can be applied in the given state."""
return state.has_all(self.requires)
def apply(self, state: PrivilegeState) -> PrivilegeState:
"""Return the new privilege state after applying this transition."""
return PrivilegeState(
subject=state.subject,
rights=state.rights | self.grants,
)
@dataclass
class EscalationChain:
"""A sequence of transitions leading from an initial to a target state."""
steps: List[tuple] # (transition_name, cve, resulting_state)
def depth(self) -> int:
return len(self.steps)
def summary(self) -> str:
lines = []
for i, (name, cve, state) in enumerate(self.steps, 1):
lines.append(f" {i}. {name} ({cve}) -> {sorted(state.rights)}")
return "\n".join(lines)
def find_escalation_chains(
initial: PrivilegeState,
target_rights: FrozenSet[str],
transitions: List[EscalationTransition],
max_depth: int = 5,
) -> List[EscalationChain]:
"""
BFS over privilege state space to find all chains reaching target_rights.
Implements bounded reachability over the state sequence in Eq. 5.
"""
results: List[EscalationChain] = []
# Queue entries: (current_state, chain_so_far)
queue: deque = deque()
queue.append((initial, []))
# Track visited states at each depth to avoid cycles
visited_at_depth: dict = {}
while queue:
current_state, chain = queue.popleft()
depth = len(chain)
if depth > max_depth:
continue
state_key = (current_state.rights, depth)
if state_key in visited_at_depth:
continue
visited_at_depth[state_key] = True
# Check if target is reached
if target_rights.issubset(current_state.rights):
if chain: # only record non-trivial chains
results.append(EscalationChain(steps=chain))
continue # do not extend further once target is reached
for t in transitions:
if not t.applicable(current_state):
continue
new_state = t.apply(current_state)
if new_state.rights == current_state.rights:
continue # transition adds nothing new, skip
new_chain = chain + [(t.name, t.cve, new_state)]
queue.append((new_state, new_chain))
return results
if __name__ == "__main__":
# Initial state: web app process running as www-data
initial = PrivilegeState(
subject="www-data",
rights=frozenset({"read", "exec", "net_bind"}),
)
# Target: full root rights
root_rights = frozenset({"read", "write", "exec", "setuid", "cap_sys_admin"})
# Define available transitions based on CVEs and misconfigs
transitions = [
EscalationTransition(
name="PwnKit (pkexec SUID memory corruption)",
cve="CVE-2021-4034",
requires=frozenset({"exec"}),
grants=frozenset({"write", "setuid", "cap_sys_admin"}),
technique="SUID binary exploitation",
),
EscalationTransition(
name="cgroup release_agent escape",
cve="CVE-2022-0492",
requires=frozenset({"exec", "net_bind"}),
grants=frozenset({"cap_sys_admin", "write"}),
technique="Namespace boundary violation",
),
EscalationTransition(
name="nf_tables use-after-free (Flipping Pages)",
cve="CVE-2024-1086",
requires=frozenset({"exec"}),
grants=frozenset({"write", "setuid", "cap_sys_admin"}),
technique="Kernel UAF -> arbitrary write",
),
EscalationTransition(
name="sudo misconfiguration (NOPASSWD)",
cve="MISC-SUDO-001",
requires=frozenset({"exec"}),
grants=frozenset({"write", "setuid"}),
technique="sudo rules abuse",
),
EscalationTransition(
name="SUID binary with cap_sys_admin",
cve="MISC-SUID-001",
requires=frozenset({"write", "setuid"}),
grants=frozenset({"cap_sys_admin"}),
technique="Capability-enabled SUID abuse",
),
]
chains = find_escalation_chains(initial, root_rights, transitions, max_depth=5)
print(f"Found {len(chains)} escalation chain(s) to root:\n")
for i, chain in enumerate(chains, 1):
print(f"Chain {i} (depth {chain.depth()}):")
print(chain.summary())
print()
The BFS correctly enumerates both single-step chains (where one transition directly grants all target rights) and multi-step chains (where transitions must be composed). In the example above, CVE-2021-4034 and CVE-2024-1086 each provide one-step escalation paths because they grant write, setuid, and cap_sys_admin simultaneously. The sudo misconfiguration followed by the SUID capability abuse forms a two-step chain, illustrating how individually insufficient techniques compose to reach the target state.
7. Commercial Landscape and Strategic Implications
7.1 The Privileged Access Management Market
The PAM market is undergoing rapid consolidation driven by the recognition that privileged access is the primary attack vector in serious breaches. Verizon's 2024 Data Breach Investigations Report found that credential-based attacks accounted for 77% of basic web application attacks, and the majority of post-intrusion lateral movement in enterprise breaches involves some form of privilege escalation before access to sensitive data [24]. This empirical pattern has translated directly into investment: the PAM market grew from $2.4 billion in 2022 to $3.46 billion in 2024, and current projections from MarketsandMarkets and Grand View Research place it at $16.49 billion by 2032.
CyberArk's acquisition of Venafi for $1.54 billion in October 2024 signals a strategic expansion from traditional PAM (managing shared privileged accounts and recording sessions) toward machine identity management, the governance of the non-human credentials (TLS certificates, SSH keys, API tokens, Kubernetes service accounts) that increasingly outnumber human credentials in enterprise environments [3]. Every machine identity is a potential privilege escalation vector: a compromised TLS certificate on an internal service can facilitate a man-in-the-middle attack against an authentication flow, and a leaked SSH key with root access to a production server is functionally identical to a credential for a privileged human account. The convergence of PAM and machine identity management reflects the industry's recognition that the relevant threat model extends well beyond human administrator accounts.
BeyondTrust's product strategy, anchored in its Just-in-Time Access and Endpoint Privilege Management offerings, reflects a different architectural response to the same threat. Rather than vaulting and rotating credentials for persistent privileged accounts, BeyondTrust's model eliminates persistent elevated access by granting privileges only for the duration of a specific approved task and withdrawing them immediately upon completion. This is the operational implementation of the principle of least privilege: the formal guarantee in Equation (1) is approximated not by preventing escalation statically but by ensuring that any escalation is time-bounded and logged. The distinction between these approaches, vault-and-rotate versus just-in-time elimination, is a design choice with meaningful security consequences that the formal models do not adjudicate: both approaches are consistent with implementing least privilege, but they differ in their residual attack surface during the windows of elevated access.
7.2 Detection and the EDR Response
The commercial response to privilege escalation has a second track: detection and response. Endpoint Detection and Response (EDR) vendors including CrowdStrike, SentinelOne, and Microsoft Defender for Endpoint instrument the operating system at the kernel level to detect privilege escalation attempts in real time. The detection strategies map directly onto the formal model: anomalous capability acquisition (a process gaining CAP_SYS_ADMIN outside of a whitelisted code path), unexpected SUID execution chains, and token manipulation API calls are all detectable as anomalous state transitions in the privilege graph.
The adversarial response to EDR-based detection has been to shift the exploit surface toward living-off-the-land techniques that use signed, whitelisted binaries (the LOLBAS catalog on Windows, GTFOBins on Linux) to perform privileged operations. A PowerShell script invoking Start-Process with -Verb RunAs is behaviorally identical whether it is run by a system administrator or an attacker; the behavioral signal that distinguishes them is not the API call but the parent process, the user context, and the sequence of events preceding the call. Modern EDR systems therefore treat privilege escalation detection as a sequence classification problem over the process tree, using machine learning models trained on sequences of system calls and API calls, rather than as a single-event pattern match.
"The problem with ML-based escalation detection isn't the model, it's the ground truth. If your training data is generated from red team exercises, your model learns to detect red teamers, not real attackers. Real escalation paths include noise that red teams don't introduce." — Katie Nickels, MITRE ATT&CK Lead, BSides Las Vegas, 2023
7.3 Open-Source C2 Frameworks and the Economics of Privilege Exploitation
The commercial C2 framework market provides useful context for understanding how privilege escalation techniques are operationalized at scale. Cobalt Strike, long the dominant commercial C2, costs approximately $5,900 per operator per year and has a pervasive presence in both legitimate red team operations and criminal threat actor infrastructure due to widespread license cracking [25]. Bishop Fox's Sliver C2 framework, released as open source in 2020, has emerged as a technically sophisticated alternative used by both authorized testers and advanced threat actors. Brute Ratel C4, developed by Chetan Nayak (Paranoid Ninja), offers a commercial alternative priced at $1,500 to $2,500 per operator per year with a deliberate focus on detection evasion against modern EDR systems.
The Havoc C2 framework, released as open source in 2022, introduced a modular post-exploitation capability architecture that includes dedicated privilege escalation modules for both Windows and Linux. The modular design maps directly onto the transition set $\mathcal{T}$ in the graph model: each module is an implementation of one or more escalation transitions, with precondition checks that determine applicability in the current environment. This architecture reflects the maturation of privilege escalation tooling from collections of standalone scripts toward structured, composable frameworks that can enumerate applicable techniques and recommend escalation paths automatically. Horizon3.ai's NodeZero autonomous penetration testing platform, which raised $100 million in a Series D round in 2024 bringing total funding to $178.5 million, applies a similar graph-based approach to attack path finding at enterprise scale, automatically chaining privilege escalation techniques across multiple hosts to find paths to critical assets.
8. Conclusion and Open Problems
The theoretical foundations of access control have been established for half a century: the HRU undecidability result, the Bell-LaPadula and Biba formal models, Denning's lattice framework, and the Clark-Wilson transaction model collectively define the space within which privilege escalation operates. Every real vulnerability is a violation of one of these formal structures, and every mitigation is an attempt to enforce a formal property in an implementation that resists complete formalization. The gap between the theory and the implementation is where privilege escalation lives.
Several open problems remain. First, the safety problem for modern operating systems with user namespaces, cgroup v2 hierarchies, and eBPF programs is formally unexplored: no one has characterized the decidability or complexity of the safety problem for the full Linux security model as currently implemented. Second, the interaction between formal MAC systems (SELinux, AppArmor) and memory-safety vulnerabilities is theoretically unmodeled: current MAC theory assumes that transitions happen through defined system call interfaces, but memory corruption exploits operate below the level at which MAC hooks fire. Third, the automated escalation chain discovery problem for heterogeneous environments (mixing Linux, Windows, cloud IAM, and Kubernetes RBAC within a single escalation path) has no principled solution: current tools handle each substrate separately and require manual composition. Fourth, the verification gap between access control policy specifications (written in SELinux policy language or AWS IAM policy JSON) and their runtime enforcement is an open problem in both formal verification and practical tooling; misconfiguration continues to be a more common root cause of privilege escalation than software vulnerability in enterprise environments.
The practitioner takeaway is that least privilege is not an endpoint but a property that must be continuously verified against a dynamic threat model. The formal models provide the vocabulary for that verification; the tooling described in this article provides the practical means. Building systems that durably implement least privilege requires treating the access control policy as a formal specification, continuously comparing the policy against the implemented state, and treating every deviation as a potential escalation vector rather than a configuration artifact.
References
[1] M. A. Harrison, W. L. Ruzzo, and J. D. Ullman, "Protection in Operating Systems," Communications of the ACM, vol. 19, no. 8, pp. 461-471, 1976.
[2] MarketsandMarkets, "Privileged Access Management Market — Global Forecast to 2032," Market Research Report, 2024.
[3] CyberArk, "CyberArk Completes Acquisition of Venafi," Press Release, October 2024.
[4] BeyondTrust, "BeyondTrust Annual Report and ARR Update," Investor Relations, 2024.
[5] B. W. Lampson, "Protection," Proceedings of the 5th Princeton Symposium on Information Sciences and Systems, pp. 437-443, 1971.
[6] D. E. Bell and L. J. LaPadula, "Secure Computer Systems: Unified Exposition and Multics Interpretation," MITRE Technical Report MTR-2997, 1976.
[7] P. Corbet, "Dirty COW: CVE-2016-5195 Analysis," Linux Weekly News, October 2016.
[8] K. J. Biba, "Integrity Considerations for Secure Computer Systems," MITRE Technical Report MTR-3153, 1977.
[9] D. D. Clark and D. R. Wilson, "A Comparison of Commercial and Military Computer Security Policies," Proceedings of the IEEE Symposium on Security and Privacy, pp. 184-194, 1987.
[10] D. E. Denning, "A Lattice Model of Secure Information Flow," Communications of the ACM, vol. 19, no. 5, pp. 236-243, 1976.
[11] Y. Yarom and K. Falkner, "FLUSH+RELOAD: A High Resolution, Low Noise, L3 Cache Side-Channel Attack," Proceedings of USENIX Security, pp. 719-732, 2014.
[12] M. Tim Jones, "Anatomy of the Linux Capabilities System," IBM Developer, 2009.
[13] Sysdream, "CVE-2022-0492: Linux Privilege Escalation via cgroup v1 Release Agent," Security Advisory, March 2022.
[14] Qualys Research Labs, "PwnKit: Local Privilege Escalation Vulnerability Discovered in polkit's pkexec (CVE-2021-4034)," Security Advisory, January 2022.
[15] Notselwyn, "CVE-2024-1086: Universal Local Privilege Escalation Exploit for Linux Kernel 5.14-6.6 (Flipping Pages)," GitHub Advisory, March 2024.
[16] Microsoft, "Access Tokens," Windows Security Documentation, Microsoft Learn, 2024.
[17] Fortra, "CVE-2024-6769: Windows UAC Bypass via NT Object Namespace Drive Letter Mapping," Security Advisory, January 2025.
[18] itm4n, "PrintSpoofer: Abusing Impersonation Privileges on Windows 10 and Server 2019," Security Research Blog, 2020.
[19] W. Schroeder and L. Christensen, "Certified Pre-Owned: Abusing Active Directory Certificate Services," SpecterOps, August 2021.
[20] C. Polop, "PEASS-ng: Privilege Escalation Awesome Scripts Suite," GitHub Repository, github.com/carlospolop/PEASS-ng, 2024.
[21] E. Pinna and A. Cardaci, "GTFOBins: Curated List of Unix Binaries That Can Be Used to Bypass Local Security Restrictions," gtfobins.github.io, 2024.
[22] LOLBAS Project, "Living Off The Land Binaries, Scripts and Libraries," lolbas-project.github.io, 2024.
[23] A. Robbins, R. Vazarkar, and W. Schroeder, "Six Degrees of Domain Admin: BloodHound at DEF CON 24," DEF CON 24 Briefings, 2016.
[24] Verizon, "2024 Data Breach Investigations Report," Verizon Business, 2024.
[25] Recorded Future, "Cobalt Strike Licensing Analysis and Threat Actor Distribution," Threat Intelligence Report, 2023.
Word count: approximately 9,200 words.
Comments
Post a Comment