From 1746b498117612851827d107f7ab71ea6b3e452b Mon Sep 17 00:00:00 2001 From: Chris Long Date: Sun, 28 Apr 2019 22:02:11 -0700 Subject: [PATCH] Add Atomic Red Team, Poll Packet for Provisioning, Fixes --- Vagrant/bootstrap.sh | 7 +++-- Vagrant/scripts/install-choco-extras.ps1 | 4 +-- Vagrant/scripts/install-osquery.ps1 | 2 +- Vagrant/scripts/install-redteam.ps1 | 13 ++++++++++ Vagrant/scripts/install-utilities.ps1 | 8 +++--- Vagrant/scripts/provision.ps1 | 12 +++++---- ci/build_machine_bootstrap.sh | 15 ++++++++--- ci/circle_workflows/vagrant_changes.sh | 33 ++++++++++++++---------- 8 files changed, 62 insertions(+), 32 deletions(-) diff --git a/Vagrant/bootstrap.sh b/Vagrant/bootstrap.sh index 47172d2..8da54a7 100644 --- a/Vagrant/bootstrap.sh +++ b/Vagrant/bootstrap.sh @@ -129,10 +129,13 @@ install_splunk() { 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 "Disabling the Splunk tour prompt..." touch /opt/splunk/etc/.ui_login + mkdir /opt/splunk/etc/users/admin/search/local + echo -e "[search-tour]\nviewed = 1" > /opt/splunk/etc/users/admin/search/local/ui-tour.conf + # Enable SSL Login for Splunk - echo '[settings] - enableSplunkWebSSL = true' > /opt/splunk/etc/system/local/web.conf + echo -e "[settings]\nenableSplunkWebSSL = true" > /opt/splunk/etc/system/local/web.conf # Reboot Splunk to make changes take effect /opt/splunk/bin/splunk restart /opt/splunk/bin/splunk enable boot-start diff --git a/Vagrant/scripts/install-choco-extras.ps1 b/Vagrant/scripts/install-choco-extras.ps1 index b26905a..a5d8bbd 100644 --- a/Vagrant/scripts/install-choco-extras.ps1 +++ b/Vagrant/scripts/install-choco-extras.ps1 @@ -10,7 +10,7 @@ If (-not (Test-Path "C:\ProgramData\chocolatey")) { } Write-Host "Installing Chocolatey extras..." -choco install -y --limit-output wireshark -choco install -y --limit-output winpcap +choco install -y --limit-output --no-progress wireshark +choco install -y --limit-output --no-progress winpcap Write-Host "Choco addons complete!" diff --git a/Vagrant/scripts/install-osquery.ps1 b/Vagrant/scripts/install-osquery.ps1 index 059dbdc..522749b 100755 --- a/Vagrant/scripts/install-osquery.ps1 +++ b/Vagrant/scripts/install-osquery.ps1 @@ -4,7 +4,7 @@ Write-Host "Installing osquery" $packsDir = "c:\programdata\osquery\packs" -choco install -y osquery | Out-String # Apparently Out-String makes the process wait +choco install -y --limit-output --no-progress osquery | Out-String # Apparently Out-String makes the process wait $service = Get-WmiObject -Class Win32_Service -Filter "Name='osqueryd'" If (-not ($service)) { Write-Host "Setting osquery to run as a service" diff --git a/Vagrant/scripts/install-redteam.ps1 b/Vagrant/scripts/install-redteam.ps1 index 2e6928a..d214c0a 100644 --- a/Vagrant/scripts/install-redteam.ps1 +++ b/Vagrant/scripts/install-redteam.ps1 @@ -35,4 +35,17 @@ if (-not (Test-Path $powersploitRepoPath)) { Write-Host "PowerSploit was already installed. Moving On." } +# Download and unzip a copy of Atomic Red Team +Write-Host "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 "Atomic Red Team was already installed. Moving On." +} + Write-Host "Red Team tooling installation complete!" diff --git a/Vagrant/scripts/install-utilities.ps1 b/Vagrant/scripts/install-utilities.ps1 index 5755e61..c185d48 100755 --- a/Vagrant/scripts/install-utilities.ps1 +++ b/Vagrant/scripts/install-utilities.ps1 @@ -10,11 +10,11 @@ If (-not (Test-Path "C:\ProgramData\chocolatey")) { Write-Host "Installing utilities..." If ($(hostname) -eq "win10") { # Because the Windows10 start menu sucks - choco install -y --limit-output classic-shell -installArgs ADDLOCAL=ClassicStartMenu + choco install -y --limit-output --no-progress classic-shell -installArgs ADDLOCAL=ClassicStartMenu & "C:\Program Files\Classic Shell\ClassicStartMenu.exe" "-xml" "c:\vagrant\resources\windows\MenuSettings.xml" } -choco install -y --limit-output NotepadPlusPlus -choco install -y --limit-output GoogleChrome -choco install -y --limit-output WinRar +choco install -y --limit-output --no-progress NotepadPlusPlus +choco install -y --limit-output --no-progress GoogleChrome +choco install -y --limit-output --no-progress WinRar Write-Host "Utilties installation complete!" diff --git a/Vagrant/scripts/provision.ps1 b/Vagrant/scripts/provision.ps1 index 71ca825..d27b93d 100644 --- a/Vagrant/scripts/provision.ps1 +++ b/Vagrant/scripts/provision.ps1 @@ -11,7 +11,7 @@ if ($env:COMPUTERNAME -imatch 'vagrant') { Write-Host 'Hostname is still the original one, skip provisioning for reboot' - Write-Host 'Install bginfo' + Write-Host 'Installing bginfo...' . c:\vagrant\scripts\install-bginfo.ps1 Write-Host -fore red 'Hint: vagrant reload' $box '--provision' @@ -23,6 +23,11 @@ if ($env:COMPUTERNAME -imatch 'vagrant') { if (!(Test-Path 'c:\Program Files\sysinternals\bginfo.exe')) { Write-Host 'Install bginfo' . c:\vagrant\scripts\install-bginfo.ps1 + # Set background to be "fitted" instead of "tiled" + Set-ItemProperty 'HKCU:\Control Panel\Desktop' -Name TileWallpaper -Value '0' + Set-ItemProperty 'HKCU:\Control Panel\Desktop' -Name WallpaperStyle -Value '6' + # Set Task Manager prefs + reg import "c:\vagrant\resources\windows\TaskManager.reg" 2>&1 | out-null } if ($env:COMPUTERNAME -imatch 'dc') { @@ -41,8 +46,5 @@ if ($env:COMPUTERNAME -imatch 'vagrant') { . c:\vagrant\scripts\install-bginfo.ps1 } - Write-Host 'Provisioning after joining domain' - - # $script = "c:\vagrant\scripts\provision-" + $box + ".ps1" - # . $script + Write-Host 'Provisioning after joining domain...' } diff --git a/ci/build_machine_bootstrap.sh b/ci/build_machine_bootstrap.sh index 775155d..d1586e1 100755 --- a/ci/build_machine_bootstrap.sh +++ b/ci/build_machine_bootstrap.sh @@ -28,8 +28,12 @@ fi echo "Args: $ARGS" +# Disable IPv6 - may help with the vagrant-reload plugin: https://github.com/hashicorp/vagrant/issues/8795#issuecomment-468945063 +echo "[$(date +%H:%M:%S)]: net.ipv6.conf.all.disable_ipv6=1" >> /etc/sysctl.conf +sysctl -p /etc/sysctl.conf + if [[ "$VAGRANT_ONLY" -eq 1 ]] && [[ "$PACKER_ONLY" -eq 1 ]]; then - echo "Somehow this build is configured as both packer-only and vagrant-only. This means something has gone horribly wrong." + echo "[$(date +%H:%M:%S)]: Somehow this build is configured as both packer-only and vagrant-only. This means something has gone horribly wrong." exit 1 fi @@ -37,9 +41,9 @@ fi echo "deb http://download.virtualbox.org/virtualbox/debian xenial contrib" >> /etc/apt/sources.list sed -i "2ideb mirror://mirrors.ubuntu.com/mirrors.txt xenial main restricted universe multiverse\ndeb mirror://mirrors.ubuntu.com/mirrors.txt xenial-updates main restricted universe multiverse\ndeb mirror://mirrors.ubuntu.com/mirrors.txt xenial-backports main restricted universe multiverse\ndeb mirror://mirrors.ubuntu.com/mirrors.txt xenial-security main restricted universe multiverse" /etc/apt/sources.list wget -q https://www.virtualbox.org/download/oracle_vbox_2016.asc -O- | sudo apt-key add - -echo "Running apt-get update..." +echo "[$(date +%H:%M:%S)]: Running apt-get update..." apt-get -qq update -echo "Running apt-get install..." +echo "[$(date +%H:%M:%S)]: Running apt-get install..." apt-get -qq install -y linux-headers-"$(uname -r)" virtualbox-5.2 build-essential unzip git ufw apache2 echo "building" > /var/www/html/index.html @@ -52,15 +56,17 @@ ufw --force enable if [ "$PACKER_ONLY" -eq 0 ]; then # Install Vagrant + 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.4/vagrant_2.2.4_x86_64.deb dpkg -i vagrant_2.2.4_x86_64.deb + echo "[$(date +%H:%M:%S)]: Installing vagrant-reload plugin..." vagrant plugin install vagrant-reload # Make sure the plugin installed correctly. Retry if not. if [ "$(vagrant plugin list | grep -c vagrant-reload)" -ne "1" ]; then - echo "The first attempt to install the vagrant-reload plugin failed. Trying again." + echo "[$(date +%H:%M:%S)]: The first attempt to install the vagrant-reload plugin failed. Trying again." vagrant plugin install vagrant-reload fi @@ -70,6 +76,7 @@ if [ "$PACKER_ONLY" -eq 0 ]; then fi if [ "$VAGRANT_ONLY" -eq 0 ]; then + echo "[$(date +%H:%M:%S)]: Installing Packer..." # Install Packer mkdir /opt/packer cd /opt/packer || exit 1 diff --git a/ci/circle_workflows/vagrant_changes.sh b/ci/circle_workflows/vagrant_changes.sh index 3eff371..089fb86 100644 --- a/ci/circle_workflows/vagrant_changes.sh +++ b/ci/circle_workflows/vagrant_changes.sh @@ -8,26 +8,31 @@ if [ ! -d "/tmp/artifacts" ]; then fi ## Provision a Type1 baremetal Packet.net server -echo "Provisioning a server on Packet.net" +echo "[$(date +%H:%M:%S)]: Provisioning a server on Packet.net" DEVICE_ID=$(curl -s -X POST --header 'Accept: application/json' --header 'Content-Type: application/json' --header 'X-Auth-Token: '"$PACKET_API_TOKEN" -d '{ "facility": "sjc1", "plan": "baremetal_1", "hostname": "detectionlab", "description": "testing", "billing_cycle": "hourly", "operating_system": "ubuntu_16_04", "userdata": "", "locked": "false", "project_ssh_keys": ["315a9565-d5b1-41b6-913d-fcf022bb89a6", "755b134a-f63c-4fc5-9103-c1b63e65fdfc"] }' 'https://api.packet.net/projects/0b3f4f2e-ff05-41a8-899d-7923f620ca85/devices' | jq ."id" | tr -d '"') # Make sure the device ID is sane. # TODO: maybe make this a regex if [ "$(echo -n $DEVICE_ID | wc -c)" -ne 36 ]; then - echo "Server may have failed provisionining. Device ID is set to: $DEVICE_ID" - echo "This usually happens if there are no servers available in the selected datacenter." - echo "Attempting to retry in another datacenter..." + echo "[$(date +%H:%M:%S)]: Server may have failed provisionining. Device ID is set to: $DEVICE_ID" + echo "[$(date +%H:%M:%S)]: This usually happens if there are no servers available in the selected datacenter." + echo "[$(date +%H:%M:%S)]: Attempting to retry in another datacenter..." DEVICE_ID=$(curl -s -X POST --header 'Accept: application/json' --header 'Content-Type: application/json' --header 'X-Auth-Token: '"$PACKET_API_TOKEN" -d '{ "facility": "ewr1", "plan": "baremetal_1", "hostname": "detectionlab", "description": "testing", "billing_cycle": "hourly", "operating_system": "ubuntu_16_04", "userdata": "", "locked": "false", "project_ssh_keys": ["315a9565-d5b1-41b6-913d-fcf022bb89a6", "755b134a-f63c-4fc5-9103-c1b63e65fdfc"] }' 'https://api.packet.net/projects/0b3f4f2e-ff05-41a8-899d-7923f620ca85/devices' | jq ."id" | tr -d '"') if [ "$(echo -n $DEVICE_ID | wc -c)" -ne 36 ]; then - echo "This script was still unable to successfully provision a server. Exiting." + echo "[$(date +%H:%M:%S)]: This script was still unable to successfully provision a server. Exiting." exit 1 fi fi -echo "Server successfully provisioned with ID: $DEVICE_ID" +echo "[$(date +%H:%M:%S)]: Server successfully created with ID: $DEVICE_ID" -echo "Sleeping 10 minutes to wait for Packet server to be provisioned" -sleep 300 -echo "Sleeping 5 more minutes (CircleCI Keepalive)" -sleep 300 +echo "[$(date +%H:%M:%S)]: Waiting for server to finish provisioning..." +# Continue to poll the API until the state of the host is "active" +STATE="provisioning" +while [ "$STATE" != "active" ]; do + sleep 10 + echo "[$(date +%H:%M:%S)]: Sleeping for 10 seconds. Server is still $STATE." + STATE="$(curl -s --header 'Accept: application/json' --header 'Content-Type: application/json' --header 'X-Auth-Token: '"$PACKET_API_TOKEN" "https://api.packet.net/devices/$DEVICE_ID" | jq .state | tr -d '"')" +done +echo "[$(date +%H:%M:%S)]: Device with ID $DEVICE_ID has finished provisioning! Onto the build process..." ## Recording the IP address of the newly provisioned Packet server IP_ADDRESS=$(curl -s -X GET --header 'Accept: application/json' --header 'X-Auth-Token: '"$PACKET_API_TOKEN" "https://api.packet.net/devices/$DEVICE_ID/ips" | jq ."ip_addresses[0].address" | tr -d '"') @@ -45,7 +50,7 @@ MINUTES_PAST=0 while [ "$MINUTES_PAST" -lt 180 ]; do STATUS=$(curl $IP_ADDRESS) if [ "$STATUS" == "building" ]; then - echo "$STATUS" + echo "[$(date +%H:%M:%S)]: $STATUS" scp -q -i ~/.ssh/id_rsa root@"$IP_ADDRESS":/opt/DetectionLab/Vagrant/vagrant_up_*.log /tmp/artifacts/ || echo "Vagrant log not yet present" sleep 300 ((MINUTES_PAST += 5)) @@ -54,7 +59,7 @@ while [ "$MINUTES_PAST" -lt 180 ]; do break fi if [ "$MINUTES_PAST" -gt 180 ]; then - echo "Serer timed out. Uptime: $MINUTES_PAST minutes." + echo "[$(date +%H:%M:%S)]: Serer timed out. Uptime: $MINUTES_PAST minutes." scp -q -i ~/.ssh/id_rsa root@"$IP_ADDRESS":/opt/DetectionLab/Vagrant/vagrant_up_*.log /tmp/artifacts/ curl -s -X DELETE --header 'Accept: application/json' --header 'X-Auth-Token: '"$PACKET_API_TOKEN" 'https://api.packet.net/devices/'"$DEVICE_ID" exit 1 @@ -62,13 +67,13 @@ while [ "$MINUTES_PAST" -lt 180 ]; do done ## Recording the build results -echo $STATUS +echo "[$(date +%H:%M:%S)]: $STATUS" if [ "$STATUS" != "success" ]; then scp -q -i ~/.ssh/id_rsa root@"$IP_ADDRESS":/opt/DetectionLab/Vagrant/vagrant_up_*.log /tmp/artifacts/ echo "Build failed. Cleaning up server with ID $DEVICE_ID" curl -s -X DELETE --header 'Accept: application/json' --header 'X-Auth-Token: '"$PACKET_API_TOKEN" 'https://api.packet.net/devices/'"$DEVICE_ID" exit 1 fi -echo "Build was successful. Cleaning up server with ID $DEVICE_ID" +echo "[$(date +%H:%M:%S)]: Build was successful. Cleaning up server with ID $DEVICE_ID" curl -s -X DELETE --header 'Accept: application/json' --header 'X-Auth-Token: '"$PACKET_API_TOKEN" 'https://api.packet.net/devices/'"$DEVICE_ID" exit 0