Quick Deploy Pentest Lab with Vagrant
Building a Quickly Deployable Red Team/Blue Team Lab with Vagrant
Software Used
Virtual Box [https://www.virtualbox.org/]
-Version Used: 7.1.4
-Update PATH variable to include the Virtual Box Directory
-VBoxManage is used multiple times
Vagrant [https://www.vagrantup.com/]
-Version Used: 2.4.3
Before we Begin
If you are planning on implementing Windows Operating Systems into your environment, please read my guide on how to setup a Windows Base Box first. This guide assumes that you already have your base-boxes present.
LINK WINDOWS BASE BOX TO GUIDE <https://chazae.github.io/>
The workflow I found most effective for preparing a multi-machine vagrant environment is to boot/configure the Vagrantfile of any new operating system you would like to add to the lab environment.
After successfully booting the OS through vagrant using a single-machine vagrantfile then you can easily transfer that config to a multi-machine environment by placing the specifications under
Red-Team Host
- Kali -
- hashicorp cloud link
- Vagrantfile configuration
$script = <<-SCRIPT
sudo apt-get -y purge network-manager > /dev/null
sudo ifdown eth0 &2>/dev/null &
sudo ip link set eth1 up
sudo ip route del default dev eth0
sudo ip route add default dev eth1
sudo ip addr add 192.168.30.2/24 dev eth1 &>/dev/null &
SCRIPT
config.vm.define "kali", autostart: true, primary: true do |kali|
kali.vm.box = "kalilinux/rolling"
kali.vm.network "private_network", virtualbox__intnet: "pentestLab", adapter: 2,
auto_config: false
kali.vm.provider "virtualbox" do |vb|
vb.name = "kaliVagrant"
vb.gui = true
vb.memory = "2048"
end
kali.vm.provision "shell", run: "always" do |s|
s.inline = $script
end
end
Only one host is necessary
Blue-Team: Linux OS Options
- Ubuntu Host - https://ubuntu.com/
- hashicorp box link
- Vagrantfile Configuration
config.vm.define "ubuntuHost", autostart: false do |ubuntuHost|
ubuntuHost.vm.box = "hashicorp/precise64"
ubuntuHost.vm.box_version = "1.1.0"
ubuntuHost.vm.network "private_network", ip: "192.168.30.180", adapter: 2, virtualbox__intnet: "pentestLab", auto_config: true
ubuntuHost.vm.provider "virtualbox" do |vb|
vb.name = "ubuntuHostVagrant"
vb.gui = false
vb.memory = "1024"
vb.customize 'post-boot', ["controlvm", :id, "setlinkstate1", "on"]
end
ubuntuHost.trigger.after "up" do |t|
t.run = {inline: 'VBoxManage controlvm ubuntuHostVagrant setlinkstate1 off'}
end
end
- Ubuntu Server
- hashicorp box link
- Vagrantfile Configuration
# Defines an ubuntu server as "web"
# Downloads an ubuntuServer box from the hasicorp cloud
# after vagrant is done with initilization it sets the network address to private
config.vm.define "ubuntuServer", autostart: true do |ubuntuServer|
ubuntuServer.vm.box = "ubuntu/trusty64"
ubuntuServer.vm.box_version = "20191107.0.0"
ubuntuServer.vm.network "private_network", ip: "192.168.30.170", adapter: 2, virtualbox__intnet: "pentestLab", auto_config: true
ubuntuServer.vm.provider "virtualbox" do |vb|
vb.name = "ubuntuServerVagrant"
vb.gui = false
vb.memory = "1024"
vb.customize 'post-boot', ["controlvm", :id, "setlinkstate1", "on"]
end
ubuntuServer.trigger.after "up" do |t|
t.run = {inline: 'VBoxManage controlvm ubuntuServerVagrant setlinkstate1 off'}
end
end
Blue-Team: Windows OS Options
Disclaimer - I am not suggesting to do this in a professional setting. This is for home network use only.
Windows ISO Acquisition
Windows
- Newer versions can be done through EVAL
- This website has hashes that may be able to help you find any version of Windows you need for non-professional use.
Windows Hosts
Windows 7 Vagrantfile configuration
config.vm.define "windows7Host", autostart: true do |windows7Host|
#Name the box found in "PS ...\vagrant\>vagrant box list"
#If not found then the command will attempt to install it from URL/Local Path below
#Point to the box from wherever this Vagrantfile is launched
#forward the port required for RDP
#create a private network NIC, assign IP, and assign it to named network "pentestLab"
windows7Host.vm.box = "windows7Base"
windows7Host.vm.box_url = "windows7BaseBox/windows7Base.box"
windows7Host.vm.network "forwarded_port", host: 33389, guest: 3389
windows7Host.vm.network "private_network", ip: "192.168.30.151", adapter: 2,
virtualbox__intnet: "pentestLab"
windows7Host.vm.provider "virtualbox" do |vb|
vb.name = "windows7HostVagrant"
vb.gui = false
vb.memory = "1024"
vb.customize 'post-boot', ["controlvm", :id, "setlinkstate1", "on"]
end
windows7Host.vm.communicator = "winrm"
windows7Host.winrm.username = "vagrant"
windows7Host.winrm.password = "vagrant"
windows7Host.trigger.after "up" do |t|
t.run = {inline: 'VBoxManage controlvm windows7HostVagrant setlinkstate1 off'}
end
end
Windows 10 Vagrantfile configuration
config.vm.define "windows10Host", autostart: false do |windows10Host|
#Name the box found in "PS ...\vagrant\>vagrant box list"
#If not found then the command will attempt to install it from URL/Local Path below
#Point to the box from wherever this Vagrantfile is launched
#forward the port required for RDP
#create a private network NIC, assign IP, and assign it to a named network
windows10Host.vm.box = "windows10Base"
windows10Host.vm.box_url = "windows10BaseBox/windows10Base.box"
windows10Host.vm.network "private_network", ip: "192.168.30.152", adapter: 2, virtualbox__intnet: "pentestLab"
#name the virtual machine
#launch without a VirtualBox View
#set RAM to 1gb
#"plug" back in the virtual NIC that allows vagrant to communicate via SSH [NAT NIC]
windows10Host.vm.provider "virtualbox" do |vb|
vb.name = "windows10HostVagrant"
vb.gui = false
vb.memory = "1024"
vb.customize 'post-boot', ["controlvm", :id, "setlinkstate1", "on"]
end
#Establish winrm as the communicator (Default is usually SSH)
#initialize winrm username
#initialize winrm password
windows10Host.vm.communicator = "winrm"
windows10Host.winrm.username = "vagrant"
windows10Host.winrm.password = "vagrant"
#Turn off the virtual NIC after vagrant "up" command to contain private network
windows10Host.trigger.after "up" do |t|
t.run = {inline: 'VBoxManage controlvm windows10HostVagrant setlinkstate1 off'}
end
end
Windows 11 Vagrantfile configuration
config.vm.define "windows11Host", autostart: false do |windows11Host|
#Name the box found in "PS ...\vagrant\>vagrant box list"
#If not found then the command will attempt to install it from URL/Local Path below
#Point to the box from wherever this Vagrantfile is launched
#forward the port required for RDP
#create a private network NIC, assign IP, and assign it to a named network
windows11Host.vm.box = "windows11Base"
windows11Host.vm.box_url = "windows11BaseBox/windows11Base.box"
windows11Host.vm.network "private_network", ip: "192.168.30.153", adapter: 2, virtualbox__intnet: "pentestLab"
#name the virtual machine
#launch without a VirtualBox View
#set RAM to 1gb
#"plug" back in the virtual NIC that allows vagrant to communicate via SSH [NAT NIC]
windows11Host.vm.provider "virtualbox" do |vb|
vb.name = "windows11HostVagrant"
vb.gui = false
vb.memory = "1024"
vb.customize 'post-boot', ["controlvm", :id, "setlinkstate1", "on"]
end
#Establish winrm as the communicator (Default is usually SSH)
#initialize winrm username
#initialize winrm password
windows11Host.vm.communicator = "winrm"
windows11Host.winrm.username = "vagrant"
windows11Host.winrm.password = "vagrant"
#Turn off the virtual NIC after vagrant "up" command to contain private network
#uses Virtual Machine name set above
windows11Host.trigger.after "up" do |t|
t.run = {inline: 'VBoxManage controlvm windows11HostVagrant setlinkstate1 off'}
end
end
Windows Servers
These instructions BELOW configure a windows server with BARE FUNCTIONALITY and NO ROLES
If you would like to ADD ROLES such as (Active Directory, DHCP, Web, etc.) then I suggest provisioning the machines using chef-solo
Creating a Windows Server 2022 Base Box
Windows Server 2022 Vagrantfile configuration
config.vm.define "db", autostart: false do |db|
#Name the box found in "PS ...\vagrant\>vagrant box list"
#If not found then the command will attempt to install it from URL/Local Path below
#Point to the box from wherever this Vagrantfile is launched
#forward the port required for RDP
#create a private network NIC, assign IP, and assign it to named network "pentestLab"
db.vm.box = "windows2022Base"
db.vm.box_url = "windows2022BaseBox/windows2022Base.box"
db.vm.network "forwarded_port", host: 33389, guest: 3389
db.vm.network "private_network", ip: "192.168.30.160", adapter: 2,
virtualbox__intnet: "pentestLab"
#name the virtual machine
#launch without a VirtualBox View
#set RAM to 1gb
#"plug" back in the virtual NIC that allows vagrant to communicate via SSH [NAT NIC]
db.vm.provider "virtualbox" do |vb|
vb.name = "windows2022Vagrant"
vb.gui = false
vb.memory = "1024"
vb.customize 'post-boot', ["controlvm", :id, "setlinkstate1", "on"]
end
#Establish winrm as the communicator (Default is usually SSH)
#initialize winrm username
#initialize winrm password
db.vm.communicator = "winrm"
db.winrm.username = "vagrant"
db.winrm.password = "vagrant"
#Turn off the virtual NIC after vagrant "up" command to contain private network
db.trigger.after "up" do |t|
t.run = {inline: 'VBoxManage controlvm windows2022Vagrant setlinkstate1 off'}
end
end
Windows Server 2012 Vagrantfile configuration
config.vm.define "win2k12Server", autostart: false do |win2k12Server|
#Name the box found in "PS ...\vagrant\>vagrant box list"
#If not found then the command will attempt to install it from URL/Local Path below
#Point to the box from wherever this Vagrantfile is launched
#forward the port required for RDP
#create a private network NIC, assign IP, and assign it to a named network
win2k12Server.vm.box = "windows2012Base"
win2k12Server.vm.box_url = "windows2012BaseBox/windows2012Base.box"
win2k12Server.vm.network "private_network", ip: "192.168.30.161", adapter: 2, virtualbox__intnet: "pentestLab"
#name the virtual machine
#launch without a VirtualBox View
#set RAM to 1gb
#"plug" back in the virtual NIC that allows vagrant to communicate via SSH [NAT NIC]
win2k12Server.vm.provider "virtualbox" do |vb|
vb.name = "windows2012Vagrant"
vb.gui = false
vb.memory = "1024"
vb.customize 'post-boot', ["controlvm", :id, "setlinkstate1", "on"]
end
#Establish winrm as the communicator (Default is usually SSH)
#initialize winrm username
#initialize winrm password
win2k12Server.vm.communicator = "winrm"
win2k12Server.winrm.username = "vagrant"
win2k12Server.winrm.password = "vagrant"
#Turn off the virtual NIC after vagrant "up" command to contain private network
win2k12Server.trigger.after "up" do |t|
t.run = {inline: 'VBoxManage controlvm windows2012Vagrant setlinkstate1 off'}
end
end
Windows Server 2008 Vagrantfile configuration
config.vm.define "win2k8Server", autostart: false do |win2k8Server|
#Name the box found in "PS ...\vagrant\>vagrant box list"
#If not found then the command will attempt to install it from URL/Local Path below
#Point to the box from wherever this Vagrantfile is launched
#forward the port required for RDP
#create a private network NIC, assign IP, and assign it to a named network
win2k8Server.vm.box = "windows2k8Base"
win2k8Server.vm.box_url = "windows2008BaseBox/windows2008Base.box"
win2k8Server.vm.network "private_network", ip: "192.168.30.162", adapter: 2, virtualbox__intnet: "pentestLab"
#name the virtual machine
#launch without a VirtualBox View
#set RAM to 1gb
#"plug" back in the virtual NIC that allows vagrant to communicate via SSH [NAT NIC]
win2k8Server.vm.provider "virtualbox" do |vb|
vb.name = "windows2008R2Vagrant"
vb.gui = false
vb.memory = "1024"
vb.customize 'post-boot', ["controlvm", :id, "setlinkstate1", "on"]
end
#Establish winrm as the communicator (Default is usually SSH)
#initialize winrm username
#initialize winrm password
win2k8Server.vm.communicator = "winrm"
win2k8Server.winrm.username = "vagrant"
win2k8Server.winrm.password = "vagrant"
#Turn off the virtual NIC after vagrant "up" command to contain private network
win2k8Server.trigger.after "up" do |t|
t.run = {inline: 'VBoxManage controlvm windows2008R2Vagrant setlinkstate1 off'}
end
end
Multi-Machine Vagrantfile Configuration
Vagrant.configure("2") do |config|
# Defines the primary kali box
# Only box initially ran
# Set on private ip once initialized
# Provision will run a shell that will reinitialize the eth0 interace, which is the default interface setup
# This is important as without this, kali will be able to ping computers
# in your internal network while also being able to communicate to the internet
$scriptKali = <<-SCRIPT
sudo apt-get -y purge network-manager > /dev/null
sudo ifdown eth0 &2>/dev/null &
sudo ip link set eth1 up > /dev/null
sudo ip route del default dev eth0
sudo ip route add default dev eth1
sudo ip addr add 192.168.30.2/24 dev eth1 &>/dev/null &
exit
SCRIPT
config.vm.define "kali", autostart: true, primary: true do |kali|
kali.vm.box = "kalilinux/rolling"
kali.vm.network "private_network", virtualbox__intnet: "pentestLab", adapter: 2, auto_config: false
kali.vm.provider "virtualbox" do |vb|
vb.name = "kaliVagrant"
vb.gui = true
vb.memory = "2048"
vb.customize 'post-boot', ["controlvm", :id, "setlinkstate1", "on"]
end
kali.vm.provision "shell", run: "always" do |s|
s.inline = $scriptKali
end
kali.trigger.after "up" do |t|
t.run = {inline: 'VBoxManage controlvm kaliVagrant setlinkstate1 off'}
end
end
# Defines the Windows 7 box as "windows7" which will be a host
# uses winrm instead of ssh so it must be defined
# after vagrant is done with initilization it sets the network address to private
config.vm.define "windows7Host", autostart: false do |windows7Host|
#Name the box found in "PS ...\vagrant\>vagrant box list"
#If not found then the command will attempt to install it from URL/Local Path below
#Point to the box from wherever this Vagrantfile is launched
#forward the port required for RDP
#create a private network NIC, assign IP, and assign it to a named network
windows7Host.vm.box = "windows7Base"
windows7Host.vm.box_url = "windows7BaseBox/windows7Base.box"
windows7Host.vm.network "private_network", ip: "192.168.30.151", adapter: 2, virtualbox__intnet: "pentestLab"
#name the virtual machine
#launch without a VirtualBox View
#set RAM to 1gb
#"plug" back in the virtual NIC that allows vagrant to communicate via SSH [NAT NIC]
windows7Host.vm.provider "virtualbox" do |vb|
vb.name = "windows7HostVagrant"
vb.gui = false
vb.memory = "1024"
vb.customize 'post-boot', ["controlvm", :id, "setlinkstate1", "on"]
end
#Establish winrm as the communicator (Default is usually SSH)
#initialize winrm username
#initialize winrm password
windows7Host.vm.communicator = "winrm"
windows7Host.winrm.username = "vagrant"
windows7Host.winrm.password = "vagrant"
#Turn off the virtual NIC after vagrant "up" command to contain private network
windows7Host.trigger.after "up" do |t|
t.run = {inline: 'VBoxManage controlvm windows7HostVagrant setlinkstate1 off'}
end
end
config.vm.define "windows10Host", autostart: false do |windows10Host|
windows10Host.vm.box = "windows10Base"
windows10Host.vm.box_url = "windows10BaseBox/windows10Base.box"
windows10Host.vm.network "private_network", ip: "192.168.30.152", adapter: 2, virtualbox__intnet: "pentestLab"
windows10Host.vm.provider "virtualbox" do |vb|
vb.name = "windows10HostVagrant"
vb.gui = false
vb.memory = "1024"
vb.customize 'post-boot', ["controlvm", :id, "setlinkstate1", "on"]
end
windows10Host.vm.communicator = "winrm"
windows10Host.winrm.username = "vagrant"
windows10Host.winrm.password = "vagrant"
windows10Host.trigger.after "up" do |t|
t.run = {inline: 'VBoxManage controlvm windows10HostVagrant setlinkstate1 off'}
end
end
config.vm.define "windows11Host", autostart: false do |windows11Host|
windows11Host.vm.box = "windows11Base"
windows11Host.vm.box_url = "windows11BaseBox/windows11Base.box"
windows11Host.vm.network "private_network", ip: "192.168.30.153", adapter: 2, virtualbox__intnet: "pentestLab"
windows11Host.vm.provider "virtualbox" do |vb|
vb.name = "windows11HostVagrant"
vb.gui = false
vb.memory = "1024"
vb.customize 'post-boot', ["controlvm", :id, "setlinkstate1", "on"]
end
windows11Host.vm.communicator = "winrm"
windows11Host.winrm.username = "vagrant"
windows11Host.winrm.password = "vagrant"
windows11Host.trigger.after "up" do |t|
t.run = {inline: 'VBoxManage controlvm windows11HostVagrant setlinkstate1 off'}
end
end
config.vm.define "win2k22Server", autostart: false do |win2k22Server|
win2k22Server.vm.box = "windows2022Base"
win2k22Server.vm.box_url = "windows2022BaseBox/windows2022Base.box"
win2k22Server.vm.network "private_network", ip: "192.168.30.160", adapter: 2, virtualbox__intnet: "pentestLab"
win2k22Server.vm.provider "virtualbox" do |vb|
vb.name = "windows2022Vagrant"
vb.gui = false
vb.memory = "1024"
vb.customize 'post-boot', ["controlvm", :id, "setlinkstate1", "on"]
end
win2k22Server.vm.communicator = "winrm"
win2k22Server.winrm.username = "vagrant"
win2k22Server.winrm.password = "vagrant"
win2k22Server.trigger.after "up" do |t|
t.run = {inline: 'VBoxManage controlvm windows2022Vagrant setlinkstate1 off'}
end
end
config.vm.define "win2k12Server", autostart: false do |win2k12Server|
win2k12Server.vm.box = "windows2012Base"
win2k12Server.vm.box_url = "windows2012BaseBox/windows2012Base.box"
win2k12Server.vm.network "private_network", ip: "192.168.30.161", adapter: 2, virtualbox__intnet: "pentestLab"
win2k12Server.vm.provider "virtualbox" do |vb|
vb.name = "windows2012Vagrant"
vb.gui = false
vb.memory = "1024"
vb.customize 'post-boot', ["controlvm", :id, "setlinkstate1", "on"]
end
win2k12Server.vm.communicator = "winrm"
win2k12Server.winrm.username = "vagrant"
win2k12Server.winrm.password = "vagrant"
win2k12Server.trigger.after "up" do |t|
t.run = {inline: 'VBoxManage controlvm windows2012Vagrant setlinkstate1 off'}
end
end
config.vm.define "win2k8Server", autostart: false do |win2k8Server|
win2k8Server.vm.box = "windows2k8Base"
win2k8Server.vm.box_url = "windows2008BaseBox/windows2008Base.box"
win2k8Server.vm.network "private_network", ip: "192.168.30.162", adapter: 2, virtualbox__intnet: "pentestLab"
win2k8Server.vm.provider "virtualbox" do |vb|
vb.name = "windows2008R2Vagrant"
vb.gui = false
vb.memory = "1024"
vb.customize 'post-boot', ["controlvm", :id, "setlinkstate1", "on"]
end
win2k8Server.vm.communicator = "winrm"
win2k8Server.winrm.username = "vagrant"
win2k8Server.winrm.password = "vagrant"
win2k8Server.trigger.after "up" do |t|
t.run = {inline: 'VBoxManage controlvm windows2008R2Vagrant setlinkstate1 off'}
end
end
# Defines an ubuntu server as "web"
# Downloads an ubuntuServer box from the hasicorp cloud
# after vagrant is done with initilization it sets the network address to private
config.vm.define "ubuntuServer", autostart: false do |ubuntuServer|
ubuntuServer.vm.box = "ubuntu/trusty64"
ubuntuServer.vm.box_version = "20191107.0.0"
ubuntuServer.vm.network "private_network", ip: "192.168.30.170", adapter: 2, virtualbox__intnet: "pentestLab", auto_config: true
ubuntuServer.vm.provider "virtualbox" do |vb|
vb.name = "ubuntuServerVagrant"
vb.gui = false
vb.memory = "1024"
vb.customize 'post-boot', ["controlvm", :id, "setlinkstate1", "on"]
end
ubuntuServer.trigger.after "up" do |t|
t.run = {inline: 'VBoxManage controlvm ubuntuServerVagrant setlinkstate1 off'}
end
end
# Defines an ubuntu Host as "ubuntuHost"
# Downloads an ubuntu Host box from the hasicorp cloud
# after vagrant is done with initilization it sets the network address to private
config.vm.define "ubuntuHost", autostart: false do |ubuntuHost|
ubuntuHost.vm.box = "hashicorp/precise64"
ubuntuHost.vm.box_version = "1.1.0"
ubuntuHost.vm.network "private_network", ip: "192.168.30.180", adapter: 2, virtualbox__intnet: "pentestLab", auto_config: true
ubuntuHost.vm.provider "virtualbox" do |vb|
vb.name = "ubuntuHostVagrant"
vb.gui = false
vb.memory = "1024"
vb.customize 'post-boot', ["controlvm", :id, "setlinkstate1", "on"]
end
ubuntuHost.trigger.after "up" do |t|
t.run = {inline: 'VBoxManage controlvm ubuntuHostVagrant setlinkstate1 off'}
end
end
end
Multi-Machine Vagrantfile Configuration Explanation
When defining a Multi-Machine Vagrantfile, the only real differences are how “vagrant up” is used, which is controlled by the autostart: false configuration option.
In the case of the ubuntuHost this is shown as:
config.vm.define "ubuntuHost", autostart: false do |ubuntuHost|
This is required as using “vagrant up” will bring up every single virtual machine listed in the Multi-Machine Vagrantfile unless explicitly told not to. This switch allows you to customize your lab on the fly, and quickly configure a large amount of environments.
Usage
vagrant up
Brings up all of the boxes without the autoconfig: false property set
vagrant up
Only brings up the specified Virtual Machine
vagrant suspend -f
Suspends all machines for future use.
vagrant halt -f
Halts all currently running Virtual Machines, and does so through the Hypervisor as opposed to an ssh shutdown command. As this environment is private, and not meant to communicate post setup, the -f switch is required.
vagrant destroy -f
Destroys all virtual machines created. This is used when you are done with the lab as a whole, and would like to start entirely fresh. -f switch is used for a similar purpose
Demonstration
Pentest Lab Internal Network Topology
Strengths of this approach
Less disk space is used
- vagrant boxes are more lightweight than a traditional VM
- The fast setup of labs allows you to delete them when unused with vagrant destroy -f
Low setup time for additional labs
- Now that this platform is initialized, setting up a specific lab is as easy as changing this configuration file
High amount of customization
- Easily add, change, or delete configs that you do not need
Weaknesses of this approach
Vagrants NAT requirement
- Upon starting up a machine with vagrant up vagrant will enable the first NIC as NAT and connect it to the machine
- As we want our lab to be completely private, the configuration above will disconnect the cable but this only happens once the machine is completely booted up.
Static IP’s for hosts are not realistic in a business setting
What I learned
Configuring network settings through SSH that will effectively close your SSH connection is tricky. I had to set some commands as a background process, and trust that the exit command executed prior to being kicked. This allows the script to run without waiting for a response from the Kali box.
Network Manager is a pain to work with when trying to set up a golden configuration.
vagrant needs to work on removing the requirement for the first interface being NAT. While other options exist, vagrant makes for a wonderful virtual machine manager by combining cloud-based
What Is Next For This Lab?
As of right now this lab is fully functional for a basic demo involving metasploit. While that lab would be quick and fun, I want to brush up on my software provisioning skills. My next goal is to provision an Ubuntu Server within this lab to automatically download and setup OWASP Juice Shop.
This is for two reasons.
The first being that I want to demonstrate my ability to provision software across multiple devices using chef.
The second reason being that I would like to practice web application vulnerability once I have successfully setup software provisioning for my virtual machines.
Various guides/posts I used during setup
Guides referenced
- Windows Vagrant File Configuration [https://vitaminac.github.io/Windows7-Vagrant/]
Guides referenced in showcase
- Windows Vagrant File Configuration
- Vagrant Multi-machine
- VBoxManage commands
- solution to NIC resetting in kali