Penetration Testing Lab Setup
Build your own practice environments for penetration testing. From online platforms to home lab setups with vulnerable VMs and Active Directory networks.
Lab Comparison at a Glance
| Lab Type | RAM | Disk | Setup Time | Difficulty | Cost |
|---|---|---|---|---|---|
| Kali Setup | 4GB | 80GB | ~1 hr | Beginner | Free |
| Web App Lab | 2GB | 10GB | ~15 min | Beginner | Free |
| Vulnerable VMs | 4GB | 40GB | ~30 min | Beginner | Free |
| AD Lab | 16GB+ | 160GB | ~2 hrs | Intermediate | Free |
| Malware Lab | 8GB+ | 100GB | ~2 hrs | Intermediate | Free |
| Wireless Lab | 4GB | 20GB | ~1 hr | Intermediate | $30-60 |
| Purple Team / SIEM | 32GB+ | 200GB | ~3 hrs | Advanced | Free |
| CI/CD Pipeline | 8GB+ | 50GB | ~1 hr | Advanced | Free |
| Cloud Lab | 4GB | 20GB | ~1 hr | Advanced | $$ |
Recommended Lab Network Layout
NAT Network — Internet Access
10.0.0.0/24 • VMs can reach the internet for updates & cloud tools
Kali (Attacker)
.100
Cloud Tools
.200
CI/CD (Docker)
.201
Web Lab (Docker)
.202
Kali bridges both networks via dual NICs
Host-Only / Internal Network — Isolated
10.10.10.0/24 • No internet • Attack targets & detection
Kali (2nd NIC)
.100
DC01 (AD Lab)
.10
WS01 (Joined)
.20
SIEM (Wazuh/ELK)
.50
Use dual NICs on Kali: NAT for internet/updates, Host-Only for isolated lab attacks. Never expose vulnerable VMs to your home network.
Recommended Learning Path
Start with your attack machine, practice on web apps, then progress to enterprise, cloud, and detection environments.
Kali Setup
Attack machine ยท Free ยท ~1hr
Vulnerable VMs
Practice targets ยท Free ยท ~30min
Web App Lab
Docker web apps ยท Free ยท ~15min
AD Lab
Windows domain ยท Free ยท ~2hrs
Malware Lab
Analysis sandbox ยท Free ยท ~2hrs
Cloud Lab
AWS, Azure, GCP ยท $$ ยท ~1hr
Purple Team Lab
SIEM & detection ยท Free ยท ~3hrs
Wireless Lab
WiFi testing ยท $30-60 ยท ~1hr
CI/CD Lab
Pipeline security ยท Free ยท ~1hr
Online Learning Platforms
Hack The Box
Active machines to hack, both Windows and Linux. Pro Labs for enterprise environments.
- โ 200+ retired machines
- โ Active Directory labs
- โ Starting Point for beginners
- โ Academy for structured learning
TryHackMe
Beginner-friendly with guided rooms. Learning paths from basics to advanced.
- โ Guided walkthroughs
- โ Learning paths
- โ Browser-based AttackBox
- โ Great for beginners
PentesterLab
Web application security focused. Excellent for learning specific vulnerabilities.
- โ Web app focused
- โ Badge system progression
- โ Real-world scenarios
- โ API security labs
Proving Grounds
OffSec's practice platform. PG Play is free; PG Practice for OSCP prep.
offsec.com โHackMyVM
Free community-driven vulnerable VMs with flag submission and leaderboards.
hackmyvm.eu โCyberDefenders
Blue team/DFIR focused labs with real-world incident response challenges.
cyberdefenders.org โBuilding a Home Lab
Hardware Requirements
Budget Lab Hardware
Refurbished enterprise mini PCs are the best value for home labs:
- โข Dell OptiPlex Micro/SFF โ i5/i7, upgradeable to 64GB RAM, under $150 refurbished
- โข HP EliteDesk 800 G5/G6 โ compact, reliable, easy RAM/SSD upgrades
- โข Lenovo ThinkCentre M series โ similar specs, often available on eBay/Amazon Renewed
- โข Add a 1TB NVMe SSD (~$60) and 32-64GB RAM (~$50-90) for a complete lab under $300
Virtualization Setup
Choose a hypervisor that suits your operating system and needs:
VMware Workstation Pro
Free for personal use (since May 2024). Best compatibility, snapshots, and networking.
DownloadProxmox VE
Free bare-metal hypervisor. Runs VMs and containers, web UI, ideal for dedicated lab servers.
DownloadNetwork Configuration
Proper network isolation is crucial. Configure your hypervisor with the following networks:
- NAT Network: VMs can reach the internet but are isolated from your host LAN.
- Host-Only Network: VMs communicate with each other and the host, but no internet.
- Internal Network: Completely isolated VM-to-VM communication.
Kali Linux Attack Machine
Download the official VM image from kali.org. Once installed, run the following commands to set up your environment:
# Update system
sudo apt update && sudo apt upgrade -y
# Install additional tools
sudo apt install -y \
gobuster feroxbuster \
bloodhound neo4j \
netexec evil-winrm \
seclists \
docker.io docker-compose-v2
# Enable services
sudo systemctl enable ssh
sudo systemctl start ssh
sudo systemctl enable postgresql
sudo systemctl start postgresql
# Initialize Metasploit database
sudo msfdb init
# Create directory structure
mkdir -p ~/engagements/client_name/{recon,scans,exploits,loot,notes}
# Clone useful repos
git clone https://github.com/danielmiessler/SecLists ~/tools/SecLists
git clone https://github.com/carlospolop/PEASS-ng ~/tools/PEASS-ng
git clone https://github.com/samratashok/nishang ~/tools/nishang
# Install Python tools via pipx (isolated environments)
pipx install impacket
pipx install netexec
# Start BloodHound CE
sudo neo4j console &
bloodhound
# Or use BloodHound Community Edition (Docker):
# curl -L https://ghst.ly/getbhce | docker compose -f - up# Update system
sudo apt update && sudo apt upgrade -y
# Install additional tools
sudo apt install -y \
gobuster feroxbuster \
bloodhound neo4j \
netexec evil-winrm \
seclists \
docker.io docker-compose-v2
# Enable services
sudo systemctl enable ssh
sudo systemctl start ssh
sudo systemctl enable postgresql
sudo systemctl start postgresql
# Initialize Metasploit database
sudo msfdb init
# Create directory structure
mkdir -p ~/engagements/client_name/{recon,scans,exploits,loot,notes}
# Clone useful repos
git clone https://github.com/danielmiessler/SecLists ~/tools/SecLists
git clone https://github.com/carlospolop/PEASS-ng ~/tools/PEASS-ng
git clone https://github.com/samratashok/nishang ~/tools/nishang
# Install Python tools via pipx (isolated environments)
pipx install impacket
pipx install netexec
# Start BloodHound CE
sudo neo4j console &
bloodhound
# Or use BloodHound Community Edition (Docker):
# curl -L https://ghst.ly/getbhce | docker compose -f - upRecommended Vulnerable VMs
Linux VMs
- Metasploitable 2/3
Classic intentionally vulnerable VM
- DVWA (Damn Vulnerable Web App)
Web vulnerabilities - SQLi, XSS, etc.
- bWAPP
100+ web vulnerabilities
- VulnHub Machines
Kioptrix, Mr. Robot, Stapler
Windows VMs
- Windows 10/11 Eval
90-day evaluation licenses from Microsoft
- Windows Server Eval
180-day eval for AD labs
- Yourcomputer (VulnHub)
Vulnerable Windows machine
- YOURCOMPANY
HTB-style Windows targets
# Quick Vulnerable Web App Setup with Docker
# DVWA
docker run -d -p 80:80 vulnerables/web-dvwa
# Access at http://localhost
# Login: admin/password
# bWAPP
docker run -d -p 8080:80 raesene/bwapp
# Access at http://localhost:8080/install.php
# OWASP Juice Shop
docker run -d -p 3000:3000 bkimminich/juice-shop
# Access at http://localhost:3000
# WebGoat (OWASP)
docker run -d -p 8081:8080 -p 9090:9090 webgoat/webgoat
# Access at http://localhost:8081/WebGoat
# SQLi-labs
docker run -d -p 8082:80 acgpiano/sqli-labs
# Access at http://localhost:8082
# NodeGoat
docker run -d -p 4000:4000 owasp/nodegoat
# Access at http://localhost:4000
# Run multiple with docker compose
cat > docker-compose.yml << 'EOF'
services:
dvwa:
image: vulnerables/web-dvwa
ports:
- "80:80"
juiceshop:
image: bkimminich/juice-shop
ports:
- "3000:3000"
webgoat:
image: webgoat/webgoat
ports:
- "8080:8080"
- "9090:9090"
EOF
docker compose up -d# Quick Vulnerable Web App Setup with Docker
# DVWA
docker run -d -p 80:80 vulnerables/web-dvwa
# Access at http://localhost
# Login: admin/password
# bWAPP
docker run -d -p 8080:80 raesene/bwapp
# Access at http://localhost:8080/install.php
# OWASP Juice Shop
docker run -d -p 3000:3000 bkimminich/juice-shop
# Access at http://localhost:3000
# WebGoat (OWASP)
docker run -d -p 8081:8080 -p 9090:9090 webgoat/webgoat
# Access at http://localhost:8081/WebGoat
# SQLi-labs
docker run -d -p 8082:80 acgpiano/sqli-labs
# Access at http://localhost:8082
# NodeGoat
docker run -d -p 4000:4000 owasp/nodegoat
# Access at http://localhost:4000
# Run multiple with docker compose
cat > docker-compose.yml << 'EOF'
services:
dvwa:
image: vulnerables/web-dvwa
ports:
- "80:80"
juiceshop:
image: bkimminich/juice-shop
ports:
- "3000:3000"
webgoat:
image: webgoat/webgoat
ports:
- "8080:8080"
- "9090:9090"
EOF
docker compose up -dActive Directory Lab Setup
Lab Requirements
- Domain Controller: Windows Server 2019/2022 (4GB RAM)
- Workstations: 2x Windows 10/11 (2GB RAM each)
- Attacker: Kali Linux (4GB RAM)
- Total RAM: ~12GB minimum
Network Configuration
Use a static IP scheme on an isolated network:
- DC01: 10.0.0.1
- WS01: 10.0.0.10
- WS02: 10.0.0.11
- Kali: 10.0.0.100
# ==========================================
# Step 1: Domain Controller Setup
# ==========================================
# Open PowerShell as Admin
# Set computer name
Rename-Computer -NewName DC01 -Restart
# Install AD DS role
Install-WindowsFeature -Name AD-Domain-Services -IncludeManagementTools
# Promote to Domain Controller
Install-ADDSForest -DomainName "lab.local" -DomainNetbiosName "LAB" -InstallDns
# After restart, create users and groups
Import-Module ActiveDirectory
# Create OUs
New-ADOrganizationalUnit -Name "Lab Users" -Path "DC=lab,DC=local"
New-ADOrganizationalUnit -Name "Lab Computers" -Path "DC=lab,DC=local"
New-ADOrganizationalUnit -Name "Lab Groups" -Path "DC=lab,DC=local"
# Create users with weak passwords (for testing)
$users = @(
@{Name="John Smith"; SamAccountName="jsmith"; Password="Password123!"},
@{Name="Jane Doe"; SamAccountName="jdoe"; Password="Summer2026!"},
@{Name="Admin User"; SamAccountName="admin.user"; Password="Admin@123"},
@{Name="Service Account"; SamAccountName="svc_sql"; Password="SQLService1!"}
)
foreach ($user in $users) {
New-ADUser -Name $user.Name -SamAccountName $user.SamAccountName -UserPrincipalName "$($user.SamAccountName)@lab.local" -AccountPassword (ConvertTo-SecureString $user.Password -AsPlainText -Force) -Enabled $true -PasswordNeverExpires $true -Path "OU=Lab Users,DC=lab,DC=local"
}
# Create groups
New-ADGroup -Name "IT Admins" -GroupScope Global -Path "OU=Lab Groups,DC=lab,DC=local"
New-ADGroup -Name "HR" -GroupScope Global -Path "OU=Lab Groups,DC=lab,DC=local"
# Add users to groups
Add-ADGroupMember -Identity "IT Admins" -Members "admin.user"
Add-ADGroupMember -Identity "Domain Admins" -Members "admin.user"
# ==========================================
# Step 2: Configure Vulnerabilities
# ==========================================
# Kerberoastable user (SPN)
setspn -a MSSQLSvc/dc01.lab.local:1433 svc_sql
# AS-REP Roastable user
Set-ADAccountControl -Identity jdoe -DoesNotRequirePreAuth $true
# SMB Signing disabled (via Registry for lab simplicity)
Set-ItemProperty -Path "HKLM:\System\CurrentControlSet\Services\LanmanServer\Parameters" -Name "requiresecuritysignature" -Value 0
# ==========================================
# Step 3: Join Workstations (Run on Workstation)
# ==========================================
# Set DNS to DC IP
Set-DnsClientServerAddress -InterfaceAlias "Ethernet0" -ServerAddresses "10.0.0.1"
# Join Domain
Add-Computer -DomainName "lab.local" -Restart# ==========================================
# Step 1: Domain Controller Setup
# ==========================================
# Open PowerShell as Admin
# Set computer name
Rename-Computer -NewName DC01 -Restart
# Install AD DS role
Install-WindowsFeature -Name AD-Domain-Services -IncludeManagementTools
# Promote to Domain Controller
Install-ADDSForest -DomainName "lab.local" -DomainNetbiosName "LAB" -InstallDns
# After restart, create users and groups
Import-Module ActiveDirectory
# Create OUs
New-ADOrganizationalUnit -Name "Lab Users" -Path "DC=lab,DC=local"
New-ADOrganizationalUnit -Name "Lab Computers" -Path "DC=lab,DC=local"
New-ADOrganizationalUnit -Name "Lab Groups" -Path "DC=lab,DC=local"
# Create users with weak passwords (for testing)
$users = @(
@{Name="John Smith"; SamAccountName="jsmith"; Password="Password123!"},
@{Name="Jane Doe"; SamAccountName="jdoe"; Password="Summer2026!"},
@{Name="Admin User"; SamAccountName="admin.user"; Password="Admin@123"},
@{Name="Service Account"; SamAccountName="svc_sql"; Password="SQLService1!"}
)
foreach ($user in $users) {
New-ADUser -Name $user.Name -SamAccountName $user.SamAccountName -UserPrincipalName "$($user.SamAccountName)@lab.local" -AccountPassword (ConvertTo-SecureString $user.Password -AsPlainText -Force) -Enabled $true -PasswordNeverExpires $true -Path "OU=Lab Users,DC=lab,DC=local"
}
# Create groups
New-ADGroup -Name "IT Admins" -GroupScope Global -Path "OU=Lab Groups,DC=lab,DC=local"
New-ADGroup -Name "HR" -GroupScope Global -Path "OU=Lab Groups,DC=lab,DC=local"
# Add users to groups
Add-ADGroupMember -Identity "IT Admins" -Members "admin.user"
Add-ADGroupMember -Identity "Domain Admins" -Members "admin.user"
# ==========================================
# Step 2: Configure Vulnerabilities
# ==========================================
# Kerberoastable user (SPN)
setspn -a MSSQLSvc/dc01.lab.local:1433 svc_sql
# AS-REP Roastable user
Set-ADAccountControl -Identity jdoe -DoesNotRequirePreAuth $true
# SMB Signing disabled (via Registry for lab simplicity)
Set-ItemProperty -Path "HKLM:\System\CurrentControlSet\Services\LanmanServer\Parameters" -Name "requiresecuritysignature" -Value 0
# ==========================================
# Step 3: Join Workstations (Run on Workstation)
# ==========================================
# Set DNS to DC IP
Set-DnsClientServerAddress -InterfaceAlias "Ethernet0" -ServerAddresses "10.0.0.1"
# Join Domain
Add-Computer -DomainName "lab.local" -RestartAutomated Lab Deployment
GOAD (Game of AD)
Full AD lab with multiple forests, trusts, and vulnerabilities. Deploy with Vagrant.
GitHub: Orange-Cyberdefense/GOAD โLudus
Automated lab platform by Badsector Labs. Deploy AD, Linux, and security tooling with Proxmox.
docs.ludus.cloud โGOAD Installation
Requires Vagrant and a provider (VirtualBox, VMware, etc.).
# Clone GOAD repository
git clone https://github.com/Orange-Cyberdefense/GOAD.git
cd GOAD
# Install python dependencies
pip install ansible pywinrm
# Deploy with Vagrant (VirtualBox provider)
cd ad/GOAD/providers/virtualbox
vagrant up# Clone GOAD repository
git clone https://github.com/Orange-Cyberdefense/GOAD.git
cd GOAD
# Install python dependencies
pip install ansible pywinrm
# Deploy with Vagrant (VirtualBox provider)
cd ad/GOAD/providers/virtualbox
vagrant upLudus Installation
# Ludus requires a dedicated Proxmox server
# Install via the official installer:
curl -s https://ludus.cloud/install | bash
# Configure your first range
ludus range config get > config.yml
# Edit config.yml to define your lab VMs
ludus range config set -f config.yml
# Deploy the range
ludus range deploy
# Check status
ludus range status# Ludus requires a dedicated Proxmox server
# Install via the official installer:
curl -s https://ludus.cloud/install | bash
# Configure your first range
ludus range config get > config.yml
# Edit config.yml to define your lab VMs
ludus range config set -f config.yml
# Deploy the range
ludus range deploy
# Check status
ludus range statusLab Best Practices
Lab Maintenance & Lifecycle
๐ Regular Maintenance
- โข Weekly: Update Kali tools (
sudo apt update && sudo apt upgrade) - โข Monthly: Snapshot VMs in clean state before major changes
- โข Quarterly: Rebuild from scratch to practice setup and avoid config drift
- โข After testing: Revert to clean snapshots โ don't let exploits persist
๐พ Snapshot Strategy
- โข Base Install: Clean OS with updates applied
- โข Configured: All tools installed, services running
- โข Vulnerable: Intentional misconfigs added (for labs)
- โข Pre-Engagement: Right before running specific attacks
Export & Share Lab Configs
Export your lab VMs as OVA files for backup, sharing with teammates, or rebuilding on different hardware.
# VMware - Export from GUI:
# File > Export to OVF > Choose OVA format
# VirtualBox - Export from CLI:
VBoxManage export "Kali-Lab" -o kali-lab.ova
VBoxManage export "DC01" -o dc01-lab.ova
VBoxManage export "WS01" -o ws01-lab.ova
# Import on another machine:
VBoxManage import kali-lab.ova
# Compress for sharing (OVAs can be large):
# Windows
Compress-Archive -Path *.ova -DestinationPath lab-export.zip
# Linux
tar czf lab-export.tar.gz *.ova# VMware - Export from GUI:
# File > Export to OVF > Choose OVA format
# VirtualBox - Export from CLI:
VBoxManage export "Kali-Lab" -o kali-lab.ova
VBoxManage export "DC01" -o dc01-lab.ova
VBoxManage export "WS01" -o ws01-lab.ova
# Import on another machine:
VBoxManage import kali-lab.ova
# Compress for sharing (OVAs can be large):
# Windows
Compress-Archive -Path *.ova -DestinationPath lab-export.zip
# Linux
tar czf lab-export.tar.gz *.ovaInfrastructure as Code Alternative
Related Topics
Web Pentesting
Test web vulnerabilities on DVWA, Juice Shop, and more.
AD Attack Paths
Practice Kerberos attacks in GOAD and Ludus.
DFIR
Digital forensics and incident response with lab data.
Binary Exploitation
Build CTF challenge environments for pwn practice.
Internal Network
Simulate full enterprise networks for internal assessments.