#! /bin/bash
if ! curl -s 169.254.169.254 --connect-timeout 2 >/dev/null; then
echo -e " eth1:\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
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
apt_install_prerequisites() {
echo "[$(date +%H:%M:%S)]: Adding apt repositories..."
add-apt-repository -y ppa:apt-fast/stable
add-apt-repository -y ppa:rmescandon/yq
add-apt-repository -y ppa:oisf/suricata-stable
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..."
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
chmod -x /etc/update-motd.d/10-help-text
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..."
if ! dpkg -S $package >/dev/null; then
echo "[-] $package was not found. Attempting to reinstall."
apt-get -qq update && apt-get install -y $package
if ! which $package >/dev/null; then
echo "[X] Unable to install $package even after a retry. Exiting."
exit 1
fi
else
echo "[+] $package was successfully installed!"
fi
done
}
fix_eth1_static_ip() {
USING_KVM=$(sudo lsmod | grep kvm)
if [ ! -z "$USING_KVM" ]; then
echo "[*] Using KVM, no need to fix DHCP for eth1 iface"
return 0
fi
echo -e 'interface "eth1" {
send host-name = gethostname();
send dhcp-requested-address 192.168.38.105;
}' >>/etc/dhcp/dhclient.conf
netplan apply
ETH1_IP=$(ip -4 addr show eth1 | grep -oP '(?<=inet\s)\d+(\.\d+){3}')
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
while true; do
if [ "$(dig +short @8.8.8.8 github.com)" ]; then break; fi
sleep 1
done
}
download_palantir_osquery_config() {
if [ -f /opt/osquery-configuration ]; then
echo "[$(date +%H:%M:%S)]: osquery configs have already been downloaded"
else
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
mysql -uroot -e "ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'kolide';"
mysql -uroot -pkolide -e "create database kolide;"
wget --progress=bar:force https://github.com/kolide/fleet/releases/download/3.0.0/fleet.zip
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
fleet prepare db --mysql_address=127.0.0.1:3306 --mysql_database=kolide --mysql_username=root --mysql_password=kolide
cp /vagrant/resources/fleet/server.* /opt/fleet/
cp /vagrant/resources/fleet/fleet.service /etc/systemd/system/fleet.service
mkdir /var/log/kolide
/bin/systemctl enable fleet.service
/bin/systemctl start fleet.service
echo "[$(date +%H:%M:%S)]: Waiting for fleet service..."
fleetctl config set --address https://192.168.38.105:8412
fleetctl config set --tls-skip-verify true
fleetctl setup --email info@cyberdefenders.org --username vagrant --password vagrant --org-name DetectionLabELK
fleetctl login --email info@cyberdefenders.org --password vagrant
mysql -uroot --password=kolide -e 'use kolide; update enroll_secrets set secret = "enrollmentsecret" where active=1;'
echo "Updated enrollment secret"
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
fleetctl get options >/tmp/options.yaml
/usr/bin/yq w -i /tmp/options.yaml 'spec.config.options.logger_snapshot_event_type' 'true'
sed -i 's/kind: option/kind: options/g' /tmp/options.yaml
fleetctl apply -f /tmp/options.yaml
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
fi
}
install_zeek() {
echo "[$(date +%H:%M:%S)]: Installing Zeek..."
NODECFG=/opt/zeek/etc/node.cfg
touch /opt/zeek/etc/node.cfg
touch /opt/zeek/share/zeek/site/local.zeek
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
apt-get -qq -ym update
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
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
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
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)"
cp /vagrant/resources/zeek/zeek.service /lib/systemd/system/zeek.service
systemctl enable zeek
systemctl start zeek
}
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 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"
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
echo "[$(date +%H:%M:%S)]: Creating admin user..."
sudo -u velociraptor ./velociraptor --config /opt/velociraptor/server.config.yaml user add --role administrator vagrant vagrant
rm -rf /opt/velociraptor/users/admin.db /opt/velociraptor/acl/admin.json.db
}
install_suricata() {
" 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 eth1
# 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
# 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
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() {
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/
chown tomcat8 /etc/guacamole/user-mapping.xml
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/zeek/bin" >>~/.bashrc
# Ping DetectionLab server for usage statistics
# curl -A "DetectionLab-logger" "https://cyberdefenders.org/logger"
}
main() {
apt_install_prerequisites
modify_motd
test_prerequisites
download_palantir_osquery_config
install_fleet_import_osquery_config
install_velociraptor
install_suricata
install_zeek
install_guacamole
postinstall_tasks
}
main
exit 0