Skip to content

Local Privilege Escalation Paths

This page groups local privilege escalation paths by the permissions or operations that provide a starting point. Check each technique’s prerequisites before consulting the relevant section.

A low-privilege child process may inherit a handle opened by a process running as SYSTEM. If the inherited handle retains strong access rights, it may allow operations on the target process. See Leaked Handle Exploitation and analysis of process and thread handles for ways to check this.

Named pipes let processes exchange data. A pipe server that meets conditions such as having SeImpersonatePrivilege can perform operations with the privileges of a connected client. Controlling a pipe that a highly privileged process connects to can therefore provide a privilege escalation path. See Named Pipe Client Impersonation and From High Integrity to SYSTEM for details.

Other tools include pipe-intercept, which intercepts named pipe traffic with a tool such as Burp, and PipeViewer, which enumerates and inspects pipes to find privilege escalation opportunities.

See https://filesec.io/.

After obtaining a shell as a user, you may find scheduled tasks or other processes that pass credentials on the command line. The following script retrieves process command lines every two seconds and prints differences from the previous snapshot.

Terminal window
while($true)
{
$process = Get-WmiObject Win32_Process | Select-Object CommandLine
Start-Sleep 1
$process2 = Get-WmiObject Win32_Process | Select-Object CommandLine
Compare-Object -ReferenceObject $process -DifferenceObject $process2
}

From a low-privilege user to SYSTEM: CVE-2019-1388

Section titled “From a low-privilege user to SYSTEM: CVE-2019-1388”

With GUI access (console or RDP) and UAC enabled, some Windows versions may allow an unprivileged user to launch a “NT\AUTHORITY SYSTEM” terminal or another process.

This can achieve privilege escalation and a UAC bypass at the same time through the same vulnerability. Nothing needs to be installed, and the binaries used during the process are Microsoft-signed.

Examples of affected systems:

SERVER
======
Windows 2008r2 7601 ** link OPENED AS SYSTEM **
Windows 2012r2 9600 ** link OPENED AS SYSTEM **
Windows 2016 14393 ** link OPENED AS SYSTEM **
Windows 2019 17763 link NOT opened
WORKSTATION
===========
Windows 7 SP1 7601 ** link OPENED AS SYSTEM **
Windows 8 9200 ** link OPENED AS SYSTEM **
Windows 8.1 9600 ** link OPENED AS SYSTEM **
Windows 10 1511 10240 ** link OPENED AS SYSTEM **
Windows 10 1607 14393 ** link OPENED AS SYSTEM **
Windows 10 1703 15063 link NOT opened
Windows 10 1709 16299 link NOT opened

Exploitation steps:

1) Right-click HHUPD.EXE and run it as administrator.
2) When the UAC prompt appears, select "Show more details".
3) Click "Show publisher certificate information".
4) On a vulnerable system, click the URL under "Issued by" to open the default browser.
5) Wait until the site has fully loaded, then select "Save as" to open an explorer.exe window.
6) Enter cmd.exe, powershell.exe, or similar in Explorer's address bar.
7) A "NT\AUTHORITY SYSTEM" command prompt opens.
8) Cancel the setup and UAC prompt to return to the desktop.

The required files and information are on GitHub:

https://github.com/jas502n/CVE-2019-1388

From medium to high integrity as an administrator

Section titled “From medium to high integrity as an administrator”

For Integrity Levels, see:

Integrity Levels

For UAC and UAC bypasses, see:

UAC: User Account Control

From folder deletion, movement, or renaming rights to SYSTEM

Section titled “From folder deletion, movement, or renaming rights to SYSTEM”

The technique is described in this blog post, with exploit code here.

The attack abuses Windows Installer’s rollback feature to replace a legitimate file with a malicious one during uninstallation. The attacker must create a malicious MSI installer and take over the C:\Config.Msi folder. Windows Installer stores rollback files there while uninstalling other MSI packages, so the attacker modifies those files to include a payload.

Summary of the steps:

  1. Stage 1 – Prepare the hijack (empty C:\Config.Msi)
  • Step 1: Install an MSI

    • Create an .msi that installs a harmless file (for example, dummy.txt) into a writable folder (TARGETDIR).
    • Mark the installer “UAC Compliant” so a non-administrator can run it.
    • After installation, keep a handle to the file open.
  • Step 2: Start uninstallation

    • Uninstall the same .msi.
    • The uninstaller starts moving the file into C:\Config.Msi and renaming it to an .rbf (rollback backup).
    • Poll the open file handle with GetFinalPathNameByHandle to detect when the file becomes C:\Config.Msi\<random>.rbf.
  • Step 3: Custom synchronization

    • Include a custom uninstall action (SyncOnRbfWritten) in the .msi:
      • Signal when the .rbf has been written.
      • Then wait for another event before continuing uninstallation.
  • Step 4: Block deletion of the .rbf

    • On receiving the signal, open the .rbf without FILE_SHARE_DELETE to prevent deletion.
    • Signal back and let the uninstaller finish.
    • Windows Installer cannot delete the .rbf or remove all the contents, so C:\Config.Msi is not deleted.
  • Step 5: Delete the .rbf manually

    • The attacker manually deletes the .rbf.
    • C:\Config.Msi is now empty, ready for the hijack.

At this point, trigger a SYSTEM-level arbitrary folder deletion vulnerability to delete C:\Config.Msi.

  1. Stage 2 – Replace the rollback script with a malicious one
  • Step 6: Recreate C:\Config.Msi with a weak ACL

    • Recreate C:\Config.Msi yourself.
    • Set a weak DACL (for example, Everyone:F) and keep a handle open with WRITE_DAC.
  • Step 7: Run another installation

    • Install the .msi again with these conditions:
      • TARGETDIR: A writable location.
      • ERROROUT: A variable that forces failure.
    • This triggers rollback again and causes .rbs / .rbf files to be read.
  • Step 8: Monitor the .rbs

    • Watch C:\Config.Msi with ReadDirectoryChangesW for a new .rbs.
    • Record its filename.
  • Step 9: Synchronize before rollback

    • Include a custom install action (SyncBeforeRollback) in the .msi:
      • Signal an event when the .rbs is created.
      • Then wait before continuing.
  • Step 10: Reapply the weak ACL

    • After receiving the .rbs created event:
      • Windows Installer reapplies a strong ACL to C:\Config.Msi.
      • But the handle opened with WRITE_DAC lets you reapply the weak ACL.

Because ACLs are enforced only when a handle is opened, writing to the folder remains possible.

  • Step 11: Place fake .rbs / .rbf files

    • Overwrite the .rbs with a fake rollback script that makes Windows:
      • Restore the .rbf (a malicious DLL) to a privileged path (for example, C:\Program Files\Common Files\microsoft shared\ink\HID.DLL).
    • Place a fake .rbf containing the malicious SYSTEM-level payload DLL.
  • Step 12: Trigger rollback

    • Signal the synchronization event to resume the installer.
    • Configure a type 19 custom action (ErrorOut) to deliberately fail the installation at a known time.
    • This starts rollback.
  • Step 13: SYSTEM installs the DLL

    • Windows Installer:
      • Reads the malicious .rbs.
      • Copies the .rbf DLL to the target location.
    • The malicious DLL is placed where a SYSTEM process will load it.
  • Final step: Execute code as SYSTEM

    • Run a trusted auto-elevated binary (for example, osk.exe) that loads the hijacked DLL.
    • Boom: Code runs as SYSTEM.

From file deletion, movement, or renaming rights to SYSTEM

Section titled “From file deletion, movement, or renaming rights to SYSTEM”

The MSI rollback technique above assumes you can delete an entire folder (for example, C:\Config.Msi). What if the vulnerability allows arbitrary file deletion only?

You can exploit NTFS internals. Every folder has a hidden alternate data stream named:

C:\SomeFolder::$INDEX_ALLOCATION

This stream stores the folder’s index metadata.

Therefore, deleting a folder’s ::$INDEX_ALLOCATION stream causes NTFS to delete the entire folder.

You can use a standard file deletion API:

DeleteFileW(L"C:\\Config.Msi::$INDEX_ALLOCATION");

Even though you call a file deletion API, the folder itself is deleted.

From deletion rights within a folder to SYSTEM

Section titled “From deletion rights within a folder to SYSTEM”

What if you cannot delete an arbitrary file or folder, but can delete the contents of an attacker-controlled folder?

  1. Step 1: Create a trap folder and file
  • Create: C:\temp\folder1
  • Inside it: C:\temp\folder1\file1.txt
  1. Step 2: Set an oplock on file1.txt
  • The oplock pauses execution when a privileged process tries to delete file1.txt.
// pseudo-code
RequestOplock("C:\\temp\\folder1\\file1.txt");
WaitForDeleteToTriggerOplock();
  1. Step 3: Trigger a SYSTEM process (for example, SilentCleanup)
  • It scans a folder (for example, %TEMP%) and tries to delete its contents.
  • When it reaches file1.txt, the oplock fires and returns control to the callback.
  1. Step 4: Redirect the deletion target in the oplock callback
  • Option A: Move file1.txt elsewhere

    • This empties folder1 but retains the oplock.
    • Do not delete file1.txt directly, because doing so releases the oplock too early.
  • Option B: Turn folder1 into a junction:

Terminal window
# folder1 is now a junction to \RPC Control (non-filesystem namespace)
mklink /J C:\temp\folder1 \\?\GLOBALROOT\RPC Control
  • Option C: Create a symlink in \RPC Control:
Terminal window
# Make file1.txt point to a sensitive folder stream
CreateSymlink("\\RPC Control\\file1.txt", "C:\\Config.Msi::$INDEX_ALLOCATION")

This targets the NTFS internal stream that stores the folder’s metadata. Deleting the stream deletes the folder.

  1. Step 5: Release the oplock
  • The SYSTEM process continues and attempts to delete file1.txt.
  • Because of the junction and symlink, it actually deletes:
C:\Config.Msi::$INDEX_ALLOCATION

Result: SYSTEM deletes C:\Config.Msi.

From arbitrary folder creation to persistent DoS

Section titled “From arbitrary folder creation to persistent DoS”

Abuse a primitive that lets you create an arbitrary folder as SYSTEM/admin (even without file writing or weak permission settings).

Create a folder (not a file) with the name of a critical Windows driver, for example:

C:\Windows\System32\cng.sys
  • Normally this path points to the cng.sys kernel-mode driver.
  • If you create a folder first, Windows cannot load the real driver at boot.
  • Windows attempts to load cng.sys during startup.
  • Because the folder exists, it cannot resolve the real driver and crashes or stops booting.
  • There is no fallback, and recovery requires external intervention (boot repair or disk access).

If you already run in a High Integrity process, the path to SYSTEM may be as simple as creating and starting a new service:

sc create newservicename binPath= "C:\windows\system32\notepad.exe"
sc start newservicename

[!TIP] When creating a service binary, make sure it is a valid service or performs its work quickly enough. An invalid service is killed after 20 seconds.

From a High Integrity process, you may be able to enable the AlwaysInstallElevated registry entries and install a reverse shell wrapped as an .msi.
See the relevant registry keys and how to install an .msi package.

From High Integrity and SeImpersonatePrivilege to SYSTEM

Section titled “From High Integrity and SeImpersonatePrivilege to SYSTEM”

Code here: https://book.hacktricks.wiki/en/windows-hardening/windows-local-privilege-escalation/seimpersonate-from-high-to-system.html

From SeDebugPrivilege and SeImpersonatePrivilege to full token rights

Section titled “From SeDebugPrivilege and SeImpersonatePrivilege to full token rights”

With these token privileges (often already present in a High Integrity process), SeDebug allows you to open almost any unprotected process, copy its token, and create any process with that token.
For this technique, the usual target is a SYSTEM process with all token rights (some SYSTEM processes do not have all token rights).
Implementation example: https://book.hacktricks.wiki/en/windows-hardening/windows-local-privilege-escalation/sedebug-+-seimpersonate-copy-token.html

Meterpreter’s getsystem uses this technique. Create a pipe and create or abuse a service to make it write to the pipe; a server with SeImpersonate can then impersonate the pipe client’s (the service’s) token and obtain SYSTEM privileges.
More on named pipes: Named Pipe Client Impersonation.
Example of moving from High Integrity to SYSTEM: https://book.hacktricks.wiki/en/windows-hardening/windows-local-privilege-escalation/from-high-integrity-to-system-with-name-pipes.html

If you can hijack a DLL loaded by a process running as SYSTEM, you can execute arbitrary code with that process’s privileges. DLL hijacking is useful for this kind of privilege escalation and is easier from a High Integrity process because it may have write access to DLL load folders.
Details: https://book.hacktricks.wiki/en/windows-hardening/windows-local-privilege-escalation/dll-hijacking/index.html

From Administrator or Network Service to SYSTEM

Section titled “From Administrator or Network Service to SYSTEM”

Expand privileges from LOCAL SERVICE / NETWORK SERVICE

Section titled “Expand privileges from LOCAL SERVICE / NETWORK SERVICE”

Read: https://github.com/itm4n/FullPowers