1
.gitignore
vendored
1
.gitignore
vendored
@@ -12,3 +12,4 @@ inventory.yml
|
||||
inventory.yml.bak
|
||||
*.box
|
||||
manifest.xml
|
||||
HyperV/.vagrant/*
|
||||
@@ -404,9 +404,7 @@
|
||||
LATEST_VELOCIRAPTOR_LINUX_URL=$(curl -sL https://github.com/Velocidex/velociraptor/releases/latest | grep 'linux-amd64' | grep -Eo "/(?[^\"]+)" | grep amd | sed 's#^#https://github.com#g')
|
||||
echo "[$(date +%H:%M:%S)]: The URL for the latest release was extracted as $LATEST_VELOCIRAPTOR_LINUX_URL"
|
||||
echo "[$(date +%H:%M:%S)]: Attempting to download..."
|
||||
#wget -P /opt/velociraptor --progress=bar:force "$LATEST_VELOCIRAPTOR_LINUX_URL"
|
||||
# Harcoding until the release after v0.4.7
|
||||
wget -P /opt/velociraptor --progress=bar:force "https://github.com/Velocidex/velociraptor/releases/download/v0.4.7/velociraptor-v0.4.7-1-linux-amd64"
|
||||
wget -P /opt/velociraptor --progress=bar:force "$LATEST_VELOCIRAPTOR_LINUX_URL"
|
||||
if [ "$(file /opt/velociraptor/velociraptor*linux-amd64 | grep -c 'ELF 64-bit LSB executable')" -eq 1 ]; then
|
||||
echo "[$(date +%H:%M:%S)]: Velociraptor successfully downloaded!"
|
||||
else
|
||||
|
||||
15
ESXi/main.tf
15
ESXi/main.tf
@@ -43,23 +43,26 @@ resource "esxi_guest" "logger" {
|
||||
}
|
||||
}
|
||||
# This is the network that bridges your host machine with the ESXi VM
|
||||
# If this interface doesn't provide connectivity, you will have to uncomment
|
||||
# the interface below and add a virtual network that does
|
||||
network_interfaces {
|
||||
virtual_network = var.vm_network
|
||||
mac_address = "00:50:56:a3:b1:c2"
|
||||
nic_type = "e1000"
|
||||
}
|
||||
# OPTIONAL: You can comment out this interface stanza if your vm_network provides internet access
|
||||
network_interfaces {
|
||||
virtual_network = var.nat_network
|
||||
mac_address = "00:50:56:a3:b1:c3"
|
||||
nic_type = "e1000"
|
||||
}
|
||||
# This is the local network that will be used for 192.168.38.x addressing
|
||||
network_interfaces {
|
||||
virtual_network = var.hostonly_network
|
||||
mac_address = "00:50:56:a3:b1:c4"
|
||||
nic_type = "e1000"
|
||||
}
|
||||
# OPTIONAL: Uncomment out this interface stanza if your vm_network doesn't
|
||||
# provide internet access
|
||||
# network_interfaces {
|
||||
# virtual_network = var.nat_network
|
||||
# mac_address = "00:50:56:a3:b1:c3"
|
||||
# nic_type = "e1000"
|
||||
# }
|
||||
guest_startup_timeout = 45
|
||||
guest_shutdown_timeout = 30
|
||||
}
|
||||
|
||||
@@ -3,14 +3,7 @@ network:
|
||||
ethernets:
|
||||
eth0:
|
||||
dhcp4: true
|
||||
routes:
|
||||
- to: 192.168.1.0/24
|
||||
via: 192.168.3.1
|
||||
eth1:
|
||||
dhcp4: true
|
||||
gateway4: 192.168.76.1
|
||||
nameservers:
|
||||
addresses: [8.8.8.8,8.8.4.4]
|
||||
eth2:
|
||||
dhcp4: false
|
||||
addresses: [192.168.38.105/24]
|
||||
|
||||
|
||||
41
HyperV/README.md
Normal file
41
HyperV/README.md
Normal file
@@ -0,0 +1,41 @@
|
||||
# Detection Lab for Hyper-V
|
||||
|
||||
This build does not undergo the same level of weekly testing as what is found in the main part of Detectionlab.
|
||||
Hyper-V support is only in beta and needs more testing by more users to ensure its stability and usability.
|
||||
|
||||
## Requirements
|
||||
|
||||
The version of Hyper-V will need to be compatible with Hyper-V VM configuration version 9.0.
|
||||
You will need to be running one of the following operating systems:
|
||||
* Windows 10 1809 or later
|
||||
* Windows Server 2019
|
||||
* Windows Hyper-V Server 2019
|
||||
|
||||
For a breakdown of what Operating Systems support which VM configuration versions please visit: (https://docs.microsoft.com/en-us/windows-server/virtualization/hyper-v/deploy/upgrade-virtual-machine-version-in-hyper-v-on-windows-or-windows-server)
|
||||
This build also requires vagrant-reload. If you do not have it installed, you will be prompted to install it.
|
||||
|
||||
## Known Issues Important!
|
||||
|
||||
Unfortunately, due to some issues with Vagrant and Microsoft, running DetectionLab with Hyper-V is not as easy as it is with other providers. You will need to do the following BEFORE trying to run `vagrant up`.
|
||||
1) Patch Vagant
|
||||
Vagrant does not play nice with Windows SMB share authentication. It uses cmdkey which is not properly implemented. More details about the issue can be found in this issue:(https://github.com/hashicorp/vagrant/issues/10661)
|
||||
To patch this, go find the mount_shared_folder.rb file and replace `"cmdkey /add:#{options[:smb_host]} /user:#{options[:smb_username]} /pass:\"#{options[:smb_password]}\""` with `"cmdkey '/add:\"#{options[:smb_host]}\"' '/user:\"#{options[:smb_username]}\"' '/pass:\"#{options[:smb_password]}\"'"`
|
||||
|
||||
2) Windows will require you to enter an administrator username and password to be able to create and mount the SMB share.
|
||||
This means the build will not be fully automated. One thing you can do is add `config.vm.synced_folder '../Vagrant', '/vagrant', smb_username: "username", smb_password: "password"` to the Vagrantfile on line 2. For security reasons, this is not a good idea as you will be storing your username and password in plaintext.
|
||||
By not having this line added to the Vagrantfile you will be required to put in your username and password at least 2 times per machine.
|
||||
|
||||
3) Selecting Virtual Switch
|
||||
During the build you will also have to select the virtual switch you want to use for each server. This cannot be avoided. There is a option that can be used to force the network adapter to use a particular switch; however, using that option breaks this build process.
|
||||
|
||||
A really hacky workaround is, if you are using the smb_username and smb_password options, would be to press the option number corresponding with the virtual switch you want to use then enter four times after `vagrant up`. So, if you know you want the virtual switch 1 `vagrant up` 1 enter 1 enter 1 enter 1 enter
|
||||
|
||||
Yes, I know hacky but it works.
|
||||
|
||||
## How this build works
|
||||
|
||||
The majority of this build works the same as the VirtualBox build. The most notable difference is on the Windows builds. There is a script that will create an internal virtual switch called "NATSwitch." Throughout the build process, a script will create a second network adapter and attach it to the NATSwitch on the VM being built. After the machine is built the original network adapter will be removed from the VM.
|
||||
|
||||
## Note
|
||||
|
||||
This build will run two scripts on the host machine. It is advisable to always check any scripts that will be run on your machine before running them.
|
||||
221
HyperV/Vagrantfile
vendored
Normal file
221
HyperV/Vagrantfile
vendored
Normal file
@@ -0,0 +1,221 @@
|
||||
Vagrant.configure("2") do |config|
|
||||
config.vm.synced_folder '../Vagrant', '/vagrant'
|
||||
config.vagrant.plugins = "vagrant-reload"
|
||||
# Set up the Hyper-V switch
|
||||
config.trigger.before :up do |trigger|
|
||||
trigger.info = "Creating 'NATSwitch' Hyper-V switch if it does not exist..."
|
||||
trigger.run = {privileged: "true", powershell_elevated_interactive: "true", path: "./hyperv-create-nat-switch.ps1"}
|
||||
end
|
||||
|
||||
config.vm.define "logger" do |cfg|
|
||||
cfg.vm.box = "bento/ubuntu-18.04"
|
||||
cfg.vm.hostname = "logger"
|
||||
cfg.vm.boot_timeout = 600
|
||||
cfg.vm.provision :shell, path: "fix-eth0-static-ip.sh"
|
||||
cfg.vm.provision "reload"
|
||||
cfg.vm.provision :shell, path: "check-eth0-ip.sh"
|
||||
cfg.vm.provision :shell, path: "../Vagrant/bootstrap.sh"
|
||||
cfg.vm.provision :shell, path: "fix-motd.sh"
|
||||
|
||||
|
||||
# Change the switch to the NATSwitch
|
||||
cfg.trigger.before :reload do |trigger|
|
||||
trigger.info = "Setting Hyper-V switch to 'NATSwitch' to allow for static IP..."
|
||||
trigger.run = {
|
||||
privileged: "true",
|
||||
powershell_elevated_interactive: "true",
|
||||
path: "./hyperv-change-switch.ps1" ,
|
||||
args: "-vmname logger"
|
||||
}
|
||||
end
|
||||
|
||||
cfg.vm.provider "hyperv" do |h, override|
|
||||
h.vmname = "logger"
|
||||
h.memory = 4096
|
||||
h.cpus = 2
|
||||
h.ip_address_timeout = 60
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
config.vm.define "dc" do |cfg|
|
||||
|
||||
cfg.vm.box = "man715/Windows2016"
|
||||
cfg.vm.hostname = "dc"
|
||||
cfg.vm.boot_timeout = 600
|
||||
cfg.winrm.transport = :plaintext
|
||||
cfg.vm.communicator = "winrm"
|
||||
cfg.winrm.basic_auth_only = true
|
||||
cfg.winrm.timeout = 300
|
||||
cfg.winrm.retry_limit = 20
|
||||
|
||||
# Create a new network adapter on the NATSwitch
|
||||
cfg.trigger.before :reload do |trigger|
|
||||
trigger.info = "Setting Hyper-V switch to 'NATSwitch' to allow for static IP..."
|
||||
trigger.run = {
|
||||
privileged: "true",
|
||||
powershell_elevated_interactive: "true",
|
||||
path: "./hyperv-set-switch.ps1",
|
||||
args: "-vmname dc.windomain.local"
|
||||
}
|
||||
end
|
||||
|
||||
# Remove the network adapter that was used to set up the box
|
||||
cfg.trigger.after :up do |trigger|
|
||||
trigger.info = "Removing the maintenance ethernet adapter"
|
||||
trigger.run = {
|
||||
privileged: "true",
|
||||
powershell_elevated_interactive: "true",
|
||||
path: "./hyperv-remove-networkadapter.ps1",
|
||||
args: "-vmname dc.windomain.local"
|
||||
}
|
||||
end
|
||||
|
||||
cfg.vm.provision "reload"
|
||||
cfg.vm.provision "shell", path: "hyperv-set-static-ip.ps1", privileged: true, args: "-ip 192.168.38.102 -dns 8.8.8.8"
|
||||
cfg.vm.provision "shell", path: "../Vagrant/scripts/provision.ps1", privileged: true
|
||||
cfg.vm.provision "reload"
|
||||
cfg.vm.provision "shell", path: "../Vagrant/scripts/provision.ps1", privileged: true
|
||||
cfg.vm.provision "shell", path: "../Vagrant/scripts/download_palantir_wef.ps1", privileged: true
|
||||
cfg.vm.provision "shell", path: "../Vagrant/scripts/install-utilities.ps1", privileged: true
|
||||
cfg.vm.provision "shell", path: "../Vagrant/scripts/install-redteam.ps1", privileged: true
|
||||
cfg.vm.provision "shell", path: "../Vagrant/scripts/install-choco-extras.ps1", privileged: true
|
||||
cfg.vm.provision "shell", path: "../Vagrant/scripts/install-osquery.ps1", privileged: true
|
||||
cfg.vm.provision "shell", path: "../Vagrant/scripts/install-sysinternals.ps1", privileged: true
|
||||
cfg.vm.provision "shell", path: "../Vagrant/scripts/install-velociraptor.ps1", privileged: true
|
||||
cfg.vm.provision "shell", path: "../Vagrant/scripts/configure-ou.ps1", privileged: true
|
||||
cfg.vm.provision "shell", path: "../Vagrant/scripts/configure-wef-gpo.ps1", privileged: true
|
||||
cfg.vm.provision "shell", path: "../Vagrant/scripts/configure-powershelllogging.ps1", privileged: true
|
||||
cfg.vm.provision "shell", path: "../Vagrant/scripts/configure-AuditingPolicyGPOs.ps1", privileged: true
|
||||
cfg.vm.provision "shell", path: "../Vagrant/scripts/configure-rdp-user-gpo.ps1", privileged: true
|
||||
cfg.vm.provision "shell", path: "../Vagrant/scripts/configure-disable-windows-defender-gpo.ps1", privileged: true
|
||||
cfg.vm.provision "shell", path: "../Vagrant/scripts/install-autorunstowineventlog.ps1", privileged: true
|
||||
cfg.vm.provision "shell", inline: 'wevtutil el | Select-String -notmatch "Microsoft-Windows-LiveId" | Foreach-Object {wevtutil cl "$_"}', privileged: true
|
||||
cfg.vm.provision "shell", inline: "Set-SmbServerConfiguration -AuditSmb1Access $true -Force", privileged: true
|
||||
cfg.vm.provision "shell", inline: 'cscript c:\windows\system32\slmgr.vbs /dlv', privileged: true
|
||||
|
||||
cfg.vm.provider "hyperv" do |h, override|
|
||||
h.vmname = "dc.windomain.local"
|
||||
h.memory = 4096
|
||||
h.cpus = 2
|
||||
h.ip_address_timeout = 600
|
||||
end
|
||||
end
|
||||
|
||||
config.vm.define "wef" do |cfg|
|
||||
cfg.vm.box = "man715/Windows2016"
|
||||
cfg.vm.hostname = "wef"
|
||||
cfg.vm.boot_timeout = 600
|
||||
cfg.vm.communicator = "winrm"
|
||||
cfg.winrm.basic_auth_only = true
|
||||
cfg.winrm.timeout = 300
|
||||
cfg.winrm.retry_limit = 20
|
||||
|
||||
# Create a new network adapter on the NATSwitch
|
||||
cfg.trigger.before :reload do |trigger|
|
||||
trigger.info = "Setting Hyper-V switch to 'NATSwitch' to allow for static IP..."
|
||||
trigger.run = {
|
||||
privileged: "true",
|
||||
powershell_elevated_interactive: "true",
|
||||
path: "./hyperv-set-switch.ps1",
|
||||
args: "-vmname wef.windomain.local"
|
||||
}
|
||||
end
|
||||
|
||||
# Remove the network adapter that was used to set up the box
|
||||
cfg.trigger.after :up do |trigger|
|
||||
trigger.info = "Removing the maintenance ethernet adapter"
|
||||
trigger.run = {
|
||||
privileged: "true",
|
||||
powershell_elevated_interactive: "true",
|
||||
path: "./hyperv-remove-networkadapter.ps1",
|
||||
args: "-vmname wef.windomain.local"
|
||||
}
|
||||
end
|
||||
|
||||
cfg.vm.provision "reload"
|
||||
cfg.vm.provision "shell", path: "hyperv-set-static-ip.ps1", privileged: true, args: "-ip 192.168.38.103 -dns 8.8.8.8"
|
||||
cfg.vm.provision "shell", path: "../Vagrant/scripts/provision.ps1", privileged: true
|
||||
cfg.vm.provision "reload"
|
||||
cfg.vm.provision "shell", path: "../Vagrant/scripts/provision.ps1", privileged: true
|
||||
cfg.vm.provision "shell", path: "../Vagrant/scripts/download_palantir_wef.ps1", privileged: true
|
||||
cfg.vm.provision "shell", inline: 'wevtutil el | Select-String -notmatch "Microsoft-Windows-LiveId" | Foreach-Object {wevtutil cl "$_"}', privileged: true
|
||||
cfg.vm.provision "shell", path: "../Vagrant/scripts/install-wefsubscriptions.ps1", privileged: true
|
||||
cfg.vm.provision "shell", path: "../Vagrant/scripts/install-splunkuf.ps1", privileged: true
|
||||
cfg.vm.provision "shell", path: "../Vagrant/scripts/install-windows_ta.ps1", privileged: true
|
||||
cfg.vm.provision "shell", path: "../Vagrant/scripts/install-utilities.ps1", privileged: true
|
||||
cfg.vm.provision "shell", path: "../Vagrant/scripts/install-redteam.ps1", privileged: true
|
||||
cfg.vm.provision "shell", path: "../Vagrant/scripts/install-choco-extras.ps1", privileged: true
|
||||
cfg.vm.provision "shell", path: "../Vagrant/scripts/install-osquery.ps1", privileged: true
|
||||
cfg.vm.provision "shell", path: "../Vagrant/scripts/install-sysinternals.ps1", privileged: true
|
||||
cfg.vm.provision "shell", path: "../Vagrant/scripts/install-velociraptor.ps1", privileged: true
|
||||
cfg.vm.provision "shell", path: "../Vagrant/scripts/configure-pslogstranscriptsshare.ps1", privileged: true
|
||||
cfg.vm.provision "shell", path: "../Vagrant/scripts/install-autorunstowineventlog.ps1", privileged: true
|
||||
cfg.vm.provision "shell", inline: "Set-SmbServerConfiguration -AuditSmb1Access $true -Force", privileged: true
|
||||
cfg.vm.provision "shell", path: "../Vagrant/scripts/install-microsoft-ata.ps1", privileged: true
|
||||
cfg.vm.provision "shell", inline: 'cscript c:\windows\system32\slmgr.vbs /dlv', privileged: true
|
||||
|
||||
cfg.vm.provider "hyperv" do |h, override|
|
||||
h.vmname = "wef.windomain.local"
|
||||
h.memory = 4096
|
||||
h.cpus = 2
|
||||
h.ip_address_timeout = 600
|
||||
end
|
||||
end
|
||||
|
||||
config.vm.define "win10" do |cfg|
|
||||
cfg.vm.box = "man715/Windows10"
|
||||
cfg.vm.hostname = "win10"
|
||||
cfg.vm.boot_timeout = 600
|
||||
cfg.vm.communicator = "winrm"
|
||||
cfg.winrm.basic_auth_only = true
|
||||
cfg.winrm.timeout = 300
|
||||
cfg.winrm.retry_limit = 20
|
||||
|
||||
# Create a new network adapter on the NATSwitch
|
||||
cfg.trigger.before :reload do |trigger|
|
||||
trigger.info = "Setting Hyper-V switch to 'NATSwitch' to allow for static IP..."
|
||||
trigger.run = {
|
||||
privileged: "true",
|
||||
powershell_elevated_interactive: "true",
|
||||
path: "./hyperv-set-switch.ps1",
|
||||
args: "-vmname win10.windomain.local"
|
||||
}
|
||||
end
|
||||
|
||||
# Remove the network adapter that was used to set up the box
|
||||
cfg.trigger.after :up do |trigger|
|
||||
trigger.info = "Removing the maintenance ethernet adapter"
|
||||
trigger.run = {
|
||||
privileged: "true",
|
||||
powershell_elevated_interactive: "true",
|
||||
path: "./hyperv-remove-networkadapter.ps1",
|
||||
args: "-vmname win10.windomain.local"
|
||||
}
|
||||
end
|
||||
|
||||
cfg.vm.provision "reload"
|
||||
cfg.vm.provision "shell", path: "hyperv-set-static-ip.ps1", privileged: true, args: "-ip 192.168.38.104 -dns 8.8.8.8"
|
||||
cfg.vm.provision "shell", path: "../Vagrant/scripts/MakeWindows10GreatAgain.ps1", privileged: true
|
||||
cfg.vm.provision "shell", path: "../Vagrant/scripts/provision.ps1", privileged: true
|
||||
cfg.vm.provision "reload"
|
||||
cfg.vm.provision "shell", path: "../Vagrant/scripts/provision.ps1", privileged: true
|
||||
cfg.vm.provision "shell", path: "../Vagrant/scripts/download_palantir_wef.ps1", privileged: true
|
||||
cfg.vm.provision "shell", inline: 'wevtutil el | Select-String -notmatch "Microsoft-Windows-LiveId" | Foreach-Object {wevtutil cl "$_"}', privileged: true
|
||||
cfg.vm.provision "shell", path: "../Vagrant/scripts/install-utilities.ps1", privileged: true
|
||||
cfg.vm.provision "shell", path: "../Vagrant/scripts/install-redteam.ps1", privileged: true
|
||||
cfg.vm.provision "shell", path: "../Vagrant/scripts/install-choco-extras.ps1", privileged: true
|
||||
cfg.vm.provision "shell", path: "../Vagrant/scripts/install-osquery.ps1", privileged: true
|
||||
cfg.vm.provision "shell", path: "../Vagrant/scripts/install-sysinternals.ps1", privileged: true
|
||||
cfg.vm.provision "shell", path: "../Vagrant/scripts/install-velociraptor.ps1", privileged: true
|
||||
cfg.vm.provision "shell", path: "../Vagrant/scripts/install-autorunstowineventlog.ps1", privileged: true
|
||||
cfg.vm.provision "shell", inline: 'cscript c:\windows\system32\slmgr.vbs /dlv', privileged: true
|
||||
|
||||
cfg.vm.provider "hyperv" do |h, override|
|
||||
h.vmname = "win10.windomain.local"
|
||||
h.memory = 4096
|
||||
h.cpus = 2
|
||||
h.ip_address_timeout = 600
|
||||
end
|
||||
end
|
||||
end
|
||||
498
HyperV/bootstrap.sh
Normal file
498
HyperV/bootstrap.sh
Normal file
@@ -0,0 +1,498 @@
|
||||
#! /bin/bash
|
||||
|
||||
# Override existing DNS Settings using netplan, but don't do it for Terraform builds
|
||||
if ! curl -s 169.254.169.254 --connect-timeout 2 >/dev/null; then
|
||||
echo -e " eth0:\n dhcp4: true\n nameservers:\n addresses: [8.8.8.8,8.8.4.4]" >>/etc/netplan/01-netcfg.yaml
|
||||
netplan apply
|
||||
fi
|
||||
sed -i 's/nameserver 127.0.0.53/nameserver 8.8.8.8/g' /etc/resolv.conf && chattr +i /etc/resolv.conf
|
||||
|
||||
# Get a free Maxmind license here: https://www.maxmind.com/en/geolite2/signup
|
||||
# Required for the ASNgen app to work: https://splunkbase.splunk.com/app/3531/
|
||||
export MAXMIND_LICENSE=
|
||||
if [ -n "$MAXMIND_LICENSE" ]; then
|
||||
echo "Note: You have not entered a MaxMind license key on line 5 of bootstrap.sh, so the ASNgen Splunk app may not work correctly."
|
||||
echo "However, it is not required and everything else should function correctly."
|
||||
fi
|
||||
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
echo "apt-fast apt-fast/maxdownloads string 10" | debconf-set-selections
|
||||
echo "apt-fast apt-fast/dlflag boolean true" | debconf-set-selections
|
||||
|
||||
sed -i "2ideb mirror://mirrors.ubuntu.com/mirrors.txt bionic main restricted universe multiverse\ndeb mirror://mirrors.ubuntu.com/mirrors.txt bionic-updates main restricted universe multiverse\ndeb mirror://mirrors.ubuntu.com/mirrors.txt bionic-backports main restricted universe multiverse\ndeb mirror://mirrors.ubuntu.com/mirrors.txt bionic-security main restricted universe multiverse" /etc/apt/sources.list
|
||||
|
||||
apt_install_prerequisites() {
|
||||
echo "[$(date +%H:%M:%S)]: Adding apt repositories..."
|
||||
# Add repository for apt-fast
|
||||
add-apt-repository -y ppa:apt-fast/stable
|
||||
# Add repository for yq
|
||||
add-apt-repository -y ppa:rmescandon/yq
|
||||
# Add repository for suricata
|
||||
add-apt-repository -y ppa:oisf/suricata-stable
|
||||
# Install prerequisites and useful tools
|
||||
echo "[$(date +%H:%M:%S)]: Running apt-get clean..."
|
||||
apt-get clean
|
||||
echo "[$(date +%H:%M:%S)]: Running apt-get update..."
|
||||
apt-get -qq update
|
||||
apt-get -qq install -y apt-fast
|
||||
echo "[$(date +%H:%M:%S)]: Running apt-fast install..."
|
||||
apt-fast -qq install -y jq whois build-essential git unzip htop yq mysql-server redis-server python-pip
|
||||
}
|
||||
|
||||
modify_motd() {
|
||||
echo "[$(date +%H:%M:%S)]: Updating the MOTD..."
|
||||
# Force color terminal
|
||||
sed -i 's/#force_color_prompt=yes/force_color_prompt=yes/g' /root/.bashrc
|
||||
sed -i 's/#force_color_prompt=yes/force_color_prompt=yes/g' /home/vagrant/.bashrc
|
||||
# Remove some stock Ubuntu MOTD content
|
||||
chmod -x /etc/update-motd.d/10-help-text
|
||||
# Copy the DetectionLab MOTD
|
||||
cp /vagrant/resources/logger/20-detectionlab /etc/update-motd.d/
|
||||
chmod +x /etc/update-motd.d/20-detectionlab
|
||||
}
|
||||
|
||||
test_prerequisites() {
|
||||
for package in jq whois build-essential git unzip yq mysql-server redis-server python-pip; do
|
||||
echo "[$(date +%H:%M:%S)]: [TEST] Validating that $package is correctly installed..."
|
||||
# Loop through each package using dpkg
|
||||
if ! dpkg -S $package >/dev/null; then
|
||||
# If which returns a non-zero return code, try to re-install the package
|
||||
echo "[-] $package was not found. Attempting to reinstall."
|
||||
apt-get -qq update && apt-get install -y $package
|
||||
if ! which $package >/dev/null; then
|
||||
# If the reinstall fails, give up
|
||||
echo "[X] Unable to install $package even after a retry. Exiting."
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
echo "[+] $package was successfully installed!"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
install_splunk() {
|
||||
# Check if Splunk is already installed
|
||||
if [ -f "/opt/splunk/bin/splunk" ]; then
|
||||
echo "[$(date +%H:%M:%S)]: Splunk is already installed"
|
||||
else
|
||||
echo "[$(date +%H:%M:%S)]: Installing Splunk..."
|
||||
# Get download.splunk.com into the DNS cache. Sometimes resolution randomly fails during wget below
|
||||
dig @8.8.8.8 download.splunk.com >/dev/null
|
||||
dig @8.8.8.8 splunk.com >/dev/null
|
||||
dig @8.8.8.8 www.splunk.com >/dev/null
|
||||
|
||||
# Try to resolve the latest version of Splunk by parsing the HTML on the downloads page
|
||||
echo "[$(date +%H:%M:%S)]: Attempting to autoresolve the latest version of Splunk..."
|
||||
LATEST_SPLUNK=$(curl https://www.splunk.com/en_us/download/splunk-enterprise.html | grep -i deb | grep -Eo "data-link=\"................................................................................................................................" | cut -d '"' -f 2)
|
||||
# Sanity check what was returned from the auto-parse attempt
|
||||
if [[ "$(echo "$LATEST_SPLUNK" | grep -c "^https:")" -eq 1 ]] && [[ "$(echo "$LATEST_SPLUNK" | grep -c "\.deb$")" -eq 1 ]]; then
|
||||
echo "[$(date +%H:%M:%S)]: The URL to the latest Splunk version was automatically resolved as: $LATEST_SPLUNK"
|
||||
echo "[$(date +%H:%M:%S)]: Attempting to download..."
|
||||
wget --progress=bar:force -P /opt "$LATEST_SPLUNK"
|
||||
else
|
||||
echo "[$(date +%H:%M:%S)]: Unable to auto-resolve the latest Splunk version. Falling back to hardcoded URL..."
|
||||
# Download Hardcoded Splunk
|
||||
wget --progress=bar:force -O /opt/splunk-8.0.2-a7f645ddaf91-linux-2.6-amd64.deb 'https://download.splunk.com/products/splunk/releases/8.0.2/linux/splunk-8.0.2-a7f645ddaf91-linux-2.6-amd64.deb&wget=true'
|
||||
fi
|
||||
if ! ls /opt/splunk*.deb 1>/dev/null 2>&1; then
|
||||
echo "Something went wrong while trying to download Splunk. This script cannot continue. Exiting."
|
||||
exit 1
|
||||
fi
|
||||
if ! dpkg -i /opt/splunk*.deb >/dev/null; then
|
||||
echo "Something went wrong while trying to install Splunk. This script cannot continue. Exiting."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
/opt/splunk/bin/splunk start --accept-license --answer-yes --no-prompt --seed-passwd changeme
|
||||
/opt/splunk/bin/splunk add index wineventlog -auth 'admin:changeme'
|
||||
/opt/splunk/bin/splunk add index osquery -auth 'admin:changeme'
|
||||
/opt/splunk/bin/splunk add index osquery-status -auth 'admin:changeme'
|
||||
/opt/splunk/bin/splunk add index sysmon -auth 'admin:changeme'
|
||||
/opt/splunk/bin/splunk add index powershell -auth 'admin:changeme'
|
||||
/opt/splunk/bin/splunk add index zeek -auth 'admin:changeme'
|
||||
/opt/splunk/bin/splunk add index suricata -auth 'admin:changeme'
|
||||
/opt/splunk/bin/splunk add index threathunting -auth 'admin:changeme'
|
||||
/opt/splunk/bin/splunk install app /vagrant/resources/splunk_forwarder/splunk-add-on-for-microsoft-windows_700.tgz -auth 'admin:changeme'
|
||||
/opt/splunk/bin/splunk install app /vagrant/resources/splunk_server/splunk-add-on-for-microsoft-sysmon_1062.tgz -auth 'admin:changeme'
|
||||
/opt/splunk/bin/splunk install app /vagrant/resources/splunk_server/asn-lookup-generator_110.tgz -auth 'admin:changeme'
|
||||
/opt/splunk/bin/splunk install app /vagrant/resources/splunk_server/lookup-file-editor_331.tgz -auth 'admin:changeme'
|
||||
/opt/splunk/bin/splunk install app /vagrant/resources/splunk_server/splunk-add-on-for-zeek-aka-bro_400.tgz -auth 'admin:changeme'
|
||||
/opt/splunk/bin/splunk install app /vagrant/resources/splunk_server/force-directed-app-for-splunk_200.tgz -auth 'admin:changeme'
|
||||
/opt/splunk/bin/splunk install app /vagrant/resources/splunk_server/punchcard-custom-visualization_130.tgz -auth 'admin:changeme'
|
||||
/opt/splunk/bin/splunk install app /vagrant/resources/splunk_server/sankey-diagram-custom-visualization_130.tgz -auth 'admin:changeme'
|
||||
/opt/splunk/bin/splunk install app /vagrant/resources/splunk_server/link-analysis-app-for-splunk_161.tgz -auth 'admin:changeme'
|
||||
/opt/splunk/bin/splunk install app /vagrant/resources/splunk_server/threathunting_144.tgz -auth 'admin:changeme'
|
||||
|
||||
# Install the Maxmind license key for the ASNgen App
|
||||
if [ -n "$MAXMIND_LICENSE" ]; then
|
||||
mkdir /opt/splunk/etc/apps/TA-asngen/local
|
||||
cp /opt/splunk/etc/apps/TA-asngen/default/asngen.conf /opt/splunk/etc/apps/TA-asngen/local/asngen.conf
|
||||
sed -i "s/license_key =/license_key = $MAXMIND_LICENSE/g" /opt/splunk/etc/apps/TA-asngen/local/asngen.conf
|
||||
fi
|
||||
|
||||
# Replace the props.conf for Sysmon TA and Windows TA
|
||||
# Removed all the 'rename = xmlwineventlog' directives
|
||||
# I know youre not supposed to modify files in "default",
|
||||
# but for some reason adding them to "local" wasnt working
|
||||
cp /vagrant/resources/splunk_server/windows_ta_props.conf /opt/splunk/etc/apps/Splunk_TA_windows/default/props.conf
|
||||
cp /vagrant/resources/splunk_server/sysmon_ta_props.conf /opt/splunk/etc/apps/TA-microsoft-sysmon/default/props.conf
|
||||
|
||||
# Add custom Macro definitions for ThreatHunting App
|
||||
cp /vagrant/resources/splunk_server/macros.conf /opt/splunk/etc/apps/ThreatHunting/default/macros.conf
|
||||
# Fix props.conf in ThreatHunting App
|
||||
sed -i 's/EVAL-host_fqdn = Computer/EVAL-host_fqdn = ComputerName/g' /opt/splunk/etc/apps/ThreatHunting/default/props.conf
|
||||
# Fix Windows TA macros
|
||||
mkdir /opt/splunk/etc/apps/Splunk_TA_windows/local
|
||||
cp /opt/splunk/etc/apps/Splunk_TA_windows/default/macros.conf /opt/splunk/etc/apps/Splunk_TA_windows/local
|
||||
sed -i 's/wineventlog_windows/wineventlog/g' /opt/splunk/etc/apps/Splunk_TA_windows/local/macros.conf
|
||||
# Fix Force Directed App until 2.0.1 is released (https://answers.splunk.com/answers/668959/invalid-key-in-stanza-default-value-light.html#answer-669418)
|
||||
rm /opt/splunk/etc/apps/force_directed_viz/default/savedsearches.conf
|
||||
|
||||
# Add a Splunk TCP input on port 9997
|
||||
echo -e "[splunktcp://9997]\nconnection_host = ip" >/opt/splunk/etc/apps/search/local/inputs.conf
|
||||
# Add props.conf and transforms.conf
|
||||
cp /vagrant/resources/splunk_server/props.conf /opt/splunk/etc/apps/search/local/
|
||||
cp /vagrant/resources/splunk_server/transforms.conf /opt/splunk/etc/apps/search/local/
|
||||
cp /opt/splunk/etc/system/default/limits.conf /opt/splunk/etc/system/local/limits.conf
|
||||
# Bump the memtable limits to allow for the ASN lookup table
|
||||
sed -i.bak 's/max_memtable_bytes = 10000000/max_memtable_bytes = 30000000/g' /opt/splunk/etc/system/local/limits.conf
|
||||
|
||||
# Skip Splunk Tour and Change Password Dialog
|
||||
echo "[$(date +%H:%M:%S)]: Disabling the Splunk tour prompt..."
|
||||
touch /opt/splunk/etc/.ui_login
|
||||
mkdir -p /opt/splunk/etc/users/admin/search/local
|
||||
echo -e "[search-tour]\nviewed = 1" >/opt/splunk/etc/system/local/ui-tour.conf
|
||||
# Source: https://answers.splunk.com/answers/660728/how-to-disable-the-modal-pop-up-help-us-to-improve.html
|
||||
if [ ! -d "/opt/splunk/etc/users/admin/user-prefs/local" ]; then
|
||||
mkdir -p "/opt/splunk/etc/users/admin/user-prefs/local"
|
||||
fi
|
||||
echo '[general]
|
||||
render_version_messages = 1
|
||||
dismissedInstrumentationOptInVersion = 4
|
||||
notification_python_3_impact = false
|
||||
display.page.home.dashboardId = /servicesNS/nobody/search/data/ui/views/logger_dashboard' >/opt/splunk/etc/users/admin/user-prefs/local/user-prefs.conf
|
||||
# Enable SSL Login for Splunk
|
||||
echo -e "[settings]\nenableSplunkWebSSL = true" >/opt/splunk/etc/system/local/web.conf
|
||||
# Copy over the Logger Dashboard
|
||||
if [ ! -d "/opt/splunk/etc/apps/search/local/data/ui/views" ]; then
|
||||
mkdir -p "/opt/splunk/etc/apps/search/local/data/ui/views"
|
||||
fi
|
||||
cp /vagrant/resources/splunk_server/logger_dashboard.xml /opt/splunk/etc/apps/search/local/data/ui/views || echo "Unable to find dashboard"
|
||||
# Reboot Splunk to make changes take effect
|
||||
/opt/splunk/bin/splunk restart
|
||||
/opt/splunk/bin/splunk enable boot-start
|
||||
fi
|
||||
}
|
||||
|
||||
download_palantir_osquery_config() {
|
||||
if [ -f /opt/osquery-configuration ]; then
|
||||
echo "[$(date +%H:%M:%S)]: osquery configs have already been downloaded"
|
||||
else
|
||||
# Import Palantir osquery configs into Fleet
|
||||
echo "[$(date +%H:%M:%S)]: Downloading Palantir osquery configs..."
|
||||
cd /opt && git clone https://github.com/palantir/osquery-configuration.git
|
||||
fi
|
||||
}
|
||||
|
||||
install_fleet_import_osquery_config() {
|
||||
if [ -f "/opt/fleet" ]; then
|
||||
echo "[$(date +%H:%M:%S)]: Fleet is already installed"
|
||||
else
|
||||
cd /opt || exit 1
|
||||
|
||||
echo "[$(date +%H:%M:%S)]: Installing Fleet..."
|
||||
echo -e "\n127.0.0.1 kolide" >>/etc/hosts
|
||||
echo -e "\n127.0.0.1 logger" >>/etc/hosts
|
||||
|
||||
# Set MySQL username and password, create kolide database
|
||||
mysql -uroot -e "ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'kolide';"
|
||||
mysql -uroot -pkolide -e "create database kolide;"
|
||||
|
||||
# Always download the latest release of Fleet
|
||||
curl -s https://api.github.com/repos/kolide/fleet/releases/latest | grep 'https://github.com' | grep "/fleet.zip" | cut -d ':' -f 2,3 | tr -d '"' | wget --progress=bar:force -i -
|
||||
unzip fleet.zip -d fleet
|
||||
cp fleet/linux/fleetctl /usr/local/bin/fleetctl && chmod +x /usr/local/bin/fleetctl
|
||||
cp fleet/linux/fleet /usr/local/bin/fleet && chmod +x /usr/local/bin/fleet
|
||||
|
||||
# Prepare the DB
|
||||
fleet prepare db --mysql_address=127.0.0.1:3306 --mysql_database=kolide --mysql_username=root --mysql_password=kolide
|
||||
|
||||
# Copy over the certs and service file
|
||||
cp /vagrant/resources/fleet/server.* /opt/fleet/
|
||||
cp /vagrant/resources/fleet/fleet.service /etc/systemd/system/fleet.service
|
||||
|
||||
mkdir /var/log/fleet
|
||||
|
||||
/bin/systemctl enable fleet.service
|
||||
/bin/systemctl start fleet.service
|
||||
|
||||
echo "[$(date +%H:%M:%S)]: Waiting for fleet service to start..."
|
||||
while true; do
|
||||
result=$(curl --silent -k https://127.0.0.1:8412)
|
||||
if echo "$result" | grep -q setup; then break; fi
|
||||
sleep 1
|
||||
done
|
||||
|
||||
fleetctl config set --address https://192.168.38.105:8412
|
||||
fleetctl config set --tls-skip-verify true
|
||||
fleetctl setup --email admin@detectionlab.network --username admin --password 'admin123#' --org-name DetectionLab
|
||||
fleetctl login --email admin@detectionlab.network --password 'admin123#'
|
||||
|
||||
# Set the enrollment secret to match what we deploy to Windows hosts
|
||||
mysql -uroot --password=kolide -e 'use kolide; update enroll_secrets set secret = "enrollmentsecret" where active=1;'
|
||||
echo "Updated enrollment secret"
|
||||
|
||||
# Change the query invervals to reflect a lab environment
|
||||
# Every hour -> Every 3 minutes
|
||||
# Every 24 hours -> Every 15 minutes
|
||||
sed -i 's/interval: 3600/interval: 180/g' osquery-configuration/Fleet/Endpoints/MacOS/osquery.yaml
|
||||
sed -i 's/interval: 3600/interval: 180/g' osquery-configuration/Fleet/Endpoints/Windows/osquery.yaml
|
||||
sed -i 's/interval: 28800/interval: 900/g' osquery-configuration/Fleet/Endpoints/MacOS/osquery.yaml
|
||||
sed -i 's/interval: 28800/interval: 900/g' osquery-configuration/Fleet/Endpoints/Windows/osquery.yaml
|
||||
|
||||
# Don't log osquery INFO messages
|
||||
# Fix snapshot event formatting
|
||||
fleetctl get options > /tmp/options.yaml
|
||||
/usr/bin/yq w -i /tmp/options.yaml 'spec.config.options.enroll_secret' 'enrollmentsecret'
|
||||
/usr/bin/yq w -i /tmp/options.yaml 'spec.config.options.logger_snapshot_event_type' 'true'
|
||||
# Fleet 3.0 requires the "kind" to be "options" instead of "option"
|
||||
sed -i 's/kind: option/kind: options/g' /tmp/options.yaml
|
||||
fleetctl apply -f /tmp/options.yaml
|
||||
|
||||
# Use fleetctl to import YAML files
|
||||
fleetctl apply -f osquery-configuration/Fleet/Endpoints/MacOS/osquery.yaml
|
||||
fleetctl apply -f osquery-configuration/Fleet/Endpoints/Windows/osquery.yaml
|
||||
for pack in osquery-configuration/Fleet/Endpoints/packs/*.yaml; do
|
||||
fleetctl apply -f "$pack"
|
||||
done
|
||||
|
||||
# Add Splunk monitors for Fleet
|
||||
# Files must exist before splunk will add a monitor
|
||||
touch /var/log/fleet/osquery_result
|
||||
touch /var/log/fleet/osquery_status
|
||||
/opt/splunk/bin/splunk add monitor "/var/log/fleet/osquery_result" -index osquery -sourcetype 'osquery:json' -auth 'admin:changeme'
|
||||
/opt/splunk/bin/splunk add monitor "/var/log/fleet/osquery_status" -index osquery-status -sourcetype 'osquery:status' -auth 'admin:changeme'
|
||||
fi
|
||||
}
|
||||
|
||||
install_zeek() {
|
||||
echo "[$(date +%H:%M:%S)]: Installing Zeek..."
|
||||
# Environment variables
|
||||
NODECFG=/opt/zeek/etc/node.cfg
|
||||
sh -c "echo 'deb http://download.opensuse.org/repositories/security:/zeek/xUbuntu_18.04/ /' > /etc/apt/sources.list.d/security:zeek.list"
|
||||
wget -nv https://download.opensuse.org/repositories/security:zeek/xUbuntu_18.04/Release.key -O /tmp/Release.key
|
||||
apt-key add - </tmp/Release.key &>/dev/null
|
||||
# Update APT repositories
|
||||
apt-get -qq -ym update
|
||||
# Install tools to build and configure Zeek
|
||||
apt-get -qq -ym install zeek crudini
|
||||
export PATH=$PATH:/opt/zeek/bin
|
||||
pip install zkg==2.1.1
|
||||
zkg refresh
|
||||
zkg autoconfig
|
||||
zkg install --force salesforce/ja3
|
||||
# Load Zeek scripts
|
||||
echo '
|
||||
@load protocols/ftp/software
|
||||
@load protocols/smtp/software
|
||||
@load protocols/ssh/software
|
||||
@load protocols/http/software
|
||||
@load tuning/json-logs
|
||||
@load policy/integration/collective-intel
|
||||
@load policy/frameworks/intel/do_notice
|
||||
@load frameworks/intel/seen
|
||||
@load frameworks/intel/do_notice
|
||||
@load frameworks/files/hash-all-files
|
||||
@load base/protocols/smb
|
||||
@load policy/protocols/conn/vlan-logging
|
||||
@load policy/protocols/conn/mac-logging
|
||||
@load ja3
|
||||
|
||||
redef Intel::read_files += {
|
||||
"/opt/zeek/etc/intel.dat"
|
||||
};
|
||||
' >>/opt/zeek/share/zeek/site/local.zeek
|
||||
|
||||
# Configure Zeek
|
||||
crudini --del $NODECFG zeek
|
||||
crudini --set $NODECFG manager type manager
|
||||
crudini --set $NODECFG manager host localhost
|
||||
crudini --set $NODECFG proxy type proxy
|
||||
crudini --set $NODECFG proxy host localhost
|
||||
|
||||
# Setup $CPUS numbers of Zeek workers
|
||||
crudini --set $NODECFG worker-eth0 type worker
|
||||
crudini --set $NODECFG worker-eth0 host localhost
|
||||
crudini --set $NODECFG worker-eth0 interface eth0
|
||||
crudini --set $NODECFG worker-eth0 lb_method pf_ring
|
||||
crudini --set $NODECFG worker-eth0 lb_procs "$(nproc)"
|
||||
|
||||
# Setup Zeek to run at boot
|
||||
cp /vagrant/resources/zeek/zeek.service /lib/systemd/system/zeek.service
|
||||
systemctl enable zeek
|
||||
systemctl start zeek
|
||||
|
||||
# Configure the Splunk inputs
|
||||
mkdir -p /opt/splunk/etc/apps/Splunk_TA_bro/local && touch /opt/splunk/etc/apps/Splunk_TA_bro/local/inputs.conf
|
||||
crudini --set /opt/splunk/etc/apps/Splunk_TA_bro/local/inputs.conf monitor:///opt/zeek/spool/manager index zeek
|
||||
crudini --set /opt/splunk/etc/apps/Splunk_TA_bro/local/inputs.conf monitor:///opt/zeek/spool/manager sourcetype bro:json
|
||||
crudini --set /opt/splunk/etc/apps/Splunk_TA_bro/local/inputs.conf monitor:///opt/zeek/spool/manager whitelist '.*\.log$'
|
||||
crudini --set /opt/splunk/etc/apps/Splunk_TA_bro/local/inputs.conf monitor:///opt/zeek/spool/manager blacklist '.*(communication|stderr)\.log$'
|
||||
crudini --set /opt/splunk/etc/apps/Splunk_TA_bro/local/inputs.conf monitor:///opt/zeek/spool/manager disabled 0
|
||||
|
||||
# Ensure permissions are correct and restart splunk
|
||||
chown -R splunk:splunk /opt/splunk/etc/apps/Splunk_TA_bro
|
||||
/opt/splunk/bin/splunk restart
|
||||
|
||||
# Verify that Zeek is running
|
||||
if ! pgrep -f zeek >/dev/null; then
|
||||
echo "Zeek attempted to start but is not running. Exiting"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
install_velociraptor() {
|
||||
echo "[$(date +%H:%M:%S)]: Installing Velociraptor..."
|
||||
if [ ! -d "/opt/velociraptor" ]; then
|
||||
mkdir /opt/velociraptor
|
||||
fi
|
||||
echo "[$(date +%H:%M:%S)]: Attempting to determine the URL for the latest release of Velociraptor"
|
||||
LATEST_VELOCIRAPTOR_LINUX_URL=$(curl -sL https://github.com/Velocidex/velociraptor/releases/latest | grep 'linux-amd64' | grep -Eo "/(?[^\"]+)" | grep amd | sed 's#^#https://github.com#g')
|
||||
echo "[$(date +%H:%M:%S)]: The URL for the latest release was extracted as $LATEST_VELOCIRAPTOR_LINUX_URL"
|
||||
echo "[$(date +%H:%M:%S)]: Attempting to download..."
|
||||
#wget -P /opt/velociraptor --progress=bar:force "$LATEST_VELOCIRAPTOR_LINUX_URL"
|
||||
# Harcoding until the release after v0.4.7
|
||||
wget -P /opt/velociraptor --progress=bar:force "https://github.com/Velocidex/velociraptor/releases/download/v0.4.7/velociraptor-v0.4.7-1-linux-amd64"
|
||||
if [ "$(file /opt/velociraptor/velociraptor*linux-amd64 | grep -c 'ELF 64-bit LSB executable')" -eq 1 ]; then
|
||||
echo "[$(date +%H:%M:%S)]: Velociraptor successfully downloaded!"
|
||||
else
|
||||
echo "[$(date +%H:%M:%S)]: Failed to download the latest version of Velociraptor. Please open a DetectionLab issue on Github."
|
||||
return
|
||||
fi
|
||||
|
||||
cd /opt/velociraptor || exit 1
|
||||
mv velociraptor-*-linux-amd64 velociraptor
|
||||
chmod +x velociraptor
|
||||
cp /vagrant/resources/velociraptor/server.config.yaml /opt/velociraptor
|
||||
echo "[$(date +%H:%M:%S)]: Creating Velociraptor dpkg..."
|
||||
./velociraptor --config /opt/velociraptor/server.config.yaml debian server
|
||||
echo "[$(date +%H:%M:%S)]: Installing the dpkg..."
|
||||
if dpkg -i velociraptor_*_server.deb >/dev/null; then
|
||||
echo "[$(date +%H:%M:%S)]: Installation complete!"
|
||||
else
|
||||
echo "[$(date +%H:%M:%S)]: Failed to install the dpkg"
|
||||
return
|
||||
fi
|
||||
}
|
||||
|
||||
install_suricata() {
|
||||
# Run iwr -Uri testmyids.com -UserAgent "BlackSun" in Powershell to generate test alerts from Windows
|
||||
echo "[$(date +%H:%M:%S)]: Installing Suricata..."
|
||||
|
||||
# Install suricata
|
||||
apt-get -qq -y install suricata crudini
|
||||
test_suricata_prerequisites
|
||||
# Install suricata-update
|
||||
cd /opt || exit 1
|
||||
git clone https://github.com/OISF/suricata-update.git
|
||||
cd /opt/suricata-update || exit 1
|
||||
pip install pyyaml
|
||||
python setup.py install
|
||||
|
||||
cp /vagrant/resources/suricata/suricata.yaml /etc/suricata/suricata.yaml
|
||||
crudini --set --format=sh /etc/default/suricata '' iface eth0
|
||||
# update suricata signature sources
|
||||
suricata-update update-sources
|
||||
# disable protocol decode as it is duplicative of Zeek
|
||||
echo re:protocol-command-decode >>/etc/suricata/disable.conf
|
||||
# enable et-open and attackdetection sources
|
||||
suricata-update enable-source et/open
|
||||
suricata-update enable-source ptresearch/attackdetection
|
||||
|
||||
# Configure the Splunk inputs
|
||||
mkdir -p /opt/splunk/etc/apps/SplunkLightForwarder/local && touch /opt/splunk/etc/apps/SplunkLightForwarder/local/inputs.conf
|
||||
crudini --set /opt/splunk/etc/apps/SplunkLightForwarder/local/inputs.conf monitor:///var/log/suricata index suricata
|
||||
crudini --set /opt/splunk/etc/apps/SplunkLightForwarder/local/inputs.conf monitor:///var/log/suricata sourcetype suricata:json
|
||||
crudini --set /opt/splunk/etc/apps/SplunkLightForwarder/local/inputs.conf monitor:///var/log/suricata whitelist 'eve.json'
|
||||
crudini --set /opt/splunk/etc/apps/SplunkLightForwarder/local/inputs.conf monitor:///var/log/suricata disabled 0
|
||||
crudini --set /opt/splunk/etc/apps/SplunkLightForwarder/local/props.conf json_suricata TRUNCATE 0
|
||||
|
||||
# Update suricata and restart
|
||||
suricata-update
|
||||
service suricata stop
|
||||
service suricata start
|
||||
sleep 3
|
||||
|
||||
# Verify that Suricata is running
|
||||
if ! pgrep -f suricata >/dev/null; then
|
||||
echo "Suricata attempted to start but is not running. Exiting"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
test_suricata_prerequisites() {
|
||||
for package in suricata crudini; do
|
||||
echo "[$(date +%H:%M:%S)]: [TEST] Validating that $package is correctly installed..."
|
||||
# Loop through each package using dpkg
|
||||
if ! dpkg -S $package >/dev/null; then
|
||||
# If which returns a non-zero return code, try to re-install the package
|
||||
echo "[-] $package was not found. Attempting to reinstall."
|
||||
apt-get clean && apt-get -qq update && apt-get install -y $package
|
||||
if ! which $package >/dev/null; then
|
||||
# If the reinstall fails, give up
|
||||
echo "[X] Unable to install $package even after a retry. Exiting."
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
echo "[+] $package was successfully installed!"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
install_guacamole() {
|
||||
echo "[$(date +%H:%M:%S)]: Installing Guacamole..."
|
||||
cd /opt || exit 1
|
||||
apt-get -qq install -y libcairo2-dev libjpeg62-dev libpng-dev libossp-uuid-dev libfreerdp-dev libpango1.0-dev libssh2-1-dev libssh-dev tomcat8 tomcat8-admin tomcat8-user
|
||||
wget --progress=bar:force "http://apache.org/dyn/closer.cgi?action=download&filename=guacamole/1.0.0/source/guacamole-server-1.0.0.tar.gz" -O guacamole-server-1.0.0.tar.gz
|
||||
tar -xf guacamole-server-1.0.0.tar.gz && cd guacamole-server-1.0.0 || echo "[-] Unable to find the Guacamole folder."
|
||||
./configure &>/dev/null && make --quiet &>/dev/null && make --quiet install &>/dev/null || echo "[-] An error occurred while installing Guacamole."
|
||||
ldconfig
|
||||
cd /var/lib/tomcat8/webapps || echo "[-] Unable to find the tomcat8/webapps folder."
|
||||
wget --progress=bar:force "http://apache.org/dyn/closer.cgi?action=download&filename=guacamole/1.0.0/binary/guacamole-1.0.0.war" -O guacamole.war
|
||||
mkdir /etc/guacamole
|
||||
mkdir /usr/share/tomcat8/.guacamole
|
||||
cp /vagrant/resources/guacamole/user-mapping.xml /etc/guacamole/
|
||||
cp /vagrant/resources/guacamole/guacamole.properties /etc/guacamole/
|
||||
cp /vagrant/resources/guacamole/guacd.service /lib/systemd/system
|
||||
sudo ln -s /etc/guacamole/guacamole.properties /usr/share/tomcat8/.guacamole/
|
||||
sudo ln -s /etc/guacamole/user-mapping.xml /usr/share/tomcat8/.guacamole/
|
||||
systemctl enable guacd
|
||||
systemctl enable tomcat8
|
||||
systemctl start guacd
|
||||
systemctl start tomcat8
|
||||
}
|
||||
|
||||
postinstall_tasks() {
|
||||
# Include Splunk and Zeek in the PATH
|
||||
echo export PATH="$PATH:/opt/splunk/bin:/opt/zeek/bin" >>~/.bashrc
|
||||
echo "export SPLUNK_HOME=/opt/splunk" >>~/.bashrc
|
||||
# Ping DetectionLab server for usage statistics
|
||||
curl -s -A "DetectionLab-logger" "https:/ping.detectionlab.network/logger"
|
||||
}
|
||||
|
||||
main() {
|
||||
apt_install_prerequisites
|
||||
modify_motd
|
||||
test_prerequisites
|
||||
install_splunk
|
||||
download_palantir_osquery_config
|
||||
install_fleet_import_osquery_config
|
||||
install_velociraptor
|
||||
install_suricata
|
||||
install_zeek
|
||||
install_guacamole
|
||||
postinstall_tasks
|
||||
}
|
||||
|
||||
main
|
||||
exit 0
|
||||
18
HyperV/check-eth0-ip.sh
Normal file
18
HyperV/check-eth0-ip.sh
Normal file
@@ -0,0 +1,18 @@
|
||||
check_eth0_ip() {
|
||||
ETH1_IP=$(ip -4 addr show eth1 | grep -oP '(?<=inet\s)\d+(\.\d+){3}' | head -1)
|
||||
if [ "$ETH1_IP" != "192.168.38.105" ]; then
|
||||
echo "Incorrect IP Address settings detected. Attempting to fix."
|
||||
ifdown eth1
|
||||
ip addr flush dev eth1
|
||||
ifup eth1
|
||||
ETH1_IP=$(ifconfig eth1 | grep 'inet addr' | cut -d ':' -f 2 | cut -d ' ' -f 1)
|
||||
if [ "$ETH1_IP" == "192.168.38.105" ]; then
|
||||
echo "[$(date +%H:%M:%S)]: The static IP has been fixed and set to 192.168.38.105"
|
||||
else
|
||||
echo "[$(date +%H:%M:%S)]: Failed to fix the broken static IP for eth1. Exiting because this will cause problems with other VMs."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
check_eth0_ip
|
||||
31
HyperV/fix-eth0-static-ip.sh
Normal file
31
HyperV/fix-eth0-static-ip.sh
Normal file
@@ -0,0 +1,31 @@
|
||||
fix_eth0_static_ip() {
|
||||
# There's a fun issue where dhclient keeps messing with eth0 despite the fact
|
||||
# that eth0 has a static IP set. We workaround this by setting a static DHCP lease.
|
||||
echo -e 'interface "eth0" {
|
||||
send host-name = gethostname();
|
||||
send dhcp-requested-address 192.168.38.105;
|
||||
}' >>/etc/dhcp/dhclient.conf
|
||||
netplan apply
|
||||
# Set the ip address on eth0 and rename the adapter to eth1
|
||||
ETH0_IP=$(ip -4 addr show eth0 | grep -oP '(?<=inet\s)\d+(\.\d+){3}')
|
||||
if [ "$ETH0_IP" != "192.168.38.105" ]; then
|
||||
MAC=$(ip a | grep "link/ether" | cut -d ' ' -f 6)
|
||||
cat > /etc/netplan/01-netcfg.yaml << EOL
|
||||
network:
|
||||
ethernets:
|
||||
eth0:
|
||||
match:
|
||||
macaddress: $MAC
|
||||
dhcp4: no
|
||||
addresses: [192.168.38.105/24]
|
||||
gateway4: 192.168.38.1
|
||||
nameservers:
|
||||
addresses: [8.8.8.8,8.8.4.4]
|
||||
set-name: eth1
|
||||
version: 2
|
||||
renderer: networkd
|
||||
EOL
|
||||
fi
|
||||
}
|
||||
|
||||
fix_eth0_static_ip
|
||||
4
HyperV/fix-motd.sh
Normal file
4
HyperV/fix-motd.sh
Normal file
@@ -0,0 +1,4 @@
|
||||
#! /bin/sh
|
||||
# Fix the motd script
|
||||
cp /etc/update-motd.d/20-detectionlab .
|
||||
tr -d '\15\32' < 20-detectionlab > /etc/update-motd.d/20-detectionlab
|
||||
5
HyperV/hyperv-change-switch.ps1
Normal file
5
HyperV/hyperv-change-switch.ps1
Normal file
@@ -0,0 +1,5 @@
|
||||
# See: https://www.thomasmaurer.ch/2016/01/change-hyper-v-vm-switch-of-virtual-machines-using-powershell/
|
||||
# https://superuser.com/questions/1354658/hyperv-static-ip-with-vagrant#:~:text=%20HyperV%20-%20Static%20Ip%20with%20Vagrant%20,static%20IP%20address%20will%20be%20set...%20More%20
|
||||
|
||||
param ([String] $vmname)
|
||||
Get-VM "$vmname" | Get-VMNetworkAdapter | Connect-VMNetworkAdapter -SwitchName "NATSwitch"
|
||||
32
HyperV/hyperv-create-nat-switch.ps1
Normal file
32
HyperV/hyperv-create-nat-switch.ps1
Normal file
@@ -0,0 +1,32 @@
|
||||
# See: https://www.petri.com/using-nat-virtual-switch-hyper-v
|
||||
|
||||
If ("NATSwitch" -in (Get-VMSwitch | Select-Object -ExpandProperty Name) -eq $FALSE) {
|
||||
'Creating Internal-only switch named "NATSwitch" on Windows Hyper-V host...'
|
||||
|
||||
New-VMSwitch -SwitchName "NATSwitch" -SwitchType Internal
|
||||
|
||||
New-NetIPAddress -IPAddress 192.168.38.1 -PrefixLength 24 -InterfaceAlias "vEthernet (NATSwitch)"
|
||||
|
||||
New-NetNAT -Name "NATNetwork" -InternalIPInterfaceAddressPrefix 192.168.38.0/24
|
||||
}
|
||||
else {
|
||||
'"NATSwitch" for static IP configuration already exists; skipping'
|
||||
}
|
||||
|
||||
If ("192.168.38.1" -in (Get-NetIPAddress | Select-Object -ExpandProperty IPAddress) -eq $FALSE) {
|
||||
'Registering new IP address 192.168.38.1 on Windows Hyper-V host...'
|
||||
|
||||
New-NetIPAddress -IPAddress 192.168.38.1 -PrefixLength 24 -InterfaceAlias "vEthernet (NATSwitch)"
|
||||
}
|
||||
else {
|
||||
'"192.168.38.1" for static IP configuration already registered; skipping'
|
||||
}
|
||||
|
||||
If ("192.168.38.0/24" -in (Get-NetNAT | Select-Object -ExpandProperty InternalIPInterfaceAddressPrefix) -eq $FALSE) {
|
||||
'Registering new NAT adapter for 192.168.38.0/24 on Windows Hyper-V host...'
|
||||
|
||||
New-NetNAT -Name "NATNetwork" -InternalIPInterfaceAddressPrefix 192.168.38.0/24
|
||||
}
|
||||
else {
|
||||
'"192.168.38.0/24" for static IP configuration already registered; skipping'
|
||||
}
|
||||
3
HyperV/hyperv-remove-networkadapter.ps1
Normal file
3
HyperV/hyperv-remove-networkadapter.ps1
Normal file
@@ -0,0 +1,3 @@
|
||||
param ([String] $vmname)
|
||||
|
||||
Remove-VMNetworkAdapter -VMName $vmname -Name "Network Adapter"
|
||||
29
HyperV/hyperv-set-static-ip.ps1
Normal file
29
HyperV/hyperv-set-static-ip.ps1
Normal file
@@ -0,0 +1,29 @@
|
||||
# Source: https://github.com/StefanScherer/adfs
|
||||
|
||||
param ([String] $ip, [String] $dns)
|
||||
|
||||
Write-Host "$('[{0:HH:mm}]' -f (Get-Date))"
|
||||
Write-Host "Setting IP address and DNS information."
|
||||
Write-Host "If this step times out, it's because vagrant is connecting to the VM on the wrong interface"
|
||||
Write-Host "See https://github.com/clong/DetectionLab/issues/114 for more information"
|
||||
|
||||
$subnet = $ip -replace "\.\d+$", ""
|
||||
$name = (Get-NetIPAddress -AddressFamily IPv4 `
|
||||
| Where-Object -FilterScript { ($_.IPAddress).StartsWith("169") } `
|
||||
).InterfaceAlias
|
||||
if (!$name) {
|
||||
$name = (Get-NetIPAddress -AddressFamily IPv4 `
|
||||
| Where-Object -FilterScript { ($_.IPAddress).StartsWith("192.168.38") } `
|
||||
).InterfaceAlias
|
||||
}
|
||||
if ($name) {
|
||||
Write-Host "Set IP address to $ip of interface $name"
|
||||
& netsh.exe int ip set address $name static $ip 255.255.255.0 "$subnet.1"
|
||||
Write-Host "Set DNS server address to $dns of interface $name"
|
||||
& netsh.exe interface ipv4 add dnsserver $name address=192.168.38.102 index=1
|
||||
if ($dns) {
|
||||
& netsh.exe interface ipv4 add dnsserver $name address=$dns index=2
|
||||
}
|
||||
} else {
|
||||
Write-Error "Could not find a interface with subnet $subnet.xx"
|
||||
}
|
||||
8
HyperV/hyperv-set-switch.ps1
Normal file
8
HyperV/hyperv-set-switch.ps1
Normal file
@@ -0,0 +1,8 @@
|
||||
# See: https://www.thomasmaurer.ch/2016/01/change-hyper-v-vm-switch-of-virtual-machines-using-powershell/
|
||||
param ([String] $vmname)
|
||||
# Get-VM $vmname | Get-VMNetworkAdapter | Connect-VMNetworkAdapter -SwitchName "NATSwitch"
|
||||
if (((Get-VMNetworkAdapter -VMName $vmname).Name).Contains("NATAdapter")){
|
||||
Write-Host "The NATAdapter already exits"
|
||||
} else {
|
||||
Add-VMNetworkAdapter -VMName $vmname -SwitchName "NATSwitch" -Name NATAdapter -DeviceNaming On
|
||||
}
|
||||
@@ -15,6 +15,8 @@ if ("$env:PACKER_BUILDER_TYPE" -eq "vmware-iso") {
|
||||
|
||||
if (!(Test-Path "C:\Windows\Temp\windows.iso")) {
|
||||
Try {
|
||||
# Disabling the progress bar speeds up IWR https://github.com/PowerShell/PowerShell/issues/2138
|
||||
$ProgressPreference = 'SilentlyContinue'
|
||||
$pageContentLinks = (Invoke-WebRequest('https://softwareupdate.vmware.com/cds/vmw-desktop/ws') -UseBasicParsing).Links | where-object {$_.href -Match "[0-9]"} | Select-Object href | % { $_.href.Trim('/') }
|
||||
$versionObject = $pageContentLinks | %{ new-object System.Version ($_) } | sort-object -Descending | select-object -First 1 -Property:Major,Minor,Build
|
||||
$newestVersion = $versionObject.Major.ToString()+"."+$versionObject.Minor.ToString()+"."+$versionObject.Build.ToString() | out-string
|
||||
|
||||
@@ -93,7 +93,8 @@
|
||||
"winrm_username": "vagrant",
|
||||
"winrm_password": "vagrant",
|
||||
"winrm_timeout": "4h",
|
||||
"shutdown_command": "shutdown /s /t 10 /f /d p:4:1 /c \"Packer Shutdown\"",
|
||||
"shutdown_command": "a:/sysprep.bat",
|
||||
"shutdown_timeout": "2h",
|
||||
"accelerator": "kvm",
|
||||
"disk_size": "{{user `disk_size`}}",
|
||||
"output_directory": "{{ user `packer_build_dir`}}",
|
||||
@@ -177,4 +178,4 @@
|
||||
"autounattend_virtio": "./answer_files/2016_virtio/Autounattend.xml",
|
||||
"packer_build_dir": "./win2016"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
54
README.md
54
README.md
@@ -37,43 +37,29 @@ NOTE: This lab has not been hardened in any way and runs with default vagrant cr
|
||||
* Zeek and Suricata are pre-configured to monitor and alert on network traffic
|
||||
* Apache Guacamole is installed to easily access all hosts from your local browser
|
||||
|
||||
## Requirements for VMware or Virtualbox
|
||||
* 55GB+ of free disk space
|
||||
* 16GB+ of RAM
|
||||
* Packer 1.6.0 or newer
|
||||
* Vagrant 2.2.9 or newer
|
||||
* Virtualbox or VMWare Fusion/Workstation
|
||||
|
||||
---
|
||||
|
||||
## Building Detection Lab
|
||||
|
||||
Please view the quickstart guides based on the operating system you are using. The AWS and Azure deployment options for DetectionLab can be launched from any operating system.
|
||||
|
||||
* [AWS via Terraform](https://github.com/clong/DetectionLab/wiki/Quickstart---AWS-(Terraform))
|
||||
* [Azure via Terraform & Ansible](https://github.com/clong/DetectionLab/tree/master/Azure)
|
||||
* [MacOS](https://github.com/clong/DetectionLab/wiki/Quickstart---MacOS)
|
||||
* [Windows](https://github.com/clong/DetectionLab/wiki/Quickstart---Windows)
|
||||
* [Linux](https://github.com/clong/DetectionLab/wiki/Quickstart-Linux)
|
||||
* [ESXi](https://github.com/clong/DetectionLab/tree/master/ESXi)
|
||||
* [Prerequisites](https://www.detectionlab.network/introduction/prerequisites/)
|
||||
* [MacOS - Virtualbox or VMware Fusion](https://www.detectionlab.network/deployment/macosvm/)
|
||||
* [Windows - Virtualbox or VMware Workstation](https://www.detectionlab.network/deployment/windowsvm/)
|
||||
* [Linux - Virtualbox or VMware Workstation](https://www.detectionlab.network/deployment/linuxvm/)
|
||||
* [AWS via Terraform](https://www.detectionlab.network/deployment/aws/)
|
||||
* [Azure via Terraform & Ansible](https://www.detectionlab.network/deployment/azure/)
|
||||
* [ESXi via Terraform & Ansible](https://www.detectionlab.network/deployment/esxi/)
|
||||
* [HyperV](https://www.detectionlab.network/deployment/hyperv/)
|
||||
* [LibVirt](https://www.detectionlab.network/deployment/libvirt/)
|
||||
|
||||
---
|
||||
|
||||
## Basic Vagrant Usage
|
||||
## DetectionLab Documentation
|
||||
|
||||
Moved to the wiki: [Basic Vagrant Usage](https://github.com/clong/DetectionLab/wiki/Vagrant-Usage)
|
||||
The primary documentation site is located at https://detectionlab.network
|
||||
|
||||
---
|
||||
|
||||
## Lab Information
|
||||
|
||||
Moved to the wiki: [Lab Information & Credentials](https://github.com/clong/DetectionLab/wiki/Lab-Information-&-Credentials)
|
||||
|
||||
---
|
||||
|
||||
## Known Issues and Workarounds
|
||||
|
||||
Moved to the wiki: [Known Issues and Workarounds](https://github.com/clong/DetectionLab/wiki/Known-Issues-and-Workarounds)
|
||||
* [Basic Vagrant Usage](https://www.detectionlab.network/introduction/basicvagrant/)
|
||||
* [Lab Information & Credentials](https://www.detectionlab.network/introduction/infoandcreds/)
|
||||
* [Troubleshooting and Known Issues](https://www.detectionlab.network/deployment/troubleshooting/)
|
||||
|
||||
---
|
||||
|
||||
@@ -111,24 +97,30 @@ A sizable percentage of this code was borrowed and adapted from [Stefan Scherer]
|
||||
* [sysmon-modular](https://github.com/olafhartong/sysmon-modular)
|
||||
* [Atomic Red Team](https://github.com/redcanaryco/atomic-red-team)
|
||||
* [Hunting for Beacons](http://findingbad.blogspot.com/2020/05/hunting-for-beacons-part-2.html)
|
||||
* [Velociraptor](https://github.com/Velocidex/velociraptor)
|
||||
* [BadBlood](https://github.com/davidprowe/BadBlood)
|
||||
* [PurpleSharp](https://github.com/mvelazc0/PurpleSharp)
|
||||
|
||||
# DetectionLab Sponsors
|
||||
#### Lated updated: 8/8/2020
|
||||
#### Lated updated: 9/16/2020
|
||||
I would like to extend thanks to the following sponsors for funding DetectionLab development. If you are interested in becoming a sponsor, please visit the [sponsors page](https://github.com/sponsors/clong).
|
||||
|
||||
### Diamond Sponsors:
|
||||
* [Veramine](https://github.com/veramine)
|
||||
* [Thinkst](https://github.com/ThinkstAppliedResearch)
|
||||
* [csterner82](https://github.com/csterner82)
|
||||
* [swizzlez](https://github.com/swizzlez)
|
||||
* [CyDefUnicorn](https://github.com/CyDefUnicorn)
|
||||
* [olliencc](https://github.com/olliencc)
|
||||
|
||||
### Premium Sponsors:
|
||||
* [CyDefUnicorn](https://github.com/CyDefUnicorn)
|
||||
* [mikeesparza](https://github.com/mikeesparza)
|
||||
* [dlee35](https://github.com/dlee35)
|
||||
* [chrissanders](https://github.com/chrissanders)
|
||||
* [punchdrunktux](https://github.com/punchdrunktux)
|
||||
* [jaredhaight](https://github.com/jaredhaight)
|
||||
* [iamfuntime](https://github.com/iamfuntime)
|
||||
* +1 private sponsor
|
||||
* [Luct0r](https://github.com/Luct0r)
|
||||
|
||||
### Standard Sponsors:
|
||||
* [dtonomy](https://github.com/dtonomy)
|
||||
|
||||
@@ -294,7 +294,7 @@ install_fleet_import_osquery_config() {
|
||||
|
||||
# Don't log osquery INFO messages
|
||||
# Fix snapshot event formatting
|
||||
fleetctl get options > /tmp/options.yaml
|
||||
fleetctl get options >/tmp/options.yaml
|
||||
/usr/bin/yq w -i /tmp/options.yaml 'spec.config.options.enroll_secret' 'enrollmentsecret'
|
||||
/usr/bin/yq w -i /tmp/options.yaml 'spec.config.options.logger_snapshot_event_type' 'true'
|
||||
# Fleet 3.0 requires the "kind" to be "options" instead of "option"
|
||||
@@ -399,12 +399,10 @@ install_velociraptor() {
|
||||
mkdir /opt/velociraptor
|
||||
fi
|
||||
echo "[$(date +%H:%M:%S)]: Attempting to determine the URL for the latest release of Velociraptor"
|
||||
LATEST_VELOCIRAPTOR_LINUX_URL=$(curl -sL https://github.com/Velocidex/velociraptor/releases/latest | grep 'linux-amd64' | grep -Eo "/(?[^\"]+)" | grep amd | sed 's#^#https://github.com#g')
|
||||
LATEST_VELOCIRAPTOR_LINUX_URL=$(curl -sL https://github.com/Velocidex/velociraptor/releases/latest | grep linux-amd64 | grep href | head -1 | cut -d '"' -f 2 | sed 's#^#https://github.com#g')
|
||||
echo "[$(date +%H:%M:%S)]: The URL for the latest release was extracted as $LATEST_VELOCIRAPTOR_LINUX_URL"
|
||||
echo "[$(date +%H:%M:%S)]: Attempting to download..."
|
||||
#wget -P /opt/velociraptor --progress=bar:force "$LATEST_VELOCIRAPTOR_LINUX_URL"
|
||||
# Harcoding until the release after v0.4.7
|
||||
wget -P /opt/velociraptor --progress=bar:force "https://github.com/Velocidex/velociraptor/releases/download/v0.4.7/velociraptor-v0.4.7-1-linux-amd64"
|
||||
wget -P /opt/velociraptor --progress=bar:force "$LATEST_VELOCIRAPTOR_LINUX_URL"
|
||||
if [ "$(file /opt/velociraptor/velociraptor*linux-amd64 | grep -c 'ELF 64-bit LSB executable')" -eq 1 ]; then
|
||||
echo "[$(date +%H:%M:%S)]: Velociraptor successfully downloaded!"
|
||||
else
|
||||
@@ -470,6 +468,22 @@ install_suricata() {
|
||||
echo "Suricata attempted to start but is not running. Exiting"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cat >/etc/logrotate.d/suricata <<EOF
|
||||
/var/log/suricata/*.log /var/log/suricata/*.json
|
||||
{
|
||||
hourly
|
||||
rotate 0
|
||||
missingok
|
||||
nocompress
|
||||
size=500M
|
||||
sharedscripts
|
||||
postrotate
|
||||
/bin/kill -HUP \`cat /var/run/suricata.pid 2>/dev/null\` 2>/dev/null || true
|
||||
endscript
|
||||
}
|
||||
EOF
|
||||
|
||||
}
|
||||
|
||||
test_suricata_prerequisites() {
|
||||
@@ -519,7 +533,7 @@ postinstall_tasks() {
|
||||
echo export PATH="$PATH:/opt/splunk/bin:/opt/zeek/bin" >>~/.bashrc
|
||||
echo "export SPLUNK_HOME=/opt/splunk" >>~/.bashrc
|
||||
# Ping DetectionLab server for usage statistics
|
||||
curl -s -A "DetectionLab-logger" "https:/ping.detectionlab.network/logger"
|
||||
curl -s -A "DetectionLab-logger" "https:/ping.detectionlab.network/logger" || echo "Unable to connect to ping.detectionlab.network"
|
||||
}
|
||||
|
||||
main() {
|
||||
|
||||
83
Vagrant/post_build_checks.ps1
Normal file
83
Vagrant/post_build_checks.ps1
Normal file
@@ -0,0 +1,83 @@
|
||||
function download {
|
||||
param(
|
||||
[string]$URL,
|
||||
[string]$PatternToMatch,
|
||||
[switch]$SuccessOn401
|
||||
)
|
||||
[System.Net.ServicePointManager]::ServerCertificateValidationCallback = { $true }
|
||||
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
|
||||
|
||||
$wc = New-Object System.Net.WebClient
|
||||
try {
|
||||
$result = $wc.DownloadString($URL)
|
||||
if ($result -like "*$PatternToMatch*") {
|
||||
return $true
|
||||
} else {
|
||||
return $false
|
||||
}
|
||||
}
|
||||
catch {
|
||||
if ($_.Exception.InnerException.Response.StatusCode -eq 401 -and $SuccessOn401.IsPresent) {
|
||||
return $true
|
||||
} else {
|
||||
Write-Host "Error occured on webrequest: $_" -ForegroundColor red
|
||||
return $false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function post_build_checks {
|
||||
$checkmark = ([char]8730)
|
||||
|
||||
Write-Host '[*] Verifying that Splunk is reachable...'
|
||||
$SPLUNK_CHECK = download -URL 'https://192.168.38.105:8000/en-US/account/login?return_to=%2Fen-US%2F' -PatternToMatch 'This browser is not supported by Splunk'
|
||||
if ($SPLUNK_CHECK -eq $false) {
|
||||
Write-Host '[!] Splunk was unreachable and may not have installed correctly.' -ForegroundColor red
|
||||
}
|
||||
else {
|
||||
Write-Host ' ['$($checkmark)'] Splunk is running and reachable!' -ForegroundColor Green
|
||||
}
|
||||
Write-Host ''
|
||||
|
||||
Write-Host '[*] Verifying that Fleet is reachable...'
|
||||
$FLEET_CHECK = download -URL 'https://192.168.38.105:8412' -PatternToMatch 'Kolide Fleet'
|
||||
if ($FLEET_CHECK -eq $false) {
|
||||
Write-Host '[!] Fleet was unreachable and may not have installed correctly.' -ForegroundColor red
|
||||
}
|
||||
else {
|
||||
Write-Host ' ['$($checkmark)'] Fleet is running and reachable!' -ForegroundColor Green
|
||||
}
|
||||
Write-Host ''
|
||||
|
||||
Write-Host '[*] Verifying that Microsoft ATA is reachable...'
|
||||
$ATA_CHECK = download -URL 'https://192.168.38.103' -SuccessOn401
|
||||
if ($ATA_CHECK -eq $false) {
|
||||
Write-Host '[!] Microsoft ATA was unreachable and may not have installed correctly.' -ForegroundColor red
|
||||
}
|
||||
else {
|
||||
Write-Host ' ['$($checkmark)'] Microsoft ATA is running and reachable!' -ForegroundColor Green
|
||||
}
|
||||
Write-Host ''
|
||||
|
||||
Write-Host '[*] Verifying that Velociraptor is reachable...'
|
||||
$VELOCIRAPTOR_CHECK = download -URL 'https://192.168.38.105:9999' -PatternToMatch 'app.html'
|
||||
if ($VELOCIRAPTOR_CHECK -eq $false) {
|
||||
Write-Host '[!] Velociraptor was unreachable and may not have installed correctly.' -ForegroundColor red
|
||||
}
|
||||
else {
|
||||
Write-Host ' ['$($checkmark)'] Velocirpator is running and reachable!' -ForegroundColor Green
|
||||
}
|
||||
Write-Host ''
|
||||
|
||||
Write-Host '[*] Verifying that Guacamole is reachable...'
|
||||
$GUACAMOLE_CHECK = download -URL 'http://192.168.38.105:8080/guacamole' -PatternToMatch 'Apache Software'
|
||||
if ($GUACAMOLE_CHECK -eq $false) {
|
||||
Write-Host '[!] Guacamole was unreachable and may not have installed correctly.' -ForegroundColor red
|
||||
}
|
||||
else {
|
||||
Write-Host ' ['$($checkmark)'] Guacamole is running and reachable!' -ForegroundColor Green
|
||||
}
|
||||
Write-Host ''
|
||||
}
|
||||
|
||||
post_build_checks
|
||||
68
Vagrant/post_build_checks.sh
Executable file
68
Vagrant/post_build_checks.sh
Executable file
@@ -0,0 +1,68 @@
|
||||
#! /bin/bash
|
||||
|
||||
# This script is meant to verify that DetectionLab was built successfully.
|
||||
# Only MacOS and Linux are supported. Use post_build_checks.ps1 for Windows.
|
||||
# If you encounter issues, feel free to open an issue at
|
||||
# https://github.com/clong/DetectionLab/issues
|
||||
|
||||
ERROR=$(tput setaf 1; echo -n " [!]"; tput sgr0)
|
||||
GOODTOGO=$(tput setaf 2; echo -n " [✓]"; tput sgr0)
|
||||
|
||||
# A series of checks to ensure important services are responsive after the build completes.
|
||||
post_build_checks() {
|
||||
SPLUNK_CHECK=0
|
||||
FLEET_CHECK=0
|
||||
ATA_CHECK=0
|
||||
VELOCIRAPTOR_CHECK=0
|
||||
GUACAMOLE_CHECK=0
|
||||
# If the curl operation fails, we'll just leave the variable equal to 0
|
||||
# This is needed to prevent the script from exiting if the curl operation fails
|
||||
SPLUNK_CHECK=$(curl -ks -m 2 https://192.168.38.105:8000/en-US/account/login?return_to=%2Fen-US%2F | grep -c 'This browser is not supported by Splunk')
|
||||
FLEET_CHECK=$(curl -ks -m 2 https://192.168.38.105:8412 | grep -c 'Kolide Fleet')
|
||||
ATA_CHECK=$(curl --fail --write-out "%{http_code}" -ks https://192.168.38.103 -m 2)
|
||||
VELOCIRAPTOR_CHECK=$(curl -ks -m 2 https://192.168.38.105:9999 | grep -c 'app.html')
|
||||
GUACAMOLE_CHECK=$(curl -ks -m 2 'http://192.168.38.105:8080/guacamole/#/' | grep -c 'Apache Software')
|
||||
[[ $ATA_CHECK == 401 ]] && ATA_CHECK=1
|
||||
|
||||
echo "[*] Verifying that Splunk is running and reachable..."
|
||||
if [ "$SPLUNK_CHECK" -lt 1 ]; then
|
||||
(echo >&2 "${ERROR} Warning: Splunk was unreachable and may not have installed correctly.")
|
||||
else
|
||||
(echo >&2 "${GOODTOGO} Splunk is running and reachable.")
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "[*] Verifying that Fleet is running and reachable..."
|
||||
if [ "$FLEET_CHECK" -lt 1 ]; then
|
||||
(echo >&2 "${ERROR} Warning: Fleet was unreachable and may not have installed correctly.")
|
||||
else
|
||||
(echo >&2 "${GOODTOGO} Fleet is running and reachable.")
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "[*] Verifying that Microsoft ATA is running and reachable..."
|
||||
if [ "$ATA_CHECK" -lt 1 ]; then
|
||||
(echo >&2 "${ERROR} Warning: Microsoft ATA was unreachable and may not have installed correctly.")
|
||||
else
|
||||
(echo >&2 "${GOODTOGO} Microsoft ATA is running and reachable.")
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "[*] Verifying that the Velociraptor service is running and reachable..."
|
||||
if [ "$VELOCIRAPTOR_CHECK" -lt 1 ]; then
|
||||
(echo >&2 "${ERROR} Warning: Velociraptor was unreachable and may not have installed correctly.")
|
||||
else
|
||||
(echo >&2 "${GOODTOGO} Velociraptor is running and reachable.")
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "[*] Verifying that Guacamole is running and reachable..."
|
||||
if [ "$GUACAMOLE_CHECK" -lt 1 ]; then
|
||||
(echo >&2 "${ERROR} Warning: Guacamole was unreachable and may not have installed correctly.")
|
||||
else
|
||||
(echo >&2 "${GOODTOGO} Guacamole is running and reachable.")
|
||||
fi
|
||||
}
|
||||
|
||||
post_build_checks
|
||||
exit 0
|
||||
265
Vagrant/prepare.ps1
Normal file
265
Vagrant/prepare.ps1
Normal file
@@ -0,0 +1,265 @@
|
||||
#Requires -Version 4.0
|
||||
|
||||
<#
|
||||
.Synopsis
|
||||
This script is used to ensure prerequisites for DetectionLab
|
||||
are properly installed.
|
||||
|
||||
.DESCRIPTION
|
||||
This scripts runs a series of tests. It checks:
|
||||
|
||||
* If Packer and Vagrant are installed
|
||||
* If VirtualBox and/or VMware are installed
|
||||
* If the proper vagrant plugins are available
|
||||
* Various aspects of system health
|
||||
|
||||
If you encounter issues, feel free to open an issue at
|
||||
https://github.com/clong/DetectionLab/issues
|
||||
|
||||
|
||||
.EXAMPLE
|
||||
./prepare.ps1
|
||||
|
||||
This runs a series of checks to ensure your system will successfully be
|
||||
able to build DetectionLab.
|
||||
#>
|
||||
|
||||
$VAGRANT_DIR = Split-Path -Parent -Path $MyInvocation.MyCommand.Definition
|
||||
$checkmark = ([char]8730)
|
||||
|
||||
function install_checker {
|
||||
param(
|
||||
[string]$Name
|
||||
)
|
||||
$results = Get-ItemProperty 'HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*' | Select-Object DisplayName
|
||||
$results += Get-ItemProperty 'HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*' | Select-Object DisplayName
|
||||
|
||||
forEach ($result in $results) {
|
||||
if ($result -like "*$Name*") {
|
||||
return $true
|
||||
}
|
||||
}
|
||||
return $false
|
||||
}
|
||||
|
||||
function check_packer_path {
|
||||
# Check if Packer is in path
|
||||
Try {
|
||||
Get-Command packer.exe -ErrorAction Stop | Out-Null
|
||||
}
|
||||
Catch {
|
||||
Write-Host ' [-] Packer was not found in your PATH.' -ForegroundColor yellow
|
||||
Write-Host ' [-] This is only needed if you plan to build your own boxes, otherwise you can ignore this message.' -ForegroundColor yellow
|
||||
}
|
||||
}
|
||||
function check_vagrant_path {
|
||||
# Check if Vagrant is in path
|
||||
Try {
|
||||
Get-Command vagrant.exe -ErrorAction Stop | Out-Null
|
||||
}
|
||||
Catch {
|
||||
Write-Host ' [!] Vagrant was not found in your PATH. Please correct this before continuing.' -ForegroundColor red
|
||||
Write-Host ' [!] Correct this by installing Vagrant with Choco or downloading from https://www.vagrantup.com/downloads.html' -ForegroundColor red
|
||||
Break
|
||||
}
|
||||
|
||||
# Check Vagrant version >= 2.2.9
|
||||
[System.Version]$vagrant_version = $(vagrant --version).Split(' ')[1]
|
||||
[System.Version]$version_comparison = 2.2.9
|
||||
|
||||
if ($vagrant_version -lt $version_comparison) {
|
||||
Write-Host ' [-] It is highly recommended to use Vagrant 2.2.9 or above before continuing' -ForegroundColor yellow
|
||||
}
|
||||
else {
|
||||
Write-Host ' ['$($checkmark)'] Your version of Vagrant ('$vagrant_version') is supported' -ForegroundColor Green
|
||||
}
|
||||
}
|
||||
|
||||
# Returns false if not installed or true if installed
|
||||
function check_virtualbox_installed {
|
||||
Write-Host ''
|
||||
Write-Host '[+] Checking if Virtualbox is installed...'
|
||||
if (install_checker -Name "VirtualBox") {
|
||||
Write-Host ' ['$($checkmark)'] Virtualbox found.' -ForegroundColor green
|
||||
return $true
|
||||
}
|
||||
else {
|
||||
return $false
|
||||
}
|
||||
}
|
||||
function check_vmware_workstation_installed {
|
||||
Write-Host ''
|
||||
Write-Host '[+] Checking if VMware Workstation is installed...'
|
||||
if (install_checker -Name "VMware Workstation") {
|
||||
Write-Host ' ['$($checkmark)'] VMware Workstation found.' -ForegroundColor green
|
||||
return $true
|
||||
}
|
||||
else {
|
||||
return $false
|
||||
}
|
||||
}
|
||||
|
||||
function check_vmware_vagrant_plugin_installed {
|
||||
Write-Host ''
|
||||
Write-Host '[+] Checking if the vagrant_vmware_desktop plugin is installed...'
|
||||
if (vagrant plugin list | Select-String 'vagrant-vmware-workstation') {
|
||||
Write-Host ' [!] The vagrant VMware Workstation plugin is no longer supported.' -ForegroundColor red
|
||||
Write-Host ' [-] Please upgrade to the VMware Desktop plugin: https://www.vagrantup.com/docs/vmware/installation.html' -ForegroundColor yellow
|
||||
Write-Host ' [-] Please also uninstall the vagrant-vmware-fusion plugin and install the vmware-vagrant-desktop plugin' -ForegroundColor yellow
|
||||
Write-Host ' [-] HINT: `vagrant plugin uninstall vagrant-vmware-workstation; vagrant plugin install vagrant-vmware-desktop`' -ForegroundColor yellow
|
||||
return $false
|
||||
}
|
||||
if (vagrant plugin list | Select-String 'vagrant-vmware-desktop') {
|
||||
Write-Host ' ['$($checkmark)'] Vagrant VMware Desktop plugin found.' -ForegroundColor green
|
||||
return $true
|
||||
}
|
||||
else {
|
||||
Write-Host ' [!] VMware Workstation is installed, but the vagrant-vmware-desktop plugin is not.' -ForegroundColor red
|
||||
Write-Host ' [-] Visit https://www.vagrantup.com/vmware/index.html#buy-now for more information on how to purchase ($80) and install it' -ForegroundColor yellow
|
||||
Write-Host ' [-] VMware Workstation will not be listed as a provider until the Vagrant plugin has been installed.' -ForegroundColor yellow
|
||||
Write-Host ' [-] NOTE: The plugin does not work with trial versions of VMware Workstation' -ForegroundColor yellow
|
||||
return $false
|
||||
}
|
||||
}
|
||||
|
||||
function check_vagrant_vmware_utility_installed {
|
||||
Write-Host ''
|
||||
Write-Host '[+] Checking if the Vagrant VMware Utility is installed...'
|
||||
if (install_checker -Name "Vagrant VMware Utility") {
|
||||
Write-Host ' ['$($checkmark)'] Vagrant VMware Utility is installed' -ForegroundColor green
|
||||
return $true
|
||||
}
|
||||
else {
|
||||
Write-Host ' [!] To use VMware Workstation as a provider, you need to install the Vagrant VMware Utility.' -ForegroundColor Red
|
||||
Write-Host ' [-] To download and install it, visit https://www.vagrantup.com/docs/providers/vmware/vagrant-vmware-utility'
|
||||
return $false
|
||||
}
|
||||
}
|
||||
|
||||
function list_providers {
|
||||
[cmdletbinding()]
|
||||
param()
|
||||
|
||||
$vboxInstalled = 0
|
||||
$vmwareInstalled = 0
|
||||
if (check_virtualbox_installed) {
|
||||
$vboxInstalled = 1
|
||||
}
|
||||
if (check_vmware_workstation_installed) {
|
||||
if ((check_vmware_vagrant_plugin_installed) -and (check_vagrant_vmware_utility_installed)) {
|
||||
$vmwareInstalled = 1
|
||||
}
|
||||
}
|
||||
# Warn users if Virtualbox and VMware Workstation are both installed.
|
||||
if (( $vboxInstalled -eq 1 ) -and ( $vmwareInstalled -eq 1 )) {
|
||||
Write-Host " [-] Both VMware Workstation and Virtualbox appear to be installed on this system." -ForegroundColor Yellow
|
||||
Write-Host " [-] Please consider setting the VAGRANT_DEFAULT_PROVIDER environment variable to prevent confusion." -ForegroundColor Yellow
|
||||
Write-Host " [-] More details can be found here: https://www.vagrantup.com/docs/providers/default" -ForegroundColor Yellow
|
||||
Write-Host " [-] Additionally, please ensure only one providers' network adapters are active at any given time." -ForegroundColor Yellow
|
||||
}
|
||||
if (($vboxInstalled -eq 0) -and ($vmwareInstalled -eq 0)) {
|
||||
Write-Error ' [!] You need to install a provider such as VirtualBox or VMware Workstation to continue.' -ForegroundColor red
|
||||
Write-Error ' [!] Virtualbox is free, the VMware Vagrant Plugin costs $80.' -ForegroundColor red
|
||||
break
|
||||
}
|
||||
Write-Host ''
|
||||
Write-Host '[+] Enumerating available providers...'
|
||||
Write-Host "[+] Available Providers: "
|
||||
if ($vboxInstalled -eq 1) {
|
||||
Write-Host ' [*] virtualbox' -ForegroundColor green
|
||||
}
|
||||
if ($vmwareInstalled -eq 1) {
|
||||
Write-Host ' [*] vmware_desktop' -ForegroundColor green
|
||||
}
|
||||
}
|
||||
|
||||
function preflight_checks {
|
||||
Write-Host ''
|
||||
Write-Host '[+] Checking if CredentialGuard is enabled...'
|
||||
# Verify CredentialGuard isn't enabled
|
||||
if (('CredentialGuard' -match ((Get-ComputerInfo).DeviceGuardSecurityServicesConfigured) -eq "True")) {
|
||||
Write-Host ' [!] CredentialGuard appears to be enabled on this system which can cause issues with Virtualbox.' -ForegroundColor red
|
||||
Write-Host ' [!] See this thread for more info: https://forums.virtualbox.org/viewtopic.php?f=25&t=82106' -ForegroundColor red
|
||||
}
|
||||
|
||||
Write-Host ''
|
||||
Write-Host '[+] Checking if any boxes have been manually built...'
|
||||
if ((Get-ChildItem "$VAGRANT_DIR\..\Boxes\*.box").Count -gt 0) {
|
||||
Write-Host ' [-] You seem to have at least one .box file present in the Boxes directory already.' -ForegroundColor yellow
|
||||
Write-Host ' [-] If you would like to use the pre-built boxes, please remove all .box files from the Boxes directory' -ForegroundColor yellow
|
||||
}
|
||||
else {
|
||||
Write-Host ' ['$($checkmark)'] No custom Packer boxes found' -ForegroundColor green
|
||||
}
|
||||
|
||||
# Check to see that no Vagrant instances exist
|
||||
Write-Host ''
|
||||
Write-Host '[+] Checking if any Vagrant instances have been created...'
|
||||
$CurrentDir = Get-Location
|
||||
Set-Location "$VAGRANT_DIR"
|
||||
if (($(vagrant status) | Select-String -Pattern "not[ _]created").Count -ne 4) {
|
||||
Write-Host ' [-] You appear to have already created at least one Vagrant instance.' -ForegroundColor yellow
|
||||
vagrant status | Select-String 'not[ _]created' -NotMatch | Select-String -Pattern 'logger|dc|wef|win10'
|
||||
Write-Host ''
|
||||
Write-Host ' [-] If you want to start with a fresh install, you should run `vagrant destroy -f` to remove existing instances.' -ForegroundColor yellow
|
||||
}
|
||||
else {
|
||||
Write-Host ' ['$($checkmark)'] No Vagrant instances have been created' -ForegroundColor green
|
||||
}
|
||||
Set-Location $CurrentDir
|
||||
|
||||
# Check available disk space. Recommend 80GB free, warn if less
|
||||
Write-Host ''
|
||||
Write-Host '[+] Checking available disk space...'
|
||||
$drives = Get-PSDrive | Where-Object { $_.Provider -like '*FileSystem*' }
|
||||
$drivesList = @()
|
||||
|
||||
forEach ($drive in $drives) {
|
||||
if ($drive.free -lt 80GB) {
|
||||
$DrivesList = $DrivesList + $drive
|
||||
}
|
||||
}
|
||||
|
||||
if ($DrivesList.Count -gt 0) {
|
||||
Write-Host " [-] The following drives have less than 80GB of free space. They should not be used for deploying DetectionLab" -ForegroundColor yellow
|
||||
forEach ($drive in $DrivesList) {
|
||||
Write-Host " [*] $($drive.Name)" -ForegroundColor yellow
|
||||
}
|
||||
Write-Host ' [-] You can safely ignore this warning if you are deploying DetectionLab to a different drive.' -ForegroundColor yellow
|
||||
}
|
||||
else {
|
||||
Write-Host ' ['$($checkmark)'] You have more than 80GB of free space on your primary partition' -ForegroundColor green
|
||||
}
|
||||
|
||||
# Ensure the vagrant-reload plugin is installed
|
||||
Write-Host ''
|
||||
Write-Host '[+] Checking if vagrant-reload is installed...'
|
||||
if (-Not (vagrant plugin list | Select-String 'vagrant-reload')) {
|
||||
Write-Host ' [-] The vagrant-reload plugin is required and not currently installed. This script will attempt to install it now.' -ForegroundColor yellow
|
||||
(vagrant plugin install 'vagrant-reload')
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Write-Host ' [!] Unable to install the vagrant-reload plugin. Please try to do so manually via `vagrant plugin install vagrant-reload` and re-run this script.' -ForegroundColor red
|
||||
break
|
||||
}
|
||||
}
|
||||
else {
|
||||
Write-Host ' ['$($checkmark)'] The vagrant-reload plugin is installed' -ForegroundColor green
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# Run check functions
|
||||
Write-Host ''
|
||||
Write-Host '[+] Begining pre-build checks for DetectionLab'
|
||||
Write-Host ''
|
||||
Write-Host '[+] Checking for necessary tools in PATH...'
|
||||
check_packer_path
|
||||
check_vagrant_path
|
||||
preflight_checks
|
||||
list_providers
|
||||
|
||||
Write-Host ''
|
||||
Write-Host 'To get started building DetectionLab, simply cd to DetectionLab/Vagrant'
|
||||
Write-Host 'and run "vagrant up". If you run into any issues along the way, check out'
|
||||
Write-Host 'the troubleshooting and known issues page: https://www.detectionlab.network/deployment/troubleshooting/'
|
||||
Write-Host ''
|
||||
252
Vagrant/prepare.sh
Executable file
252
Vagrant/prepare.sh
Executable file
@@ -0,0 +1,252 @@
|
||||
#! /bin/bash
|
||||
|
||||
# This script is meant to verify that your system is configured to
|
||||
# build DetectionLab successfully.
|
||||
# Only MacOS and Linux are supported. Use prepare.ps1 for Windows.
|
||||
# If you encounter issues, feel free to open an issue at
|
||||
# https://github.com/clong/DetectionLab/issues
|
||||
|
||||
ERROR=$(tput setaf 1; echo -n " [!]"; tput sgr0)
|
||||
GOODTOGO=$(tput setaf 2; echo -n " [✓]"; tput sgr0)
|
||||
INFO=$(tput setaf 3; echo -n " [-]"; tput sgr0)
|
||||
|
||||
print_usage() {
|
||||
echo "Usage: ./prepare.sh"
|
||||
exit 0
|
||||
}
|
||||
|
||||
check_packer_path() {
|
||||
# Check for existence of Packer in PATH
|
||||
if ! which packer >/dev/null; then
|
||||
(echo >&2 "${INFO} Packer was not found in your PATH.")
|
||||
(echo >&2 "${INFO} This is only needed if you plan to build you own boxes, otherwise you can ignore this message.")
|
||||
else
|
||||
(echo >&2 "${GOODTOGO} Packer was found in your PATH")
|
||||
fi
|
||||
}
|
||||
|
||||
check_vagrant_path() {
|
||||
# Check for existence of Vagrant in PATH
|
||||
if ! which vagrant >/dev/null; then
|
||||
(echo >&2 "${ERROR} Vagrant was not found in your PATH.")
|
||||
(echo >&2 "${ERROR} Please correct this before continuing. Exiting.")
|
||||
(echo >&2 "${ERROR} Correct this by installing Vagrant with Homebrew or downloading from https://www.vagrantup.com/downloads.html")
|
||||
exit 1
|
||||
else
|
||||
(echo >&2 "${GOODTOGO} Vagrant was found in your PATH")
|
||||
fi
|
||||
|
||||
|
||||
check_curl_path(){
|
||||
# Check to see if curl is in PATH - needed for post-install checks
|
||||
if ! which curl >/dev/null; then
|
||||
(echo >&2 "${ERROR} Please install curl and make sure it is in your PATH.")
|
||||
exit 1
|
||||
else
|
||||
(echo >&2 "${GOODTOGO} Curl was found in your PATH")
|
||||
fi
|
||||
}
|
||||
|
||||
# Ensure Vagrant >= 2.2.9
|
||||
# https://unix.stackexchange.com/a/285928
|
||||
VAGRANT_VERSION="$(vagrant --version | cut -d ' ' -f 2)"
|
||||
REQUIRED_VERSION="2.2.9"
|
||||
# If the version of Vagrant is not greater or equal to the required version
|
||||
if ! [ "$(printf '%s\n' "$REQUIRED_VERSION" "$VAGRANT_VERSION" | sort -V | head -n1)" = "$REQUIRED_VERSION" ]; then
|
||||
(echo >&2 "${ERROR} WARNING: It is highly recommended to use Vagrant $REQUIRED_VERSION or above before continuing")
|
||||
else
|
||||
(echo >&2 "${GOODTOGO} Your version of Vagrant ($VAGRANT_VERSION) is supported")
|
||||
fi
|
||||
}
|
||||
|
||||
# Returns 0 if not installed or 1 if installed
|
||||
check_virtualbox_installed() {
|
||||
if which VBoxManage >/dev/null; then
|
||||
echo "1"
|
||||
else
|
||||
echo "0"
|
||||
fi
|
||||
}
|
||||
|
||||
# Returns 0 if not installed or 1 if installed
|
||||
# Check for VMWare Workstation on Linux
|
||||
check_vmware_workstation_installed() {
|
||||
if which vmrun >/dev/null; then
|
||||
echo "1"
|
||||
else
|
||||
echo "0"
|
||||
fi
|
||||
}
|
||||
|
||||
# Returns 0 if not installed or 1 if installed
|
||||
check_vmware_fusion_installed() {
|
||||
if [ -e "/Applications/VMware Fusion.app" ]; then
|
||||
echo "1"
|
||||
else
|
||||
echo "0"
|
||||
fi
|
||||
}
|
||||
|
||||
# Returns 0 if not installed or 1 if installed
|
||||
check_vmware_desktop_vagrant_plugin_installed() {
|
||||
LEGACY_PLUGIN_CHECK="$(vagrant plugin list | grep -c 'vagrant-vmware-fusion')"
|
||||
if [ "$LEGACY_PLUGIN_CHECK" -gt 0 ]; then
|
||||
(echo >&2 "${ERROR} The VMware Fusion Vagrant plugin is deprecated and is no longer supported.")
|
||||
(echo >&2 "${INFO} Please upgrade to the VMware Desktop plugin: https://www.vagrantup.com/docs/vmware/installation.html")
|
||||
(echo >&2 "${INFO} Please also uninstall the vagrant-vmware-fusion plugin and install the vmware-vagrant-desktop plugin")
|
||||
(echo >&2 "${INFO} HINT: \`vagrant plugin uninstall vagrant-vmware-fusion && vagrant plugin install vagrant-vmware-desktop\`")
|
||||
(echo >&2 "${INFO} NOTE: The VMware plugin does not work with trial versions of VMware Fusion")
|
||||
echo "0"
|
||||
fi
|
||||
|
||||
VMWARE_DESKTOP_PLUGIN_PRESENT="$(vagrant plugin list | grep -c 'vagrant-vmware-desktop')"
|
||||
if [ "$VMWARE_DESKTOP_PLUGIN_PRESENT" -eq 0 ]; then
|
||||
(echo >&2 "VMWare Fusion or Workstation is installed, but the vagrant-vmware-desktop plugin is not.")
|
||||
(echo >&2 "Visit https://www.hashicorp.com/blog/introducing-the-vagrant-vmware-desktop-plugin for more information on how to purchase and install it")
|
||||
(echo >&2 "VMWare Fusion or Workstation will not be listed as a provider until the vagrant-vmware-desktop plugin has been installed.")
|
||||
echo "0"
|
||||
else
|
||||
echo "1"
|
||||
fi
|
||||
}
|
||||
|
||||
check_vagrant_vmware_utility_installed() {
|
||||
# Ensure the helper utility is installed: https://www.vagrantup.com/docs/providers/vmware/vagrant-vmware-utility
|
||||
if pgrep -f vagrant-vmware-utility > /dev/null; then
|
||||
echo "1"
|
||||
else
|
||||
echo "0"
|
||||
fi
|
||||
}
|
||||
|
||||
# List the available Vagrant providers present on the system
|
||||
list_providers() {
|
||||
VBOX_PRESENT=0
|
||||
VMWARE_FUSION_PRESENT=0
|
||||
|
||||
if [ "$(uname)" == "Darwin" ]; then
|
||||
# Detect Providers on OSX
|
||||
VBOX_PRESENT=$(check_virtualbox_installed)
|
||||
VMWARE_FUSION_PRESENT=$(check_vmware_fusion_installed)
|
||||
VMWARE_WORKSTATION_PRESENT=0 # Workstation doesn't exist on Darwain-based OS
|
||||
VAGRANT_VMWARE_DESKTOP_PLUGIN_PRESENT=$(check_vmware_desktop_vagrant_plugin_installed)
|
||||
VAGRANT_VMWARE_UTILITY_PRESENT=$(check_vagrant_vmware_utility_installed)
|
||||
else
|
||||
VBOX_PRESENT=$(check_virtualbox_installed)
|
||||
VMWARE_WORKSTATION_PRESENT=$(check_vmware_workstation_installed)
|
||||
VMWARE_FUSION_PRESENT=0 # Fusion doesn't exist on non-Darwin OS
|
||||
VAGRANT_VMWARE_DESKTOP_PLUGIN_PRESENT=$(check_vmware_desktop_vagrant_plugin_installed)
|
||||
VAGRANT_VMWARE_UTILITY_PRESENT=$(check_vagrant_vmware_utility_installed)
|
||||
fi
|
||||
|
||||
(echo >&2 "Available Providers:")
|
||||
if [ "$VBOX_PRESENT" == "1" ]; then
|
||||
(echo >&2 "${GOODTOGO} virtualbox")
|
||||
fi
|
||||
if [[ $VMWARE_FUSION_PRESENT -eq 1 ]] && [[ $VAGRANT_VMWARE_DESKTOP_PLUGIN_PRESENT -eq 1 ]] && [[ $VAGRANT_VMWARE_UTILITY_PRESENT -eq 1 ]]; then
|
||||
(echo >&2 "${GOODTOGO} vmware_desktop")
|
||||
fi
|
||||
if [[ $VMWARE_WORKSTATION_PRESENT -eq 1 ]] && [[ $VAGRANT_VMWARE_DESKTOP_PLUGIN_PRESENT -eq 1 ]] && [[ $VAGRANT_VMWARE_UTILITY_PRESENT -eq 1 ]]; then
|
||||
(echo >&2 "${GOODTOGO} vmware_desktop")
|
||||
fi
|
||||
if [[ $VBOX_PRESENT -eq 0 ]] && [[ $VMWARE_FUSION_PRESENT -eq 0 ]] && [[ $VMWARE_WORKSTATION -eq 0 ]]; then
|
||||
(echo >&2 "${ERROR} You need to install a provider such as VirtualBox or VMware Fusion/Workstation to build DetectionLab.")
|
||||
exit 1
|
||||
fi
|
||||
if [[ $VBOX_PRESENT -eq 1 ]] && [[ $VMWARE_FUSION_PRESENT -eq 1 || $VMWARE_WORKSTATION_PRESENT -eq 1 ]]; then
|
||||
(echo >&2 "${INFO} Both VMware Workstation/Fusion and Virtualbox appear to be installed on this system.")
|
||||
(echo >&2 "${INFO} Please consider setting the VAGRANT_DEFAULT_PROVIDER environment variable to prevent confusion." )
|
||||
(echo >&2 "${INFO} More details can be found here: https://www.vagrantup.com/docs/providers/default" )
|
||||
(echo >&2 "${INFO} Additionally, please ensure only one providers' network adapters are active at any given time." )
|
||||
fi
|
||||
}
|
||||
|
||||
# Check to see if boxes exist in the "Boxes" directory already
|
||||
check_boxes_built() {
|
||||
BOXES_BUILT=$(find "$VAGRANT_DIR"/../Boxes -name "*.box" | wc -l)
|
||||
if [ "$BOXES_BUILT" -gt 0 ]; then
|
||||
(echo >&2 "${INFO} WARNING: You seem to have at least one .box file present in the Boxes directory already.")
|
||||
(echo >&2 "${INFO} If you would like to use the pre-built boxes, please remove all files from the Boxes directory.")
|
||||
(echo >&2 "${INFO} See https://www.detectionlab.network/customization/buildpackerboxes/ for more information about this message")
|
||||
else
|
||||
(echo >&2 "${GOODTOGO} No custom built boxes found")
|
||||
fi
|
||||
}
|
||||
|
||||
# Check to see if any Vagrant instances exist already
|
||||
check_vagrant_instances_exist() {
|
||||
cd "$VAGRANT_DIR"|| exit 1
|
||||
# Vagrant status has the potential to return a non-zero error code, so we work around it with "|| true"
|
||||
VAGRANT_STATUS_OUTPUT=$(vagrant status)
|
||||
VAGRANT_BUILT=$(echo "$VAGRANT_STATUS_OUTPUT" | grep -c 'not created') || true
|
||||
if [ "$VAGRANT_BUILT" -ne 4 ]; then
|
||||
(echo >&2 "${INFO} You appear to have already created at least one Vagrant instance:")
|
||||
# shellcheck disable=SC2164
|
||||
cd "$VAGRANT_DIR" && echo "$VAGRANT_STATUS_OUTPUT" | grep -v 'not created' | grep -E 'logger|dc|wef|win10'
|
||||
(echo >&2 "${INFO} If you want to start with a fresh install, you should run \`vagrant destroy -f\` to remove existing instances.")
|
||||
else
|
||||
(echo >&2 "${GOODTOGO} No Vagrant instances have been created yet")
|
||||
fi
|
||||
}
|
||||
|
||||
check_vagrant_reload_plugin() {
|
||||
# Ensure the vagrant-reload plugin is installed
|
||||
VAGRANT_RELOAD_PLUGIN_INSTALLED=$(vagrant plugin list | grep -c 'vagrant-reload')
|
||||
if [ "$VAGRANT_RELOAD_PLUGIN_INSTALLED" != "1" ]; then
|
||||
(echo >&2 "${ERROR} The vagrant-reload plugin is required and was not found. This script will attempt to install it now.")
|
||||
if ! $(which vagrant) plugin install "vagrant-reload"; then
|
||||
(echo >&2 "Unable to install the vagrant-reload plugin. Please try to do so manually and re-run this script.")
|
||||
exit 1
|
||||
else
|
||||
(echo >&2 "${GOODTOGO} The vagrant-reload plugin was successfully installed!")
|
||||
fi
|
||||
else
|
||||
(echo >&2 "${GOODTOGO} The vagrant-reload plugin is currently installed")
|
||||
fi
|
||||
}
|
||||
|
||||
# Check available disk space. Recommend 80GB free, warn if less.
|
||||
check_disk_free_space() {
|
||||
FREE_DISK_SPACE=$(df -m "$HOME" | tr -s ' ' | grep '/' | cut -d ' ' -f 4)
|
||||
if [ "$FREE_DISK_SPACE" -lt 80000 ]; then
|
||||
(echo >&2 -e "Warning: You appear to have less than 80GB of HDD space free on your primary partition. If you are using a separate parition, you may ignore this warning.\n")
|
||||
(df >&2 -m "$HOME")
|
||||
(echo >&2 "")
|
||||
else
|
||||
(echo >&2 "${GOODTOGO} You have more than 80GB of free space on your primary partition")
|
||||
fi
|
||||
}
|
||||
|
||||
main() {
|
||||
# Get location of prepare.sh
|
||||
# https://stackoverflow.com/questions/59895/getting-the-source-directory-of-a-bash-script-from-within
|
||||
VAGRANT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
(echo >&2 "[+] Checking for necessary tools in PATH...")
|
||||
check_packer_path
|
||||
check_vagrant_path
|
||||
check_curl_path
|
||||
(echo >&2 "")
|
||||
(echo >&2 "[+] Checking if any boxes have been manually built...")
|
||||
check_boxes_built
|
||||
(echo >&2 "")
|
||||
(echo >&2 "[+] Checking for disk free space...")
|
||||
check_disk_free_space
|
||||
(echo >&2 "")
|
||||
(echo >&2 "[+] Checking if any Vagrant instances have been created...")
|
||||
check_vagrant_instances_exist
|
||||
(echo >&2 "")
|
||||
(echo >&2 "[+] Checking if the vagrant-reload plugin is installed...")
|
||||
check_vagrant_reload_plugin
|
||||
(echo >&2 "")
|
||||
(echo >&2 "[+] Enumerating available providers...")
|
||||
list_providers
|
||||
|
||||
(echo >&2 '')
|
||||
# shellcheck disable=SC2016
|
||||
(echo >&2 'To get started building DetectionLab, run `vagrant up`.')
|
||||
(echo >&2 'If you run into any issues along the way, check out the troubleshooting and known issues page: ')
|
||||
(echo >&2 'https://www.detectionlab.network/deployment/troubleshooting/')
|
||||
}
|
||||
|
||||
main
|
||||
exit 0
|
||||
@@ -11,15 +11,6 @@ if ($onedrive) {
|
||||
}
|
||||
c:\Windows\SysWOW64\OneDriveSetup.exe /uninstall
|
||||
|
||||
# Fix in 1903
|
||||
#Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Removing Microsoft Store and Edge shortcuts from the taskbar..."
|
||||
#$appname = "Microsoft Edge"
|
||||
#((New-Object -Com Shell.Application).NameSpace('shell:::{4234d49b-0245-4df3-b780-3893943456e1}').Items() | ?{$_.Name -eq $appname}).Verbs() | ?{$_.Name.replace('&','') -match 'Unpin from taskbar'} | %{$_.DoIt(); $exec = $true}
|
||||
#$appname = "Microsoft Store"
|
||||
#((New-Object -Com Shell.Application).NameSpace('shell:::{4234d49b-0245-4df3-b780-3893943456e1}').Items() | ?{$_.Name -eq $appname}).Verbs() | ?{$_.Name.replace('&','') -match 'Unpin from taskbar'} | %{$_.DoIt(); $exec = $true}
|
||||
#$appname = "Mail"
|
||||
#((New-Object -Com Shell.Application).NameSpace('shell:::{4234d49b-0245-4df3-b780-3893943456e1}').Items() | ?{$_.Name -eq $appname}).Verbs() | ?{$_.Name.replace('&','') -match 'Unpin from taskbar'} | %{$_.DoIt(); $exec = $true}
|
||||
|
||||
Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Disabling automatic screen turnoff in order to prevent screen locking..."
|
||||
powercfg -change -monitor-timeout-ac 0
|
||||
powercfg -change -standby-timeout-ac 0
|
||||
@@ -28,6 +19,8 @@ powercfg -change -hibernate-timeout-ac 0
|
||||
# Download and install ShutUp10
|
||||
Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Downloading ShutUp10..."
|
||||
[Net.ServicePointManager]::SecurityProtocol = "tls12, tls11, tls"
|
||||
# Disabling the progress bar speeds up IWR https://github.com/PowerShell/PowerShell/issues/2138
|
||||
$ProgressPreference = 'SilentlyContinue'
|
||||
$shutUp10DownloadUrl = "https://dl5.oo-software.com/files/ooshutup10/OOSU10.exe"
|
||||
$shutUp10RepoPath = "C:\Users\vagrant\AppData\Local\Temp\OOSU10.exe"
|
||||
if (-not (Test-Path $shutUp10RepoPath)) {
|
||||
|
||||
@@ -8,6 +8,8 @@ If (-not (Test-Path $wefRepoPath))
|
||||
{
|
||||
# GitHub requires TLS 1.2 as of 2/1/2018
|
||||
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
|
||||
# Disabling the progress bar speeds up IWR https://github.com/PowerShell/PowerShell/issues/2138
|
||||
$ProgressPreference = 'SilentlyContinue'
|
||||
Invoke-WebRequest -Uri "https://github.com/palantir/windows-event-forwarding/archive/master.zip" -OutFile $wefRepoPath
|
||||
Expand-Archive -path "$wefRepoPath" -destinationpath 'c:\Users\vagrant\AppData\Local\Temp' -Force
|
||||
}
|
||||
|
||||
@@ -45,6 +45,8 @@ If (-not (Test-Path "C:\Program Files\Microsoft Advanced Threat Analytics\Center
|
||||
If ($download -eq $true)
|
||||
{
|
||||
Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Downloading $title..."
|
||||
# Disabling the progress bar speeds up IWR https://github.com/PowerShell/PowerShell/issues/2138
|
||||
$ProgressPreference = 'SilentlyContinue'
|
||||
Invoke-WebRequest -Uri $downloadUrl -OutFile "$env:temp\$title.iso"
|
||||
$actualHash = (Get-FileHash -Algorithm SHA256 -Path "$env:temp\$title.iso").Hash
|
||||
If (-not ($actualHash -eq $fileHash))
|
||||
@@ -111,6 +113,8 @@ Invoke-Command -computername dc -Credential (new-object pscredential("windomain\
|
||||
|
||||
If (-not (Test-Path "$env:temp\gatewaysetup.zip")) {
|
||||
Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) [$env:computername] Downloading ATA Lightweight Gateway from WEF now..."
|
||||
# Disabling the progress bar speeds up IWR https://github.com/PowerShell/PowerShell/issues/2138
|
||||
$ProgressPreference = 'SilentlyContinue'
|
||||
Invoke-WebRequest -uri https://wef/api/management/softwareUpdates/gateways/deploymentPackage -UseBasicParsing -OutFile "$env:temp\gatewaysetup.zip" -Credential (new-object pscredential("wef\vagrant", (convertto-securestring -AsPlainText -Force -String "vagrant")))
|
||||
Expand-Archive -Path "$env:temp\gatewaysetup.zip" -DestinationPath "$env:temp\gatewaysetup" -Force
|
||||
}
|
||||
|
||||
@@ -11,6 +11,8 @@ If (-not ($service)) {
|
||||
# Download the flags file from the Palantir osquery-configuration Github
|
||||
# GitHub requires TLS 1.2 as of 2/1/2018
|
||||
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
|
||||
# Disabling the progress bar speeds up IWR https://github.com/PowerShell/PowerShell/issues/2138
|
||||
$ProgressPreference = 'SilentlyContinue'
|
||||
Invoke-WebRequest -Uri "https://raw.githubusercontent.com/palantir/osquery-configuration/master/Classic/Endpoints/Windows/osquery.flags" -OutFile $flagfile
|
||||
|
||||
## Use the TLS config
|
||||
|
||||
@@ -3,6 +3,11 @@
|
||||
Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Installing Red Team Tooling..."
|
||||
$hostname = $(hostname)
|
||||
|
||||
# Disabling the progress bar speeds up IWR https://github.com/PowerShell/PowerShell/issues/2138
|
||||
$ProgressPreference = 'SilentlyContinue'
|
||||
# GitHub requires TLS 1.2 as of 2/27
|
||||
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
|
||||
|
||||
# Windows Defender should be disabled already by O&O ShutUp10 and the GPO
|
||||
If ($hostname -eq "win10") {
|
||||
# Adding Defender exclusions just in case
|
||||
@@ -18,75 +23,81 @@ If ($hostname -ne "win10" -And (Get-Service -Name WinDefend -ErrorAction Silentl
|
||||
Try {
|
||||
Uninstall-WindowsFeature Windows-Defender -ErrorAction Stop
|
||||
Uninstall-WindowsFeature Windows-Defender-Features -ErrorAction Stop
|
||||
}
|
||||
Catch {
|
||||
} Catch {
|
||||
Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Windows Defender did not uninstall successfully..."
|
||||
Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) We'll try again during install-red-team.ps1"
|
||||
}
|
||||
}
|
||||
Else {
|
||||
} Else {
|
||||
Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Windows Defender has already been disabled or uninstalled."
|
||||
}
|
||||
|
||||
# Purpose: Downloads and unzips a copy of the latest Mimikatz trunk
|
||||
Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Determining latest release of Mimikatz..."
|
||||
# GitHub requires TLS 1.2 as of 2/27
|
||||
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
|
||||
$tag = (Invoke-WebRequest "https://api.github.com/repos/gentilkiwi/mimikatz/releases" -UseBasicParsing | ConvertFrom-Json)[0].tag_name
|
||||
$mimikatzDownloadUrl = "https://github.com/gentilkiwi/mimikatz/releases/download/$tag/mimikatz_trunk.zip"
|
||||
$mimikatzRepoPath = 'C:\Users\vagrant\AppData\Local\Temp\mimikatz_trunk.zip'
|
||||
if (-not (Test-Path $mimikatzRepoPath)) {
|
||||
If (-not (Test-Path $mimikatzRepoPath)) {
|
||||
Invoke-WebRequest -Uri "$mimikatzDownloadUrl" -OutFile $mimikatzRepoPath
|
||||
Expand-Archive -path "$mimikatzRepoPath" -destinationpath 'c:\Tools\Mimikatz' -Force
|
||||
}
|
||||
else {
|
||||
} Else {
|
||||
Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Mimikatz was already installed. Moving On."
|
||||
}
|
||||
|
||||
# Download and unzip a copy of PowerSploit
|
||||
Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Downloading Powersploit..."
|
||||
# GitHub requires TLS 1.2 as of 2/27
|
||||
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
|
||||
$powersploitDownloadUrl = "https://github.com/PowerShellMafia/PowerSploit/archive/dev.zip"
|
||||
$powersploitRepoPath = "C:\Users\vagrant\AppData\Local\Temp\powersploit.zip"
|
||||
if (-not (Test-Path $powersploitRepoPath)) {
|
||||
If (-not (Test-Path $powersploitRepoPath)) {
|
||||
Invoke-WebRequest -Uri "$powersploitDownloadUrl" -OutFile $powersploitRepoPath
|
||||
Expand-Archive -path "$powersploitRepoPath" -destinationpath 'c:\Tools\PowerSploit' -Force
|
||||
Copy-Item "c:\Tools\PowerSploit\PowerSploit-dev\*" "$Env:windir\System32\WindowsPowerShell\v1.0\Modules" -Recurse -Force
|
||||
}
|
||||
else {
|
||||
} Else {
|
||||
Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) PowerSploit was already installed. Moving On."
|
||||
}
|
||||
|
||||
# Download and unzip a copy of Atomic Red Team
|
||||
Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Downloading Atomic Red Team..."
|
||||
# GitHub requires TLS 1.2 as of 2/27
|
||||
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
|
||||
$atomicRedTeamDownloadUrl = "https://github.com/redcanaryco/atomic-red-team/archive/master.zip"
|
||||
$atomicRedTeamRepoPath = "C:\Users\vagrant\AppData\Local\Temp\atomic_red_team.zip"
|
||||
if (-not (Test-Path $atomicRedTeamRepoPath)) {
|
||||
Invoke-WebRequest -Uri "$atomicRedTeamDownloadUrl" -OutFile "$atomicRedTeamRepoPath"
|
||||
Expand-Archive -path "$atomicRedTeamRepoPath" -destinationpath 'c:\Tools\Atomic Red Team' -Force
|
||||
}
|
||||
else {
|
||||
Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Atomic Red Team was already installed. Moving On."
|
||||
}
|
||||
|
||||
# Download and unzip a copy of BadBlood
|
||||
Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Downloading BadBlood..."
|
||||
# GitHub requires TLS 1.2 as of 2/27
|
||||
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
|
||||
$badbloodDownloadUrl = "https://github.com/davidprowe/BadBlood/archive/master.zip"
|
||||
$badbloodRepoPath = "C:\Users\vagrant\AppData\Local\Temp\badblood.zip"
|
||||
if (-not (Test-Path $badbloodRepoPath)) {
|
||||
If (-not (Test-Path $badbloodRepoPath)) {
|
||||
Invoke-WebRequest -Uri "$badbloodDownloadUrl" -OutFile "$badbloodRepoPath"
|
||||
Expand-Archive -path "$badbloodRepoPath" -destinationpath 'c:\Tools\BadBlood' -Force
|
||||
# Lower the number of default users to be created by BadBlood
|
||||
$invokeBadBloodPath = "c:\Tools\BadBlood\BadBlood-master\Invoke-BadBlood.ps1"
|
||||
((Get-Content -path $invokeBadBloodPath -Raw) -replace '1000..5000','500..1500') | Set-Content -Path $invokeBadBloodPath
|
||||
}
|
||||
else {
|
||||
} Else {
|
||||
Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) BadBlood was already installed. Moving On."
|
||||
}
|
||||
|
||||
Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Red Team tooling installation complete!"
|
||||
# Download and install Invoke-AtomicRedTeam
|
||||
Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Downloading Invoke-AtomicRedTeam and atomic tests..."
|
||||
If (-not (Test-Path "C:\Tools\AtomicRedTeam")) {
|
||||
Install-PackageProvider -Name NuGet -Force
|
||||
IEX (IWR 'https://raw.githubusercontent.com/redcanaryco/invoke-atomicredteam/master/install-atomicredteam.ps1' -UseBasicParsing);
|
||||
Install-AtomicRedTeam -getAtomics -InstallPath "c:\Tools\AtomicRedTeam"
|
||||
Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Updating Profile.ps1 to import the Invoke-AtomicRedTeam module..."
|
||||
Add-Content -Path C:\Windows\System32\WindowsPowerShell\v1.0\Profile.ps1 'Import-Module "C:\Tools\AtomicRedTeam\invoke-atomicredteam\Invoke-AtomicRedTeam.psd1" -Force
|
||||
$PSDefaultParameterValues = @{"Invoke-AtomicTest:PathToAtomicsFolder"="C:\Tools\AtomicRedTeam\atomics"}' -Force
|
||||
} Else {
|
||||
Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Invoke-AtomicRedTeam was already installed. Moving On."
|
||||
}
|
||||
|
||||
# Purpose: Downloads the latest release of PurpleSharpNewtonsoft.Json.dll
|
||||
If (-not (Test-Path "c:\Tools\PurpleSharp")) {
|
||||
New-Item -Path "c:\Tools\" -Name "PurpleSharp" -ItemType "directory"
|
||||
} Else {
|
||||
Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) PurpleSharp folder already exists. Moving On."
|
||||
}
|
||||
|
||||
Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Determining latest release of Purplesharp..."
|
||||
$tag = (Invoke-WebRequest "https://api.github.com/repos/mvelazc0/PurpleSharp/releases" -UseBasicParsing | ConvertFrom-Json)[0].tag_name
|
||||
$purplesharpDownloadUrl = "https://github.com/mvelazc0/PurpleSharp/releases/download/$tag/PurpleSharp.exe"
|
||||
$purplesharpDllDownloadURL = "https://github.com/mvelazc0/PurpleSharp/releases/download/$tag/Newtonsoft.Json.dll"
|
||||
If (-not (Test-Path "c:\Tools\PurpleSharp\PurpleSharp.exe")) {
|
||||
Invoke-WebRequest -Uri $purplesharpDownloadUrl -OutFile "c:\Tools\PurpleSharp\PurpleSharp.exe"
|
||||
Invoke-WebRequest -Uri $purplesharpDllDownloadUrl -OutFile "c:\Tools\PurpleSharp\Newtonsoft.Json.dll"
|
||||
} Else {
|
||||
Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) PurpleSharp was already installed. Moving On."
|
||||
}
|
||||
|
||||
Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Red Team tooling installation complete!"
|
||||
|
||||
@@ -12,6 +12,8 @@ If (Select-String -Path "c:\windows\system32\drivers\etc\hosts" -Pattern "logger
|
||||
Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Determining latest release of Velociraptor..."
|
||||
# GitHub requires TLS 1.2 as of 2/27
|
||||
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
|
||||
# Disabling the progress bar speeds up IWR https://github.com/PowerShell/PowerShell/issues/2138
|
||||
$ProgressPreference = 'SilentlyContinue'
|
||||
$tag = (Invoke-WebRequest "https://api.github.com/repos/Velocidex/velociraptor/releases" -UseBasicParsing | ConvertFrom-Json)[0].tag_name
|
||||
# Workaround hardcoded URL until this issue gets fixed: https://github.com/Velocidex/velociraptor/issues/528
|
||||
$velociraptorDownloadUrl = "https://github.com/Velocidex/velociraptor/releases/download/v0.4.7/velociraptor-v0.4.7-1-windows-amd64.msi"
|
||||
|
||||
@@ -9,7 +9,8 @@ If (Test-Path "C:\Program Files\SplunkUniversalForwarder\etc\apps\Splunk_TA_wind
|
||||
}
|
||||
|
||||
# Install Windows TA (this only needs to be done on the WEF server)
|
||||
$windowstaPath = "C:\vagrant\resources\splunk_forwarder\splunk-add-on-for-microsoft-windows_700.tgz"
|
||||
Copy-Item -Path "C:\vagrant\resources\splunk_forwarder\splunk-add-on-for-microsoft-windows_700.tgz" -Destination $env:temp
|
||||
$windowstaPath = $env:temp + "\splunk-add-on-for-microsoft-windows_700.tgz"
|
||||
$inputsPath = "C:\Program Files\SplunkUniversalForwarder\etc\apps\Splunk_TA_windows\local\inputs.conf"
|
||||
Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Installing the Windows TA"
|
||||
Start-Process -FilePath "C:\Program Files\SplunkUniversalForwarder\bin\splunk.exe" -ArgumentList "install app $windowstaPath -auth admin:changeme" -NoNewWindow
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
# Purpose: Sets timezone to UTC, sets hostname, creates/joins domain.
|
||||
# Source: https://github.com/StefanScherer/adfs2
|
||||
|
||||
$ProfilePath = "C:\Windows\System32\WindowsPowerShell\v1.0\profile.ps1"
|
||||
$box = Get-ItemProperty -Path HKLM:SYSTEM\CurrentControlSet\Control\ComputerName\ComputerName -Name "ComputerName"
|
||||
$box = $box.ComputerName.ToString().ToLower()
|
||||
|
||||
@@ -10,8 +11,21 @@ c:\windows\system32\tzutil.exe /s "UTC"
|
||||
Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Checking if Windows evaluation is expiring soon or expired..."
|
||||
. c:\vagrant\scripts\fix-windows-expiration.ps1
|
||||
|
||||
If (!(Test-Path $ProfilePath)) {
|
||||
Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Disabling the Invoke-WebRequest download progress bar globally for speed improvements."
|
||||
Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) See https://github.com/PowerShell/PowerShell/issues/2138 for more info"
|
||||
New-Item -Path $ProfilePath | Out-Null
|
||||
If (!(Get-Content $Profilepath| % { $_ -match "SilentlyContinue" } )) {
|
||||
Add-Content -Path $ProfilePath -Value "$ProgressPreference = 'SilentlyContinue'"
|
||||
}
|
||||
}
|
||||
|
||||
# Ping DetectionLab server for usage statistics
|
||||
curl -userAgent "DetectionLab-$box" "https://ping.detectionlab.network/$box" -UseBasicParsing | out-null
|
||||
Try {
|
||||
curl -userAgent "DetectionLab-$box" "https://ping.detectionlab.network/$box" -UseBasicParsing | out-null
|
||||
} Catch {
|
||||
Write-Host "Unable to connect to ping.detectionlab.network"
|
||||
}
|
||||
|
||||
Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Disabling IPv6 on all network adatpers..."
|
||||
Get-NetAdapterBinding -ComponentID ms_tcpip6 | ForEach-Object {Disable-NetAdapterBinding -Name $_.Name -ComponentID ms_tcpip6}
|
||||
|
||||
439
build.ps1
439
build.ps1
@@ -1,439 +0,0 @@
|
||||
#Requires -Version 4.0
|
||||
|
||||
<#
|
||||
.Synopsis
|
||||
This script is used to deploy a fresh install of DetectionLab
|
||||
|
||||
.DESCRIPTION
|
||||
This scripts runs a series of tests before running through the
|
||||
DetectionLab deployment. It checks:
|
||||
|
||||
* If Packer and Vagrant are installed
|
||||
* If VirtualBox or VMware are installed
|
||||
* If the proper vagrant plugins are available
|
||||
* Various aspects of system health
|
||||
|
||||
Post deployment it also verifies that services are installed and
|
||||
running.
|
||||
|
||||
If you encounter issues, feel free to open an issue at
|
||||
https://github.com/clong/DetectionLab/issues
|
||||
|
||||
.PARAMETER ProviderName
|
||||
The Hypervisor you're using for the lab. Valid options are 'virtualbox' or 'vmware_desktop'
|
||||
|
||||
.PARAMETER PackerOnly
|
||||
This switch skips deploying boxes with vagrant after being built by Packer
|
||||
|
||||
.PARAMETER VagrantOnly
|
||||
This switch skips building Packer boxes and instead downloads from Vagrant Cloud
|
||||
|
||||
.EXAMPLE
|
||||
build.ps1 -ProviderName virtualbox
|
||||
|
||||
This builds DetectionLab using virtualbox and the default path for Packer (C:\Hashicorp\packer.exe)
|
||||
.EXAMPLE
|
||||
build.ps1 -ProviderName vmware_desktop
|
||||
|
||||
This builds the DetectionLab using VMware and sets the Packer path to 'C:\packer.exe'
|
||||
.EXAMPLE
|
||||
build.ps1 -ProviderName vmware_desktop -VagrantOnly
|
||||
|
||||
This command builds the DetectionLab using VMware and skips the Packer process, downloading the boxes instead.
|
||||
#>
|
||||
|
||||
[cmdletbinding()]
|
||||
Param(
|
||||
# Vagrant provider to use.
|
||||
[ValidateSet('virtualbox', 'vmware_desktop')]
|
||||
[string]$ProviderName,
|
||||
[switch]$PackerOnly,
|
||||
[switch]$VagrantOnly
|
||||
)
|
||||
|
||||
$DL_DIR = Split-Path -Parent -Path $MyInvocation.MyCommand.Definition
|
||||
$LAB_HOSTS = ('logger', 'dc', 'wef', 'win10')
|
||||
|
||||
function install_checker {
|
||||
param(
|
||||
[string]$Name
|
||||
)
|
||||
$results = Get-ItemProperty 'HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*' | Select-Object DisplayName
|
||||
$results += Get-ItemProperty 'HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*' | Select-Object DisplayName
|
||||
|
||||
forEach ($result in $results) {
|
||||
if ($result -like "*$Name*") {
|
||||
return $true
|
||||
}
|
||||
}
|
||||
return $false
|
||||
}
|
||||
|
||||
function check_packer {
|
||||
# Check if Packer is in path
|
||||
Try {
|
||||
Get-Command packer.exe -ErrorAction Stop | Out-Null
|
||||
} Catch {
|
||||
Write-Error 'Packer was not found in your PATH. Please correct this before continuing.' -ForegroundColor yellow
|
||||
Write-Error 'Please note that packer is not required if you pass the "-VagrantOnly" flag to the build.ps1 script.' -ForegroundColor yellow
|
||||
Write-Error 'Packer is only required if you prefer to create boxes from scratch rather than using the pre-built ones.' -ForegroundColor yellow
|
||||
break
|
||||
}
|
||||
}
|
||||
function check_vagrant {
|
||||
# Check if Vagrant is in path
|
||||
Try {
|
||||
Get-Command vagrant.exe -ErrorAction Stop | Out-Null
|
||||
}
|
||||
Catch {
|
||||
Write-Error 'Vagrant was not found. Please correct this before continuing.' -ForegroundColor red
|
||||
Break
|
||||
}
|
||||
|
||||
# Check Vagrant version >= 2.2.9
|
||||
[System.Version]$vagrant_version = $(vagrant --version).Split(' ')[1]
|
||||
[System.Version]$version_comparison = 2.2.9
|
||||
|
||||
if ($vagrant_version -lt $version_comparison) {
|
||||
Write-Warning 'It is highly recommended to use Vagrant 2.2.9 or above before continuing' -ForegroundColor yellow
|
||||
}
|
||||
}
|
||||
|
||||
# Returns false if not installed or true if installed
|
||||
function check_virtualbox_installed {
|
||||
Write-Host '[check_virtualbox_installed] Running..' -ForegroundColor green
|
||||
if (install_checker -Name "VirtualBox") {
|
||||
Write-Host '[check_virtualbox_installed] Virtualbox found.' -ForegroundColor green
|
||||
return $true
|
||||
}
|
||||
else {
|
||||
Write-Host '[check_virtualbox_installed] Virtualbox not found.' -ForegroundColor green
|
||||
return $false
|
||||
}
|
||||
}
|
||||
function check_vmware_workstation_installed {
|
||||
Write-Host '[check_vmware_workstation_installed] Running..' -ForegroundColor green
|
||||
if (install_checker -Name "VMware Workstation") {
|
||||
Write-Host '[check_vmware_workstation_installed] VMware Workstation found.' -ForegroundColor green
|
||||
return $true
|
||||
}
|
||||
else {
|
||||
Write-Host '[check_vmware_workstation_installed] VMware Workstation not found.' -ForegroundColor green
|
||||
return $false
|
||||
}
|
||||
}
|
||||
|
||||
function check_vmware_vagrant_plugin_installed {
|
||||
Write-Host '[check_vmware_vagrant_plugin_installed] Running..' -ForegroundColor green
|
||||
if (vagrant plugin list | Select-String 'vagrant-vmware-workstation') {
|
||||
Write-Host 'The vagrant VMware Workstation plugin is no longer supported.' -ForegroundColor red
|
||||
Write-Host 'Please upgrade to the VMware Desktop plugin: https://www.vagrantup.com/docs/vmware/installation.html' -ForegroundColor red
|
||||
return $false
|
||||
}
|
||||
if (vagrant plugin list | Select-String 'vagrant-vmware-desktop') {
|
||||
Write-Host '[check_vmware_vagrant_plugin_installed] Vagrant VMware Desktop plugin found.' -ForegroundColor green
|
||||
return $true
|
||||
}
|
||||
else {
|
||||
Write-Host 'VMware Workstation is installed, but the vagrant-vmware-desktop plugin is not.' -ForegroundColor yellow
|
||||
Write-Host 'Visit https://www.vagrantup.com/vmware/index.html#buy-now for more information on how to purchase ($80) and install it' -ForegroundColor yellow
|
||||
Write-Host 'VMware Workstation will not be listed as a provider until the Vagrant plugin has been installed.' -ForegroundColor yellow
|
||||
Write-Host 'NOTE: The plugin does not work with trial versions of VMware Workstation' -ForegroundColor yellow
|
||||
return $false
|
||||
}
|
||||
}
|
||||
|
||||
function list_providers {
|
||||
[cmdletbinding()]
|
||||
param()
|
||||
|
||||
$vboxInstalled = 0
|
||||
$vmwareInstalled = 0
|
||||
if (check_virtualbox_installed) {
|
||||
$vboxInstalled=1
|
||||
}
|
||||
if (check_vmware_workstation_installed) {
|
||||
if (check_vmware_vagrant_plugin_installed) {
|
||||
$vmwareInstalled=1
|
||||
}
|
||||
}
|
||||
# Warn users if Virtualbox and VMware Workstation are both installed.
|
||||
if (( $vboxInstalled -eq 1 ) -and ( $vmwareInstalled -eq 1 )) {
|
||||
Write-Host "NOTE:" -ForegroundColor yellow
|
||||
Write-Host "Both VMware Workstation and Virtualbox appear to be installed on this system." -ForegroundColor yellow
|
||||
Write-Host "Please consider setting the VAGRANT_DEFAULT_PROVIDER environment variable to prevent confusion." -ForegroundColor yellow
|
||||
Write-Host "More details can be found here: https://www.vagrantup.com/docs/providers/default" -ForegroundColor yellow
|
||||
Write-Host "Additionally, please ensure only one providers' network adapters are active at any given time." -ForegroundColor yellow
|
||||
}
|
||||
if (($vboxInstalled -eq 0) -and ($vmwareInstalled -eq 0)) {
|
||||
Write-Error 'You need to install a provider such as VirtualBox or VMware Workstation to continue.' -ForegroundColor red
|
||||
Write-Error 'Virtualbox is free, the VMware Vagrant Plugin costs $80.' -ForegroundColor red
|
||||
break
|
||||
}
|
||||
while (-Not ($ProviderName -eq 'virtualbox' -or $ProviderName -eq 'vmware_desktop')) {
|
||||
Write-Host "Available Providers: "
|
||||
if ($vboxInstalled -eq 1) {
|
||||
Write-Host '[*] virtualbox' -ForegroundColor green
|
||||
}
|
||||
if ($vmwareInstalled -eq 1) {
|
||||
Write-Host '[*] vmware_desktop' -ForegroundColor green
|
||||
}
|
||||
$ProviderName = Read-Host 'Which provider would you like to use?'
|
||||
Write-Debug "ProviderName = $ProviderName"
|
||||
if (-Not ($ProviderName -eq 'virtualbox' -or $ProviderName -eq 'vmware_desktop')) {
|
||||
Write-Error "Please choose a valid provider. $ProviderName is not a valid option"
|
||||
}
|
||||
}
|
||||
return $ProviderName
|
||||
}
|
||||
|
||||
function preflight_checks {
|
||||
Write-Host '[preflight_checks] Running..' -ForegroundColor green
|
||||
# Verify CredentialGuard isn't enabled
|
||||
if (('CredentialGuard' -match ((Get-ComputerInfo).DeviceGuardSecurityServicesConfigured) -eq "True")) {
|
||||
Write-Host "WARNING: CredentialGuard appears to be enabled on this system which can cause issues with Virtualbox." -ForegroundColor yellow
|
||||
Write-Host "See this thread for more info: https://forums.virtualbox.org/viewtopic.php?f=25&t=82106" -ForegroundColor yellow
|
||||
$Confirmation = Read-Host "Please type 'y' to continue or any other key to exit: "
|
||||
If ($Confirmation.ToLower() -ne "y") {
|
||||
Write-Host "You entered \"$Confirmation\", exiting." -ForegroundColor red
|
||||
exit 0
|
||||
}
|
||||
}
|
||||
|
||||
if (-Not ($VagrantOnly)) {
|
||||
Write-Host '[preflight_checks] Checking if Packer is installed' -ForegroundColor green
|
||||
check_packer
|
||||
}
|
||||
if (-Not ($PackerOnly)) {
|
||||
Write-Host '[preflight_checks] Checking if Vagrant is installed' -ForegroundColor green
|
||||
check_vagrant
|
||||
|
||||
Write-Host '[preflight_checks] Checking for pre-existing boxes..' -ForegroundColor green
|
||||
if ((Get-ChildItem "$DL_DIR\Boxes\*.box").Count -gt 0) {
|
||||
Write-Host 'You seem to have at least one .box file present in the Boxes directory already. If you would like fresh boxes downloaded, please remove all .box files from the Boxes directory and re-run this script.' -ForegroundColor yellow
|
||||
}
|
||||
|
||||
# Check to see that no Vagrant instances exist
|
||||
Write-Host '[preflight_checks] Checking for vagrant instances..' -ForegroundColor green
|
||||
$CurrentDir = Get-Location
|
||||
Set-Location "$DL_DIR\Vagrant"
|
||||
if (($(vagrant status) | Select-String -Pattern "not[ _]created").Count -ne 4) {
|
||||
vagrant status
|
||||
Write-Host 'You appear to have already created at least one Vagrant instance. This script does not support already created instances.' -ForegroundColor red
|
||||
Write-Host 'To continue, cd to the Vagrant directory and run "vagrant destroy -f"' -ForegroundColor red
|
||||
Write-Host 'After that completes, "cd .." and re-run this script.' -ForegroundColor red
|
||||
Set-Location "$DL_DIR"
|
||||
exit 1
|
||||
}
|
||||
Set-Location $CurrentDir
|
||||
|
||||
# Check available disk space. Recommend 80GB free, warn if less
|
||||
Write-Host '[preflight_checks] Checking disk space..' -ForegroundColor green
|
||||
$drives = Get-PSDrive | Where-Object {$_.Provider -like '*FileSystem*'}
|
||||
$drivesList = @()
|
||||
|
||||
forEach ($drive in $drives) {
|
||||
if ($drive.free -lt 80GB) {
|
||||
$DrivesList = $DrivesList + $drive
|
||||
}
|
||||
}
|
||||
|
||||
if ($DrivesList.Count -gt 0) {
|
||||
Write-Host "The following drives have less than 80GB of free space. They should not be used for deploying DetectionLab" -ForegroundColor yellow
|
||||
forEach ($drive in $DrivesList) {
|
||||
Write-Host "[*] $($drive.Name)"
|
||||
}
|
||||
Write-Host "You can safely ignore this warning if you are deploying DetectionLab to a different drive." -ForegroundColor yellow
|
||||
}
|
||||
|
||||
# Ensure the vagrant-reload plugin is installed
|
||||
Write-Host '[preflight_checks] Checking if vagrant-reload is installed..' -ForegroundColor green
|
||||
if (-Not (vagrant plugin list | Select-String 'vagrant-reload')) {
|
||||
Write-Host 'The vagrant-reload plugin is required and not currently installed. This script will attempt to install it now.' -ForegroundColor yellow
|
||||
(vagrant plugin install 'vagrant-reload')
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Write-Error 'Unable to install the vagrant-reload plugin. Please try to do so manually and re-run this script.' -ForegroundColor red
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
Write-Host '[preflight_checks] Finished.' -ForegroundColor green
|
||||
}
|
||||
|
||||
function packer_build_box {
|
||||
param(
|
||||
[string]$Box
|
||||
)
|
||||
|
||||
Write-Host "[packer_build_box] Running for $Box" -ForegroundColor green
|
||||
$CurrentDir = Get-Location
|
||||
Set-Location "$DL_DIR\Packer"
|
||||
Write-Host "Using Packer to build the $BOX Box. This can take 90-180 minutes depending on bandwidth and hardware." -ForegroundColor green
|
||||
$env:PACKER_LOG=1
|
||||
$env:PACKER_LOG_PATH="$DL_DIR\Packer\packer.log"
|
||||
&packer @('build', "--only=$PackerProvider-iso", "$box.json")
|
||||
Write-Host "[packer_build_box] Finished for $Box. Got exit code: $LASTEXITCODE" -ForegroundColor green
|
||||
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Write-Error "Something went wrong while attempting to build the $BOX box."
|
||||
Write-Host "To file an issue, please visit https://github.com/clong/DetectionLab/issues/"
|
||||
break
|
||||
}
|
||||
Set-Location $CurrentDir
|
||||
}
|
||||
|
||||
function move_boxes {
|
||||
Write-Host "[move_boxes] Running.." -ForegroundColor green
|
||||
Move-Item -Path $DL_DIR\Packer\*.box -Destination $DL_DIR\Boxes
|
||||
if (-Not (Test-Path "$DL_DIR\Boxes\windows_10_$PackerProvider.box")) {
|
||||
Write-Host "Windows 10 box is missing from the Boxes directory. Quitting." -ForegroundColor red
|
||||
break
|
||||
}
|
||||
if (-Not (Test-Path "$DL_DIR\Boxes\windows_2016_$PackerProvider.box")) {
|
||||
Write-Error "Windows 2016 box is missing from the Boxes directory. Quitting." -ForegroundColor red
|
||||
break
|
||||
}
|
||||
Write-Host "[move_boxes] Finished." -ForegroundColor green
|
||||
}
|
||||
|
||||
function vagrant_up_host {
|
||||
param(
|
||||
[string]$VagrantHost
|
||||
)
|
||||
Write-Host "[vagrant_up_host] Running for $VagrantHost" -ForegroundColor green
|
||||
Write-Host "Attempting to bring up the $VagrantHost host using Vagrant" -ForegroundColor green
|
||||
$CurrentDir = Get-Location
|
||||
Set-Location "$DL_DIR\Vagrant"
|
||||
Set-Variable VAGRANT_LOG=info
|
||||
&vagrant.exe @('up', $VagrantHost, '--provider', "$ProviderName") 2>&1 | Out-File -FilePath ".\vagrant_up_$VagrantHost.log"
|
||||
Set-Location $CurrentDir
|
||||
Write-Host "[vagrant_up_host] Finished for $VagrantHost. Got exit code: $LASTEXITCODE" -ForegroundColor green
|
||||
return $LASTEXITCODE
|
||||
}
|
||||
|
||||
function vagrant_reload_host {
|
||||
param(
|
||||
[string]$VagrantHost
|
||||
)
|
||||
Write-Host "[vagrant_reload_host] Running for $VagrantHost" -ForegroundColor green
|
||||
$CurrentDir = Get-Location
|
||||
Set-Location "$DL_DIR\Vagrant"
|
||||
&vagrant.exe @('reload', $VagrantHost, '--provision') 2>&1 | Out-File -FilePath ".\vagrant_up_$VagrantHost.log" -Append
|
||||
Set-Location $CurrentDir
|
||||
Write-Host "[vagrant_reload_host] Finished for $VagrantHost. Got exit code: $LASTEXITCODE" -ForegroundColor green
|
||||
return $LASTEXITCODE
|
||||
}
|
||||
|
||||
function download {
|
||||
param(
|
||||
[string]$URL,
|
||||
[string]$PatternToMatch,
|
||||
[switch]$SuccessOn401
|
||||
|
||||
)
|
||||
Write-Host "[download] Running for $URL, looking for $PatternToMatch" -ForegroundColor green
|
||||
[System.Net.ServicePointManager]::ServerCertificateValidationCallback = { $true }
|
||||
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
|
||||
|
||||
$wc = New-Object System.Net.WebClient
|
||||
try
|
||||
{
|
||||
$result = $wc.DownloadString($URL)
|
||||
if ($result -like "*$PatternToMatch*") {
|
||||
Write-Host "[download] Found $PatternToMatch at $URL" -ForegroundColor green
|
||||
return $true
|
||||
}
|
||||
else {
|
||||
Write-Host "[download] Could not find $PatternToMatch at $URL" -ForegroundColor red
|
||||
return $false
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
if ($_.Exception.InnerException.Response.StatusCode -eq 401 -and $SuccessOn401.IsPresent)
|
||||
{
|
||||
return $true
|
||||
}
|
||||
else
|
||||
{
|
||||
Write-Host "Error occured on webrequest: $_" -ForegroundColor red
|
||||
return $false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function post_build_checks {
|
||||
|
||||
Write-Host '[post_build_checks] Running Splunk Check.'
|
||||
$SPLUNK_CHECK = download -URL 'https://192.168.38.105:8000/en-US/account/login?return_to=%2Fen-US%2F' -PatternToMatch 'This browser is not supported by Splunk'
|
||||
Write-Host "[post_build_checks] Splunk Result: $SPLUNK_CHECK"
|
||||
|
||||
Write-Host '[post_build_checks] Running Fleet Check.'
|
||||
$FLEET_CHECK = download -URL 'https://192.168.38.105:8412' -PatternToMatch 'Kolide Fleet'
|
||||
Write-Host "[post_build_checks] Fleet Result: $FLEET_CHECK"
|
||||
|
||||
Write-Host '[post_build_checks] Running MS ATA Check.'
|
||||
$ATA_CHECK = download -URL 'https://192.168.38.103' -SuccessOn401
|
||||
Write-Host "[post_build_checks] ATA Result: $ATA_CHECK"
|
||||
|
||||
if ($SPLUNK_CHECK -eq $false) {
|
||||
Write-Warning 'Splunk failed post-build tests and may not be functioning correctly.' -ForegroundColor yellow
|
||||
}
|
||||
if ($FLEET_CHECK -eq $false) {
|
||||
Write-Warning 'Fleet failed post-build tests and may not be functioning correctly.' -ForegroundColor yellow
|
||||
}
|
||||
if ($ATA_CHECK -eq $false) {
|
||||
Write-Warning 'MS ATA failed post-build tests and may not be functioning correctly.' -ForegroundColor yellow
|
||||
}
|
||||
}
|
||||
|
||||
# If no ProviderName was provided, get a provider
|
||||
if ($ProviderName -eq $Null -or $ProviderName -eq "") {
|
||||
$ProviderName = list_providers
|
||||
}
|
||||
|
||||
# Set Provider variable for use deployment functions
|
||||
if ($ProviderName -eq 'vmware_desktop') {
|
||||
$PackerProvider = 'vmware'
|
||||
}
|
||||
else {
|
||||
$PackerProvider = 'virtualbox'
|
||||
}
|
||||
|
||||
# Run check functions
|
||||
preflight_checks
|
||||
|
||||
# Build Packer Boxes
|
||||
if (!($VagrantOnly)) {
|
||||
packer_build_box -Box 'windows_2016'
|
||||
packer_build_box -Box 'windows_10'
|
||||
# Move Packer Boxes
|
||||
move_boxes
|
||||
}
|
||||
|
||||
if (!($PackerOnly)) {
|
||||
# Vagrant up each box and attempt to reload one time if it fails
|
||||
forEach ($VAGRANT_HOST in $LAB_HOSTS) {
|
||||
Write-Host "[main] Running vagrant_up_host for: $VAGRANT_HOST" -ForegroundColor green
|
||||
$result = vagrant_up_host -VagrantHost $VAGRANT_HOST
|
||||
Write-Host "[main] vagrant_up_host finished. Exitcode: $result" -ForegroundColor green
|
||||
if ($result -eq '0') {
|
||||
Write-Host "Good news! $VAGRANT_HOST was built successfully!" -ForegroundColor green
|
||||
}
|
||||
else {
|
||||
Write-Warning "Something went wrong while attempting to build the $VAGRANT_HOST box." -ForegroundColor yellow
|
||||
Write-Host "Attempting to reload and reprovision the host..." -ForegroundColor green
|
||||
Write-Host "[main] Running vagrant_reload_host for: $VAGRANT_HOST" -ForegroundColor green
|
||||
$retryResult = vagrant_reload_host -VagrantHost $VAGRANT_HOST
|
||||
if ($retryResult -ne 0) {
|
||||
Write-Error "Failed to bring up $VAGRANT_HOST after a reload. Exiting" -ForegroundColor red
|
||||
break
|
||||
}
|
||||
}
|
||||
Write-Host "[main] Finished for: $VAGRANT_HOST" -ForegroundColor green
|
||||
}
|
||||
|
||||
Write-Host "[main] Running post_build_checks" -ForegroundColor green
|
||||
post_build_checks
|
||||
Write-Host "[main] Finished post_build_checks" -ForegroundColor green
|
||||
}
|
||||
424
build.sh
424
build.sh
@@ -1,424 +0,0 @@
|
||||
#! /bin/bash
|
||||
|
||||
# This script is meant to be used with a fresh clone of DetectionLab and
|
||||
# will fail to run if boxes have already been created or any of the steps
|
||||
# from the README have already been run followed.
|
||||
# Only MacOS and Linux are supported. Use build.ps1 for Windows.
|
||||
# If you encounter issues, feel free to open an issue at
|
||||
# https://github.com/clong/DetectionLab/issues
|
||||
|
||||
print_usage() {
|
||||
echo "Usage: ./build.sh <virtualbox | vmware_desktop> <--vagrant-only | --packer-only>"
|
||||
exit 0
|
||||
}
|
||||
|
||||
check_packer_path() {
|
||||
# Check for existence of Packer in PATH
|
||||
if ! which packer >/dev/null; then
|
||||
(echo >&2 "Packer was not found in your PATH.")
|
||||
(echo >&2 "Please correct this before continuing. Quitting.")
|
||||
(echo >&2 "Hint: sudo cp ./packer /usr/local/bin/packer; sudo chmod +x /usr/local/bin/packer")
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
check_vagrant_path() {
|
||||
# Check for existence of Vagrant in PATH
|
||||
if ! which vagrant >/dev/null; then
|
||||
(echo >&2 "Vagrant was not found in your PATH.")
|
||||
(echo >&2 "Please correct this before continuing. Quitting.")
|
||||
exit 1
|
||||
fi
|
||||
# Ensure Vagrant >= 2.2.7
|
||||
# https://unix.stackexchange.com/a/285928
|
||||
VAGRANT_VERSION="$(vagrant --version | cut -d ' ' -f 2)"
|
||||
REQUIRED_VERSION="2.2.7"
|
||||
# If the version of Vagrant is not greater than the required version
|
||||
if ! [ "$(printf '%s\n' "$REQUIRED_VERSION" "$VAGRANT_VERSION" | sort -V | head -n1)" = "$REQUIRED_VERSION" ]; then
|
||||
(echo >&2 "WARNING: It is highly recommended to use Vagrant $REQUIRED_VERSION or above before continuing")
|
||||
fi
|
||||
}
|
||||
|
||||
# Returns 0 if not installed or 1 if installed
|
||||
check_virtualbox_installed() {
|
||||
if which VBoxManage >/dev/null; then
|
||||
echo "1"
|
||||
else
|
||||
echo "0"
|
||||
fi
|
||||
}
|
||||
|
||||
# Returns 0 if not installed or 1 if installed
|
||||
# Check for VMWare Workstation on Linux
|
||||
check_vmware_workstation_installed() {
|
||||
if which vmrun >/dev/null; then
|
||||
echo "1"
|
||||
else
|
||||
echo "0"
|
||||
fi
|
||||
}
|
||||
|
||||
# Returns 0 if not installed or 1 if installed
|
||||
check_vmware_fusion_installed() {
|
||||
if [ -e "/Applications/VMware Fusion.app" ]; then
|
||||
echo "1"
|
||||
else
|
||||
echo "0"
|
||||
fi
|
||||
}
|
||||
|
||||
# Returns 0 if not installed or 1 if installed
|
||||
check_vmware_desktop_vagrant_plugin_installed() {
|
||||
LEGACY_PLUGIN_CHECK="$(vagrant plugin list | grep -c 'vagrant-vmware-fusion')"
|
||||
if [ "$LEGACY_PLUGIN_CHECK" -gt 0 ]; then
|
||||
(echo >&2 "The VMware Fusion Vagrant plugin is deprecated and is no longer supported by the DetectionLab build script.")
|
||||
(echo >&2 "Please upgrade to the VMware Desktop plugin: https://www.vagrantup.com/docs/vmware/installation.html")
|
||||
(echo >&2 "NOTE: The VMware plugin does not work with trial versions of VMware Fusion")
|
||||
echo "0"
|
||||
fi
|
||||
VAGRANT_VMWARE_DESKTOP_PLUGIN_PRESENT="$(vagrant plugin list | grep -c 'vagrant-vmware-desktop')"
|
||||
if [ "$VAGRANT_VMWARE_DESKTOP_PLUGIN_PRESENT" -eq 0 ]; then
|
||||
(echo >&2 "VMWare Fusion or Workstation is installed, but the vagrant-vmware-desktop plugin is not.")
|
||||
(echo >&2 "If you are seeing this, you may have the deprecated vagrant-vmware-fusion plugin installed. Please remove it and install the vagrant-vmware-desktop plugin.")
|
||||
(echo >&2 "Visit https://www.hashicorp.com/blog/introducing-the-vagrant-vmware-desktop-plugin for more information on how to purchase and install it")
|
||||
(echo >&2 "VMWare Fusion or Workstation will not be listed as a provider until the vagrant-vmware-desktop plugin has been installed.")
|
||||
echo "0"
|
||||
else
|
||||
echo "$VAGRANT_VMWARE_DESKTOP_PLUGIN_PRESENT"
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
|
||||
# List the available Vagrant providers present on the system
|
||||
list_providers() {
|
||||
VBOX_PRESENT=0
|
||||
VMWARE_FUSION_PRESENT=0
|
||||
|
||||
if [ "$(uname)" == "Darwin" ]; then
|
||||
# Detect Providers on OSX
|
||||
VBOX_PRESENT=$(check_virtualbox_installed)
|
||||
VMWARE_FUSION_PRESENT=$(check_vmware_fusion_installed)
|
||||
VMWARE_WORKSTATION_PRESENT=0 # Workstation doesn't exists on Darwain-based OS
|
||||
VAGRANT_VMWARE_DESKTOP_PLUGIN_PRESENT=$(check_vmware_desktop_vagrant_plugin_installed)
|
||||
else
|
||||
# Assume the only other available provider is VirtualBox
|
||||
VBOX_PRESENT=$(check_virtualbox_installed)
|
||||
VMWARE_WORKSTATION_PRESENT=$(check_vmware_workstation_installed)
|
||||
VMWARE_FUSION_PRESENT=0 # Fusion doesn't exist on non-Darwin OS
|
||||
VAGRANT_VMWARE_DESKTOP_PLUGIN_PRESENT=$(check_vmware_desktop_vagrant_plugin_installed)
|
||||
fi
|
||||
|
||||
(echo >&2 "Available Providers:")
|
||||
if [ "$VBOX_PRESENT" == "1" ]; then
|
||||
(echo >&2 "virtualbox")
|
||||
fi
|
||||
if [[ $VMWARE_FUSION_PRESENT -eq 1 ]] && [[ $VAGRANT_VMWARE_DESKTOP_PLUGIN_PRESENT -eq 1 ]]; then
|
||||
(echo >&2 "vmware_desktop")
|
||||
fi
|
||||
if [[ $VMWARE_WORKSTATION_PRESENT -eq 1 ]] && [[ $VAGRANT_VMWARE_DESKTOP_PLUGIN_PRESENT -eq 1 ]]; then
|
||||
(echo >&2 "vmware_desktop")
|
||||
fi
|
||||
if [[ $VBOX_PRESENT -eq 0 ]] && [[ $VMWARE_FUSION_PRESENT -eq 0 ]] && [[ $VMWARE_WORKSTATION -eq 0 ]]; then
|
||||
(echo >&2 "You need to install a provider such as VirtualBox or VMware Fusion to continue.")
|
||||
exit 1
|
||||
fi
|
||||
(echo >&2 -e "\\nWhich provider would you like to use?")
|
||||
read -r PROVIDER
|
||||
# Sanity check
|
||||
if [[ "$PROVIDER" != "virtualbox" ]] && [[ "$PROVIDER" != "vmware_desktop" ]]; then
|
||||
(echo >&2 "Please choose a valid provider. \"$PROVIDER\" is not a valid option.")
|
||||
exit 1
|
||||
fi
|
||||
echo "$PROVIDER"
|
||||
}
|
||||
|
||||
# Check to see if boxes exist in the "Boxes" directory already
|
||||
check_boxes_built() {
|
||||
BOXES_BUILT=$(find "$DL_DIR"/Boxes -name "*.box" | wc -l)
|
||||
if [ "$BOXES_BUILT" -gt 0 ]; then
|
||||
if [ "$VAGRANT_ONLY" -eq 1 ]; then
|
||||
(echo >&2 "WARNING: You seem to have at least one .box file present in $DL_DIR/Boxes already. If you would like fresh boxes downloaded, please remove all files from the Boxes directory and re-run this script.")
|
||||
else
|
||||
(echo >&2 "You seem to have at least one .box file in $DL_DIR/Boxes. This script does not support pre-built boxes. Please either delete the existing boxes or follow the build steps in the README to continue.")
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# Check to see if any Vagrant instances exist already
|
||||
check_vagrant_instances_exist() {
|
||||
cd "$DL_DIR"/Vagrant/ || exit 1
|
||||
# Vagrant status has the potential to return a non-zero error code, so we work around it with "|| true"
|
||||
VAGRANT_BUILT=$(vagrant status | grep -c 'not created') || true
|
||||
if [ "$VAGRANT_BUILT" -ne 4 ]; then
|
||||
(echo >&2 "You appear to have already created at least one Vagrant instance. This script does not support pre-created instances. Please either destroy the existing instances or follow the build steps in the README to continue.")
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
check_vagrant_reload_plugin() {
|
||||
# Ensure the vagrant-reload plugin is installed
|
||||
VAGRANT_RELOAD_PLUGIN_INSTALLED=$(vagrant plugin list | grep -c 'vagrant-reload')
|
||||
if [ "$VAGRANT_RELOAD_PLUGIN_INSTALLED" != "1" ]; then
|
||||
(echo >&2 "The vagrant-reload plugin is required and not currently installed. This script will attempt to install it now.")
|
||||
if ! $(which vagrant) plugin install "vagrant-reload"; then
|
||||
(echo >&2 "Unable to install the vagrant-reload plugin. Please try to do so manually and re-run this script.")
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# Check available disk space. Recommend 80GB free, warn if less.
|
||||
check_disk_free_space() {
|
||||
FREE_DISK_SPACE=$(df -m "$HOME" | tr -s ' ' | grep '/' | cut -d ' ' -f 4)
|
||||
if [ "$FREE_DISK_SPACE" -lt 80000 ]; then
|
||||
(echo >&2 -e "Warning: You appear to have less than 80GB of HDD space free on your primary partition. If you are using a separate parition, you may ignore this warning.\n")
|
||||
(df >&2 -m "$HOME")
|
||||
(echo >&2 "")
|
||||
fi
|
||||
}
|
||||
|
||||
# Check to see if curl is in PATH - needed for post-install checks
|
||||
check_curl(){
|
||||
if ! which curl >/dev/null; then
|
||||
(echo >&2 "Please install curl and make sure it is in your PATH.")
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Check Packer version against known "bad" versions
|
||||
check_packer_known_bad() {
|
||||
if [ "$(packer --version)" == '1.1.2' ]; then
|
||||
(echo >&2 "Packer 1.1.2 is not supported. Please upgrade to a newer version and see https://github.com/hashicorp/packer/issues/5622 for more information.")
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# A series of checks to identify potential issues before starting the build
|
||||
preflight_checks() {
|
||||
# If it's not a Vagrant-only build, then run Packer-related checks
|
||||
if [ "$VAGRANT_ONLY" -eq 0 ]; then
|
||||
check_packer_path
|
||||
check_packer_known_bad
|
||||
fi
|
||||
|
||||
# If it's not a Packer-only build, then run Vagrant-related checks
|
||||
if [ "$PACKER_ONLY" -eq 0 ]; then
|
||||
check_vagrant_path
|
||||
check_vagrant_instances_exist
|
||||
check_vagrant_reload_plugin
|
||||
fi
|
||||
|
||||
check_boxes_built
|
||||
check_disk_free_space
|
||||
check_curl
|
||||
}
|
||||
|
||||
# Builds a box using Packer
|
||||
packer_build_box() {
|
||||
BOX="$1"
|
||||
cd "$DL_DIR/Packer" || exit 1
|
||||
(echo >&2 "Using Packer to build the $BOX Box. This can take 90-180 minutes depending on bandwidth and hardware.")
|
||||
PACKER_LOG=1 PACKER_LOG_PATH="$DL_DIR/Packer/packer_build.log" $(which packer) build --only="$PACKER_PROVIDER-iso" "$BOX".json >&2
|
||||
echo "$?"
|
||||
}
|
||||
|
||||
# Moves the boxes from the Packer directory to the Boxes directory
|
||||
move_boxes() {
|
||||
mv "$DL_DIR"/Packer/*.box "$DL_DIR"/Boxes
|
||||
# Ensure Windows 10 box exists
|
||||
if [ ! -f "$DL_DIR"/Boxes/windows_10_"$PACKER_PROVIDER".box ]; then
|
||||
(echo >&2 "Windows 10 box is missing from the Boxes directory. Qutting.")
|
||||
exit 1
|
||||
fi
|
||||
# Ensure Windows 2016 box exists
|
||||
if [ ! -f "$DL_DIR"/Boxes/windows_2016_"$PACKER_PROVIDER".box ]; then
|
||||
(echo >&2 "Windows 2016 box is missing from the Boxes directory. Qutting.")
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Brings up a single host using Vagrant
|
||||
vagrant_up_host() {
|
||||
HOST="$1"
|
||||
(echo >&2 "Attempting to bring up the $HOST host using Vagrant")
|
||||
cd "$DL_DIR"/Vagrant || exit 1
|
||||
$(which vagrant) up "$HOST" --provider="$PROVIDER" &> "$DL_DIR/Vagrant/vagrant_up_$HOST.log"
|
||||
echo "$?"
|
||||
}
|
||||
|
||||
# Attempts to reload and re-provision a host if the intial "vagrant up" fails
|
||||
vagrant_reload_host() {
|
||||
HOST="$1"
|
||||
cd "$DL_DIR"/Vagrant || exit 1
|
||||
# Attempt to reload the host if the vagrant up command didn't exit cleanly
|
||||
$(which vagrant) reload "$HOST" --provision >>"$DL_DIR/Vagrant/vagrant_up_$HOST.log" 2>&1
|
||||
echo "$?"
|
||||
}
|
||||
|
||||
# A series of checks to ensure important services are responsive after the build completes.
|
||||
post_build_checks() {
|
||||
# If the curl operation fails, we'll just leave the variable equal to 0
|
||||
# This is needed to prevent the script from exiting if the curl operation fails
|
||||
SPLUNK_CHECK=$(curl -ks -m 2 https://192.168.38.105:8000/en-US/account/login?return_to=%2Fen-US%2F | grep -c 'This browser is not supported by Splunk' || echo "")
|
||||
FLEET_CHECK=$(curl -ks -m 2 https://192.168.38.105:8412 | grep -c 'Kolide Fleet' || echo "")
|
||||
ATA_CHECK=$(curl --fail --write-out "%{http_code}" -ks https://192.168.38.103 -m 2)
|
||||
[[ $ATA_CHECK == 401 ]] && ATA_CHECK=1
|
||||
|
||||
BASH_MAJOR_VERSION=$(/bin/bash --version | grep 'GNU bash' | grep -oi version\.\.. | cut -d ' ' -f 2 | cut -d '.' -f 1)
|
||||
# Associative arrays are only supported in bash 4 and up
|
||||
if [ "$BASH_MAJOR_VERSION" -ge 4 ]; then
|
||||
declare -A SERVICES
|
||||
SERVICES=(["splunk"]="$SPLUNK_CHECK" ["fleet"]="$FLEET_CHECK" ["ms_ata"]="$ATA_CHECK")
|
||||
for SERVICE in "${!SERVICES[@]}"; do
|
||||
if [ "${SERVICES[$SERVICE]}" -lt 1 ]; then
|
||||
(echo >&2 "Warning: $SERVICE failed post-build tests and may not be functioning correctly.")
|
||||
fi
|
||||
done
|
||||
else
|
||||
if [ "$SPLUNK_CHECK" -lt 1 ]; then
|
||||
(echo >&2 "Warning: Splunk failed post-build tests and may not be functioning correctly.")
|
||||
fi
|
||||
if [ "$FLEET_CHECK" -lt 1 ]; then
|
||||
(echo >&2 "Warning: Fleet failed post-build tests and may not be functioning correctly.")
|
||||
fi
|
||||
if [ "$ATA_CHECK" -lt 1 ]; then
|
||||
(echo >&2 "Warning: MS ATA failed post-build tests and may not be functioning correctly.")
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
parse_cli_arguments() {
|
||||
# If no argument was supplied, list available providers
|
||||
if [ "$#" -eq 0 ]; then
|
||||
PROVIDER=$(list_providers)
|
||||
fi
|
||||
# If more than two arguments were supplied, print usage message
|
||||
if [ "$#" -gt 2 ]; then
|
||||
print_usage
|
||||
exit 1
|
||||
fi
|
||||
if [ "$#" -ge 1 ]; then
|
||||
# If the user specifies the provider as an agument, set the variable
|
||||
# TODO: Check to make sure they actually have their provider installed
|
||||
case "$1" in
|
||||
virtualbox)
|
||||
PROVIDER="$1"
|
||||
PACKER_PROVIDER="$1"
|
||||
;;
|
||||
vmware_desktop)
|
||||
PROVIDER="$1"
|
||||
PACKER_PROVIDER="vmware"
|
||||
;;
|
||||
*)
|
||||
echo "\"$1\" is not a valid provider. Listing available providers:"
|
||||
PROVIDER=$(list_providers)
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
if [ $# -eq 2 ]; then
|
||||
case "$2" in
|
||||
--packer-only)
|
||||
PACKER_ONLY=1
|
||||
;;
|
||||
--vagrant-only)
|
||||
VAGRANT_ONLY=1
|
||||
;;
|
||||
*)
|
||||
echo -e "\"$2\" is not recognized as an option. Available options are:\\n--packer-only\\n--vagrant-only"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
}
|
||||
|
||||
build_packer_boxes() {
|
||||
PACKER_BOXES=("windows_2016" "windows_10")
|
||||
|
||||
if [ "$(hostname)" == "packerwindows10" ]; then # Workaround for CI environment
|
||||
(echo >&2 "CI Environment detected. If you are a user and are seeing this, please file an issue on GitHub.")
|
||||
RET=$(packer_build_box "windows_10")
|
||||
if [ "$RET" -eq 0 ]; then
|
||||
(echo >&2 "Good news! The windows_10 box was built with Packer successfully!")
|
||||
else
|
||||
(echo >&2 "Something went wrong while attempting to build the windows_10 box.")
|
||||
(echo >&2 "To file an issue, please visit https://github.com/clong/DetectionLab/issues/")
|
||||
exit 1
|
||||
fi
|
||||
elif [ "$(hostname)" == "packerwindows2016" ]; then # Workaround for CI environment
|
||||
(echo >&2 "CI Environment detected. If you are a user and are seeing this, please file an issue on GitHub.")
|
||||
RET=$(packer_build_box "windows_2016")
|
||||
if [ "$RET" -eq 0 ]; then
|
||||
(echo >&2 "Good news! The windows_2016 box was built with Packer successfully!")
|
||||
else
|
||||
(echo >&2 "Something went wrong while attempting to build the windows_2016 box.")
|
||||
(echo >&2 "To file an issue, please visit https://github.com/clong/DetectionLab/issues/")
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
for PACKER_BOX in "${PACKER_BOXES[@]}"; do # Normal user workflow
|
||||
RET=$(packer_build_box "$PACKER_BOX")
|
||||
if [ "$RET" -eq 0 ]; then
|
||||
(echo >&2 "Good news! $PACKER_BOX was built successfully!")
|
||||
else
|
||||
(echo >&2 "Something went wrong while attempting to build the $PACKER_BOX box.")
|
||||
(echo >&2 "To file an issue, please visit https://github.com/clong/DetectionLab/issues/")
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
fi
|
||||
}
|
||||
|
||||
build_vagrant_hosts() {
|
||||
LAB_HOSTS=("logger" "dc" "wef" "win10")
|
||||
|
||||
# Vagrant up each box and attempt to reload one time if it fails
|
||||
for VAGRANT_HOST in "${LAB_HOSTS[@]}"; do
|
||||
RET=$(vagrant_up_host "$VAGRANT_HOST")
|
||||
if [ "$RET" -eq 0 ]; then
|
||||
(echo >&2 "Good news! $VAGRANT_HOST was built successfully!")
|
||||
fi
|
||||
# Attempt to recover if the intial "vagrant up" fails
|
||||
if [ "$RET" -ne 0 ]; then
|
||||
(echo >&2 "Something went wrong while attempting to build the $VAGRANT_HOST box.")
|
||||
(echo >&2 "Attempting to reload and reprovision the host...")
|
||||
RETRY_STATUS=$(vagrant_reload_host "$VAGRANT_HOST")
|
||||
if [ "$RETRY_STATUS" -eq 0 ]; then
|
||||
(echo >&2 "Good news! $VAGRANT_HOST was built successfully after a reload!")
|
||||
else
|
||||
(echo >&2 "Failed to bring up $VAGRANT_HOST after a reload. Exiting.")
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
main() {
|
||||
# Get location of build.sh
|
||||
# https://stackoverflow.com/questions/59895/getting-the-source-directory-of-a-bash-script-from-within
|
||||
DL_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PACKER_ONLY=0
|
||||
VAGRANT_ONLY=0
|
||||
|
||||
parse_cli_arguments "$@"
|
||||
preflight_checks
|
||||
|
||||
# Build Packer boxes if this isn't a Vagrant-only build
|
||||
if [ "$VAGRANT_ONLY" -eq 0 ]; then
|
||||
build_packer_boxes
|
||||
# The only time we will need to move boxes is if we're doing a full build
|
||||
if [ "$PACKER_ONLY" -eq 0 ]; then
|
||||
move_boxes
|
||||
fi
|
||||
fi
|
||||
|
||||
# Build and Test Vagrant hosts if this isn't a Packer-only build
|
||||
if [ "$PACKER_ONLY" -eq 0 ]; then
|
||||
build_vagrant_hosts
|
||||
post_build_checks
|
||||
fi
|
||||
}
|
||||
|
||||
main "$@"
|
||||
exit 0
|
||||
@@ -79,8 +79,8 @@ ufw --force enable
|
||||
echo "[$(date +%H:%M:%S)]: Installing Vagrant..."
|
||||
mkdir /opt/vagrant
|
||||
cd /opt/vagrant || exit 1
|
||||
wget --progress=bar:force https://releases.hashicorp.com/vagrant/2.2.9/vagrant_2.2.9_x86_64.deb
|
||||
dpkg -i vagrant_2.2.9_x86_64.deb
|
||||
wget --progress=bar:force https://releases.hashicorp.com/vagrant/2.2.10/vagrant_2.2.10_x86_64.deb
|
||||
dpkg -i vagrant_2.2.10_x86_64.deb
|
||||
echo "[$(date +%H:%M:%S)]: Installing vagrant-reload plugin..."
|
||||
vagrant plugin install vagrant-reload
|
||||
|
||||
@@ -110,11 +110,7 @@ if [ $BOXES_PRESENT -eq 1 ]; then
|
||||
sed -i 's#"detectionlab/win10"#"/mnt/windows_10_virtualbox.box"#g' /opt/DetectionLab/Vagrant/Vagrantfile
|
||||
fi
|
||||
|
||||
# Make the build script is executable
|
||||
chmod +x /opt/DetectionLab/build.sh
|
||||
cd /opt/DetectionLab || exit 1
|
||||
|
||||
# Start the build in a tmux session
|
||||
sn=tmuxsession
|
||||
tmux new-session -s "$sn" -d
|
||||
tmux send-keys -t "$sn:0" './build.sh virtualbox --vagrant-only && echo "success" > /var/www/html/index.html || echo "failed" > /var/www/html/index.html; umount /mnt && /usr/local/bin/packet-block-storage-detach' Enter
|
||||
tmux send-keys -t "$sn:0" 'cd /opt/DetectionLab/Vagrant && vagrant up | tee -a vagrant_up_all.log && echo "success" > /var/www/html/index.html || echo "failed" > /var/www/html/index.html; umount /mnt && /usr/local/bin/packet-block-storage-detach' Enter
|
||||
|
||||
@@ -25,8 +25,8 @@ git clone https://github.com/clong/DetectionLab.git /opt/DetectionLab
|
||||
# Install Vagrant
|
||||
mkdir /opt/vagrant
|
||||
cd /opt/vagrant || exit 1
|
||||
wget https://releases.hashicorp.com/vagrant/2.2.9/vagrant_2.2.9_x86_64.deb
|
||||
dpkg -i vagrant_2.2.9_x86_64.deb
|
||||
wget https://releases.hashicorp.com/vagrant/2.2.10/vagrant_2.2.10_x86_64.deb
|
||||
dpkg -i vagrant_2.2.10_x86_64.deb
|
||||
|
||||
# Disable IPv6 - may help with the vagrant-reload plugin: https://github.com/hashicorp/vagrant/issues/8795#issuecomment-468945063
|
||||
echo "net.ipv6.conf.all.disable_ipv6=1" >> /etc/sysctl.conf
|
||||
@@ -50,6 +50,3 @@ for file in *.json; do
|
||||
sed -i 's/"headless": false,/"headless": true,/g' "$file";
|
||||
done
|
||||
|
||||
# Ensure the script is executable
|
||||
chmod +x /opt/DetectionLab/build.sh
|
||||
cd /opt/DetectionLab || exit 1
|
||||
|
||||
@@ -28,8 +28,8 @@ git clone https://github.com/clong/DetectionLab.git /opt/DetectionLab
|
||||
# Install Vagrant
|
||||
mkdir /opt/vagrant
|
||||
cd /opt/vagrant || exit 1
|
||||
wget --progress=bar:force https://releases.hashicorp.com/vagrant/2.2.9/vagrant_2.2.9_x86_64.deb
|
||||
dpkg -i vagrant_2.2.9_x86_64.deb
|
||||
wget --progress=bar:force https://releases.hashicorp.com/vagrant/2.2.10/vagrant_2.2.10_x86_64.deb
|
||||
dpkg -i vagrant_2.2.10_x86_64.deb
|
||||
# Disable IPv6 - may help with the vagrant-reload plugin: https://github.com/hashicorp/vagrant/issues/8795#issuecomment-468945063
|
||||
echo "net.ipv6.conf.all.disable_ipv6=1" >> /etc/sysctl.conf
|
||||
sysctl -p /etc/sysctl.conf > /dev/null
|
||||
@@ -37,8 +37,8 @@ vagrant plugin install vagrant-reload
|
||||
vagrant plugin install vagrant-vmware-desktop
|
||||
echo $LICENSEFILE | base64 -d > /tmp/license.lic
|
||||
vagrant plugin license vagrant-vmware-desktop /tmp/license.lic
|
||||
wget --progress=bar:force "https://releases.hashicorp.com/vagrant-vmware-utility/1.0.9/vagrant-vmware-utility_1.0.9_x86_64.deb"
|
||||
dpkg -i vagrant-vmware-utility_1.0.9_x86_64.deb
|
||||
wget --progress=bar:force "https://releases.hashicorp.com/vagrant-vmware-utility/1.0.11/vagrant-vmware-utility_1.0.11_x86_64.deb"
|
||||
dpkg -i vagrant-vmware-utility_1.0.11_x86_64.deb
|
||||
|
||||
# Make the Vagrant instances headless
|
||||
cd /opt/DetectionLab/Vagrant || exit 1
|
||||
@@ -56,7 +56,3 @@ cd /opt/DetectionLab/Packer || exit 1
|
||||
for file in *.json; do
|
||||
sed -i 's/"headless": false,/"headless": true,/g' "$file";
|
||||
done
|
||||
|
||||
# Ensure the script is executable
|
||||
chmod +x /opt/DetectionLab/build.sh
|
||||
cd /opt/DetectionLab || exit 1
|
||||
|
||||
Reference in New Issue
Block a user