Quick Deploy Pentest Lab with Vagrant

Building a Quickly Deployable Red Team/Blue Team Lab with Vagrant

Quick Deploy Pentest Lab with Vagrant | blank

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

  $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

  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
  # 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

Guides referenced in showcase