Skills · learning

Privilege Escalation

Privilege Escalation

Scope and mental model

After initial access, the foothold is often a standard user session. Privilege escalation is the process of crossing a local security boundary to obtain a more privileged security context, such as an elevated administrator token or SYSTEM.

The practical question is not “what exploit can I run?” It is:

Which higher-privileged process, account, service, or application can be made to perform an action using something the current user can control?

Every escalation hypothesis needs four pieces of evidence:

  1. A privileged execution context: what account, token, integrity level, or service identity will run the action?
  2. A controllable input: what can the current user modify - an executable, DLL, service configuration, registry value, file, or serialized data?
  3. A trigger: when will the privileged component load or execute it?
  4. A validation step: how will you prove the resulting context and access?

The activities in this note are for systems owned by, or explicitly authorized by, the engagement owner and the CRTO lab.

Windows identity and privilege boundaries

Common service identities

The account running a process determines its primary security context. These accounts are not interchangeable:

  • Standard user: normally has limited access to system objects, but exact permissions depend on group membership, ACLs, assigned rights, and the object.
  • Local Administrators: membership provides administrative capability, but a user can still be operating through a filtered, medium-integrity token until elevation occurs.
  • LocalService: a predefined service account with minimal local privileges and anonymous network credentials by default.
  • NetworkService: limited local privileges, but uses the computer account when authenticating to network resources.
  • LocalSystem / SYSTEM: highly privileged local service identity. On a domain member it normally uses the computer account on the network; on a domain controller, the consequences are substantially greater.
  • Dedicated service account: a local or domain account selected by the service owner. Its actual privileges come from its groups, rights, ACLs, and network permissions - not merely from the label “service account.”
Pasted image 20260920150014.png
Fig. 1. Pasted image 20260920150014.png

Do not treat SYSTEM as “the highest level access in every situation.” It is a very powerful local context, but effective access still depends on the host, domain role, network permissions, and security controls.

User Rights Assignment

User Rights Assignment provides granular rights to security principals. It is different from ordinary group membership and should be checked separately.

Two useful categories are:

  • Logon rights: determine how an account may log on, such as logging on as a service or as a batch job.
  • Privilege rights: enable particular operating-system actions. One example relevant to authorized escalation labs is SeImpersonatePrivilege, but having a privilege present does not by itself prove that escalation will succeed.

The useful workflow is to identify the current token, inspect enabled and disabled privileges, then connect any interesting privilege to a concrete privileged operation and a lab-approved validation step.

Service-based escalation

Windows services are attractive escalation targets because they often run when no user is logged on and may execute as LocalSystem or another privileged identity. A service weakness matters only when the current user can control the relevant object and the service can be started, restarted, or otherwise triggered.

The main service-related categories in this chapter are:

  • PATH environment-variable interception: T1574.007
  • Search-order hijacking: T1574.008
  • Unquoted path interception: T1574.009
  • Services file-permissions weakness: T1574.010
  • Services registry-permissions weakness: T1574.011
  • Exploitation of a vulnerable privileged application: T1068

Enumerating services

Beacon or course-specific helpers may expose commands such as sc_enum. Native Windows tools such as sc.exe and PowerShell can also enumerate services. The exact Beacon command set is version-dependent, so use help in the lab and record the service name, binary path, start account, start mode, dependencies, and permissions.

beacon> sc_enum

For every candidate, answer:

  1. Which account runs the service?
  2. What executable or DLL is loaded?
  3. Can the current user write to the file, its directory, or its dependencies?
  4. Can the current user modify the service configuration or start/stop it?
  5. What exact trigger will execute the controlled content?

PATH interception

PATH interception occurs when a privileged process requests an executable by a name or relative path and Windows resolves that name through a search path that contains a user-writable directory before the legitimate directory.

Beacon can display environment variables with env:

beacon> env

Path=C:\Python313\Scripts\;C:\Python313;C:\Windows\system32;C:\Windows; ... etc ...

The security issue is not simply that a non-system directory appears in PATH. The directory must be writable by the current user, and a privileged program must actually resolve a requested executable through that path. Verify both conditions with permissions and process behavior.

Pasted image 20260920151716.png
Fig. 2. Pasted image 20260920151716.png

The course example uses a program that calls timeout.exe by name. If a user-writable PATH directory is searched first, a same-named executable in that directory may be selected before the legitimate Windows copy.

Pasted image 20260920151803.png Pasted image 20260920151843.png
Fig. 3. Pasted image 20260920151803.png · Pasted image 20260920151843.png

cacls appears in the original lab material. It is retained as evidence, but it is an older permission tool; interpret its output carefully and use the tooling provided by the lab.

Search-order hijacking

Search-order hijacking is broader than PATH interception. It relies on a program requesting a module or executable without an absolute path and Windows searching multiple locations in a defined order. The exact order depends on whether the request concerns an executable or DLL, the API used, safe-search settings, the application type, and the operating-system version.

For a simplified executable example, a privileged service may request:

cmd.exe

instead of an explicit path such as:

C:\Windows\System32\cmd.exe

The relevant question is whether an attacker-controlled copy can appear in an earlier searched location. A useful conceptual model is:

Privileged service
    |
    | requests a module or executable by name
    v
Windows resolves the name through its applicable search order
    |
    +--> earlier location: user-writable?  -> possible hijack
    +--> later location: legitimate system file

Do not present the simplified list from the course as the universal Windows algorithm. Microsoft documents different search behavior for DLLs, packaged applications, safe DLL search mode, and explicit loader flags.

Unquoted service paths

An unquoted service path is a path containing spaces that is stored without surrounding quotes. Windows may try intermediate executable interpretations as it resolves the command line. For example:

C:\Program Files\Bad Application\Bad Program.exe

may lead to candidate interpretations such as C:\Program.exe or C:\Program Files\Bad.exe. This becomes an escalation path only when an intermediate location is writable and the service starts under a more privileged context. An unquoted path by itself is a finding, not proof of exploitability.

The lab's Beacon flow is retained below as a conceptual example:

beacon> sc_enum

When testing, record the exact service path, intermediate candidates, directory ACLs, service identity, and a safe trigger. Avoid dropping files merely because the string looks unquoted.

Weak service executable permissions

If a user can modify or replace the executable configured for a privileged service, the service may execute the replacement when restarted. The escalation requires all of the following: write access to the binary or its directory, a privileged service identity, and the ability to trigger the service.

beacon> cacls "C:\Program Files\Bad Windows Service\Service Executable\BadWindowsService.exe"
C:\Program Files\Bad Windows Service\Service Executable\BadWindowsService.exe NT AUTHORITY\Authenticated Users:F

The original lab sequence is:

beacon> cd C:\Program Files\Bad Windows Service\Service Executable\
beacon> sc_stop BadWindowsService
beacon> upload C:\Payloads\BadWindowsService.exe
beacon> sc_start BadWindowsService

The important learning point is the relationship between file ACL, service account, and restart permission. A writable executable that is never run by a privileged process is not an escalation path.

Weak service registry permissions

Service configuration is stored under:

HKLM\SYSTEM\CurrentControlSet\Services

Values include the service configuration and binary path. If an unprivileged user can modify the service's security descriptor or configuration, they may be able to redirect what the Service Control Manager starts. The exact permissions and the ability to trigger the service must still be verified.

beacon> powerpick Get-Acl -Path HKLM:\SYSTEM\CurrentControlSet\Services\BadWindowsService | fl

Path   : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\BadWindowsService
Owner  : BUILTIN\Administrators
Group  : NT AUTHORITY\SYSTEM
Access : NT AUTHORITY\Authenticated Users Allow  FullControl
         BUILTIN\Users Allow  ReadKey
         BUILTIN\Administrators Allow  FullControl
         NT AUTHORITY\SYSTEM Allow  FullControl

The shortened output above preserves the material point from the lab: an unexpected broad ACL on a service key deserves investigation. Validate the effective permission and the exact value that can be changed before relying on the finding.

The course demonstrates changing the binary path and restarting the service:

beacon> sc_stop BadWindowsService
beacon> sc_config BadWindowsService C:\Path\to\Payload.exe 0 2
beacon> sc_start BadWindowsService

The sc_config syntax is Beacon/course-version specific. Microsoft documents the underlying native sc.exe config syntax, including the required spacing in options such as binpath=.

DLL search-order hijacking

DLL hijacking applies the same controllable-resolution idea to a library. If an application calls a loader with a DLL name or relative path, Windows searches for the DLL according to rules that can include the application directory, system directories, the current directory, and PATH. The actual order is API- and configuration-dependent.

Pasted image 20260920154747.png
Fig. 4. Pasted image 20260920154747.png

The lab example uses a service that requests BadDll.dll without specifying a full path. The directory listing shows the executable but not the DLL:

beacon> ls C:\Program Files\Bad Windows Service\Service Executable

 Size     Type    Last Modified         Name
 ----     ----    -------------         ----
 9kb      fil     01/06/2025 16:10:12   BadWindowsService.exe

The course then examines PATH and writes a lab DLL into a candidate writable directory:

beacon> env
Path=C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Windows\System32\OpenSSH\;C:\Program Files\Bad Windows Service;C:\Users\kbowles\AppData\Local\Microsoft\WindowsApps
beacon> ls C:\Program Files\Bad Windows Service

 Size     Type    Last Modified         Name
 ----     ----    -------------         ----
          dir     01/06/2025 16:12:31   Service Executable
 10kb     fil     01/06/2025 16:10:12   BadDll.dll

# Enumerate permissions for that folder
beacon> cacls "C:\Program Files\Bad Windows Service\Service Executable"
C:\Program Files\Bad Windows Service\Service Executable NT AUTHORITY\Authenticated Users:(CI)(OI)F

# Upload the authorized lab payload
beacon> cd C:\Program Files\Bad Windows Service\Service Executable
beacon> upload C:\Payloads\dns_x64.dll
beacon> mv dns_x64.dll BadDll.dll

The complete proof requires showing that the service actually requests that DLL, that the chosen directory is searched, that the architecture matches, and that the service loads it under the privileged identity. A writable directory alone does not establish DLL hijacking.

Vulnerable privileged software

A privileged application may be exploitable through a memory-safety bug, format string, path traversal, injection, or unsafe deserialization. The escalation condition is that the vulnerable process runs with greater privileges than the current user and accepts attacker-influenced input.

BinaryFormatter example

The original course example reads a binary file from an untrusted location and deserializes it with .NET BinaryFormatter. That is a valid example of unsafe deserialization, but it needs an important modern qualification:

  • Microsoft describes BinaryFormatter.Deserialize as unsafe with untrusted input and recommends migration.
  • In .NET 9, the in-box implementation throws on use; older .NET Framework or compatibility-package deployments may behave differently.
  • The actual privilege impact depends on the identity and permissions of the consuming process.
Pasted image 20260920155210.png
Fig. 5. Pasted image 20260920155210.png

The course uses ysoserial.net to generate a lab payload. Keep this strictly inside the authorized lab and verify the target runtime before assuming the example applies.

C:\Users\Attacker>C:\Tools\ysoserial.net\ysoserial\bin\Release\ysoserial.exe -g TypeConfuseDelegate -f BinaryFormatter -c "powershell -nop -ep bypass -enc <lab-encoded-command>" -o raw --outputpath=C:\Payloads\data.bin

beacon> cd C:\Temp
beacon> upload C:\Payloads\data.bin

The encoded command is represented as <lab-encoded-command> here because its value is lab-specific. The learning objective is the trust boundary and process identity, not memorizing one payload string.

User Account Control and integrity levels

Mandatory Integrity Control (MIC) is an additional access-control layer. Windows defines low, medium, high, and system integrity levels. A standard interactive process commonly runs at medium integrity; an elevated administrator process commonly runs at high integrity; system services commonly run at system integrity.

Integrity level is not the same as group membership. A user may belong to the local Administrators group while the current process still uses a filtered, medium-integrity token. This is why “the user is an administrator” does not by itself prove that the current Beacon can perform high-integrity actions.

whoami /groups
Pasted image 20260920160358.png
Fig. 6. Pasted image 20260920160358.png

UAC is a defense-in-depth mechanism around administrative elevation. A UAC bypass is therefore not the same as elevating a standard user into an administrator; the common Cobalt Strike UAC paths require the current user to already be an administrator and depend on Windows version, policy, architecture, and the available bypass implementation.

Pasted image 20260920160439.png
Fig. 7. Pasted image 20260920160439.png

Cobalt Strike exposes two relevant command shapes:

elevate [exploit] [listener]
runasadmin [exploit] [command] [args]

elevate is used to obtain a new elevated Beacon session through a supported elevation method. runasadmin runs a selected command in an elevated context. The available exploit names and supported Windows versions are version-specific; list the available options in the lab rather than assuming every bypass works.

Validation and cleanup

After any escalation attempt, validate the result rather than trusting the task status:

  • Did the new process or Beacon actually start?
  • Which user, groups, privileges, integrity level, and architecture does it have?
  • Can it perform the specific action required by the objective?
  • Did the service, registry, DLL, or file change remain on disk?
  • What event, process, service, module-load, or UAC telemetry would a defender see?
  • What authorized cleanup is required, and can the original configuration be restored safely?

Fact-check status

  • Verified: the distinction between service identity and permissions, the LocalService/NetworkService/LocalSystem descriptions, MIC levels, service registry location, DLL search-order caveats, and UAC prerequisites against Microsoft documentation.
  • Verified: the current Cobalt Strike command shapes for elevate and runasadmin against the version-matched vendor documentation.
  • Corrected: LocalSystem is not automatically equivalent to unrestricted domain access; Administrators group membership is not the same as a high integrity process; an unquoted path or writable directory alone is not proof of exploitable escalation; and BinaryFormatter behavior is runtime-specific.
  • Version-dependent: Beacon helper commands, UAC bypass names, service command syntax, DLL search behavior, and .NET deserialization availability.
  • Lab-specific: service names, host/user names, ACL output, screenshots, PIDs, payload paths, and command results.

Practical review prompts

  1. You find a service running as LocalSystem, but the executable is not writable. What other service properties and permissions would you inspect before deciding whether it is an escalation path?
  2. A PATH entry is writable, but the service always calls an executable by an absolute path. Why does that weaken the PATH-interception hypothesis, and what evidence would you seek next?
  3. An unquoted service path contains spaces. What three facts must be true before you treat it as exploitable rather than merely misconfigured?
  4. A user belongs to Administrators, but whoami /groups shows a medium-integrity process. What boundary is UAC enforcing, and what does a UAC bypass assume about the starting account?
  5. A BinaryFormatter payload is accepted by a lab application but fails on a newer host. Which runtime, process identity, input location, and application behavior would you compare before concluding the technique is broken?

This is a living study note. Sources and understanding may change as it is reviewed.

Ryan Sacatani

Simply curious about the world, constantly building and breaking things for fun.

sacataniryan1@gmail.com ↗

BrowseBrowse topics