Build Your Hacking Lab
By the end of this lesson you will have a working practice lab: three virtual machines on a private network, with snapshots you can roll back to in seconds. You will also write a Python check that warns you if any vulnerable machine is connected to a real network.
The Cyber Security course lesson Build a Safe Practice Lab explains hypervisors, network modes and how to start Juice Shop and DVWA in Docker. Read it first. This lesson builds on it by adding a third target, Metasploitable 2, fixing the exact addresses used in every later lesson, and adding safety checks.
The lab plan
Think of the lab as a cricket practice net. The net keeps the ball inside, so you can bat as hard as you like without breaking a neighbour's window. The host-only network is your net.
| VM | Operating system | Address | What runs there |
|---|---|---|---|
kali | Kali Linux | 192.168.56.102 | Nmap, Burp Suite Community, Metasploit, Python |
web-target | Ubuntu Server | 192.168.56.101 | Juice Shop on tcp/3000, DVWA on tcp/4280 |
msf2 | Metasploitable 2 | 192.168.56.103 | Many deliberately weak network services |
The host computer is 192.168.56.1 on this network. It is out of scope: you never test your own laptop from the lab.
Hardware guide: Kali needs about 2 GB of RAM, the Ubuntu target 2 GB, and Metasploitable 2 only 512 MB. A 16 GB laptop runs all three comfortably. With 8 GB, run two at a time.
What the practice targets are
All three targets are made for training. They are not copies of real products you found somewhere.
- OWASP Juice Shop is an intentionally insecure web shop from OWASP, used for security training, demos and capture-the-flag events. It covers the OWASP Top 10 and many other flaws, and tracks your progress on a hidden score board.
- DVWA (Damn Vulnerable Web Application) is a PHP and MariaDB app built so people can practise in a legal environment. Its README warns never to upload it to a hosting provider or any internet-facing server.
- Metasploitable 2 is an intentionally vulnerable Ubuntu Linux VM published by Rapid7, the company behind Metasploit. Rapid7's guide says the image should never be exposed to a hostile network. Its default login is
msfadmin/msfadmin.
Step by step: create the network and VMs
Step 1. Check the host-only network. In VirtualBox, open File > Tools > Network Manager and confirm a host-only network with address 192.168.56.1/24 and its DHCP server enabled. From a Windows host you can also list it:
& "C:\Program Files\Oracle\VirtualBox\VBoxManage.exe" list hostonlyifsYou should see a Name: line (on Windows usually VirtualBox Host-Only Ethernet Adapter) and IPAddress: 192.168.56.1.
That output is long, so here is a small Python check you can reuse. It reads saved text in the same Key: value layout and confirms the lab network. The sample below is shortened:
import ipaddress
saved = """Name: VirtualBox Host-Only Ethernet Adapter
IPAddress: 192.168.56.1
NetworkMask: 255.255.255.0
Status: Up"""
info = {}
for line in saved.splitlines():
key, _, value = line.partition(":")
info[key.strip()] = value.strip()
net = ipaddress.ip_network(f"{info['IPAddress']}/{info['NetworkMask']}", strict=False)
print("Adapter:", info["Name"])
print("Lab network:", net)
print("Matches course lab:", net == ipaddress.ip_network("192.168.56.0/24"))
print("Status:", info["Status"])Adapter: VirtualBox Host-Only Ethernet Adapter Lab network: 192.168.56.0/24 Matches course lab: True Status: Up
partition(":") splits each line at the first colon only, and strict=False lets ipaddress turn a host address plus mask into the network it belongs to.
Step 2. Import Kali and install the Ubuntu target as described in the Cyber Security lab lesson. Give each two adapters during setup: adapter 1 NAT (for updates), adapter 2 host-only. DVWA's compose.yml publishes the app as 127.0.0.1:4280:80, which only the Ubuntu VM itself can reach. Change that line to 192.168.56.101:4280:80 so Kali can reach it, and nothing outside the lab can.
Step 3. Download Metasploitable 2 from Rapid7's official documentation link, unzip it, and create a new Linux VM that uses the existing virtual disk. Give it only a host-only adapter, never NAT. It needs no updates; its whole point is being outdated.
Step 4. Set Metasploitable's adapter from the command line, which is quicker than clicking (use your own VM and adapter names):
& "C:\Program Files\Oracle\VirtualBox\VBoxManage.exe" modifyvm "msf2" --nic1 hostonly --hostonlyadapter1 "VirtualBox Host-Only Ethernet Adapter"Step 5. Start each VM and confirm its address. On Metasploitable, log in and run ip addr (or ifconfig, which this old image has). If DHCP gives different addresses, either use those throughout the course or set static ones.
Step 6. When the Ubuntu target is fully set up, remove its NAT adapter. From now on, only Kali keeps NAT, and you switch it off during testing sessions.
Step by step: snapshots
A snapshot saves a VM's complete state. Testing will break things: a crashed service, a changed password, a full disk. With a snapshot you restore the clean state in seconds, like a tiffin box you can refill fresh every morning.
& "C:\Program Files\Oracle\VirtualBox\VBoxManage.exe" snapshot "web-target" take "clean-2026-11" --description "Juice Shop and DVWA freshly installed"
& "C:\Program Files\Oracle\VirtualBox\VBoxManage.exe" snapshot "web-target" listTake a snapshot of every VM when it is clean. Before each practice session, restore it. Before any risky test, take another.
Checking the lab is isolated
Most lab accidents come from a forgotten adapter setting. Write down each VM's adapters in a small inventory, then let Python check it. Here the inventory has one deliberate mistake:
lab = {
"kali": {"role": "attacker", "adapters": ["nat", "hostonly"]},
"web-target": {"role": "target", "adapters": ["hostonly"]},
"msf2": {"role": "target", "adapters": ["bridged"]},
}
SAFE_FOR_TARGETS = {"hostonly", "internal"}
for name, vm in lab.items():
risky = [a for a in vm["adapters"] if a not in SAFE_FOR_TARGETS]
if vm["role"] == "target" and risky:
print(f"DANGER {name}: target VM uses {', '.join(risky)}")
elif vm["role"] == "attacker" and "nat" in vm["adapters"]:
print(f"note {name}: disable NAT during testing sessions")
else:
print(f"ok {name}")note kali: disable NAT during testing sessions ok web-target DANGER msf2: target VM uses bridged
Fix msf2 to hostonly and run it again. You should see ok for both targets.
Next, check reachability from Kali. These commands should succeed for lab targets:
ping -c 2 192.168.56.103
curl -s -o /dev/null -w "%{http_code}\n" http://192.168.56.101:3000
curl -s -o /dev/null -w "%{http_code}\n" http://192.168.56.101:4280/login.phpExample output from the course lab (timings will differ):
PING 192.168.56.103 (192.168.56.103) 56(84) bytes of data. 64 bytes from 192.168.56.103: icmp_seq=1 ttl=64 time=0.412 ms 64 bytes from 192.168.56.103: icmp_seq=2 ttl=64 time=0.388 ms --- 192.168.56.103 ping statistics --- 2 packets transmitted, 2 received, 0% packet loss, time 1002ms rtt min/avg/max/mdev = 0.388/0.400/0.412/0.012 ms 200 200
Two 200 codes mean Juice Shop and the DVWA login page answer. Finally, prove the targets cannot reach the internet. On Metasploitable, ping -c 2 8.8.8.8 should fail with "Network is unreachable". That failure is the result you want.
Keeping the lab organised
Record your lab in a short table you update after every change: VM name, address, snapshot names, and default passwords you changed. Keep the lab on a separate folder or drive. When a session ends, shut down the targets rather than leaving them running.
Common mistakes
- Giving Metasploitable a NAT or bridged adapter "just for a minute". It needs neither. Host-only only.
- Assuming addresses. DHCP may hand out different ones. Check with
ip addrevery time. - No clean snapshot. Without one, a broken target means reinstalling from scratch.
- Testing the host at
192.168.56.1. It is your real laptop and is out of scope.
Key points
- The course lab has three VMs on
192.168.56.0/24: Kali (.102), the web target (.101) and Metasploitable 2 (.103). - Juice Shop, DVWA and Metasploitable 2 are intentionally vulnerable training targets and must never face a real network.
- Targets use only host-only or internal adapters; Kali's NAT adapter is off while testing.
- Take a clean snapshot of every VM and restore it before practice sessions.
- Check isolation: targets must reach each other but not the internet.
Exercise
Write a Python function lab_report(lab) that takes an inventory like the one above, plus a "snapshot" key holding the name of the clean snapshot (or an empty string). Print MISSING SNAPSHOT for any VM without one, in addition to the adapter checks.
Show solution
def lab_report(lab):
for name, vm in lab.items():
problems = []
if vm["role"] == "target" and any(a not in {"hostonly", "internal"} for a in vm["adapters"]):
problems.append("UNSAFE ADAPTER")
if not vm.get("snapshot"):
problems.append("MISSING SNAPSHOT")
print(f"{name:<11} {', '.join(problems) or 'ok'}")
lab_report({
"kali": {"role": "attacker", "adapters": ["hostonly"], "snapshot": "clean"},
"web-target": {"role": "target", "adapters": ["hostonly"], "snapshot": ""},
"msf2": {"role": "target", "adapters": ["nat"], "snapshot": "clean"},
})It prints ok for kali, MISSING SNAPSHOT for web-target and UNSAFE ADAPTER for msf2. Collecting problems in a list lets one VM show several issues at once.
Quick Quiz
1. Which network mode should Metasploitable 2 use?
Host-only keeps it reachable from Kali but away from the internet and other devices.
2. Why take a snapshot of a clean target VM?
Snapshots save the whole machine state for quick rollback.
3. In this course's lab, what is 192.168.56.1?
The hypervisor's host-only adapter is your real laptop; you never test it.
4. Which result proves a target is isolated?
Targets should reach other lab machines but fail to reach the internet.
Learn Ethical Hacking with a mentor
Free lessons get you started. Our Ethical Hacking & Cyber Security training adds real projects and code reviews from working developers.
- Project-based learning
- Mentor code reviews
- Free counselling call
