AD Testing Checklist

Below are the things you should check on every Active Directory assessment

Shortlist

Short bullet point to jog your memory. If this is not enough, click on the check to get full notes.

Extra Attacks

  1. Coercion Attacks

    1. Local Network Poising

    2. IPv6 MITM

    3. Stale Half-Duplex ARP

    4. WPAD

    5. WebDAV

    6. LNK file drop

  2. ADIDNS Wildcard Attack (Dangerous and not well understood)


Confirm AD Access (Linux)

Define Shell Variables (Bash)

read -p "Username of Active Directory account: " ADUSER;echo
read -p "Domain of Active Directory account: " ADDOMAIN;echo
read -p "Primary domain controller IP of target domain: " ADCONTROLLER;echo
read -p "Target IP/CIDR list file path: " TARGETS;echo
alias PSWPRMPT='read -sp "Password: " PSW; echo $PSW'

Define Shell Variables (zsh)

vared -p 'Username of Active Directory account: ' -c ADUSER;echo
vared -p 'Domain of Active Directory account: ' -c ADDOMAIN;echo
vared -p 'Primary domain controller IP of target domain: ' -c ADCONTROLLER;echo
vared -p 'Target IP/CIDR list file path: ' -c TARGETS;echo
alias PSWPRMPT='read -rs "PSW?Password: ";echo $PSW'

If you define the above variables, you can just copy and paste the below command into the terminal

Sync Clock to Domain Controller

sudo apt install ntpdate -y
sudo ntpdate $ADCONTROLLER

Syncing the clock to the domain controller is VERY important for Kerberos and tools that utilize Kerberos

Check access (NTLM)

impacket-GetADUsers $ADDOMAIN/$ADUSER -dc-ip $ADCONTROLLER

Check access (Kerberos)

# Get Kerberos TGT
impacket-getTGT $ADDOMAIN/$ADUSER -dc-ip $ADCONTROLLER
export KRB5CCNAME=$(realpath $ADUSER.ccache)

# Make call using TGT
impacket-GetADUsers $ADDOMAIN/$ADUSER -dc-ip $ADCONTROLLER -k -no-pass

If you are getting the error:Kerberos SessionError: KRB_AP_ERR_SKEW(Clock skew too great), you need to sync your local lock to the DC. You can do this with sudo ntpdate $ADCONTROLLER


Search for abusable ACLs (Bloodhound)

To search for abuseable ACLs, Bloodhound is the tool of choice. For further informational about how to analyze the information once you collect it, see Analyzing Data with Bloodhound.

Install Bloodhound.py

sudo apt install bloodhound.py

Collect Data (NTLM)

bloodhound-python -u $ADUSER -d $ADDOMAIN -c All --zip

Collect Data (Kerberos)

bloodhound-python -u $ADUSER -d $ADDOMAIN -p "" -k --auth-method kerberos -no-pass -c All --zip

The above has given me some issues during testing and sometimes reverted to NTLM instead of Kerberos. If you have issues, try using the NTLM version which will often attempt to use Kerberos regardless.

Collect Data (w/ Channel Binding)

The current Bloodhound.py does not support connection to LDAPS that has channel binding. In my experience, it will throw a vague issue related to a failed connection or invalid address (ldap3.core.exceptions.LDAPSocketOpenError: invalid server address). There is a pull request out there that fixes this issue but it has not been merged so far (it has been waiting about half a year). Therefore, you will have to manually install a forked version from deadjakk that supports channel binding. You will also need a forked version of LDAP3 to run the forked version of bloodhound.py.

sudo apt remove bloodhound.py -y
mkdir bloodhound-new
cd bloodhound-new
virtualenv venv
source ./venv/bin/activate
git clone https://github.com/deadjakk/BloodHound.py.git
cd BloodHound.py
pip3 install .
pip3 install git+https://github.com/ly4k/ldap3  # Fork of ldap3 needed
bloodhound-python -u $ADUSER -d $ADDOMAIN -c All --zip --ldap-channel-binding

Search for passwords in user descriptions

Run the following commands against the unzipped Bloodhound.py output

Install JQ

sudo apt install jq -y

Search for quick hits

cat *users.json | jq . | grep -E '"description":|"name":|"AllowedToDelegate":' | sed 's/"AllowedToDelegate": \[\],//g' | tr -d '",' | grep -B 1 -iE "password|pw"

List sorted user descriptions (Full Review)

cat *users.json | jq . | grep -E '"description":' | sed 's/"description": //g' | tr -d '",' | sort -u

Search for Kerberoastable accounts

Search for all SPNs in the domain that are vulnerable to Kerberoasting. For exploit information, see Kerberoasting.

Searching for affected accounts can also be done easily using Bloodhound

Check for affected accounts (NTLM)

impacket-GetUserSPNs $ADDOMAIN/$ADUSER -dc-ip $ADCONTROLLER

Check for affected accounts (Kerberos)

impacket-GetUserSPNs $ADDOMAIN/$ADUSER -no-pass -k -dc-ip $ADCONTROLLER

Search for As-Rep Roastable accounts

Search for all user accounts that do not require pre-authentication. For exploit information, see As-Rep Roasting.

Check for affected accounts (NTLM)

impacket-GetNPUsers $ADDOMAIN/$ADUSER -dc-ip $ADCONTROLLER

Check for affected accounts (Kerberos)

impacket-GetNPUsers $ADDOMAIN/$ADUSER -no-pass -k -dc-ip $ADCONTROLLER

Check for default Machine Account Quota

Get Machine Account Quota (NTLM)

nxc ldap $ADCONTROLLER -M maq -u $ADUSER -d $ADDOMAIN -p $(PSWPRMPT) --log MAQ.log;PSW=""

Get Machine Account Quota (Kerberos)

nxc ldap $ADCONTROLLER -M maq -k --use-kcache --log MAQ.log

Get Machine Account Quota (NTLM) - Alternate

ldapsearch -x -H ldap://$ADCONTROLLER -b 'DC=<DOMAIN NAME>,DC=<DOMAIN TLD>' -D "$ADUSER@$ADDOMAIN" -W -s sub "(objectclass=domain)" | grep ms-DS-MachineAccountQuota 

Check password policy

Get Password Policy (NTLM)

nxc smb $ADCONTROLLER -u $ADUSER -d $ADDOMAIN -p $(PSWPRMPT) --pass-pol --log PassPol.log;PSW=""

Note that $(read -sp "PWD: " PWD;echo $PWD) is used to prompt for a password instead of putting it into the terminal. However, this leaves a cleartext password in the $PWD variable in the current shell sessions, so it is overwritten using PWD="" at the end of the command.


Check for active WebDAV clients

Method 1 (WebClientScanner) - Faster

Install

pipx install git+https://github.com/Hackndo/WebclientServiceScanner
source ~/.zshrc

NTLM

webclientservicescanner $ADDOMAIN/$ADUSER@$TARGETS -dc-ip $ADCONTROLLER | tee WebDAV-Scan.txt

Kerberos

webclientservicescanner $ADDOMAIN/$ADUSER@$TARGETS -no-pass -k -dc-ip $ADCONTROLLER | tee WebDAV-Scan.txt

Method 2 (NetExec) - CSV Output

Scan hosts

nxc smb $TARGETS -M webdav -u "$ADUSER" -d "$ADDOMAIN" -p $(PSWPRMPT) --log WebDAV.log;PSW=""

Create affected host CSV

cat WebDAV.log | grep -a WEBDAV | grep -vE 'STATUS_ACCESS_DENIED|STATUS_OBJECT_PATH_NOT_FOUND' | awk -F' ' 'NR==1{print "IP(s),Hostname,Port"};{print $9","$11","$10"/tcp"}' > WebDAV-Service-Enabled.csv

Check for missing SMB signing

nxc smb $TARGETS --log Missing-SMB-Signing.log
grep "signing:False" Missing-SMB-Signing.log

Check for SMBv1 Support

nxc smb $TARGETS --log SMBv1-Support.log
grep "SMBv1:True" SMBv1-Support.log

Check for writable shares

NTLM

nxc smb $TARGETS -u $ADUSER -d $ADDOMAIN -p $(PSWPRMPT) --shares --log SMB-Shares.log;PSW=""
grep "WRITE" SMB-Shares.log

Check for sensitive data in shares

Collect Info (NTLM)

nxc smb $TARGETS -u $ADUSER -d $ADDOMAIN -p $(PSWPRMPT) -M spider_plus;PSW=""

See Searching SMB Shares for info on how to search these results


Check for anonymous access

nxc smb $TARGETS -u " " -p " " --local-auth --shares --log Anonymous-SMB.log

Check LDAP Configuration

NTLM

nxc ldap <FILE LIST OF DCs> -M ldap-checker -u $ADUSER -d $ADDOMAIN -p $(PSWPRMPT) --log LDAP-Signing_Binding.log;PSW=""

Check MsSQL Configuration

Install MsSQLRelay

pipx install git+https://github.com/CompassSecurity/mssqlrelay

Run all checks (Coercion, Command Execution, Signing)

mssqlrelay checkall -scheme ldap -target $ADDOMAIN -ns $ADCONTROLLER -u $ADUSER@$ADDOMAIN | tee MsSQL_Search.txt

Look for the following vulnerabilities

  • Missing Signing/Channel Binding = Encryption: not enforced

  • Coercible = Privileges: ['xp_dirtree', 'xp_fileexist'] (Either one)

  • Command Execution: Privileges: ['xp_cmdshell'] (I'm not sure if mssqlrelay checks for this)

Additional info is needed on checking for Impersonation and Server Links (Impacket's MsSQL module will be used to perform checks)


Check ADCS Configuration

Install Certipy

pipx install git+https://github.com/ly4k/Certipy.git

Run all checks

certipy find -u "$ADUSER@$ADDOMAIN" -dc-ip $ADCONTROLLER -stdout -vulnerable | tee ADCS-Vuln.txt

Check for CA when Certipy does not find CA

nxc smb $TARGETS -u $ADUSER -d $ADDOMAIN -p $(PSWPRMPT) --shares --log ADCS.log;PSW=""
grep ADCS.log | grep -i "cert"

Exploit Information can be found at ADCS Exploitation


Check SCCM Configuration

A new tool called SCCHound was recently released and could make this process easier. Once I test it I will add notes here.

Install Tools

# Install SCCMHuneter
git clone https://github.com/garrettfoster13/sccmhunter.git
cd sccmhunter
chmod +x *.py
virtualenv venv
source ./venv/bin/activate
pip install -r requirements.txt
cd ../

# Install PXETheif
git clone https://github.com/MWR-CyberSec/PXEThief
cd PXEThief
sed -i '/pywin32>=303/d' requirements.txt  # This module is not supported on linux
pip install -r requirements.txt
cd ../

Find SCCM Server (w/ SCCMHunter)

python3 sccmhunter/sccmhunter.py find -u $ADUSER -d $ADDOMAIN -dc-ip $ADCONTROLLER

Search for SCCM user accounts (Bloodhound data)

cat *users.json | jq -r .data[].Properties.name | grep -Ei 'naa|sccm|client.push'

Send PXE Boot Request via DHCP (PXEThief)

sudo python3 PXEThief/pxethief.py 1

This will not only send the request, but also auto exploit by downloading the encrypted media file and attempting to steal data if there is no password.

If you know the SCCM server IP, you can use: pxethief.py 2 <SCCM SERVER IP>

Check for Open SCCM Ports

sudo nmap -sS -iL $TARGETS -T4 --open -oA Nmap_SCCM_TCP_Scan_$(date +"%b-%d-%Y") -p 8530-8531,49152-49159,10123
sudo nmap -sU -iL $TARGETS -T4 --open -oA Nmap_SCCM_UDP_Scan_$(date +"%b-%d-%Y") -p 4011

# Search for hits
cat Nmap_SCCM_*_Scan_*.gnmap | grep open | grep -vE "filtered|scan initiated" 

It's not uncommon to see a lot of these ports open even when SCCM is not enabled. Check the output carefully

Last updated