diff --git a/Packer/scripts/debloat-windows.ps1 b/Packer/scripts/debloat-windows.ps1 index 686943c..0a58025 100755 --- a/Packer/scripts/debloat-windows.ps1 +++ b/Packer/scripts/debloat-windows.ps1 @@ -8,21 +8,27 @@ if ($env:PACKER_BUILDER_TYPE -And $($env:PACKER_BUILDER_TYPE).startsWith("hyperv (New-Object System.Net.WebClient).DownloadFile($url, "$env:TEMP\debloat.zip") Expand-Archive -Path $env:TEMP\debloat.zip -DestinationPath $env:TEMP -Force - #Write-Host Disable scheduled tasks - #. $env:TEMP\Debloat-Windows-10-master\utils\disable-scheduled-tasks.ps1 - #Write-Host Block telemetry - #. $env:TEMP\Debloat-Windows-10-master\scripts\block-telemetry.ps1 - #Write-Host Disable services - #. $env:TEMP\Debloat-Windows-10-master\scripts\disable-services.ps1 + # Disable Windows Defender Write-host Disable Windows Defender - #. $env:TEMP\Debloat-Windows-10-master\scripts\disable-windows-defender.ps1 - Uninstall-WindowsFeature Windows-Defender-Features + $os = (gwmi win32_operatingsystem).caption + if ($os -like "*Windows 10*") { + set-MpPreference -DisableRealtimeMonitoring $true + } else { + Uninstall-WindowsFeature Windows-Defender-Features + } + + # Optimize Windows Update Write-host Optimize Windows Update . $env:TEMP\Debloat-Windows-10-master\scripts\optimize-windows-update.ps1 - #Write-host Disable Windows Update - #Set-Service wuauserv -StartupType Disabled - #Write-Host Remove OneDrive - #. $env:TEMP\Debloat-Windows-10-master\scripts\remove-onedrive.ps1 + Write-host Disable Windows Update + Set-Service wuauserv -StartupType Disabled + + # Turn off shutdown event tracking + if ( -Not (Test-Path 'registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Reliability')) + { + New-Item -Path 'registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT' -Name Reliability -Force + } + Set-ItemProperty -Path 'registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Reliability' -Name ShutdownReasonOn -Value 0 rm $env:TEMP\debloat.zip rm -recurse $env:TEMP\Debloat-Windows-10-master diff --git a/Packer/windows_2016.json b/Packer/windows_2016.json index 355031e..820b2a7 100644 --- a/Packer/windows_2016.json +++ b/Packer/windows_2016.json @@ -32,6 +32,7 @@ "enable_secure_boot":true }, { + "vm_name":"WindowsServer2016", "type": "vmware-iso", "communicator": "winrm", "iso_url": "{{user `iso_url`}}", @@ -70,6 +71,7 @@ } }, { + "vm_name":"WindowsServer2016", "type": "virtualbox-iso", "communicator": "winrm", "iso_url": "{{user `iso_url`}}", diff --git a/README.md b/README.md index 55ee4ee..b239aee 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,13 @@ # Detection Lab CircleCI: [![CircleCI](https://circleci.com/gh/clong/DetectionLab/tree/master.svg?style=svg)](https://circleci.com/gh/clong/DetectionLab/tree/master) +#### Donate to the project: + +All of the infrastructure, building, and testing of DetectionLab is currently funded by myself in my spare time. If you find this project useful, feel free to buy me a coffee using one of the buttons below! + +[![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](paypal.me/clong0) +[![Donate](https://img.shields.io/badge/Donate-Crypto-blue.svg)](https://commerce.coinbase.com/checkout/838ac7a2-7b9d-4d40-b475-fd1015fdaacd) + ## Purpose This lab has been designed with defenders in mind. Its primary purpose is to allow the user to quickly build a Windows domain that comes pre-loaded with security tooling and some best practices when it comes to system logging configurations. It can easily be modified to fit most needs or expanded to include additional hosts. @@ -56,10 +63,10 @@ Windows users will want to use the following script: Provider | Box | URL | MD5 | Size ------------|-----|-----|----|---- -Virtualbox |Windows 2016 | https://www.detectionlab.network/windows_2016_virtualbox.box | f352c852ed1b849dab18442caef83712 | 6.4GB -Virtualbox | Windows 10 | https://www.detectionlab.network/windows_10_virtualbox.box | ad78b3406dd2c0e3418d1dd61e2abc2c | 5.8GB -VMware | Windows 2016 | https://www.detectionlab.network/windows_2016_vmware.box | da1111c765b2fdc2ce012b6348cf74e2 | 6.7GB -VMware | Windows 10 | https://www.detectionlab.network/windows_10_vmware.box | 14e1c4cc15e1dc47aead906b25c5b3cc | 6.0GB +Virtualbox |Windows 2016 | https://www.detectionlab.network/windows_2016_virtualbox.box | 2a0b5dbc432e27a0223da026cc1f378b | 6.4GB +Virtualbox | Windows 10 | https://www.detectionlab.network/windows_10_virtualbox.box | 94c1ff7264e67af3d7df6d19275086ac | 5.8GB +VMware | Windows 2016 | https://www.detectionlab.network/windows_2016_vmware.box | 634628e04a1c6c94b4036b76d0568948 | 6.7GB +VMware | Windows 10 | https://www.detectionlab.network/windows_10_vmware.box | 7d26d3247162dfbf6026fd5bab6a21ee | 6.0GB If you choose to download the boxes, you may skip steps 2 and 3. If you don't trust pre-built boxes, I recommend following steps 2 and 3 to build them on your machine. @@ -85,9 +92,9 @@ $ packer build --only=[vmware|virtualbox]-iso windows_2016.json * Provision the WEF host and configure it as a Windows Event Collector in the Servers OU * Provision the Win10 host and configure it as a computer in the Workstations OU -7. Navigate to https://192.168.38.5:8000 in a browser to access the Splunk instance on logger. Default credentials are admin:changeme (you will have the option to change them on the next screen) -8. Navigate to https://192.168.38.5:8412 in a browser to access the Fleet server on logger. Default credentials are admin:admin123#. Query packs are pre-configured with queries from [palantir/osquery-configuration](https://github.com/palantir/osquery-configuration). -9. Navigate to https://192.168.38.5:8888 in a browser to access the Caldera server on logger. Default credentials are admin:caldera. +7. Navigate to https://192.168.38.105:8000 in a browser to access the Splunk instance on logger. Default credentials are admin:changeme (you will have the option to change them on the next screen) +8. Navigate to https://192.168.38.105:8412 in a browser to access the Fleet server on logger. Default credentials are admin:admin123#. Query packs are pre-configured with queries from [palantir/osquery-configuration](https://github.com/palantir/osquery-configuration). +9. Navigate to https://192.168.38.105:8888 in a browser to access the Caldera server on logger. Default credentials are admin:caldera. ## Basic Vagrant Usage Vagrant commands must be run from the "Vagrant" folder. @@ -108,10 +115,10 @@ Vagrant commands must be run from the "Vagrant" folder. ## Lab Information * Domain Name: windomain.local * Admininstrator login: vagrant:vagrant -* Fleet login: https://192.168.38.5:8412 - admin:admin123# -* Splunk login: https://192.168.38.5:8000 - admin:changeme -* Caldera login: https://192.168.38.5:8888 - admin:caldera -* MS ATA login: https://192.168.38.3 - wef\vagrant:vagrant +* Fleet login: https://192.168.38.105:8412 - admin:admin123# +* Splunk login: https://192.168.38.105:8000 - admin:changeme +* Caldera login: https://192.168.38.105:8888 - admin:caldera +* MS ATA login: https://192.168.38.103 - wef\vagrant:vagrant ## Lab Hosts * DC - Windows 2016 Domain Controller @@ -143,7 +150,7 @@ Vagrant commands must be run from the "Vagrant" folder. * Fleet osquery Manager * Mitre's Caldera Server * Bro - * Suricata + * Suricata ## Splunk Indexes Index Name | Description diff --git a/Vagrant/Vagrantfile b/Vagrant/Vagrantfile index 5f50010..873e98d 100644 --- a/Vagrant/Vagrantfile +++ b/Vagrant/Vagrantfile @@ -4,15 +4,17 @@ Vagrant.configure("2") do |config| cfg.vm.box = "bento/ubuntu-16.04" cfg.vm.hostname = "logger" config.vm.provision :shell, path: "bootstrap.sh" - cfg.vm.network :private_network, ip: "192.168.38.5", gateway: "192.168.38.1", dns: "8.8.8.8" + cfg.vm.network :private_network, ip: "192.168.38.105", gateway: "192.168.38.1", dns: "8.8.8.8" cfg.vm.provider "vmware_fusion" do |v, override| + v.vmx["displayname"] = "logger" v.memory = 2048 v.cpus = 1 v.gui = true end cfg.vm.provider "vmware_desktop" do |v, override| + v.vmx["displayname"] = "logger" v.memory = 4096 v.cpus = 2 v.gui = true @@ -20,6 +22,7 @@ Vagrant.configure("2") do |config| cfg.vm.provider "virtualbox" do |vb, override| vb.gui = true + vb.name = "logger" vb.customize ["modifyvm", :id, "--memory", 4096] vb.customize ["modifyvm", :id, "--cpus", 2] vb.customize ["modifyvm", :id, "--vram", "32"] @@ -42,9 +45,9 @@ Vagrant.configure("2") do |config| cfg.winrm.basic_auth_only = true cfg.winrm.timeout = 300 cfg.winrm.retry_limit = 20 - cfg.vm.network :private_network, ip: "192.168.38.2", gateway: "192.168.38.1" + cfg.vm.network :private_network, ip: "192.168.38.102", gateway: "192.168.38.1" - cfg.vm.provision "shell", path: "scripts/fix-second-network.ps1", privileged: false, args: "192.168.38.2" + cfg.vm.provision "shell", path: "scripts/fix-second-network.ps1", privileged: false, args: "192.168.38.102" cfg.vm.provision "shell", path: "scripts/provision.ps1", privileged: false cfg.vm.provision "reload" cfg.vm.provision "shell", path: "scripts/provision.ps1", privileged: false @@ -61,10 +64,12 @@ Vagrant.configure("2") do |config| cfg.vm.provision "shell", path: "scripts/configure-powershelllogging.ps1", privileged: true cfg.vm.provision "shell", path: "scripts/configure-AuditingPolicyGPOs.ps1", privileged: true cfg.vm.provision "shell", path: "scripts/install-autorunstowineventlog.ps1", privileged: true + cfg.vm.provision "shell", inline: 'wevtutil el | Foreach-Object {wevtutil cl "$_"}', privileged: true cfg.vm.provision "shell", inline: "Set-SmbServerConfiguration -AuditSmb1Access $true -Force", privileged: true cfg.vm.provider "vmware_fusion" do |v, override| override.vm.box = "../Boxes/windows_2016_vmware.box" + v.vmx["displayname"] = "dc.windomain.local" v.memory = 2560 v.cpus = 2 v.gui = true @@ -72,6 +77,7 @@ Vagrant.configure("2") do |config| cfg.vm.provider "vmware_desktop" do |v, override| override.vm.box = "../Boxes/windows_2016_vmware.box" + v.vmx["displayname"] = "dc.windomain.local" v.memory = 2560 v.cpus = 2 v.gui = true @@ -80,6 +86,7 @@ Vagrant.configure("2") do |config| cfg.vm.provider "virtualbox" do |vb, override| vb.gui = true + vb.name = "dc.windomain.local" vb.customize ["modifyvm", :id, "--memory", 2560] vb.customize ["modifyvm", :id, "--cpus", 2] vb.customize ["modifyvm", :id, "--vram", "32"] @@ -96,14 +103,15 @@ Vagrant.configure("2") do |config| cfg.winrm.basic_auth_only = true cfg.winrm.timeout = 300 cfg.winrm.retry_limit = 20 - cfg.vm.network :private_network, ip: "192.168.38.3", gateway: "192.168.38.1", dns: "192.168.38.2" + cfg.vm.network :private_network, ip: "192.168.38.103", gateway: "192.168.38.1", dns: "192.168.38.102" - cfg.vm.provision "shell", path: "scripts/fix-second-network.ps1", privileged: false, args: "-ip 192.168.38.3 -dns 192.168.38.2" + cfg.vm.provision "shell", path: "scripts/fix-second-network.ps1", privileged: false, args: "-ip 192.168.38.103 -dns 192.168.38.102" cfg.vm.provision "shell", path: "scripts/provision.ps1", privileged: false cfg.vm.provision "reload" cfg.vm.provision "shell", path: "scripts/provision.ps1", privileged: false cfg.vm.provision "shell", path: "scripts/download_palantir_wef.ps1", privileged: true cfg.vm.provision "shell", path: "scripts/download_palantir_osquery.ps1", privileged: true + cfg.vm.provision "shell", inline: 'wevtutil el | Foreach-Object {wevtutil cl "$_"}', privileged: true cfg.vm.provision "shell", path: "scripts/install-wefsubscriptions.ps1", privileged: true cfg.vm.provision "shell", path: "scripts/install-splunkuf.ps1", privileged: true cfg.vm.provision "shell", path: "scripts/install-windows_ta.ps1", privileged: true @@ -119,6 +127,7 @@ Vagrant.configure("2") do |config| cfg.vm.provider "vmware_fusion" do |v, override| override.vm.box = "../Boxes/windows_2016_vmware.box" + v.vmx["displayname"] = "wef.windomain.local" v.memory = 2048 v.cpus = 2 v.gui = true @@ -126,6 +135,7 @@ Vagrant.configure("2") do |config| cfg.vm.provider "vmware_desktop" do |v, override| override.vm.box = "../Boxes/windows_2016_vmware.box" + v.vmx["displayname"] = "wef.windomain.local" v.memory = 2048 v.cpus = 2 v.gui = true @@ -134,6 +144,7 @@ Vagrant.configure("2") do |config| cfg.vm.provider "virtualbox" do |vb, override| vb.gui = true + vb.name = "wef.windomain.local" vb.customize ["modifyvm", :id, "--memory", 2048] vb.customize ["modifyvm", :id, "--cpus", 2] vb.customize ["modifyvm", :id, "--vram", "32"] @@ -145,19 +156,21 @@ Vagrant.configure("2") do |config| config.vm.define "win10" do |cfg| cfg.vm.box = "../Boxes/windows_10_virtualbox.box" 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 - cfg.vm.network :private_network, ip: "192.168.38.4", gateway: "192.168.38.1", dns: "192.168.38.2" + cfg.vm.network :private_network, ip: "192.168.38.104", gateway: "192.168.38.1", dns: "192.168.38.102" - cfg.vm.provision "shell", path: "scripts/fix-second-network.ps1", privileged: false, args: "-ip 192.168.38.4 -dns 192.168.38.2" + cfg.vm.provision "shell", path: "scripts/fix-second-network.ps1", privileged: false, args: "-ip 192.168.38.104 -dns 192.168.38.102" cfg.vm.provision "shell", path: "scripts/provision.ps1", privileged: false cfg.vm.provision "reload" cfg.vm.provision "shell", path: "scripts/provision.ps1", privileged: false cfg.vm.provision "shell", path: "scripts/download_palantir_wef.ps1", privileged: true cfg.vm.provision "shell", path: "scripts/download_palantir_osquery.ps1", privileged: true cfg.vm.provision "shell", path: "scripts/MakeWindows10GreatAgain.ps1", privileged: true + cfg.vm.provision "shell", inline: 'wevtutil el | Foreach-Object {wevtutil cl "$_"}', privileged: true cfg.vm.provision "shell", path: "scripts/install-splunkuf.ps1", privileged: true cfg.vm.provision "shell", path: "scripts/install-utilities.ps1", privileged: true cfg.vm.provision "shell", path: "scripts/install-osquery.ps1", privileged: true @@ -168,6 +181,7 @@ Vagrant.configure("2") do |config| cfg.vm.provider "vmware_fusion" do |v, override| override.vm.box = "../Boxes/windows_10_vmware.box" + v.vmx["displayname"] = "win10.windomain.local" v.vmx["gui.fullscreenatpoweron"] = "FALSE" v.vmx["gui.viewModeAtPowerOn"] = "windowed" v.vmx["gui.fitguestusingnativedisplayresolution"] = "FALSE" @@ -178,6 +192,7 @@ Vagrant.configure("2") do |config| cfg.vm.provider "vmware_desktop" do |v, override| override.vm.box = "../Boxes/windows_10_vmware.box" + v.vmx["displayname"] = "win10.windomain.local" v.vmx["gui.fullscreenatpoweron"] = "FALSE" v.vmx["gui.viewModeAtPowerOn"] = "windowed" v.memory = 2048 @@ -188,6 +203,7 @@ Vagrant.configure("2") do |config| cfg.vm.provider "virtualbox" do |vb, override| vb.gui = true + vb.name = "win10.windomain.local" vb.customize ["modifyvm", :id, "--memory", 2048] vb.customize ["modifyvm", :id, "--cpus", 1] vb.customize ["modifyvm", :id, "--vram", "32"] diff --git a/Vagrant/bootstrap.sh b/Vagrant/bootstrap.sh index fd24081..379d366 100644 --- a/Vagrant/bootstrap.sh +++ b/Vagrant/bootstrap.sh @@ -14,19 +14,22 @@ apt_install_prerequisites() { fix_eth1_static_ip() { # There's a fun issue where dhclient keeps messing with eth1 despite the fact - # that eth1 has a static IP set. We workaround this by telling dhclient to leave it alone. - echo 'interface "eth1" {}' >> /etc/dhcp/dhclient.conf - systemctl restart networking.service + # that eth1 has a static IP set. We workaround this by setting a static DHCP lease. + echo -e 'interface "eth1" { + send host-name = gethostname(); + send dhcp-requested-address 192.168.38.105; + }' >> /etc/dhcp/dhclient.conf + service networking restart # Fix eth1 if the IP isn't set correctly ETH1_IP=$(ifconfig eth1 | grep 'inet addr' | cut -d ':' -f 2 | cut -d ' ' -f 1) - if [ "$ETH1_IP" != "192.168.38.5" ]; then + 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.5" ]; then - echo "The static IP has been fixed and set to 192.168.38.5" + if [ "$ETH1_IP" == "192.168.38.105" ]; then + echo "The static IP has been fixed and set to 192.168.38.105" else echo "Failed to fix the broken static IP for eth1. Exiting because this will cause problems with other VMs." exit 1 @@ -35,17 +38,17 @@ fix_eth1_static_ip() { } install_python() { -# Install Python 3.6.4 -if ! which /usr/local/bin/python3.6 > /dev/null; then - echo "Installing Python v3.6.4..." - wget https://www.python.org/ftp/python/3.6.4/Python-3.6.4.tgz - tar -xvf Python-3.6.4.tgz - cd Python-3.6.4 || exit - ./configure && make && make install - cd /home/vagrant || exit -else - echo "Python seems to be downloaded already.. Skipping." -fi + # Install Python 3.6.4 + if ! which /usr/local/bin/python3.6 > /dev/null; then + echo "Installing Python v3.6.4..." + wget https://www.python.org/ftp/python/3.6.4/Python-3.6.4.tgz + tar -xvf Python-3.6.4.tgz + cd Python-3.6.4 || exit + ./configure && make && make install + cd /home/vagrant || exit + else + echo "Python seems to be downloaded already.. Skipping." + fi } install_golang() { @@ -62,6 +65,7 @@ install_golang() { echo 'export GOROOT=/usr/local/go' >> /home/vagrant/.bashrc echo 'export GOPATH=$HOME/.go' >> /root/.bashrc echo 'export GOROOT=/usr/local/go' >> /root/.bashrc + echo 'export PATH=$PATH:/opt/splunk/bin' >> /root/.bashrc source /root/.bashrc sudo update-alternatives --install "/usr/bin/go" "go" "/usr/local/go/bin/go" 0 sudo update-alternatives --set go /usr/local/go/bin/go @@ -92,11 +96,15 @@ install_splunk() { /opt/splunk/bin/splunk add index suricata -auth 'admin:changeme' /opt/splunk/bin/splunk install app /vagrant/resources/splunk_forwarder/splunk-add-on-for-microsoft-windows_500.tgz -auth 'admin:changeme' /opt/splunk/bin/splunk install app /vagrant/resources/splunk_server/add-on-for-microsoft-sysmon_800.tgz -auth 'admin:changeme' + /opt/splunk/bin/splunk install app /vagrant/resources/splunk_server/asn-lookup-generator_012.tgz -auth 'admin:changeme' # 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 touch /opt/splunk/etc/.ui_login # Enable SSL Login for Splunk @@ -105,6 +113,8 @@ install_splunk() { # Reboot Splunk to make changes take effect /opt/splunk/bin/splunk restart /opt/splunk/bin/splunk enable boot-start + # Generate the ASN lookup table + /opt/splunk/bin/splunk search "|asngen | outputlookup asn" -auth 'admin:changeme' fi } @@ -158,30 +168,30 @@ import_osquery_config_into_fleet() { cd /home/vagrant/osquery-configuration/Endpoints/Windows/ || exit # Fleet requires you to login before importing packs # Login - curl 'https://192.168.38.5:8412/api/v1/kolide/login' -H 'origin: https://192.168.38.5:8412' -H 'accept-encoding: gzip, deflate, br' -H 'accept-language: en-US,en;q=0.9' -H 'user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36' -H 'content-type: application/json' -H 'accept: application/json' -H 'referer: https://192.168.38.5:8412/login' -H 'authority: 192.168.38.5:8412' --data-binary '{"username":"admin","password":"admin123#"}' --compressed --insecure + curl 'https://192.168.38.105:8412/api/v1/kolide/login' -H 'origin: https://192.168.38.105:8412' -H 'accept-encoding: gzip, deflate, br' -H 'accept-language: en-US,en;q=0.9' -H 'user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36' -H 'content-type: application/json' -H 'accept: application/json' -H 'referer: https://192.168.38.105:8412/login' -H 'authority: 192.168.38.105:8412' --data-binary '{"username":"admin","password":"admin123#"}' --compressed --insecure sleep 1 - curl 'https://192.168.38.5:8412/setup' -H 'accept-encoding: gzip, deflate, br' -H 'accept-language: en-US,en;q=0.9' -H 'upgrade-insecure-requests: 1' -H 'user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36' -H 'accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8' -H 'authority: 192.168.38.5:8412' --compressed --insecure + curl 'https://192.168.38.105:8412/setup' -H 'accept-encoding: gzip, deflate, br' -H 'accept-language: en-US,en;q=0.9' -H 'upgrade-insecure-requests: 1' -H 'user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36' -H 'accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8' -H 'authority: 192.168.38.105:8412' --compressed --insecure sleep 1 # Setup organization name and email address - curl 'https://192.168.38.5:8412/api/v1/setup' -H 'origin: https://192.168.38.5:8412' -H 'accept-encoding: gzip, deflate, br' -H 'accept-language: en-US,en;q=0.9' -H 'user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36' -H 'content-type: application/json' -H 'accept: application/json' -H 'referer: https://192.168.38.5:8412/setup' -H 'authority: 192.168.38.5:8412' --data-binary '{"kolide_server_url":"https://192.168.38.5:8412","org_info":{"org_name":"detectionlab"},"admin":{"admin":true,"email":"example@example.com","password":"admin123#","password_confirmation":"admin123#","username":"admin"}}' --compressed --insecure + curl 'https://192.168.38.105:8412/api/v1/setup' -H 'origin: https://192.168.38.105:8412' -H 'accept-encoding: gzip, deflate, br' -H 'accept-language: en-US,en;q=0.9' -H 'user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36' -H 'content-type: application/json' -H 'accept: application/json' -H 'referer: https://192.168.38.105:8412/setup' -H 'authority: 192.168.38.105:8412' --data-binary '{"kolide_server_url":"https://192.168.38.105:8412","org_info":{"org_name":"detectionlab"},"admin":{"admin":true,"email":"example@example.com","password":"admin123#","password_confirmation":"admin123#","username":"admin"}}' --compressed --insecure sleep 3 # Import all Windows configs /home/vagrant/configimporter/configimporter -host https://localhost:8412 -user 'admin' -config osquery_to_import.conf # Get auth token - TOKEN=$(curl 'https://192.168.38.5:8412/api/v1/kolide/login' -H 'origin: https://192.168.38.5:8412' -H 'accept-encoding: gzip, deflate, br' -H 'accept-language: en-US,en;q=0.9' -H 'user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36' -H 'content-type: application/json' -H 'accept: application/json' -H 'referer: https://192.168.38.5:8412/login' -H 'authority: 192.168.38.5:8412' --data-binary '{"username":"admin","password":"admin123#"}' --compressed --insecure | grep token | cut -d '"' -f 4) + TOKEN=$(curl 'https://192.168.38.105:8412/api/v1/kolide/login' -H 'origin: https://192.168.38.105:8412' -H 'accept-encoding: gzip, deflate, br' -H 'accept-language: en-US,en;q=0.9' -H 'user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36' -H 'content-type: application/json' -H 'accept: application/json' -H 'referer: https://192.168.38.105:8412/login' -H 'authority: 192.168.38.105:8412' --data-binary '{"username":"admin","password":"admin123#"}' --compressed --insecure | grep token | cut -d '"' -f 4) # Set all packs to be targeted to Windows hosts - curl 'https://192.168.38.5:8412/api/v1/kolide/packs/1' -X PATCH -H 'origin: https://192.168.38.5:8412' -H 'accept-encoding: gzip, deflate, br' -H 'accept-language: en-US,en;q=0.9' -H "authorization: Bearer $TOKEN" -H 'content-type: application/json' -H 'accept: application/json' -H 'referer: https://192.168.38.5:8412/packs/3/edit' -H 'authority: 192.168.38.5:8412' -H 'user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36' --data-binary '{"label_ids":[10]}' --compressed --insecure + curl 'https://192.168.38.105:8412/api/v1/kolide/packs/1' -X PATCH -H 'origin: https://192.168.38.105:8412' -H 'accept-encoding: gzip, deflate, br' -H 'accept-language: en-US,en;q=0.9' -H "authorization: Bearer $TOKEN" -H 'content-type: application/json' -H 'accept: application/json' -H 'referer: https://192.168.38.105:8412/packs/3/edit' -H 'authority: 192.168.38.105:8412' -H 'user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36' --data-binary '{"label_ids":[10]}' --compressed --insecure sleep 1 - curl 'https://192.168.38.5:8412/api/v1/kolide/packs/2' -X PATCH -H 'origin: https://192.168.38.5:8412' -H 'accept-encoding: gzip, deflate, br' -H 'accept-language: en-US,en;q=0.9' -H "authorization: Bearer $TOKEN" -H 'content-type: application/json' -H 'accept: application/json' -H 'referer: https://192.168.38.5:8412/packs/3/edit' -H 'authority: 192.168.38.5:8412' -H 'user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36' --data-binary '{"label_ids":[10]}' --compressed --insecure + curl 'https://192.168.38.105:8412/api/v1/kolide/packs/2' -X PATCH -H 'origin: https://192.168.38.105:8412' -H 'accept-encoding: gzip, deflate, br' -H 'accept-language: en-US,en;q=0.9' -H "authorization: Bearer $TOKEN" -H 'content-type: application/json' -H 'accept: application/json' -H 'referer: https://192.168.38.105:8412/packs/3/edit' -H 'authority: 192.168.38.105:8412' -H 'user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36' --data-binary '{"label_ids":[10]}' --compressed --insecure sleep 1 - curl 'https://192.168.38.5:8412/api/v1/kolide/packs/3' -X PATCH -H 'origin: https://192.168.38.5:8412' -H 'accept-encoding: gzip, deflate, br' -H 'accept-language: en-US,en;q=0.9' -H "authorization: Bearer $TOKEN" -H 'content-type: application/json' -H 'accept: application/json' -H 'referer: https://192.168.38.5:8412/packs/3/edit' -H 'authority: 192.168.38.5:8412' -H 'user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36' --data-binary '{"label_ids":[10]}' --compressed --insecure + curl 'https://192.168.38.105:8412/api/v1/kolide/packs/3' -X PATCH -H 'origin: https://192.168.38.105:8412' -H 'accept-encoding: gzip, deflate, br' -H 'accept-language: en-US,en;q=0.9' -H "authorization: Bearer $TOKEN" -H 'content-type: application/json' -H 'accept: application/json' -H 'referer: https://192.168.38.105:8412/packs/3/edit' -H 'authority: 192.168.38.105:8412' -H 'user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36' --data-binary '{"label_ids":[10]}' --compressed --insecure sleep 1 - curl 'https://192.168.38.5:8412/api/v1/kolide/packs/4' -X PATCH -H 'origin: https://192.168.38.5:8412' -H 'accept-encoding: gzip, deflate, br' -H 'accept-language: en-US,en;q=0.9' -H "authorization: Bearer $TOKEN" -H 'content-type: application/json' -H 'accept: application/json' -H 'referer: https://192.168.38.5:8412/packs/3/edit' -H 'authority: 192.168.38.5:8412' -H 'user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36' --data-binary '{"label_ids":[10]}' --compressed --insecure + curl 'https://192.168.38.105:8412/api/v1/kolide/packs/4' -X PATCH -H 'origin: https://192.168.38.105:8412' -H 'accept-encoding: gzip, deflate, br' -H 'accept-language: en-US,en;q=0.9' -H "authorization: Bearer $TOKEN" -H 'content-type: application/json' -H 'accept: application/json' -H 'referer: https://192.168.38.105:8412/packs/3/edit' -H 'authority: 192.168.38.105:8412' -H 'user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36' --data-binary '{"label_ids":[10]}' --compressed --insecure sleep 1 - curl 'https://192.168.38.5:8412/api/v1/kolide/packs/5' -X PATCH -H 'origin: https://192.168.38.5:8412' -H 'accept-encoding: gzip, deflate, br' -H 'accept-language: en-US,en;q=0.9' -H "authorization: Bearer $TOKEN" -H 'content-type: application/json' -H 'accept: application/json' -H 'referer: https://192.168.38.5:8412/packs/3/edit' -H 'authority: 192.168.38.5:8412' -H 'user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36' --data-binary '{"label_ids":[10]}' --compressed --insecure + curl 'https://192.168.38.105:8412/api/v1/kolide/packs/5' -X PATCH -H 'origin: https://192.168.38.105:8412' -H 'accept-encoding: gzip, deflate, br' -H 'accept-language: en-US,en;q=0.9' -H "authorization: Bearer $TOKEN" -H 'content-type: application/json' -H 'accept: application/json' -H 'referer: https://192.168.38.105:8412/packs/3/edit' -H 'authority: 192.168.38.105:8412' -H 'user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36' --data-binary '{"label_ids":[10]}' --compressed --insecure # Rename primary pack - curl 'https://192.168.38.5:8412/api/v1/kolide/packs/5' -X PATCH -H 'origin: https://192.168.38.5:8412' -H 'accept-encoding: gzip, deflate, br' -H 'accept-language: en-US,en;q=0.9' -H "authorization: Bearer $TOKEN" -H 'content-type: application/json' -H 'accept: application/json' -H 'referer: https://192.168.38.5:8412/packs/5/edit' -H 'authority: 192.168.38.5:8412' -H 'user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36' --data-binary '{"name":"windows-pack"}' --compressed --insecure + curl 'https://192.168.38.105:8412/api/v1/kolide/packs/5' -X PATCH -H 'origin: https://192.168.38.105:8412' -H 'accept-encoding: gzip, deflate, br' -H 'accept-language: en-US,en;q=0.9' -H "authorization: Bearer $TOKEN" -H 'content-type: application/json' -H 'accept: application/json' -H 'referer: https://192.168.38.105:8412/packs/5/edit' -H 'authority: 192.168.38.105:8412' -H 'user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36' --data-binary '{"name":"windows-pack"}' --compressed --insecure # Add Splunk monitors for Fleet /opt/splunk/bin/splunk add monitor "/home/vagrant/kolide-quickstart/osquery_result" -index osquery -sourcetype 'osquery:json' -auth 'admin:changeme' /opt/splunk/bin/splunk add monitor "/home/vagrant/kolide-quickstart/osquery_status" -index osquery-status -sourcetype 'osquery:status' -auth 'admin:changeme' @@ -218,126 +228,145 @@ install_caldera() { } install_bro() { - # environment variables - NODECFG=/opt/bro/etc/node.cfg - SPLUNK_BRO_JSON=/opt/splunk/etc/apps/TA-bro_json - SPLUNK_BRO_MONITOR='monitor:///opt/bro/spool/manager' - SPLUNK_SURICATA_MONITOR='monitor:///var/log/suricata' - echo "deb http://download.opensuse.org/repositories/network:/bro/xUbuntu_16.04/ /" > /etc/apt/sources.list.d/bro.list - curl -s http://download.opensuse.org/repositories/network:/bro/xUbuntu_16.04/Release.key |apt-key add - - # update APT repositories - apt-get -qq -ym update - apt-get -qq -ym install \ - bro \ - crudini \ - # install tools to build and configure bro + # Environment variables + NODECFG=/opt/bro/etc/node.cfg + SPLUNK_BRO_JSON=/opt/splunk/etc/apps/TA-bro_json + SPLUNK_BRO_MONITOR='monitor:///opt/bro/spool/manager' + SPLUNK_SURICATA_MONITOR='monitor:///var/log/suricata' + echo "deb http://download.opensuse.org/repositories/network:/bro/xUbuntu_16.04/ /" > /etc/apt/sources.list.d/bro.list + curl -s http://download.opensuse.org/repositories/network:/bro/xUbuntu_16.04/Release.key |apt-key add - - # load bro scripts - cat<> /opt/bro/share/bro/site/local.bro + # Update APT repositories + apt-get -qq -ym update + # Install tools to build and configure bro + apt-get -qq -ym install bro crudini + # Load bro 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 policy/protocols/smb + @load policy/protocols/conn/vlan-logging + @load policy/protocols/conn/mac-logging -@load protocols/ftp/software -@load protocols/smtp/software -@load protocols/ssh/software -@load protocols/http/software + redef Intel::read_files += { + "/opt/bro/etc/intel.dat" + }; + ' >> /opt/bro/share/bro/site/local.bro -@load tuning/json-logs -@load policy/integration/collective-intel -@load policy/frameworks/intel/do_notice + # Configure Bro + crudini --del $NODECFG bro + crudini --set $NODECFG manager type manager + crudini --set $NODECFG manager host localhost + crudini --set $NODECFG proxy type proxy + crudini --set $NODECFG proxy host localhost -@load frameworks/intel/seen -@load frameworks/intel/do_notice -@load frameworks/files/hash-all-files + # Setup $CPUS numbers of bro workers + crudini --set $NODECFG worker-eth1 type worker + crudini --set $NODECFG worker-eth1 host localhost + crudini --set $NODECFG worker-eth1 interface eth1 + crudini --set $NODECFG worker-eth1 lb_method pf_ring + crudini --set $NODECFG worker-eth1 lb_procs "$(nproc)" -@load policy/protocols/smb + # Setup bro to run at boot + cp /vagrant/resources/bro/bro.service /lib/systemd/system/bro.service + systemctl enable bro + systemctl start bro -@load policy/protocols/conn/vlan-logging + # Setup splunk TA to ingest bro and suricata data + git clone https://github.com/jahshuah/splunk-ta-bro-json $SPLUNK_BRO_JSON -@load policy/protocols/conn/mac-logging + mkdir -p $SPLUNK_BRO_JSON/local + cp $SPLUNK_BRO_JSON/default/inputs.conf $SPLUNK_BRO_JSON/local/inputs.conf -redef Intel::read_files += { - "/opt/bro/etc/intel.dat" -}; + crudini --set $SPLUNK_BRO_JSON/local/inputs.conf $SPLUNK_BRO_MONITOR index bro + crudini --set $SPLUNK_BRO_JSON/local/inputs.conf $SPLUNK_BRO_MONITOR sourcetype json_bro + crudini --set $SPLUNK_BRO_JSON/local/inputs.conf $SPLUNK_BRO_MONITOR whitelist '.*\.log$' + crudini --set $SPLUNK_BRO_JSON/local/inputs.conf $SPLUNK_BRO_MONITOR blacklist '.*(communication|stderr)\.log$' + crudini --set $SPLUNK_BRO_JSON/local/inputs.conf $SPLUNK_BRO_MONITOR disabled 0 + crudini --set $SPLUNK_BRO_JSON/local/inputs.conf $SPLUNK_SURICATA_MONITOR index suricata + crudini --set $SPLUNK_BRO_JSON/local/inputs.conf $SPLUNK_SURICATA_MONITOR sourcetype json_suricata + crudini --set $SPLUNK_BRO_JSON/local/inputs.conf $SPLUNK_SURICATA_MONITOR whitelist 'eve.json' + crudini --set $SPLUNK_BRO_JSON/local/inputs.conf $SPLUNK_SURICATA_MONITOR disabled 0 -EOF + # Ensure permissions are correct and restart splunk + chown -R splunk $SPLUNK_BRO_JSON + /opt/splunk/bin/splunk restart - - # configure bro - crudini --del $NODECFG bro - crudini --set $NODECFG manager type manager - crudini --set $NODECFG manager host localhost - crudini --set $NODECFG proxy type proxy - crudini --set $NODECFG proxy host localhost - CPUS=$(lscpu -e |awk /yes/'{print $1'} |wc -l) - - # setup $CPUS numbers of bro workers - for i in eth1 - do - crudini --set $NODECFG worker-$i type worker - crudini --set $NODECFG worker-$i host localhost - crudini --set $NODECFG worker-$i interface $i - crudini --set $NODECFG worker-$i lb_method pf_ring - crudini --set $NODECFG worker-$i lb_procs $CPUS - done - - # setup bro to run at boot - cp /vagrant/resources/bro/bro.service /lib/systemd/system/bro.service - - for i in bro - do - systemctl enable $i - systemctl start $i - done - - # setup splunk TA to ingest bro and suricata data - git clone https://github.com/jahshuah/splunk-ta-bro-json $SPLUNK_BRO_JSON - - mkdir -p $SPLUNK_BRO_JSON/local - cp $SPLUNK_BRO_JSON/default/inputs.conf $SPLUNK_BRO_JSON/local/inputs.conf - - - crudini --set $SPLUNK_BRO_JSON/local/inputs.conf $SPLUNK_BRO_MONITOR index bro - crudini --set $SPLUNK_BRO_JSON/local/inputs.conf $SPLUNK_BRO_MONITOR sourcetype json_bro - crudini --set $SPLUNK_BRO_JSON/local/inputs.conf $SPLUNK_BRO_MONITOR whitelist '.*\.log$' - crudini --set $SPLUNK_BRO_JSON/local/inputs.conf $SPLUNK_BRO_MONITOR blacklist '.*(communication|stderr)\.log$' - crudini --set $SPLUNK_BRO_JSON/local/inputs.conf $SPLUNK_BRO_MONITOR disabled 0 - - - - crudini --set $SPLUNK_BRO_JSON/local/inputs.conf $SPLUNK_SURICATA_MONITOR index suricata - crudini --set $SPLUNK_BRO_JSON/local/inputs.conf $SPLUNK_SURICATA_MONITOR sourcetype json_suricata - crudini --set $SPLUNK_BRO_JSON/local/inputs.conf $SPLUNK_SURICATA_MONITOR whitelist 'eve.json' - crudini --set $SPLUNK_BRO_JSON/local/inputs.conf $SPLUNK_SURICATA_MONITOR disabled 0 - - # ensure permissions are correct and restart splunk - chown -R splunk $SPLUNK_BRO_JSON - /opt/splunk/bin/splunk restart + # Verify that Bro is running + if ! pgrep -f bro > /dev/null; then + echo "Bro attempted to start but is not running. Exiting" + exit 1 + fi } install_suricata() { - # install yq to maniuplate the suricata.yaml inline - /usr/bin/go get -u github.com/mikefarah/yq - # install suricata - add-apt-repository -y ppa:oisf/suricata-stable - apt-get -qq -y update && apt-get -qq -y install suricata crudini - # install suricata-update - pip3.6 install --pre --upgrade suricata-update - # add DC_SERVERS variable to suricata.yaml in support et-open signatures - /root/go/bin/yq w -i /etc/suricata/suricata.yaml vars.address-groups.DC_SERVERS '$HOME_NET' - crudini --set --format=sh /etc/default/suricata '' iface eth1 - # update suricata signature sources - suricata-update update-sources - # disable protocol decode as it is duplicative of bro - echo re:protocol-command-decode >> /etc/suricata/disable.conf - # enable et-open and attackdetection sources - for i in et/open ptresearch/attackdetection - do - suricata-update enable-source $i + # Run iwr -Uri testmyids.com -UserAgent "BlackSun" in Powershell to generate test alerts - done - # update suricata and restart - suricata-update - systemctl restart suricata + # Install yq to maniuplate the suricata.yaml inline + /usr/bin/go get -u github.com/mikefarah/yq + # Install suricata + add-apt-repository -y ppa:oisf/suricata-stable + apt-get -qq -y update && apt-get -qq -y install suricata crudini + # Install suricata-update + cd /home/vagrant || exit 1 + git clone https://github.com/OISF/suricata-update.git + cd /home/vagrant/suricata-update || exit 1 + python setup.py install + # Add DC_SERVERS variable to suricata.yaml in support et-open signatures + /root/go/bin/yq w -i /etc/suricata/suricata.yaml vars.address-groups.DC_SERVERS '$HOME_NET' + # It may make sense to store the suricata.yaml file as a resource file if this begins to become too complex + # Add more verbose alert logging + /root/go/bin/yq w -i /etc/suricata/suricata.yaml outputs.1.eve-log.types.0.alert.payload true + /root/go/bin/yq w -i /etc/suricata/suricata.yaml outputs.1.eve-log.types.0.alert.payload-buffer-size 4kb + /root/go/bin/yq w -i /etc/suricata/suricata.yaml outputs.1.eve-log.types.0.alert.payload-printable yes + /root/go/bin/yq w -i /etc/suricata/suricata.yaml outputs.1.eve-log.types.0.alert.packet yes + /root/go/bin/yq w -i /etc/suricata/suricata.yaml outputs.1.eve-log.types.0.alert.http yes + /root/go/bin/yq w -i /etc/suricata/suricata.yaml outputs.1.eve-log.types.0.alert.tls yes + /root/go/bin/yq w -i /etc/suricata/suricata.yaml outputs.1.eve-log.types.0.alert.ssh yes + /root/go/bin/yq w -i /etc/suricata/suricata.yaml outputs.1.eve-log.types.0.alert.smtp yes + # Turn off traffic flow logging (duplicative of Bro and wrecks Splunk trial license) + /root/go/bin/yq d -i /etc/suricata/suricata.yaml outputs.1.eve-log.types.1 # Remove HTTP + /root/go/bin/yq d -i /etc/suricata/suricata.yaml outputs.1.eve-log.types.1 # Remove DNS + /root/go/bin/yq d -i /etc/suricata/suricata.yaml outputs.1.eve-log.types.1 # Remove TLS + /root/go/bin/yq d -i /etc/suricata/suricata.yaml outputs.1.eve-log.types.2 # Remove SMTP + /root/go/bin/yq d -i /etc/suricata/suricata.yaml outputs.1.eve-log.types.2 # Remove SSH + /root/go/bin/yq d -i /etc/suricata/suricata.yaml outputs.1.eve-log.types.2 # Remove Stats + /root/go/bin/yq d -i /etc/suricata/suricata.yaml outputs.1.eve-log.types.2 # Remove Flow + # AF packet monitoring should be set to eth1 + /root/go/bin/yq w -i /etc/suricata/suricata.yaml af-packet.0.interface eth1 + + crudini --set --format=sh /etc/default/suricata '' iface eth1 + # update suricata signature sources + suricata-update update-sources + # disable protocol decode as it is duplicative of bro + 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 + # Add the YAML header to the top of the suricata config + echo "Adding the YAML header to /etc/suricata/suricata.yaml" + echo -e "%YAML 1.1\n---\n$(cat /etc/suricata/suricata.yaml)" > /etc/suricata/suricata.yaml + + # 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 } main() { diff --git a/Vagrant/resources/splunk_server/asn-lookup-generator_012.tgz b/Vagrant/resources/splunk_server/asn-lookup-generator_012.tgz new file mode 100644 index 0000000..c374125 Binary files /dev/null and b/Vagrant/resources/splunk_server/asn-lookup-generator_012.tgz differ diff --git a/Vagrant/scripts/install-caldera-agent.ps1 b/Vagrant/scripts/install-caldera-agent.ps1 index bd047ee..0d67916 100644 --- a/Vagrant/scripts/install-caldera-agent.ps1 +++ b/Vagrant/scripts/install-caldera-agent.ps1 @@ -2,7 +2,7 @@ If (-not (Test-Path 'C:\Program Files\cagent\cagent.exe')) { # Add /etc/hosts entry - Add-Content "c:\windows\system32\drivers\etc\hosts" " 192.168.38.5 logger" + Add-Content "c:\windows\system32\drivers\etc\hosts" " 192.168.38.105 logger" # Make the directory New-Item "c:\Program Files\cagent" -type directory diff --git a/Vagrant/scripts/install-osquery.ps1 b/Vagrant/scripts/install-osquery.ps1 index 6f9544f..1a6299a 100755 --- a/Vagrant/scripts/install-osquery.ps1 +++ b/Vagrant/scripts/install-osquery.ps1 @@ -19,7 +19,7 @@ If (-not ($service)) { ### --- TLS CONFIG BEGINS --- ### COMMENT ALL LINES BELOW UNTIL "TLS CONFIG ENDS" if using local configuration ## Add entry to hosts file for Kolide for SSL validation - Add-Content "c:\windows\system32\drivers\etc\hosts" " 192.168.38.5 kolide" + Add-Content "c:\windows\system32\drivers\etc\hosts" " 192.168.38.105 kolide" ## Add kolide secret and avoid BOM $Utf8NoBomEncoding = New-Object System.Text.UTF8Encoding $False [System.IO.File]::WriteAllLines("c:\ProgramData\osquery\kolide_secret.txt", "enrollmentsecret", $Utf8NoBomEncoding) diff --git a/Vagrant/scripts/install-splunkuf.ps1 b/Vagrant/scripts/install-splunkuf.ps1 index 925d067..ea291e4 100755 --- a/Vagrant/scripts/install-splunkuf.ps1 +++ b/Vagrant/scripts/install-splunkuf.ps1 @@ -6,7 +6,7 @@ If (-not (Test-Path "C:\Program Files\SplunkUniversalForwarder\bin\splunk.exe")) Write-Host "Installing & Starting Splunk" (New-Object System.Net.WebClient).DownloadFile('https://www.splunk.com/bin/splunk/DownloadActivityServlet?architecture=x86_64&platform=windows&version=7.1.0&product=universalforwarder&filename=splunkforwarder-7.1.0-2e75b3406c5b-x64-release.msi&wget=true', $msiFile) - Start-Process -FilePath "c:\windows\system32\msiexec.exe" -ArgumentList '/i', "$msiFile", 'RECEIVING_INDEXER="192.168.38.5:9997" WINEVENTLOG_SEC_ENABLE=1 WINEVENTLOG_SYS_ENABLE=1 WINEVENTLOG_APP_ENABLE=1 AGREETOLICENSE=Yes SERVICESTARTTYPE=1 LAUNCHSPLUNK=1 SPLUNKPASSWORD=changeme /quiet' -Wait + Start-Process -FilePath "c:\windows\system32\msiexec.exe" -ArgumentList '/i', "$msiFile", 'RECEIVING_INDEXER="192.168.38.105:9997" WINEVENTLOG_SEC_ENABLE=1 WINEVENTLOG_SYS_ENABLE=1 WINEVENTLOG_APP_ENABLE=1 AGREETOLICENSE=Yes SERVICESTARTTYPE=1 LAUNCHSPLUNK=1 SPLUNKPASSWORD=changeme /quiet' -Wait } Else { Write-Host "Splunk is already installed. Moving on." } diff --git a/Vagrant/scripts/join-domain.ps1 b/Vagrant/scripts/join-domain.ps1 index 009294f..8c34472 100755 --- a/Vagrant/scripts/join-domain.ps1 +++ b/Vagrant/scripts/join-domain.ps1 @@ -4,7 +4,7 @@ Write-Host 'Join the domain' Write-Host "First, set DNS to DC to join the domain" -$newDNSServers = "192.168.38.2" +$newDNSServers = "192.168.38.102" $adapters = Get-WmiObject Win32_NetworkAdapterConfiguration | Where-Object {$_.IPAddress -match "192.168.38."} $adapters | ForEach-Object {$_.SetDNSServerSearchOrder($newDNSServers)} diff --git a/Vagrant/scripts/provision.ps1 b/Vagrant/scripts/provision.ps1 index e308d22..71ca825 100644 --- a/Vagrant/scripts/provision.ps1 +++ b/Vagrant/scripts/provision.ps1 @@ -26,7 +26,7 @@ if ($env:COMPUTERNAME -imatch 'vagrant') { } if ($env:COMPUTERNAME -imatch 'dc') { - . c:\vagrant\scripts\create-domain.ps1 192.168.38.2 + . c:\vagrant\scripts\create-domain.ps1 192.168.38.102 } else { . c:\vagrant\scripts\join-domain.ps1 } diff --git a/build.ps1 b/build.ps1 index 4ffcbf3..c908d6b 100644 --- a/build.ps1 +++ b/build.ps1 @@ -180,12 +180,12 @@ function list_providers { function download_boxes { Write-Verbose '[download_boxes] Running..' if ($PackerProvider -eq 'virtualbox') { - $win10Hash = 'ad78b3406dd2c0e3418d1dd61e2abc2c' - $win2016Hash = 'f352c852ed1b849dab18442caef83712' + $win10Hash = '94c1ff7264e67af3d7df6d19275086ac' + $win2016Hash = '2a0b5dbc432e27a0223da026cc1f378b' } if ($PackerProvider -eq 'vmware') { - $win10Hash = '14e1c4cc15e1dc47aead906b25c5b3cc' - $win2016Hash = 'da1111c765b2fdc2ce012b6348cf74e2' + $win10Hash = '7d26d3247162dfbf6026fd5bab6a21ee' + $win2016Hash = '634628e04a1c6c94b4036b76d0568948' } $win10Filename = "windows_10_$PackerProvider.box" @@ -394,19 +394,19 @@ function download { function post_build_checks { Write-Verbose '[post_build_checks] Running Caldera Check.' - $CALDERA_CHECK = download -URL 'https://192.168.38.5:8888' -PatternToMatch 'CALDERA' + $CALDERA_CHECK = download -URL 'https://192.168.38.105:8888' -PatternToMatch 'CALDERA' Write-Verbose "[post_build_checks] Cladera Result: $CALDERA_CHECK" Write-Verbose '[post_build_checks] Running Splunk Check.' - $SPLUNK_CHECK = download -URL 'https://192.168.38.5:8000/en-US/account/login?return_to=%2Fen-US%2F' -PatternToMatch 'This browser is not supported by Splunk' + $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-Verbose "[post_build_checks] Splunk Result: $SPLUNK_CHECK" Write-Verbose '[post_build_checks] Running Fleet Check.' - $FLEET_CHECK = download -URL 'https://192.168.38.5:8412' -PatternToMatch 'Kolide Fleet' + $FLEET_CHECK = download -URL 'https://192.168.38.105:8412' -PatternToMatch 'Kolide Fleet' Write-Verbose "[post_build_checks] Fleet Result: $FLEET_CHECK" Write-Verbose '[post_build_checks] Running MS ATA Check.' - $ATA_CHECK = download -URL 'https://192.168.38.3' -SuccessOn401 + $ATA_CHECK = download -URL 'https://192.168.38.103' -SuccessOn401 Write-Verbose "[post_build_checks] ATA Result: $ATA_CHECK" diff --git a/build.sh b/build.sh index 9f06a5d..d971589 100755 --- a/build.sh +++ b/build.sh @@ -8,12 +8,12 @@ # https://github.com/clong/DetectionLab/issues print_usage() { - echo "Usage: ./build.sh " + echo "Usage: ./build.sh <--vagrant-only | --packer-only>" exit 0 } check_packer_path() { -# Check for existence of Packer in 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.") @@ -23,16 +23,16 @@ check_packer_path() { } 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.0.0 -if [ "$(vagrant --version | grep -o "[0-9]" | head -1)" -lt 2 ]; then - (echo >&2 "WARNING: It is highly recommended to use Vagrant 2.0.0 or above before continuing") -fi + # 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.0.0 + if [ "$(vagrant --version | grep -o "[0-9]" | head -1)" -lt 2 ]; then + (echo >&2 "WARNING: It is highly recommended to use Vagrant 2.0.0 or above before continuing") + fi } # Returns 0 if not installed or 1 if installed @@ -64,14 +64,14 @@ check_vmware_desktop_vagrant_plugin_installed() { 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 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 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 + (echo >&2 "VMWare Fusion 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 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 @@ -251,10 +251,10 @@ vagrant_reload_host() { 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 - CALDERA_CHECK=$(curl -ks -m 2 https://192.168.38.5:8888 | grep -c '302: Found' || echo "") - SPLUNK_CHECK=$(curl -ks -m 2 https://192.168.38.5: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.5:8412 | grep -c 'Kolide Fleet' || echo "") - ATA_CHECK=$(curl --fail --write-out "%{http_code}" -ks https://192.168.38.3 -m 2) + CALDERA_CHECK=$(curl -ks -m 2 https://192.168.38.105:8888 | grep -c '302: Found' || echo "") + 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 -o version\.\.. | cut -d ' ' -f 2 | cut -d '.' -f 1) @@ -298,27 +298,27 @@ parse_cli_arguments() { # TODO: Check to make sure they actually have their provider installed case "$1" in virtualbox) - PROVIDER="$1" - PACKER_PROVIDER="$1" - ;; + PROVIDER="$1" + PACKER_PROVIDER="$1" + ;; vmware_desktop) - PROVIDER="$1" - PACKER_PROVIDER="vmware" - ;; + PROVIDER="$1" + PACKER_PROVIDER="vmware" + ;; *) - echo "\"$1\" is not a valid provider. Listing available providers:" - PROVIDER=$(list_providers) - ;; + 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 - ;; + PACKER_ONLY=1 + ;; --vagrant-only) - VAGRANT_ONLY=1 - ;; + VAGRANT_ONLY=1 + ;; *) echo -e "\"$2\" is not recognized as an option. Available options are:\\n--packer-only\\n--vagrant-only" exit 1 @@ -331,37 +331,37 @@ 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 + (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 - 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 + (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 } choose_md5_tool() { @@ -397,19 +397,19 @@ download_boxes() { fi # Verify hashes of VirtualBox boxes if [ "$PACKER_PROVIDER" == "virtualbox" ]; then - if [ "$("$MD5TOOL" "$DL_DIR"/Boxes/windows_10_"$PACKER_PROVIDER".box | cut -d ' ' -f "$CUT_INDEX")" != "ad78b3406dd2c0e3418d1dd61e2abc2c" ]; then + if [ "$("$MD5TOOL" "$DL_DIR"/Boxes/windows_10_"$PACKER_PROVIDER".box | cut -d ' ' -f "$CUT_INDEX")" != "94c1ff7264e67af3d7df6d19275086ac" ]; then (echo >&2 "Hash mismatch on windows_10_virtualbox.box") fi - if [ "$("$MD5TOOL" "$DL_DIR"/Boxes/windows_2016_"$PACKER_PROVIDER".box | cut -d ' ' -f "$CUT_INDEX")" != "f352c852ed1b849dab18442caef83712" ]; then + if [ "$("$MD5TOOL" "$DL_DIR"/Boxes/windows_2016_"$PACKER_PROVIDER".box | cut -d ' ' -f "$CUT_INDEX")" != "2a0b5dbc432e27a0223da026cc1f378b" ]; then (echo >&2 "Hash mismatch on windows_2016_virtualbox.box") fi # Verify hashes of VMware boxes elif [ "$PACKER_PROVIDER" == "vmware" ]; then - if [ "$("$MD5TOOL" "$DL_DIR"/Boxes/windows_10_"$PACKER_PROVIDER".box | cut -d ' ' -f "$CUT_INDEX")" != "14e1c4cc15e1dc47aead906b25c5b3cc" ]; then + if [ "$("$MD5TOOL" "$DL_DIR"/Boxes/windows_10_"$PACKER_PROVIDER".box | cut -d ' ' -f "$CUT_INDEX")" != "7d26d3247162dfbf6026fd5bab6a21ee" ]; then (echo >&2 "Hash mismatch on windows_10_vmware.box") exit 1 fi - if [ "$("$MD5TOOL" "$DL_DIR"/Boxes/windows_2016_"$PACKER_PROVIDER".box | cut -d ' ' -f "$CUT_INDEX")" != "da1111c765b2fdc2ce012b6348cf74e2" ]; then + if [ "$("$MD5TOOL" "$DL_DIR"/Boxes/windows_2016_"$PACKER_PROVIDER".box | cut -d ' ' -f "$CUT_INDEX")" != "634628e04a1c6c94b4036b76d0568948" ]; then (echo >&2 "Hash mismatch on windows_2016_vmware.box") exit 1 fi @@ -430,7 +430,9 @@ build_vagrant_hosts() { (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" -ne 0 ]; then + 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 @@ -465,7 +467,7 @@ main() { build_vagrant_hosts post_build_checks fi - } +} main "$@" exit 0 diff --git a/ci/build_machine_bootstrap.sh b/ci/build_machine_bootstrap.sh index eca6399..75f7d5f 100755 --- a/ci/build_machine_bootstrap.sh +++ b/ci/build_machine_bootstrap.sh @@ -51,8 +51,8 @@ if [ "$PACKER_ONLY" -eq 0 ]; then # Install Vagrant mkdir /opt/vagrant cd /opt/vagrant || exit 1 - wget https://releases.hashicorp.com/vagrant/2.1.2/vagrant_2.1.2_x86_64.deb - dpkg -i vagrant_2.1.2_x86_64.deb + wget https://releases.hashicorp.com/vagrant/2.1.4/vagrant_2.1.4_x86_64.deb + dpkg -i vagrant_2.1.4_x86_64.deb vagrant plugin install vagrant-reload # Make the Vagrant instances headless @@ -64,8 +64,8 @@ if [ "$VAGRANT_ONLY" -eq 0 ]; then # Install Packer mkdir /opt/packer cd /opt/packer || exit 1 - wget https://releases.hashicorp.com/packer/1.2.3/packer_1.2.3_linux_amd64.zip - unzip packer_1.2.3_linux_amd64.zip + wget https://releases.hashicorp.com/packer/1.2.5/packer_1.2.5_linux_amd64.zip + unzip packer_1.2.5_linux_amd64.zip cp packer /usr/local/bin/packer # Make the Packer images headless diff --git a/ci/circle_workflows/vagrant_changes.sh b/ci/circle_workflows/vagrant_changes.sh index cf4ff71..27c9d22 100644 --- a/ci/circle_workflows/vagrant_changes.sh +++ b/ci/circle_workflows/vagrant_changes.sh @@ -36,7 +36,7 @@ ssh -i ~/.ssh/id_rsa root@"$IP_ADDRESS" 'bash -s' -- < ci/build_machine_bootstra ## Waiting for Packet server to post build results MINUTES_PAST=0 -while [ "$MINUTES_PAST" -lt 120 ]; do +while [ "$MINUTES_PAST" -lt 180 ]; do STATUS=$(curl $IP_ADDRESS) if [ "$STATUS" == "building" ]; then echo "$STATUS" @@ -44,9 +44,10 @@ while [ "$MINUTES_PAST" -lt 120 ]; do sleep 300 ((MINUTES_PAST += 5)) else + scp -i ~/.ssh/id_rsa root@"$IP_ADDRESS":/opt/DetectionLab/Vagrant/vagrant_up_*.log /tmp/artifacts/ || echo "Vagrant log not yet present" break fi - if [ "$MINUTES_PAST" -gt 120 ]; then + if [ "$MINUTES_PAST" -gt 180 ]; then echo "Serer timed out. Uptime: $MINUTES_PAST minutes." scp -i ~/.ssh/id_rsa root@"$IP_ADDRESS":/opt/DetectionLab/Vagrant/vagrant_up_*.log /tmp/artifacts/ curl -X DELETE --header 'Accept: application/json' --header 'X-Auth-Token: '"$PACKET_API_TOKEN" 'https://api.packet.net/devices/'"$DEVICE_ID"