diff --git a/pillar/thresholding/pillar.example b/pillar/thresholding/pillar.example new file mode 100644 index 000000000..705cb606c --- /dev/null +++ b/pillar/thresholding/pillar.example @@ -0,0 +1,44 @@ +thresholding: + sids: + 8675309: + - threshold: + gen_id: 1 + type: threshold + track: by_src + count: 10 + seconds: 10 + - threshold: + gen_id: 1 + type: limit + track: by_dst + count: 100 + seconds: 30 + - rate_filter: + gen_id: 1 + track: by_rule + count: 50 + seconds: 30 + new_action: alert + timeout: 30 + - suppress: + gen_id: 1 + track: by_either + ip: 10.10.3.7 + 11223344: + - threshold: + gen_id: 1 + type: limit + track: by_dst + count: 10 + seconds: 10 + - rate_filter: + gen_id: 1 + track: by_src + count: 50 + seconds: 20 + new_action: pass + timeout: 60 + - suppress: + gen_id: 1 + track: by_src + ip: 10.10.3.0/24 diff --git a/pillar/thresholding/pillar.usage b/pillar/thresholding/pillar.usage new file mode 100644 index 000000000..1626433b1 --- /dev/null +++ b/pillar/thresholding/pillar.usage @@ -0,0 +1,20 @@ +thresholding: + sids: + : + - threshold: + gen_id: + type: + track: + count: + seconds: + - rate_filter: + gen_id: + track: + count: + seconds: + new_action: + timeout: + - suppress: + gen_id: + track: + ip: diff --git a/pillar/top.sls b/pillar/top.sls index 17bf33e02..d8c519eac 100644 --- a/pillar/top.sls +++ b/pillar/top.sls @@ -3,20 +3,20 @@ base: - patch.needs_restarting 'G@role:so-sensor': - - sensors.{{ grains.id }} + - minions.{{ grains.id }} - static - firewall.* - brologs 'G@role:so-master': - - masters.{{ grains.id }} + - minions.{{ grains.id }} - static - firewall.* - data.* - auth 'G@role:so-eval': - - masters.{{ grains.id }} + - minions.{{ grains.id }} - static - firewall.* - data.* @@ -24,13 +24,12 @@ base: - auth 'G@role:so-node': - - nodes.{{ grains.id }} + - minions.{{ grains.id }} - static - firewall.* 'G@role:so-helix': - - masters.{{ grains.id }} - - sensors.{{ grains.id }} + - minions.{{ grains.id }} - static - firewall.* - fireeye diff --git a/salt/auth/init.sls b/salt/auth/init.sls new file mode 100644 index 000000000..bed7d18d5 --- /dev/null +++ b/salt/auth/init.sls @@ -0,0 +1,38 @@ +so-auth-api-dir: + file.directory: + - name: /opt/so/conf/auth/api + - user: 939 + - group: 939 + - makedirs: True + +so-auth-api-image: + cmd.run: + - name: docker pull --disable-content-trust=false docker.io/soshybridhunter/so-auth-api:HH1.1.4 + +so-auth-ui-image: + cmd.run: + - name: docker pull --disable-content-trust=false docker.io/soshybridhunter/so-auth-ui:HH1.1.4 + +so-auth-api: + docker_container.running: + - require: + - so-auth-api-image + - image: docker.io/soshybridhunter/so-auth-api:HH1.1.4 + - hostname: so-auth-api + - name: so-auth-api + - environment: + - BASE_PATH: "/so-auth/api" + - binds: + - /opt/so/conf/auth/api:/data + - port_bindings: + - 0.0.0.0:5656:5656 + +so-auth-ui: + docker_container.running: + - require: + - so-auth-ui-image + - image: docker.io/soshybridhunter/so-auth-ui:HH1.1.4 + - hostname: so-auth-ui + - name: so-auth-ui + - port_bindings: + - 0.0.0.0:4242:80 diff --git a/salt/bro/cron/zeek_clean b/salt/bro/cron/zeek_clean new file mode 100644 index 000000000..af47611bc --- /dev/null +++ b/salt/bro/cron/zeek_clean @@ -0,0 +1,63 @@ +#!/bin/bash +# Delete Zeek Logs based on defined CRIT_DISK_USAGE value + +# Copyright 2014,2015,2016,2017,2018, 2019 Security Onion Solutions, LLC + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +clean () { + +SENSOR_DIR='/nsm' +CRIT_DISK_USAGE=90 +CUR_USAGE=$(df -P $SENSOR_DIR | tail -1 | awk '{print $5}' | tr -d %) +LOG="/nsm/bro/logs/zeek_clean.log" + +if [ "$CUR_USAGE" -gt "$CRIT_DISK_USAGE" ]; then + while [ "$CUR_USAGE" -gt "$CRIT_DISK_USAGE" ]; + do + TODAY=$(date -u "+%Y-%m-%d") + + # find the oldest Zeek logs directory and exclude today + OLDEST_DIR=$(ls /nsm/bro/logs/ | grep -v "current" | grep -v "stats" | grep -v "packetloss" | grep -v "zeek_clean" | sort | grep -v $TODAY | head -n 1) + if [ -z "$OLDEST_DIR" -o "$OLDEST_DIR" == ".." -o "$OLDEST_DIR" == "." ] + then + echo "$(date) - No old Zeek logs available to clean up in /nsm/bro/logs/" >> $LOG + exit 0 + else + echo "$(date) - Removing directory: /nsm/bro/logs/$OLDEST_DIR" >> $LOG + rm -rf /nsm/bro/logs/"$OLDEST_DIR" + fi + + # find oldest files in extracted directory and exclude today + OLDEST_EXTRACT=$(find /nsm/bro/extracted -type f -printf '%T+ %p\n' 2>/dev/null | sort | grep -v $TODAY | head -n 1) + if [ -z "$OLDEST_EXTRACT" -o "$OLDEST_EXTRACT" == ".." -o "$OLDEST_EXTRACT" == "." ] + then + echo "$(date) - No old extracted files available to clean up in /nsm/bro/extracted/" >> $LOG + else + OLDEST_EXTRACT_DATE=`echo $OLDEST_EXTRACT | awk '{print $1}' | cut -d+ -f1` + OLDEST_EXTRACT_FILE=`echo $OLDEST_EXTRACT | awk '{print $2}'` + echo "$(date) - Removing extracted files for $OLDEST_EXTRACT_DATE" >> $LOG + find /nsm/bro/extracted -type f -printf '%T+ %p\n' | grep $OLDEST_EXTRACT_DATE | awk '{print $2}' |while read FILE + do + echo "$(date) - Removing extracted file: $FILE" >> $LOG + rm -f "$FILE" + done + fi + done +else + echo "$(date) - CRIT_DISK_USAGE value of $CRIT_DISK_USAGE not greater than current usage of $CUR_USAGE..." >> $LOG +fi +} + +clean diff --git a/salt/bro/init.sls b/salt/bro/init.sls index 422e7fbf9..6a972cbe7 100644 --- a/salt/bro/init.sls +++ b/salt/bro/init.sls @@ -79,6 +79,21 @@ plcronscript: - source: salt://bro/cron/packetloss.sh - mode: 755 +zeekcleanscript: + file.managed: + - name: /usr/local/bin/zeek_clean + - source: salt://bro/cron/zeek_clean + - mode: 755 + +/usr/local/bin/zeek_clean: + cron.present: + - user: root + - minute: '*' + - hour: '*' + - daymonth: '*' + - month: '*' + - dayweek: '*' + /usr/local/bin/packetloss.sh: cron.present: - user: root diff --git a/salt/common/nginx/nginx.conf.so-eval b/salt/common/nginx/nginx.conf.so-eval index b5cf6ef5a..d3e377881 100644 --- a/salt/common/nginx/nginx.conf.so-eval +++ b/salt/common/nginx/nginx.conf.so-eval @@ -58,9 +58,9 @@ http { # } #} server { - listen 80 default_server; - server_name _; - return 301 https://$host$request_uri; + listen 80 default_server; + server_name _; + return 301 https://$host$request_uri; } @@ -88,8 +88,8 @@ http { # } location /grafana/ { - rewrite /grafana/(.*) /$1 break; - proxy_pass http://{{ masterip }}:3000/; + rewrite /grafana/(.*) /$1 break; + proxy_pass http://{{ masterip }}:3000/; proxy_read_timeout 90; proxy_connect_timeout 90; proxy_set_header Host $host; @@ -100,10 +100,9 @@ http { } location /kibana/ { - auth_basic "Security Onion"; - auth_basic_user_file /opt/so/conf/nginx/.htpasswd; - rewrite /kibana/(.*) /$1 break; - proxy_pass http://{{ masterip }}:5601/; + auth_request /so-auth/api/auth/; + rewrite /kibana/(.*) /$1 break; + proxy_pass http://{{ masterip }}:5601/; proxy_read_timeout 90; proxy_connect_timeout 90; proxy_set_header Host $host; @@ -114,7 +113,7 @@ http { } location /playbook/ { - proxy_pass http://{{ masterip }}:3200/playbook/; + proxy_pass http://{{ masterip }}:3200/playbook/; proxy_read_timeout 90; proxy_connect_timeout 90; proxy_set_header Host $host; @@ -126,9 +125,8 @@ http { location /navigator/ { - auth_basic "Security Onion"; - auth_basic_user_file /opt/so/conf/nginx/.htpasswd; - proxy_pass http://{{ masterip }}:4200/navigator/; + auth_request /so-auth/api/auth/; + proxy_pass http://{{ masterip }}:4200/navigator/; proxy_read_timeout 90; proxy_connect_timeout 90; proxy_set_header Host $host; @@ -139,7 +137,7 @@ http { } location /api/ { - proxy_pass https://{{ masterip }}:8080/api/; + proxy_pass https://{{ masterip }}:8080/api/; proxy_read_timeout 90; proxy_connect_timeout 90; proxy_set_header Upgrade $http_upgrade; @@ -152,7 +150,7 @@ http { } location /fleet/ { - proxy_pass https://{{ masterip }}:8080/fleet/; + proxy_pass https://{{ masterip }}:8080/fleet/; proxy_read_timeout 90; proxy_connect_timeout 90; proxy_set_header Host $host; @@ -163,10 +161,10 @@ http { } location /thehive/ { - proxy_pass http://{{ masterip }}:9000/thehive/; + proxy_pass http://{{ masterip }}:9000/thehive/; proxy_read_timeout 90; proxy_connect_timeout 90; - proxy_http_version 1.1; # this is essential for chunked responses to work + proxy_http_version 1.1; # this is essential for chunked responses to work proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; @@ -175,10 +173,10 @@ http { } location /cortex/ { - proxy_pass http://{{ masterip }}:9001/cortex/; + proxy_pass http://{{ masterip }}:9001/cortex/; proxy_read_timeout 90; proxy_connect_timeout 90; - proxy_http_version 1.1; # this is essential for chunked responses to work + proxy_http_version 1.1; # this is essential for chunked responses to work proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; @@ -186,20 +184,8 @@ http { } - location /cyberchef/ { - proxy_pass http://{{ masterip }}:9080/; - proxy_read_timeout 90; - proxy_connect_timeout 90; - proxy_http_version 1.1; # this is essential for chunked responses to work - proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header Proxy ""; - - } - location /soctopus/ { - proxy_pass http://{{ masterip }}:7000/; + proxy_pass http://{{ masterip }}:7000/; proxy_read_timeout 90; proxy_connect_timeout 90; proxy_set_header Host $host; @@ -210,17 +196,16 @@ http { } location /sensoroni/ { - auth_basic "Security Onion"; - auth_basic_user_file /opt/so/conf/nginx/.htpasswd; - proxy_pass http://{{ masterip }}:9822/; + auth_request /so-auth/api/auth/; + proxy_pass http://{{ masterip }}:9822/; proxy_read_timeout 90; proxy_connect_timeout 90; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Proxy ""; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "Upgrade"; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "Upgrade"; } @@ -237,15 +222,34 @@ http { } location /sensoroniagents/ { - proxy_pass http://{{ masterip }}:9822/; + proxy_pass http://{{ masterip }}:9822/; proxy_read_timeout 90; proxy_connect_timeout 90; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Proxy ""; - } + + location /so-auth/loginpage/ { + proxy_pass http://{{ masterip }}:4242/; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + } + + location /so-auth/api/ { + proxy_pass http://{{ masterip }}:5656/; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Host $host; + } + + error_page 401 = @error401; + + location @error401 { + add_header Set-Cookie "NSREDIRECT=http://{{ masterip }}$request_uri;Domain={{ masterip }};Path=/"; + return 302 http://{{ masterip }}/so-auth/loginpage/; + } + error_page 404 /404.html; location = /40x.html { } diff --git a/salt/common/nginx/nginx.conf.so-master b/salt/common/nginx/nginx.conf.so-master index 265413fa2..0a0c31d6a 100644 --- a/salt/common/nginx/nginx.conf.so-master +++ b/salt/common/nginx/nginx.conf.so-master @@ -188,18 +188,6 @@ http { } - location /cyberchef/ { - proxy_pass http://{{ masterip }}:9080/; - proxy_read_timeout 90; - proxy_connect_timeout 90; - proxy_http_version 1.1; # this is essential for chunked responses to work - proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header Proxy ""; - - } - location /soctopus/ { proxy_pass http://{{ masterip }}:7000/; proxy_read_timeout 90; diff --git a/salt/common/tools/sbin/so-allow b/salt/common/tools/sbin/so-allow index 1685e386a..c6b756cd1 100644 --- a/salt/common/tools/sbin/so-allow +++ b/salt/common/tools/sbin/so-allow @@ -1,42 +1,101 @@ #!/bin/bash -got_root() { +# +# Copyright 2014,2015,2016,2017,2018,2019,2020 Security Onion Solutions, LLC +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . - # Make sure you are root - if [ "$(id -u)" -ne 0 ]; then - echo "This script must be run using sudo!" - exit 1 - fi +. /usr/sbin/so-common -} +SKIP=0 -got_root +while getopts "abowi:" OPTION +do + case $OPTION in -echo "This program allows you to add a firewall rule to allow connections from a new IP address." -echo "" -echo "Choose the role for the IP or Range you would like to add" -echo "" -echo "[a] - Analyst - ports 80/tcp and 443/tcp" -echo "[b] - Logstash Beat - port 5044/tcp" -echo "[o] - Osquery endpoint - port 8080/tcp" -echo "[w] - Wazuh endpoint - port 1514" -echo "" -echo "Please enter your selection (a - analyst, b - beats, o - osquery, w - wazuh):" -read ROLE -echo "Enter a single ip address or range to allow (example: 10.10.10.10 or 10.10.0.0/16):" -read IP + h) + usage + exit 0 + ;; + a) + FULLROLE="analyst" + SKIP=1 + ;; + b) + FULLROLE="beats_endpoint" + SKIP=1 + ;; + i) IP=$OPTARG + ;; + o) + FULLROLE="osquery_endpoint" + SKIP=1 + ;; + w) + FULLROLE="wazuh_endpoint" + SKIP=1 + ;; + esac +done + +if [ "$SKIP" -eq 0 ]; then + + echo "This program allows you to add a firewall rule to allow connections from a new IP address." + echo "" + echo "Choose the role for the IP or Range you would like to add" + echo "" + echo "[a] - Analyst - ports 80/tcp and 443/tcp" + echo "[b] - Logstash Beat - port 5044/tcp" + echo "[o] - Osquery endpoint - port 8080/tcp" + echo "[w] - Wazuh endpoint - port 1514" + echo "" + echo "Please enter your selection (a - analyst, b - beats, o - osquery, w - wazuh):" + read ROLE + echo "Enter a single ip address or range to allow (example: 10.10.10.10 or 10.10.0.0/16):" + read IP + + if [ "$ROLE" == "a" ]; then + FULLROLE=analyst + elif [ "$ROLE" == "b" ]; then + FULLROLE=beats_endpoint + elif [ "$ROLE" == "o" ]; then + FULLROLE=osquery_endpoint + elif [ "$ROLE" == "w" ]; then + FULLROLE=wazuh_endpoint + else + echo "I don't recognize that role" + exit 1 + fi -if [ "$ROLE" == "a" ]; then - FULLROLE=analyst -elif [ "$ROLE" == "b" ]; then - FULLROLE=beats_endpoint -elif [ "$ROLE" == "o" ]; then - FULLROLE=osquery_endpoint -elif [ "$ROLE" == "w" ]; then - FULLROLE=wazuh_endpoint -else - echo "I don't recognize that role" - exit 1 fi echo "Adding $IP to the $FULLROLE role. This can take a few seconds" /opt/so/saltstack/pillar/firewall/addfirewall.sh $FULLROLE $IP + +# Check if Wazuh enabled +if grep -q -R "wazuh: 1" /opt/so/saltstack/pillar/*; then + # If analyst, add to Wazuh AR whitelist + if [ "$FULLROLE" == "analyst" ]; then + WAZUH_MGR_CFG="/opt/so/wazuh/etc/ossec.conf" + if ! grep -q "$IP" $WAZUH_MGR_CFG ; then + DATE=`date` + sed -i 's/<\/ossec_config>//' $WAZUH_MGR_CFG + sed -i '/^$/N;/^\n$/D' $WAZUH_MGR_CFG + echo -e "\n \n $IP\n \n" >> $WAZUH_MGR_CFG + echo "Added whitelist entry for $IP in $WAZUH_MGR_CFG." + echo + echo "Restarting OSSEC Server..." + /usr/sbin/so-wazuh-restart + fi + fi +fi diff --git a/salt/common/tools/sbin/so-cortex-restart b/salt/common/tools/sbin/so-cortex-restart new file mode 100644 index 000000000..aab452475 --- /dev/null +++ b/salt/common/tools/sbin/so-cortex-restart @@ -0,0 +1,20 @@ +#!/bin/bash +# +# Copyright 2014,2015,2016,2017,2018,2019,2020 Security Onion Solutions, LLC +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +. /usr/sbin/so-common + +/usr/sbin/so-restart cortex $1 diff --git a/salt/common/tools/sbin/so-cortex-start b/salt/common/tools/sbin/so-cortex-start new file mode 100644 index 000000000..db383e2e8 --- /dev/null +++ b/salt/common/tools/sbin/so-cortex-start @@ -0,0 +1,20 @@ +#!/bin/bash +# +# Copyright 2014,2015,2016,2017,2018,2019,2020 Security Onion Solutions, LLC +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +. /usr/sbin/so-common + +/usr/sbin/so-start cortex $1 diff --git a/salt/common/tools/sbin/so-cortex-stop b/salt/common/tools/sbin/so-cortex-stop new file mode 100644 index 000000000..727b2c7fa --- /dev/null +++ b/salt/common/tools/sbin/so-cortex-stop @@ -0,0 +1,20 @@ +#!/bin/bash +# +# Copyright 2014,2015,2016,2017,2018,2019,2020 Security Onion Solutions, LLC +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +. /usr/sbin/so-common + +/usr/sbin/so-stop cortex $1 diff --git a/salt/common/tools/sbin/so-curator-restart b/salt/common/tools/sbin/so-curator-restart new file mode 100644 index 000000000..043f04b7d --- /dev/null +++ b/salt/common/tools/sbin/so-curator-restart @@ -0,0 +1,20 @@ +#!/bin/bash +# +# Copyright 2014,2015,2016,2017,2018,2019,2020 Security Onion Solutions, LLC +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +. /usr/sbin/so-common + +/usr/sbin/so-restart curator $1 diff --git a/salt/common/tools/sbin/so-curator-start b/salt/common/tools/sbin/so-curator-start new file mode 100644 index 000000000..676da0d2e --- /dev/null +++ b/salt/common/tools/sbin/so-curator-start @@ -0,0 +1,20 @@ +#!/bin/bash +# +# Copyright 2014,2015,2016,2017,2018,2019,2020 Security Onion Solutions, LLC +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +. /usr/sbin/so-common + +/usr/sbin/so-start curator $1 diff --git a/salt/common/tools/sbin/so-curator-stop b/salt/common/tools/sbin/so-curator-stop new file mode 100644 index 000000000..9aab50c8c --- /dev/null +++ b/salt/common/tools/sbin/so-curator-stop @@ -0,0 +1,20 @@ +#!/bin/bash +# +# Copyright 2014,2015,2016,2017,2018,2019,2020 Security Onion Solutions, LLC +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +. /usr/sbin/so-common + +/usr/sbin/so-stop curator $1 diff --git a/salt/common/tools/sbin/so-elastalert-create b/salt/common/tools/sbin/so-elastalert-create new file mode 100644 index 000000000..2134bc8f9 --- /dev/null +++ b/salt/common/tools/sbin/so-elastalert-create @@ -0,0 +1,1000 @@ +#!/bin/bash +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# Original written by Bryant Treacle +# https://raw.githubusercontent.com/bryant-treacle/Elastalert-Rule-Generator/master/so-elastalert-create +# Modified by Doug Burks +# +# Purpose: This script will allow you to test your elastalert rule without entering the Docker container. + +###################################################### +# Universal Rule Options # +###################################################### + +################################# +# Function for Main Menu # +################################# + +main_menu() +{ +while true; do + +rule_type_select_prompt + read rule_type + + if [ $rule_type = "1" ] ; then + rule_name_prompt + index_name_prompt + cardinality_rule_prompt + realert_prompt + filter_options_prompt + alert_options_prompt + final_prompt + elif [ $rule_type = "2" ] ; then + rule_name_prompt + index_name_prompt + blacklist_rule_prompt + realert_prompt + filter_options_prompt + alert_options_prompt + final_prompt + elif [ $rule_type = "3" ] ; then + rule_name_prompt + index_name_prompt + whitelist_rule_prompt + realert_prompt + filter_options_prompt + alert_options_prompt + final_prompt + elif [ $rule_type = "4" ] ; then + rule_name_prompt + index_name_prompt + frequency_rule_prompt + realert_prompt + filter_options_prompt + alert_options_prompt + final_prompt + elif [ $rule_type = "5" ] ; then + rule_name_prompt + index_name_prompt + change_rule_prompt + realert_prompt + filter_options_prompt + alert_options_prompt + final_prompt + elif [ $rule_type = "6" ] ; then + rule_name_prompt + index_name_prompt + spike_rule_prompt + realert_prompt + filter_options_prompt + alert_options_prompt + final_prompt + elif [ $rule_type = "7" ] ; then + rule_name_prompt + index_name_prompt + new_term_rule_prompt + realert_prompt + filter_options_prompt + alert_options_prompt + final_prompt + elif [ $rule_type = "8" ] ; then + rule_name_prompt + index_name_prompt + flatline_rule_prompt + realert_prompt + filter_options_prompt + alert_options_prompt + final_prompt + elif [ $rule_type = "9" ] ; then + exit + fi +done +} + +############################# +# Rule Type # +############################# +rule_type_select_prompt() +{ +cat << EOF + +This script will help automate the creation of Elastalert Rules. +Please choose the rule you would like to build. + +For Cardinality rules: Press 1 +For Blacklist rules: Press 2 +For Whitelist rules: Press 3 +For Frequency rules: Press 4 +For Change rules: Press 5 +For Spike rules: Press 6 +For New Term rules: Press 7 +For Flatline rules: Press 8 +To Exit: Press 9 + +EOF + +} + +############################# +# Rule Name # +############################# +rule_name_prompt() +{ + +cat << EOF +The rule name will appear in the subject of the alerts and be the name of the yaml rule file. + +What do you want to name the rule? + +EOF + + read raw_rulename + rulename=$(echo ${raw_rulename,,} | sed 's/ /_/g') + +cat << EOF >> "$rulename.yaml" +# Elasticsearch Host +es_host: elasticsearch +es_port: 9200 + +# (Required) +# Rule name, must be unique +name: $raw_rulename + +EOF +} + +############################# +# Index Name # +############################# +index_name_prompt() +{ +cat << EOF + +What elasticsearch index do you want to use? +Below are the default Index Patterns used in Security Onion: + +*:logstash-* +*:logstash-beats-* +*:elastalert_status* + +EOF + read indexname +cat << EOF >> "$rulename.yaml" + +# (Required) +# Index to search, wildcard supported +index: "$indexname" + +EOF +} + +############################# +# Alert Options # +############################# +alert_options_prompt() +{ +cat << EOF + +By default, all matches will be written back to the elastalert index. +Please choose from the below options. + + - For Email: Press 1 + - For Slack: Press 2 + - For the default (debug): Press 3 +EOF + +read alertoption + + if [ $alertoption = "1" ] ; then + echo "Please enter the email address you want to send the alerts to. Note: Ensure the Master Server is configured for SMTP." + read emailaddress + cat << EOF >> "$rulename.yaml" +# (Required) +# The alert is use when a match is found +alert: +- email + +# (required, email specific) +# a list of email addresses to send alerts to +email: + - $emailaddress +EOF + + elif [ $alertoption = "2" ] ; then + + echo "The webhook URL that includes your auth data and the ID of the channel (room) you want to post to." + echo "Go to the Incoming Webhooks section in your Slack account https://XXXXX.slack.com/services/new/incoming-webhook," + echo "choose the channel, click ‘Add Incoming Webhooks Integration’ and copy the resulting URL. You can use a list of URLs to send to multipe channels." + echo "" + echo "Please enter the webhook URL below:" + echo "" + read webhookurl + + cat << EOF >> "$rulename.yaml" +# (Required) +# The alert is use when a match is found +alert: +- slack + +# (required,Slack specific) +# Enter the webhook URL below +slack: + - $webhookurl + +EOF + + else + echo "Using default alert type of debug. Alerts will only be written to the *:elastalert_status* index." + cat << EOF >> "$rulename.yaml" +# (Required) +# The alert is use when a match is found +alert: +- debug + +EOF + + fi +} + +############################# +# Filter Options # +############################# +filter_options_prompt() +{ +cat << EOF + +By default this script will use a wildcard search that will include all logs for the index chosen above. +Would you like to use a specific filter? (Y/N) + +EOF + + read filteroption + if [ ${filteroption,,} = "y" ] ; then + echo "This script will allow you to generate basic filters. For complex filters visit https://elastalert.readthedocs.io/en/latest/recipes/writing_filters.html" + echo "" + echo "Term: Allows you to match a value in a field. For example you can select the field source_ip and the value 192.168.1.1" + echo "or choose a specific log type you want the rule to apply to ie. field_type: event_type and the field_value bro_http" + echo "" + echo "Wildcard: Allows you to use the wildcard * in the field_value. For example field_type: useragent and field_value: *Mozilla* " + echo "" + echo "Please choose from the following filter types." + echo "" + echo "term or wildcard" + read filter_type + if [ ${filter_type,,} = "term" ] ; then + echo "What field do you want to filter on?" + read field_name + echo "What is the value for the $field_name field." + read field_value + + cat << EOF >> "$rulename.yaml" +#(Required) +# A list of Elasticsearch filters used for find events +# These filters are joined with AND and nested in a filtered query +# For more info: http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl.html +filter: + +- term: + $field_name: "$field_value" + +EOF + elif [ ${filter_type,,} = "wildcard" ] ; then + echo "What field do you want to use?" + read field_name + echo "What is the value for the $field_name field." + read field_value + cat << EOF >> "$rulename.yaml" +#(Required) +# A list of Elasticsearch filters used for find events +# These filters are joined with AND and nested in a filtered query +# For more info: http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl.html +filter: + +- wildcard: + $field_name: "$field_value" + +EOF + fi + else + + cat << EOF >> "$rulename.yaml" +#(Required) +# A list of Elasticsearch filters used for find events +# These filters are joined with AND and nested in a filtered query +# For more info: http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl.html +filter: + +- wildcard: + event_type: "*" + +EOF + fi + +} + +############################ +# Re-alert Options # +############################ +realert_prompt() +{ +echo "The realert option allows you to ignore repeating alerts for a given period of time." +echo "Would you like to set a realert timeframe? (Y/N)" + read realert_option + + if [ ${realert_option,,} = "y" ] ; then + echo "Please choose from the following units of measure:" + echo "" + echo " - weeks, days, hours, minutes, or seconds" + read realert_unit_of_measure + echo "Please enter the number of $realert_unit_of_measure you want to use." + read realert_timeframe + + cat << EOF >> "$rulename.yaml" +# This option allows you to ignore repeating alerts for a period of time. +realert: + $realert_unit_of_measure: $realert_timeframe + +EOF + fi +} + +####################### +# Final prompt # +####################### +final_prompt() +{ +current_directory=$(pwd) +sleep 1 +echo "Writing rule to the following location:" +echo "" +echo " $current_directory/$rulename.yaml" +echo "" +sleep 1 +echo "Complete!" +sleep 1 +} + + +################################### +# Functions for Cardinality Rules # +################################### +cardinality_rule_prompt() +{ + echo "The Cardinality rule will be alert when the maximum or minimum number of unique values for a given field reach a threshold." + echo "What field do you want to be the Cardinality Field?" + echo "" + read cardinality_field + cat << EOF >> "$rulename.yaml" + +# (Required) +# Type of alert. +# The Cardinality rule matches when the total number of unique values for a certain field , within a given timeframe is higher or lower than a threshold. +type: cardinality + +# (Required, cardinality specific) +# Count the number of unique value for this field +cardinality_field: $cardinality_field + +EOF + echo "" + echo "To alert on values LESS than X unique values in the cardinality field: Press 1" + echo "To alert on values GREATER than X unique values in the cardinality field: Press 2" + echo "" + read cardinality_max_min + if [ $cardinality_max_min = "1" ] ; then + echo "The Minimum Cardinality value will alert you when there is less than X unique values in that field." + echo "What is the minimum Cardinality value?" + echo "" + read cardinality_min + + cat << EOF >> "$rulename.yaml" +# (Required, frequency specific) +# Alert when there is less than X unique values +min_cardinality: $cardinality_min + +EOF + + elif [ $cardinality_max_min = "2" ] ; then + echo "The Maximum Cardinality value will alert you when there is more than X unique values." + echo "What is the maximum Cardinality value?" + echo "" + read cardinality_max + + cat << EOF >> "$rulename.yaml" +# (Required, frequency specific) +# Alert when there is more than X unique values +max_cardinality: $cardinality_max + +EOF + + fi + echo "" + echo "The Cardinality Timeframe is defined as the number of unique values in the most recent X hours." + echo "" + echo "Below are the available units of measure for the timeframe field:" + echo " - weeks, days, hours, minutes, or seconds" + echo "What unit of measure do you want to use?" + read timeframe_units + echo "Please enter the number of $timeframe_units you want to use." + read timeframe + + cat << EOF >> "$rulename.yaml" +# (Required, frequency specific) +# The cardinality is defined as the number of unique values for the most recent 4 hours + +timeframe: + $timeframe_units: $timeframe + +EOF + +echo "The query_key counts by this field. For each unique value of the query_key field, cardinality will be counted separately." +echo "Would you like to set the query_key parameter? (Y/N)" + read cardinality_rule_options + if [ ${cardinality_rule_options,,} = "y" ] ; then + echo "What field do you want the query_key to be?" + read query_key + cat << EOF >> "$rulename.yaml" +# (Optional, frequency specific) +# query_key: Group cardinality counts by this field. For each unique value of the query_key field, cardinality will be counted separately. +query_key: $query_key + +EOF + fi + +} + +################################# +# Functions for Blacklist Rules # +################################# +blacklist_rule_prompt() +{ + echo "The blacklist rule will compare the values contained in a text file against the compare_key and alert if there is a match." + echo "What field do you want to compare to the blacklist?" + echo "" + read compare_key + echo "The blacklist file should be a text file with a single value per line." + echo "" + echo "The file needs to be accessible by the so-elastalert container." + echo "" + echo "Please enter the full path and filename of the blacklist." + echo "" + read -e blacklist_file_location + + cat << EOF >> "$rulename.yaml" +# (Required) +# Type of alert. +# The Blacklist rule will check a certain field against a blacklist and match if it is in the blacklist +type: blacklist + +# (Required, blacklist) +# The name of the field to use to compare to the blacklist. If the field is null, those events will be ignored. +compare_key: $compare_key + +# (Required, blacklist) +# A list of blacklisted values, and/or a list of paths to flat files which contain the blacklisted values +blacklist: + - "!file $blacklist_file_location" + +EOF + +} + +################################### +# Functions for Whitelist Rules # +################################### +whitelist_rule_prompt() +{ + echo "The whitelist rule will compare the values contained in a text file against the compare_key and alert if there is a match." + echo "What field do you want to compare to the whitelist?" + echo "" + read compare_key + + echo "The whitelist file should be a text file with a single value per line." + echo "" + echo "The file needs to be accessible by the so-elastalert container." + echo "" + echo "Please enter the full path and filename of the whitelist." + echo "" + read -e whitelist_file_location + echo "The ignore_null parameter If true, events without a compare_key field will not match." + echo "" + echo "Please enter true or false for the ignore_null parameter." + read ignore_null + + cat << EOF >> "$rulename.yaml" +# (Required) +# Type of alert. +# the whitelist rule will check a certain field against a whitelist and match if it is in the whitelist +type: whitelist + +# (Required, whitelist) +# The name of the field to use to compare to the whitelist. If the field is null, those events will be ignored. +compare_key: $compare_key + +# (Required, whitelist) +# ignore_null: If true, events without a compare_key field will not match. +ignore_null: $ignore_null + +# (Required, whitelist) +# A list of whitelisted values, and/or a list of paths to flat files which contain the whitelisted values +whitelist: + - "!file $whitelist_file_location" + +EOF +} + +################################### +# Functions for Frequency Rules # +################################### +frequency_rule_prompt() +{ +echo "The Frequency rule matches when there are at least a certain number of events in a given timeframe." +echo "" +echo "Enter the number of events you want to alert on:" + read num_events +echo "" +echo "Below are the available units of measure for the timeframe field:" +echo " - weeks, days, hours, minutes, or seconds" +echo "What unit of measure do you want to use?" + read timeframe_units +echo "Please enter the number of $timeframe_units you want to use." + read timeframe + +cat << EOF >> "$rulename.yaml" + +# (Required) +# Type of alert. +# the frequency rule type alerts when num_events events occur with timeframe time +type: frequency + +# (Required, frequency specific) +# Alert when this many documents matching the query occur within a timeframe +num_events: $num_events + +# (Required, frequency specific) +# num_events must occur within this amount of time to trigger an alert +timeframe: + $timeframe_units: $timeframe + +EOF + +cat << EOF +The frequency rule has the below optional fields: + - use_count_query: if true, ElastALert will poll Elasticsearch using the count api and not download all the matching + documents. This is useful if you only care about the numbers and not the actual data. + - use_terms_query: If true, ElastAlert will make an aggregation query against Elasticsearch to get counts of documents matching + each unique value of the query_key. This will only return the Maximum of terms_size, default 50 unique terms. + + +Would you like to set the optional settings? (Y/N) + +EOF + read frequency_rule_options + + if [ ${frequency_rule_options,,} = "y" ] ; then + echo "To set the use_count_query to true: press 1" + echo "To set the use_terms_query to true: press 2" + read frequency_query_type + if [ $frequency_query_type = "1" ] ; then + + cat << EOF >> "$rulename.yaml" + +# Only count number of records, instead of bringing all data back +use_count_query: true +doc_type: 'doc' + +EOF + elif [ $frequency_query_type = "2" ] ; then + echo "Please enter the query_key:" + read query_key + echo "Please enter the terms size:" + read term_size + + cat << EOF >> "$rulename.yaml" +# Only count number of records, instead of bringing all data back +use_terms_query: true +doc_type: 'doc' + +# Query_key count of documents will be stored independently for each value of query_key +query_key: $query_key + +# Term_size is the maximum number of terms returned per query. Default is 50. +terms_size: $term_size + +EOF + fi + fi + +} + +################################ +# Functions for Change Rules # +################################ +change_rule_prompt() +{ +echo "The change rule will monitor a certain field and match if that field changes." +echo "" +echo "The field must change with respect to the last event with the same query_key." +echo "Below is an example with a query_key of bob and a compare_key of source_ip:" +echo "" +echo " -username bob AND source_ip: 192.168.1.2" +echo " -username bob AND source_ip: 192.168.1.3" +echo "" +echo "The compare_key parameter names of the field to monitor for changes." +echo "Since this is a list of strings, we can have multiple keys. An alert will trigger if any of the fields change." +echo "" +echo "What field do you want to monitor for changes?" + read compare_key +echo "" +echo "The query_key parameter names the field that must be present in all of the events that are checked." +echo "What field do you want be the query_key?" + read query_key +echo "" +echo "The value of compare_key must change in two events that are less than the timeframe apart to trigger an alert." +echo "" +echo "Below are the available units of measure for the timeframe field:" +echo " - weeks, days, hours, minutes, or seconds" +echo "What unit of measure do you want to use?" + read timeframe_units +echo "Please enter the number of $timeframe_units you want to use." + read timeframe + cat << EOF >> "$rulename.yaml" +# (Required) +# Type of alert. +# This rule will monitor a certain field and match if that field changes. +type: change + +# (Required, change specific) +# The field to look for changes in +compare_key: $compare_key + +# (Required, change specific) +# Ignore documents without the compare_key (source_ip) field +ignore_null: true + +# (Required, change specific) +# The change must occur in two documents with the same query_key +query_key: $query_key + +# (Required, change specific) +# The value of compare_key must change in two events that are less than timeframe apart to t$ +timeframe: + $timeframe_units: $timeframe + +EOF + +} + +################################ +# Functions for Spike Rules # +################################ +spike_rule_prompt() +{ +echo "The spike rule matches when the volume of events during a given time period is spike_height times larger or smaller than during the previous time period." +echo "" +echo "Example to detect syn flood attack to public facing webserver:" +echo "Alert when the number of connection states to my web server per hour is twice as many as the previous hour." +echo "" +echo "The spike_height parameter is the ratio of number of events in the last timeframe to the previous timeframe that when hit will trigger an alert." +echo "Note: This value is a multiple!! 2 = 2x as many; 5 = 5x as many" +echo "What do you want the spike_height to be?" + read spike_height +echo "" +echo "What do you want the spike_type parameter to be?" +echo " - up: more than previous timeframe" +echo " - down: less than previous timeframe" +echo " - both: up or down" + read spike_type +echo "Below are the available units of measure for the timeframe field:" +echo " - weeks, days, hours, minutes, or seconds" +echo "What unit of measure do you want to use?" + read timeframe_units +echo "Please enter the number of $timeframe_units you want to use." + read timeframe + cat << EOF >> "$rulename.yaml" +# (Required) +# Type of alert. +# This rule matches when the volume of events during a given time period is spike_height times larger or smaller than during the previous time period. +type: spike + +# (Required, spike specific) +# The ratio of number of events in the last timeframe to the previous timeframe. +spike_height: $spike_height + +# (Required, spike specific) +# The spike being up, down or both +spike_type: $spike_type + +# (Required, spike specific) +# The value of average out the rate of events over this time period. +timeframe: + $timeframe_units: $timeframe + +EOF + +echo "The spike rule has the following optional parameters:" +echo " - field_value: When set, uses the value of the field in the document and not the number of matching documents. Note the value must be a number" +echo " - threshold_ref: The minimum number of events that must exist in the reference window for an alert to trigger." +echo " For example, if spike_height: 3 and threshold_ref: 10, then the ‘reference’ window must contain at least 10 events and the ‘current’ window at least three times that for an alert to be triggered." +echo " - threshold_cur: The minimum number of events that must exist in the current window for an alert to trigger." +echo " For example, if spike_height: 3 and threshold_cur: 60, then an alert will occur if the current window has more than 60 events and the reference window has less than a third as many." +echo "" +echo "Would you like to set one of these parameters? (Y/N)" + read spike_additional_options + if [ ${spike_additional_options,,} = "y" ] ; then + counter=0 + while [ $counter -eq 0 ]; do + counter=$(( $counter + 1 )) + echo "Please choose from the following options:" + echo "For field_value: Press 1" + echo "For threshold_ref: Press 2" + echo "For threshold_cur: Press 3" + echo "To continue: Press 4" + read spike_options_select + if [ $spike_options_select = "1" ] ; then + echo "What field would you like to use?" + read field_value_field + cat << EOF >> "$rulename.yaml" +#(Optional, spike specific) +# field_value: When set, uses the value of the field in the document and not the number of matching documents. +field_value: $spike_options_select + +EOF +# reset the counter for the while loop + counter=0 + elif [ $spike_options_select = "2" ] ; then + echo "What would you like the threshold_ref to be?" + read threshold_ref_field + cat << EOF >> "$rulename.yaml" +#(Optional, spike specific) +# The minimum number of events that must exist in the reference window for an alert to trigger. +threshold_ref: $threshold_ref_field + +EOF +#Reset the counter for the while loop + counter=0 + elif [ $spike_options_select = "3" ] ; then + echo "What would you like the threshold_cur to be?" + read threshold_cur_field + cat << EOF >> "$rulename.yaml" +#(Optional, spike specific +# The minimum number of events that must exist in the current window for an alert to trigger. +threshold_cur: $threshold_cur_field + +EOF +#Reset the counter for the while loop + counter=0 + elif [ $spike_options_select = "4" ] ; then + counter=1 + fi + done + fi +} + +################################### +# Functions for new term Rules # +################################### +new_term_rule_prompt() +{ +echo "This rule matches when a new value appears in a field that has never been seen before." +echo "When ElastAlert starts, it will use an aggregation query to gather all known terms for a list of fields." +echo "" +echo "What field(s) do you want to monitor for new terms?" + read new_term_field +cat << EOF >> "$rulename.yaml" +# (Required) +# Type of alert. +# This rule matches when a new value appears in a field that has never been seen before. +type: new_term + +# (Required, new_term specific) +# Monitor the field ip_address +fields: + - "$new_term_field" + +EOF + +echo "The New Term rule has the following additional options:" +echo " - terms_window_size: The amount of time used for the initial query to find existing terms. No term that has occurred within this time frame will trigger an alert. The default is 30 days." +echo " - window_step_size: When querying for existing terms, split up the time range into steps of this size. This is usefull when covering large timeframes" +echo " - alert_on_missing_field: Whether or not to alert when a field is missing from a document. The default is false." +echo "Would you like to set any of these options? (Y/N)" + read new_term_options + if [ ${new_term_options,,} = "y" ] ; then + counter=0 + while [ $counter -eq 0 ]; do + counter=$(( $counter + 1 )) + echo "Please choose from the following options:" + echo "" + echo "For terms_window_size: Press 1" + echo "For window_step_size: Press 2" + echo "For alert_on_missing_field: Press 3" + echo "To continue: Press 4" + read new_term_loop_option + if [ $new_term_loop_option = "1" ] ; then + echo "Below are the available units of measure for the terms_window_size field:" + echo " - weeks, days, hours, minutes, or seconds" + echo "What unit of measure do you want to use?" + read timeframe_units + echo "Please enter the number of $timeframe_units you want to use." + read timeframe + cat << EOF >> "$rulename.yaml" + +# (Optional, new_term specific) +# This means that we will query 90 days worth of data when ElastAlert starts to find which values of ip_address already exist +# If they existed in the last 90 days, no alerts will be triggered for them when they appear +terms_window_size: + $timeframe_units: $timeframe + +EOF +#Reset the while loop counter + counter=0 + elif [ $new_term_loop_option = "2" ] ; then + echo "Below are the available units of measure for the window_step_size field:" + echo " - weeks, days, hours, minutes, or seconds" + echo "What unit of measure do you want to use?" + read timeframe_units + echo "Please enter the number of $timeframe_units you want to use." + read timeframe + cat << EOF >> "$rulename.yaml" + +# (Optional, new_term specific) +# This means that we will query 90 days worth of data when ElastAlert starts to find which values of ip_address alr$ +# If they existed in the last 90 days, no alerts will be triggered for them when they appear +window_step_size: + $timeframe_units: $timeframe + +EOF +#Reset the while loop counter + counter=0 + elif [ $new_term_loop_option = "3" ] ; then + echo "Please enter either true or false for the alert_on_missing_field." + read alert_on_missing_field_option + cat << EOF >> "$rulename.yaml" +# (Optional, new_term specific) +# Whether or not to alert when a field is missing from a document. The default is false. +alert_on_missing_field: $alert_on_missing_field_option + +EOF +#reset the while loop counter + counter=0 + elif [ $new_term_loop_options = "4" ] ; then + counter=1 + fi + done + fi +} + +################################### +# Functions for Flat line Rules # +################################### +flatline_rule_prompt() +{ +echo "flatline: This rule matches when the total number of events is under a given threshold for a time period." +echo "" +echo "Please enter the minimum threshold of events." + read threshold +echo "Below are the available units of measure for the timeframe field:" +echo " - weeks, days, hours, minutes, or seconds" +echo "What unit of measure do you want to use?" + read timeframe_units +echo "Please enter the number of $timeframe_units you want to use." + read timeframe +echo "" + cat << EOF >> "$rulename.yaml" +# (Required) +# Type of alert. +# flatline: This rule matches when the total number of events is under a given threshold for a time period. +type: flatline + +# (Required, spike specific) +# threshold: The minimum number of events for an alert not to be triggered. +threshold: $threshold + +# (Required, spike specific) +# The value of average out the rate of events over this time period. +timeframe: + $timeframe_units: $timeframe + +EOF + +echo "The flatline rule has the following additional options:" +echo "" +echo " - use_count_query: If true, ElastAlert will poll Elasticsearch using the count api, and not download all of the matching documents." +echo " - use_terms_query: If true, ElastAlert will make an aggregation query against Elasticsearch to get counts of documents matching each unique value of query_key. " +echo " - terms_size: When used with use_terms_query, this is the maximum number of terms returned per query. Default is 50." +echo " - query_key: With flatline rule, query_key means that an alert will be triggered if any value of query_key has been seen at least once and then falls below the threshold." +echo " - forget_keys: Only valid when used with query_key. If this is set to true, ElastAlert will “forget” about the query_key value that triggers an alert, therefore preventing any more alerts for it until it’s seen again." +echo "" +echo "Would you like to set any of theses options? (Y/N)" + read flatline_option + if [ ${flatline_option,,} = "y" ] ; then + counter=0 + while [ $counter -eq 0 ]; do + counter=$(( $counter + 1 )) + echo "Please choose from the following options:" + echo "" + echo "For use_count_query: Press 1" + echo "For use_term_query: Press 2" + echo "For terms_size: Press 3" + echo "To continue: Press 4" + echo "" + read flatline_option_select + + if [ $flatline_option_select = "1" ] ; then + echo "Please enter true or false for the use_count_query field." + read use_count_query + cat << EOF >> "$rulename.yaml" + +# (Optional, flatline specific) +# use_count_query: If true, ElastAlert will poll Elasticsearch using the count api, and not download all of the matching documents. +use_count_query: $use_count_query +doc_type: 'doc' + +EOF +#Reset counter for while loop + counter=0 + + elif [ $flatline_option_select = "2" ] ; then + echo "Please enter true or false for the use_terms_query." + read use_terms_query + echo "Please enter the query_key field." + read query_key + echo "The forget_keys when set to true will, elastalert will forget about the query_key value, preventing any more alerts for it until it is seen again" + echo "" + echo "Please enter true of false for the forget_keys field." + read forget_keys + cat << EOF >> "$rulename.yaml" + +# (Optional, flatline specific) +# Use_terms_query: If true, ElastAlert will make an aggregation query against Elasticsearch to get counts of documents matching each unique value of query_key." +use_terms_query: $use_terms_query + +# (Optional, flatline specific) +# Query_key means that an alert will be triggered if any value of query_key has been seen at least once and then falls below the threshold." +query_key: $query_key + +# (Optional, flatline specific) +# If this is set to true, ElastAlert will “forget” about the query_key value that triggers an alert, therefore preventing any more alerts for it until it’s seen again. +forget_keys: $forget_keys + +EOF +#Reset counters for while loop + counter=0 + elif [ $flatline_option_select = "3" ] ; then + echo "Please enter the maximum number of terms returned per query, Default is 50" + read terms_size + cat << EOF >> "$rulename.yaml" + +# (Optional, flatline specific) +# When used with use_terms_query, this is the maximum number of terms returned per query. Default is 50. +terms_size: $terms_size + +EOF +#Reset counters for while loop + counter=0 + + elif [ $flatline_option_select = "4" ] ; then + counter=1 + fi + done +fi +} + +########################## +# Start Function # +########################## +main_menu diff --git a/salt/common/tools/sbin/so-elastalert-restart b/salt/common/tools/sbin/so-elastalert-restart new file mode 100644 index 000000000..46e66ec40 --- /dev/null +++ b/salt/common/tools/sbin/so-elastalert-restart @@ -0,0 +1,20 @@ +#!/bin/bash +# +# Copyright 2014,2015,2016,2017,2018,2019,2020 Security Onion Solutions, LLC +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +. /usr/sbin/so-common + +/usr/sbin/so-restart elastalert $1 diff --git a/salt/common/tools/sbin/so-elastalert-start b/salt/common/tools/sbin/so-elastalert-start new file mode 100644 index 000000000..7101eec15 --- /dev/null +++ b/salt/common/tools/sbin/so-elastalert-start @@ -0,0 +1,20 @@ +#!/bin/bash +# +# Copyright 2014,2015,2016,2017,2018,2019,2020 Security Onion Solutions, LLC +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +. /usr/sbin/so-common + +/usr/sbin/so-start elastalert $1 diff --git a/salt/common/tools/sbin/so-elastalert-stop b/salt/common/tools/sbin/so-elastalert-stop new file mode 100644 index 000000000..731312e8c --- /dev/null +++ b/salt/common/tools/sbin/so-elastalert-stop @@ -0,0 +1,20 @@ +#!/bin/bash +# +# Copyright 2014,2015,2016,2017,2018,2019,2020 Security Onion Solutions, LLC +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +. /usr/sbin/so-common + +/usr/sbin/so-stop elastalert $1 diff --git a/salt/common/tools/sbin/so-elastalert-test b/salt/common/tools/sbin/so-elastalert-test new file mode 100644 index 000000000..575865bd0 --- /dev/null +++ b/salt/common/tools/sbin/so-elastalert-test @@ -0,0 +1,142 @@ +#!/bin/bash +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# Originally written by Bryant Treacle +# https://raw.githubusercontent.com/bryant-treacle/so-elastalert-test-rule/master/so-elastalert-test +# Modified by Doug Burks and Wes Lambert +# +# Purpose: This script will allow you to test your elastalert rule without entering the Docker container. + +. /usr/sbin/so-elastic-common + +OPTIONS="" +SKIP=0 +RESULTS_TO_LOG="n" +RULE_NAME="" +FILE_SAVE_LOCATION="" + +usage() +{ +cat < Write results to specified log file + -o '' Specify Elastalert options ( Ex. --schema-only , --count-only, --days N ) + -r Specify path/name of rule to test + +EOF +} + +while getopts "hal:o:r:" OPTION +do + case $OPTION in + h) + usage + exit 0 + ;; + a) + OPTIONS="--alert" + ;; + l) + RESULTS_TO_LOG="y" + FILE_SAVE_LOCATION=$OPTARG + ;; + + o) + OPTIONS=$OPTARG + ;; + + r) + RULE_NAME=$OPTARG + SKIP=1 + ;; + *) + usage + exit 0 + ;; + esac +done + +docker_exec(){ + if [ ${RESULTS_TO_LOG,,} = "y" ] ; then + docker exec -it so-elastalert bash -c "elastalert-test-rule $RULE_NAME $OPTIONS" > $FILE_SAVE_LOCATION + else + docker exec -it so-elastalert bash -c "elastalert-test-rule $RULE_NAME $OPTIONS" + fi +} + +rule_prompt(){ + CURRENT_RULES=$(find /opt/so/rules/elastalert -name "*.yaml") + echo + echo "This script will allow you to test an Elastalert rule." + echo + echo "Below is a list of active Elastalert rules:" + echo + echo "-----------------------------------" + echo + echo "$CURRENT_RULES" + echo + echo "-----------------------------------" + echo + echo "Note: To test a rule it must be accessible by the Elastalert Docker container." + echo + echo "Make sure to swap the local path (/opt/so/rules/elastalert/) for the docker path (/etc/elastalert/rules/)" + echo "Example: /opt/so/rules/elastalert/nids2hive.yaml would be /etc/elastalert/rules/nids2hive.yaml" + echo + while [ -z $RULE_NAME ]; do + echo "Please enter the file path and rule name you want to test." + read -e RULE_NAME + done +} + +log_save_prompt(){ + RESULTS_TO_LOG="" + while [ -z $RESULTS_TO_LOG ]; do + echo "The results can be rather long. Would you like to write the results to a file? (Y/N)" + read RESULTS_TO_LOG + done +} + +log_path_prompt(){ + while [ -z $FILE_SAVE_LOCATION ]; do + echo "Please enter the file path and file name." + read -e FILE_SAVE_LOCATION + done + echo "Depending on the rule this may take a while." +} + +if [ $SKIP -eq 0 ]; then + rule_prompt + log_save_prompt + if [ ${RESULTS_TO_LOG,,} = "y" ] ; then + log_path_prompt + fi +fi + +docker_exec + +if [ $? -eq 0 ]; then + echo "Test completed successfully!" +else + echo "Something went wrong..." +fi + +echo + + + diff --git a/salt/common/tools/sbin/so-elastic-diagnose b/salt/common/tools/sbin/so-elastic-diagnose new file mode 100644 index 000000000..0a8acc0ae --- /dev/null +++ b/salt/common/tools/sbin/so-elastic-diagnose @@ -0,0 +1,33 @@ +#!/bin/bash +# +# Copyright 2014,2015,2016,2017,2018,2019,2020 Security Onion Solutions, LLC +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# Source common settings +. /usr/sbin/so-common + +# Check for log files +for FILE in /opt/so/log/elasticsearch/*.log /opt/so/log/logstash/*.log /opt/so/log/kibana/*.log /opt/so/log/elastalert/*.log /opt/so/log/curator/*.log /opt/so/log/freqserver/*.log /opt/so/log/nginx/*.log; do + +# If file exists, then look for errors or warnings +if [ -f $FILE ]; then + MESSAGE=`grep -i 'ERROR\|FAIL\|WARN' $FILE` + if [ ! -z "$MESSAGE" ]; then + header $FILE + echo $MESSAGE | sed 's/WARN/\nWARN/g' | sed 's/WARNING/\nWARNING/g' | sed 's/ERROR/\nERROR/g' | sort | uniq -c | sort -nr + echo + fi +fi +done diff --git a/salt/common/tools/sbin/so-elasticsearch-restart b/salt/common/tools/sbin/so-elasticsearch-restart new file mode 100644 index 000000000..e13a89ba8 --- /dev/null +++ b/salt/common/tools/sbin/so-elasticsearch-restart @@ -0,0 +1,20 @@ +#!/bin/bash +# +# Copyright 2014,2015,2016,2017,2018,2019,2020 Security Onion Solutions, LLC +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +. /usr/sbin/so-common + +/usr/sbin/so-restart elasticsearch $1 diff --git a/salt/common/tools/sbin/so-elasticsearch-start b/salt/common/tools/sbin/so-elasticsearch-start new file mode 100644 index 000000000..76a3baac6 --- /dev/null +++ b/salt/common/tools/sbin/so-elasticsearch-start @@ -0,0 +1,20 @@ +#!/bin/bash +# +# Copyright 2014,2015,2016,2017,2018,2019,2020 Security Onion Solutions, LLC +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +. /usr/sbin/so-common + +/usr/sbin/so-start elasticsearch $1 diff --git a/salt/common/tools/sbin/so-elasticsearch-stop b/salt/common/tools/sbin/so-elasticsearch-stop new file mode 100644 index 000000000..9d03a64ae --- /dev/null +++ b/salt/common/tools/sbin/so-elasticsearch-stop @@ -0,0 +1,20 @@ +#!/bin/bash +# +# Copyright 2014,2015,2016,2017,2018,2019,2020 Security Onion Solutions, LLC +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +. /usr/sbin/so-common + +/usr/sbin/so-stop elasticsearch $1 diff --git a/salt/common/tools/sbin/so-filebeat-restart b/salt/common/tools/sbin/so-filebeat-restart index 85faf7499..d9cdeeec8 100644 --- a/salt/common/tools/sbin/so-filebeat-restart +++ b/salt/common/tools/sbin/so-filebeat-restart @@ -1,17 +1,20 @@ #!/bin/bash - -# Copyright 2014,2015,2016,2017,2018, 2019 Security Onion Solutions, LLC - -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. # -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. +# Copyright 2014,2015,2016,2017,2018,2019,2020 Security Onion Solutions, LLC # -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -docker stop so-filebeat && sudo docker rm so-filebeat && salt-call state.apply filebeat +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +. /usr/sbin/so-common + +/usr/sbin/so-restart filebeat $1 diff --git a/salt/common/tools/sbin/so-filebeat-start b/salt/common/tools/sbin/so-filebeat-start index e5ce6ed88..e15c2e5e9 100644 --- a/salt/common/tools/sbin/so-filebeat-start +++ b/salt/common/tools/sbin/so-filebeat-start @@ -1,17 +1,20 @@ #!/bin/bash - -# Copyright 2014,2015,2016,2017,2018, 2019 Security Onion Solutions, LLC - -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. # -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. +# Copyright 2014,2015,2016,2017,2018,2019,2020 Security Onion Solutions, LLC # -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -docker rm so-filebeat && salt-call state.apply filebeat +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +. /usr/sbin/so-common + +/usr/sbin/so-start filebeat $1 diff --git a/salt/common/tools/sbin/so-filebeat-stop b/salt/common/tools/sbin/so-filebeat-stop index 3b7419db7..7a5e2f28e 100644 --- a/salt/common/tools/sbin/so-filebeat-stop +++ b/salt/common/tools/sbin/so-filebeat-stop @@ -1,17 +1,20 @@ #!/bin/bash - -# Copyright 2014,2015,2016,2017,2018, 2019 Security Onion Solutions, LLC - -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. # -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. +# Copyright 2014,2015,2016,2017,2018,2019,2020 Security Onion Solutions, LLC # -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -docker stop so-filebeat +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +. /usr/sbin/so-common + +/usr/sbin/so-stop filebeat $1 diff --git a/salt/common/tools/sbin/so-fleet-restart b/salt/common/tools/sbin/so-fleet-restart new file mode 100644 index 000000000..264e9f8a7 --- /dev/null +++ b/salt/common/tools/sbin/so-fleet-restart @@ -0,0 +1,20 @@ +#!/bin/bash +# +# Copyright 2014,2015,2016,2017,2018,2019,2020 Security Onion Solutions, LLC +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +. /usr/sbin/so-common + +/usr/sbin/so-restart fleet $1 diff --git a/salt/common/tools/sbin/so-fleet-start b/salt/common/tools/sbin/so-fleet-start new file mode 100644 index 000000000..06133ef58 --- /dev/null +++ b/salt/common/tools/sbin/so-fleet-start @@ -0,0 +1,20 @@ +#!/bin/bash +# +# Copyright 2014,2015,2016,2017,2018,2019,2020 Security Onion Solutions, LLC +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +. /usr/sbin/so-common + +/usr/sbin/so-start fleet $1 diff --git a/salt/common/tools/sbin/so-fleet-stop b/salt/common/tools/sbin/so-fleet-stop new file mode 100644 index 000000000..d22df4704 --- /dev/null +++ b/salt/common/tools/sbin/so-fleet-stop @@ -0,0 +1,20 @@ +#!/bin/bash +# +# Copyright 2014,2015,2016,2017,2018,2019,2020 Security Onion Solutions, LLC +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +. /usr/sbin/so-common + +/usr/sbin/so-stop fleet $1 diff --git a/salt/common/tools/sbin/so-grafana-restart b/salt/common/tools/sbin/so-grafana-restart new file mode 100644 index 000000000..52ebbacda --- /dev/null +++ b/salt/common/tools/sbin/so-grafana-restart @@ -0,0 +1,20 @@ +#!/bin/bash +# +# Copyright 2014,2015,2016,2017,2018,2019,2020 Security Onion Solutions, LLC +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +. /usr/sbin/so-common + +/usr/sbin/so-restart grafana $1 diff --git a/salt/common/tools/sbin/so-grafana-start b/salt/common/tools/sbin/so-grafana-start new file mode 100644 index 000000000..660d1d31b --- /dev/null +++ b/salt/common/tools/sbin/so-grafana-start @@ -0,0 +1,20 @@ +#!/bin/bash +# +# Copyright 2014,2015,2016,2017,2018,2019,2020 Security Onion Solutions, LLC +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +. /usr/sbin/so-common + +/usr/sbin/so-start grafana $1 diff --git a/salt/common/tools/sbin/so-grafana-stop b/salt/common/tools/sbin/so-grafana-stop new file mode 100644 index 000000000..bb0a19545 --- /dev/null +++ b/salt/common/tools/sbin/so-grafana-stop @@ -0,0 +1,20 @@ +#!/bin/bash +# +# Copyright 2014,2015,2016,2017,2018,2019,2020 Security Onion Solutions, LLC +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +. /usr/sbin/so-common + +/usr/sbin/so-stop grafana $1 diff --git a/salt/common/tools/sbin/so-kibana-restart b/salt/common/tools/sbin/so-kibana-restart new file mode 100644 index 000000000..0349348cb --- /dev/null +++ b/salt/common/tools/sbin/so-kibana-restart @@ -0,0 +1,20 @@ +#!/bin/bash +# +# Copyright 2014,2015,2016,2017,2018,2019,2020 Security Onion Solutions, LLC +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +. /usr/sbin/so-common + +/usr/sbin/so-restart kibana $1 diff --git a/salt/common/tools/sbin/so-kibana-start b/salt/common/tools/sbin/so-kibana-start new file mode 100644 index 000000000..edf7ec61f --- /dev/null +++ b/salt/common/tools/sbin/so-kibana-start @@ -0,0 +1,20 @@ +#!/bin/bash +# +# Copyright 2014,2015,2016,2017,2018,2019,2020 Security Onion Solutions, LLC +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +. /usr/sbin/so-common + +/usr/sbin/so-start kibana $1 diff --git a/salt/common/tools/sbin/so-kibana-stop b/salt/common/tools/sbin/so-kibana-stop new file mode 100644 index 000000000..007ee54d4 --- /dev/null +++ b/salt/common/tools/sbin/so-kibana-stop @@ -0,0 +1,20 @@ +#!/bin/bash +# +# Copyright 2014,2015,2016,2017,2018,2019,2020 Security Onion Solutions, LLC +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +. /usr/sbin/so-common + +/usr/sbin/so-stop kibana $1 diff --git a/salt/common/tools/sbin/so-logstash-start b/salt/common/tools/sbin/so-logstash-start new file mode 100644 index 000000000..cd2e168f4 --- /dev/null +++ b/salt/common/tools/sbin/so-logstash-start @@ -0,0 +1,20 @@ +#!/bin/bash +# +# Copyright 2014,2015,2016,2017,2018,2019,2020 Security Onion Solutions, LLC +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +. /usr/sbin/so-common + +/usr/sbin/so-start logstash $1 diff --git a/salt/common/tools/sbin/so-logstash-stop b/salt/common/tools/sbin/so-logstash-stop new file mode 100644 index 000000000..528216ca3 --- /dev/null +++ b/salt/common/tools/sbin/so-logstash-stop @@ -0,0 +1,20 @@ +#!/bin/bash +# +# Copyright 2014,2015,2016,2017,2018,2019,2020 Security Onion Solutions, LLC +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +. /usr/sbin/so-common + +/usr/sbin/so-stop logstash $1 diff --git a/salt/common/tools/sbin/so-mysql-restart b/salt/common/tools/sbin/so-mysql-restart new file mode 100644 index 000000000..1fcb885a4 --- /dev/null +++ b/salt/common/tools/sbin/so-mysql-restart @@ -0,0 +1,20 @@ +#!/bin/bash +# +# Copyright 2014,2015,2016,2017,2018,2019,2020 Security Onion Solutions, LLC +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +. /usr/sbin/so-common + +/usr/sbin/so-restart mysql $1 diff --git a/salt/common/tools/sbin/so-mysql-start b/salt/common/tools/sbin/so-mysql-start new file mode 100644 index 000000000..1a02b7658 --- /dev/null +++ b/salt/common/tools/sbin/so-mysql-start @@ -0,0 +1,20 @@ +#!/bin/bash +# +# Copyright 2014,2015,2016,2017,2018,2019,2020 Security Onion Solutions, LLC +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +. /usr/sbin/so-common + +/usr/sbin/so-start mysql $1 diff --git a/salt/common/tools/sbin/so-mysql-stop b/salt/common/tools/sbin/so-mysql-stop new file mode 100644 index 000000000..998a48ac0 --- /dev/null +++ b/salt/common/tools/sbin/so-mysql-stop @@ -0,0 +1,20 @@ +#!/bin/bash +# +# Copyright 2014,2015,2016,2017,2018,2019,2020 Security Onion Solutions, LLC +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +. /usr/sbin/so-common + +/usr/sbin/so-stop mysql $1 diff --git a/salt/common/tools/sbin/so-playbook-restart b/salt/common/tools/sbin/so-playbook-restart new file mode 100644 index 000000000..f05222eae --- /dev/null +++ b/salt/common/tools/sbin/so-playbook-restart @@ -0,0 +1,20 @@ +#!/bin/bash +# +# Copyright 2014,2015,2016,2017,2018,2019,2020 Security Onion Solutions, LLC +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +. /usr/sbin/so-common + +/usr/sbin/so-restart playbook $1 diff --git a/salt/common/tools/sbin/so-playbook-start b/salt/common/tools/sbin/so-playbook-start new file mode 100644 index 000000000..34ddf18aa --- /dev/null +++ b/salt/common/tools/sbin/so-playbook-start @@ -0,0 +1,20 @@ +#!/bin/bash +# +# Copyright 2014,2015,2016,2017,2018,2019,2020 Security Onion Solutions, LLC +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +. /usr/sbin/so-common + +/usr/sbin/so-start playbook $1 diff --git a/salt/common/tools/sbin/so-playbook-stop b/salt/common/tools/sbin/so-playbook-stop new file mode 100644 index 000000000..a1ebd7503 --- /dev/null +++ b/salt/common/tools/sbin/so-playbook-stop @@ -0,0 +1,20 @@ +#!/bin/bash +# +# Copyright 2014,2015,2016,2017,2018,2019,2020 Security Onion Solutions, LLC +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +. /usr/sbin/so-common + +/usr/sbin/so-stop playbook $1 diff --git a/salt/common/tools/sbin/so-redis-restart b/salt/common/tools/sbin/so-redis-restart new file mode 100644 index 000000000..b1e1293b8 --- /dev/null +++ b/salt/common/tools/sbin/so-redis-restart @@ -0,0 +1,20 @@ +#!/bin/bash +# +# Copyright 2014,2015,2016,2017,2018,2019,2020 Security Onion Solutions, LLC +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +. /usr/sbin/so-common + +/usr/sbin/so-restart redis $1 diff --git a/salt/common/tools/sbin/so-redis-start b/salt/common/tools/sbin/so-redis-start new file mode 100644 index 000000000..3ef2d3c01 --- /dev/null +++ b/salt/common/tools/sbin/so-redis-start @@ -0,0 +1,20 @@ +#!/bin/bash +# +# Copyright 2014,2015,2016,2017,2018,2019,2020 Security Onion Solutions, LLC +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +. /usr/sbin/so-common + +/usr/sbin/so-start redis $1 diff --git a/salt/common/tools/sbin/so-redis-stop b/salt/common/tools/sbin/so-redis-stop new file mode 100644 index 000000000..34577814c --- /dev/null +++ b/salt/common/tools/sbin/so-redis-stop @@ -0,0 +1,20 @@ +#!/bin/bash +# +# Copyright 2014,2015,2016,2017,2018,2019,2020 Security Onion Solutions, LLC +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +. /usr/sbin/so-common + +/usr/sbin/so-stop redis $1 diff --git a/salt/common/tools/sbin/so-restart b/salt/common/tools/sbin/so-restart index e07fd5010..968b7233a 100644 --- a/salt/common/tools/sbin/so-restart +++ b/salt/common/tools/sbin/so-restart @@ -20,7 +20,7 @@ . /usr/sbin/so-common echo $banner -printf "Restarting $1\n" +printf "Restarting $1...\n\nThis could take a while if another Salt job is running. \nRun this command with --force to stop all Salt jobs before proceeding.\n" echo $banner if [ "$2" = "--force" ] @@ -31,6 +31,5 @@ fi case $1 in "cortex") docker stop so-thehive-cortex so-thehive && docker rm so-thehive-cortex so-thehive && salt-call state.apply hive queue=True;; - "fleet") docker stop so-fleet so-redis && docker rm so-fleet so-redis && salt-call state.apply fleet queue=True;; - *) docker stop so-$1 && docker rm so-$1 && salt-call state.apply $1 queue=True;; + *) docker stop so-$1 ; docker rm so-$1 ; salt-call state.apply $1 queue=True;; esac diff --git a/salt/common/tools/sbin/so-soctopus-restart b/salt/common/tools/sbin/so-soctopus-restart new file mode 100644 index 000000000..144ddbf3e --- /dev/null +++ b/salt/common/tools/sbin/so-soctopus-restart @@ -0,0 +1,20 @@ +#!/bin/bash +# +# Copyright 2014,2015,2016,2017,2018,2019,2020 Security Onion Solutions, LLC +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +. /usr/sbin/so-common + +/usr/sbin/so-restart soctopus $1 diff --git a/salt/common/tools/sbin/so-soctopus-start b/salt/common/tools/sbin/so-soctopus-start new file mode 100644 index 000000000..e0d2a2a35 --- /dev/null +++ b/salt/common/tools/sbin/so-soctopus-start @@ -0,0 +1,20 @@ +#!/bin/bash +# +# Copyright 2014,2015,2016,2017,2018,2019,2020 Security Onion Solutions, LLC +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +. /usr/sbin/so-common + +/usr/sbin/so-start soctopus $1 diff --git a/salt/common/tools/sbin/so-soctopus-stop b/salt/common/tools/sbin/so-soctopus-stop new file mode 100644 index 000000000..f38eecc08 --- /dev/null +++ b/salt/common/tools/sbin/so-soctopus-stop @@ -0,0 +1,20 @@ +#!/bin/bash +# +# Copyright 2014,2015,2016,2017,2018,2019,2020 Security Onion Solutions, LLC +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +. /usr/sbin/so-common + +/usr/sbin/so-stop soctopus $1 diff --git a/salt/common/tools/sbin/so-start b/salt/common/tools/sbin/so-start index 8ad0326db..70b8d6aed 100644 --- a/salt/common/tools/sbin/so-start +++ b/salt/common/tools/sbin/so-start @@ -1 +1,36 @@ -sudo salt-call state.highstate +#!/bin/bash +# +# Copyright 2014,2015,2016,2017,2018,2019,2020 Security Onion Solutions, LLC +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# Usage: so-start all | filebeat | kibana | playbook | thehive + +. /usr/sbin/so-common + +echo $banner +printf "Starting $1...\n\nThis could take a while if another Salt job is running. \nRun this command with --force to stop all Salt jobs before proceeding.\n" +echo $banner + +if [ "$2" = "--force" ] +then + printf "\nForce-stopping all Salt jobs before proceeding\n\n" + salt-call saltutil.kill_all_jobs +fi + + +case $1 in + "all") salt-call state.highstate queue=True;; + *) if docker ps | grep -q so-$1; then printf "\n$1 is already running!\n\n"; else docker rm so-$1 >/dev/null 2>&1 ; salt-call state.apply $1 queue=True; fi +esac diff --git a/salt/common/tools/sbin/so-stop b/salt/common/tools/sbin/so-stop new file mode 100644 index 000000000..108424bb9 --- /dev/null +++ b/salt/common/tools/sbin/so-stop @@ -0,0 +1,27 @@ +#!/bin/bash +# +# Copyright 2014,2015,2016,2017,2018,2019,2020 Security Onion Solutions, LLC +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# Usage: so-stop filebeat | kibana | playbook | thehive + +. /usr/sbin/so-common + +echo $banner +printf "Stopping $1...\n" +echo $banner + +docker stop so-$1 ; docker rm so-$1 + diff --git a/salt/common/tools/sbin/so-tcpreplay b/salt/common/tools/sbin/so-tcpreplay new file mode 100755 index 000000000..69cee2f68 --- /dev/null +++ b/salt/common/tools/sbin/so-tcpreplay @@ -0,0 +1,28 @@ +#!/bin/bash +# +# Copyright 2014,2015,2016,2017,2018,2019,2020 Security Onion Solutions, LLC +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +REPLAY_ENABLED=$(docker images | grep so-tcpreplay) +REPLAY_RUNNING=$(docker ps | grep so-tcpreplay) + +if [ "$REPLAY_ENABLED" != "" ] && [ "$REPLAY_RUNNING" != "" ]; then + docker cp so-tcpreplay:/opt/samples /opt/samples + docker exec -it so-tcpreplay /usr/bin/tcpreplay -i bond0 -M10 $1 +else + echo "Replay functionality not enabled! To enable, run `so-tcpreplay-start`" + echo + echo "Note that you will need internet access to download the appropiriate components" +fi diff --git a/salt/common/tools/sbin/so-tcpreplay-restart b/salt/common/tools/sbin/so-tcpreplay-restart new file mode 100755 index 000000000..61e9016d0 --- /dev/null +++ b/salt/common/tools/sbin/so-tcpreplay-restart @@ -0,0 +1,21 @@ +#!/bin/bash +# +# Copyright 2014,2015,2016,2017,2018,2019,2020 Security Onion Solutions, LLC +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +. /usr/sbin/so-common + +/usr/sbin/so-restart tcreplay $1 + diff --git a/salt/common/tools/sbin/so-tcpreplay-start b/salt/common/tools/sbin/so-tcpreplay-start new file mode 100755 index 000000000..e6886b80c --- /dev/null +++ b/salt/common/tools/sbin/so-tcpreplay-start @@ -0,0 +1,20 @@ +#!/bin/bash +# +# Copyright 2014,2015,2016,2017,2018,2019,2020 Security Onion Solutions, LLC +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +. /usr/sbin/so-common + +/usr/sbin/so-start tcpreplay $1 diff --git a/salt/common/tools/sbin/so-tcpreplay-stop b/salt/common/tools/sbin/so-tcpreplay-stop new file mode 100755 index 000000000..d12014260 --- /dev/null +++ b/salt/common/tools/sbin/so-tcpreplay-stop @@ -0,0 +1,21 @@ +#!/bin/bash + +# Copyright 2014,2015,2016,2017,2018,2019,2020 Security Onion Solutions, LLC + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +. /usr/sbin/so-common + +/usr/sbin/so-stop tcpreplay $1 + diff --git a/salt/common/tools/sbin/so-thehive-restart b/salt/common/tools/sbin/so-thehive-restart new file mode 100644 index 000000000..4b28c0030 --- /dev/null +++ b/salt/common/tools/sbin/so-thehive-restart @@ -0,0 +1,20 @@ +#!/bin/bash +# +# Copyright 2014,2015,2016,2017,2018,2019,2020 Security Onion Solutions, LLC +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +. /usr/sbin/so-common + +/usr/sbin/so-restart thehive $1 diff --git a/salt/common/tools/sbin/so-thehive-start b/salt/common/tools/sbin/so-thehive-start new file mode 100644 index 000000000..17ec7bfaa --- /dev/null +++ b/salt/common/tools/sbin/so-thehive-start @@ -0,0 +1,20 @@ +#!/bin/bash +# +# Copyright 2014,2015,2016,2017,2018,2019,2020 Security Onion Solutions, LLC +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +. /usr/sbin/so-common + +/usr/sbin/so-start thehive $1 diff --git a/salt/common/tools/sbin/so-thehive-stop b/salt/common/tools/sbin/so-thehive-stop new file mode 100644 index 000000000..6c56e0473 --- /dev/null +++ b/salt/common/tools/sbin/so-thehive-stop @@ -0,0 +1,20 @@ +#!/bin/bash +# +# Copyright 2014,2015,2016,2017,2018,2019,2020 Security Onion Solutions, LLC +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +. /usr/sbin/so-common + +/usr/sbin/so-stop thehive $1 diff --git a/salt/common/tools/sbin/so-wazuh-start b/salt/common/tools/sbin/so-wazuh-start index 195287314..dd64354c7 100644 --- a/salt/common/tools/sbin/so-wazuh-start +++ b/salt/common/tools/sbin/so-wazuh-start @@ -14,4 +14,4 @@ # # You should have received a copy of the GNU General Public License # along with this program. If not, see . -docker rm so-wazuh && salt-call state.apply wazuh +docker stop so-wazuh diff --git a/salt/common/tools/sbin/so-zeek-restart b/salt/common/tools/sbin/so-zeek-restart new file mode 100644 index 000000000..29c50f27a --- /dev/null +++ b/salt/common/tools/sbin/so-zeek-restart @@ -0,0 +1,20 @@ +#!/bin/bash +# +# Copyright 2014,2015,2016,2017,2018,2019,2020 Security Onion Solutions, LLC +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +. /usr/sbin/so-common + +/usr/sbin/so-restart bro $1 diff --git a/salt/common/tools/sbin/so-zeek-start b/salt/common/tools/sbin/so-zeek-start new file mode 100644 index 000000000..ccd475bb6 --- /dev/null +++ b/salt/common/tools/sbin/so-zeek-start @@ -0,0 +1,20 @@ +#!/bin/bash +# +# Copyright 2014,2015,2016,2017,2018,2019,2020 Security Onion Solutions, LLC +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +. /usr/sbin/so-common + +/usr/sbin/so-start bro $1 diff --git a/salt/common/tools/sbin/so-zeek-stop b/salt/common/tools/sbin/so-zeek-stop new file mode 100644 index 000000000..1e39a2c49 --- /dev/null +++ b/salt/common/tools/sbin/so-zeek-stop @@ -0,0 +1,20 @@ +#!/bin/bash +# +# Copyright 2014,2015,2016,2017,2018,2019,2020 Security Onion Solutions, LLC +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +. /usr/sbin/so-common + +/usr/sbin/so-stop bro $1 diff --git a/salt/cyberchef/init.sls b/salt/cyberchef/init.sls index 8d33f38d5..ff258c293 100644 --- a/salt/cyberchef/init.sls +++ b/salt/cyberchef/init.sls @@ -42,13 +42,13 @@ cybercheflog: so-cyberchefimage: cmd.run: - - name: docker pull --disable-content-trust=false docker.io/soshybridhunter/so-cyberchef:HH1.1.4 + - name: docker pull --disable-content-trust=false docker.io/soshybridhunter/so-cyberchef:HH1.1.3 so-cyberchef: docker_container.running: - require: - so-cyberchefimage - - image: docker.io/soshybridhunter/so-cyberchef:HH1.1.4 + - image: docker.io/soshybridhunter/so-cyberchef:HH1.1.3 - interactive: True - binds: - /opt/so/saltstack/salt/cyberchef/build:/prod:rw diff --git a/salt/domainstats/init.sls b/salt/domainstats/init.sls new file mode 100644 index 000000000..01e673764 --- /dev/null +++ b/salt/domainstats/init.sls @@ -0,0 +1,51 @@ +# Copyright 2014,2015,2016,2017,2018,2019,2020 Security Onion Solutions, LLC + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# Create the group +dstatsgroup: + group.present: + - name: domainstats + - gid: 936 + +# Add user +domainstats: + user.present: + - uid: 936 + - gid: 936 + - home: /opt/so/conf/domainstats + - createhome: False + +# Create the log directory +dstatslogdir: + file.directory: + - name: /opt/so/log/domainstats + - user: 936 + - group: 939 + - makedirs: True + +so-domainstatsimage: + cmd.run: + - name: docker pull --disable-content-trust=false docker.io/soshybridhunter/so-domainstats:HH1.0.3 + +so-domainstats: + docker_container.running: + - require: + - so-domainstatsimage + - image: docker.io/soshybridhunter/so-domainstats:HH1.0.3 + - hostname: domainstats + - name: so-domainstats + - user: domainstats + - binds: + - /opt/so/log/domainstats:/var/log/domain_stats diff --git a/salt/elastalert/files/modules/so/thehive.py b/salt/elastalert/files/modules/so/thehive.py index 42b6f9e1d..af18b412e 100644 --- a/salt/elastalert/files/modules/so/thehive.py +++ b/salt/elastalert/files/modules/so/thehive.py @@ -1,84 +1,107 @@ # -*- coding: utf-8 -*- -from __future__ import unicode_literals +# HiveAlerter modified from original at: https://raw.githubusercontent.com/Nclose-ZA/elastalert_hive_alerter/master/elastalert_hive_alerter/hive_alerter.py + import uuid -import re from elastalert.alerts import Alerter from thehive4py.api import TheHiveApi from thehive4py.models import Alert, AlertArtifact, CustomFieldHelper + class TheHiveAlerter(Alerter): """ Use matched data to create alerts containing observables in an instance of TheHive - This is a modified version for use with Security Onion """ required_options = set(['hive_connection', 'hive_alert_config']) - def alert(self, matches): + def get_aggregation_summary_text(self, matches): + text = super(TheHiveAlerter, self).get_aggregation_summary_text(matches) + if text: + text = '```\n{0}```\n'.format(text) + return text + def create_artifacts(self, match): + artifacts = [] + context = {'rule': self.rule, 'match': match} + for mapping in self.rule.get('hive_observable_data_mapping', []): + for observable_type, match_data_key in mapping.items(): + try: + artifacts.append(AlertArtifact(dataType=observable_type, data=match_data_key.format(**context))) + except KeyError as e: + print(('format string {} fail cause no key {} in {}'.format(e, match_data_key, context))) + return artifacts + + def create_alert_config(self, match): + context = {'rule': self.rule, 'match': match} + alert_config = { + 'artifacts': self.create_artifacts(match), + 'sourceRef': str(uuid.uuid4())[0:6], + 'title': '{rule[name]}'.format(**context) + } + + alert_config.update(self.rule.get('hive_alert_config', {})) + + for alert_config_field, alert_config_value in alert_config.items(): + if alert_config_field == 'customFields': + custom_fields = CustomFieldHelper() + for cf_key, cf_value in alert_config_value.items(): + try: + func = getattr(custom_fields, 'add_{}'.format(cf_value['type'])) + except AttributeError: + raise Exception('unsupported custom field type {}'.format(cf_value['type'])) + value = cf_value['value'].format(**context) + func(cf_key, value) + alert_config[alert_config_field] = custom_fields.build() + elif isinstance(alert_config_value, str): + alert_config[alert_config_field] = alert_config_value.format(**context) + elif isinstance(alert_config_value, (list, tuple)): + formatted_list = [] + for element in alert_config_value: + try: + formatted_list.append(element.format(**context)) + except (AttributeError, KeyError, IndexError): + formatted_list.append(element) + alert_config[alert_config_field] = formatted_list + + return alert_config + + def send_to_thehive(self, alert_config): connection_details = self.rule['hive_connection'] - api = TheHiveApi( - connection_details.get('hive_host'), + connection_details.get('hive_host', ''), connection_details.get('hive_apikey', ''), proxies=connection_details.get('hive_proxies', {'http': '', 'https': ''}), cert=connection_details.get('hive_verify', False)) - for match in matches: - context = {'rule': self.rule, 'match': match} + alert = Alert(**alert_config) + response = api.create_alert(alert) + if response.status_code != 201: + raise Exception('alert not successfully created in TheHive\n{}'.format(response.text)) + + def alert(self, matches): + if self.rule.get('hive_alert_config_type', 'custom') != 'classic': + for match in matches: + alert_config = self.create_alert_config(match) + self.send_to_thehive(alert_config) + else: + alert_config = self.create_alert_config(matches[0]) artifacts = [] - for mapping in self.rule.get('hive_observable_data_mapping', []): - for observable_type, match_data_key in mapping.items(): - try: - match_data_keys = re.findall(r'\{match\[([^\]]*)\]', match_data_key) - rule_data_keys = re.findall(r'\{rule\[([^\]]*)\]', match_data_key) - data_keys = match_data_keys + rule_data_keys - context_keys = list(context['match'].keys()) + list(context['rule'].keys()) - if all([True if k in context_keys else False for k in data_keys]): - artifacts.append(AlertArtifact(dataType=observable_type, data=match_data_key.format(**context))) - except KeyError: - raise KeyError('\nformat string\n{}\nmatch data\n{}'.format(match_data_key, context)) + for match in matches: + artifacts += self.create_artifacts(match) + if 'related_events' in match: + for related_event in match['related_events']: + artifacts += self.create_artifacts(related_event) - alert_config = { - 'artifacts': artifacts, - 'sourceRef': str(uuid.uuid4())[0:6], - 'title': '{rule[index]}_{rule[name]}'.format(**context) - } - alert_config.update(self.rule.get('hive_alert_config', {})) - - for alert_config_field, alert_config_value in alert_config.items(): - if alert_config_field == 'customFields': - custom_fields = CustomFieldHelper() - for cf_key, cf_value in alert_config_value.items(): - try: - func = getattr(custom_fields, 'add_{}'.format(cf_value['type'])) - except AttributeError: - raise Exception('unsupported custom field type {}'.format(cf_value['type'])) - value = cf_value['value'].format(**context) - func(cf_key, value) - alert_config[alert_config_field] = custom_fields.build() - elif isinstance(alert_config_value, str): - alert_config[alert_config_field] = alert_config_value.format(**context) - elif isinstance(alert_config_value, (list, tuple)): - formatted_list = [] - for element in alert_config_value: - try: - formatted_list.append(element.format(**context)) - except (AttributeError, KeyError, IndexError): - formatted_list.append(element) - alert_config[alert_config_field] = formatted_list - - alert = Alert(**alert_config) - response = api.create_alert(alert) - - if response.status_code != 201: - raise Exception('alert not successfully created in TheHive\n{}'.format(response.text)) + alert_config['artifacts'] = artifacts + alert_config['title'] = self.create_title(matches) + alert_config['description'] = self.create_alert_body(matches) + self.send_to_thehive(alert_config) def get_info(self): return { 'type': 'hivealerter', 'hive_host': self.rule.get('hive_connection', {}).get('hive_host', '') - } + } diff --git a/salt/elasticsearch/init.sls b/salt/elasticsearch/init.sls index e9d4b863f..94543a57b 100644 --- a/salt/elasticsearch/init.sls +++ b/salt/elasticsearch/init.sls @@ -1,4 +1,4 @@ -# Copyright 2014,2015,2016,2017,2018 Security Onion Solutions, LLC +# Copyright 2014,2015,2016,2017,2018,2019,2020 Security Onion Solutions, LLC # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -18,22 +18,16 @@ {% set esclustername = salt['pillar.get']('master:esclustername', '') %} {% set esheap = salt['pillar.get']('master:esheap', '') %} -{% set freq = salt['pillar.get']('master:freq', '0') %} -{% set dstats = salt['pillar.get']('master:dstats', '0') %} {% elif grains['role'] == 'so-eval' %} {% set esclustername = salt['pillar.get']('master:esclustername', '') %} {% set esheap = salt['pillar.get']('master:esheap', '') %} -{% set freq = salt['pillar.get']('master:freq', '0') %} -{% set dstats = salt['pillar.get']('master:dstats', '0') %} {% elif grains['role'] == 'so-node' %} {% set esclustername = salt['pillar.get']('node:esclustername', '') %} {% set esheap = salt['pillar.get']('node:esheap', '') %} -{% set freq = salt['pillar.get']('node:freq', '0') %} -{% set dstats = salt['pillar.get']('node:dstats', '0') %} {% endif %} diff --git a/salt/filebeat/etc/filebeat.yml b/salt/filebeat/etc/filebeat.yml index 0da9b68bc..4706e4c5a 100644 --- a/salt/filebeat/etc/filebeat.yml +++ b/salt/filebeat/etc/filebeat.yml @@ -3,6 +3,7 @@ {%- set BROVER = salt['pillar.get']('static:broversion', 'COMMUNITY') %} {%- set WAZUHENABLED = salt['pillar.get']('static:wazuh_enabled', '1') %} {%- set FLEETENABLED = salt['pillar.get']('static:fleet_enabled', '1') %} +{%- set STRELKAENABLED = salt['pillar.get']('static:strelka_enabled', '1') %} name: {{ HOSTNAME }} @@ -126,6 +127,19 @@ filebeat.prospectors: clean_removed: false close_removed: false +{%- endif %} + +{%- if STRELKAENABLED == '1' %} + + - type: log + paths: + - /opt/so/log/strelka/strelka.log + fields: + type: strelka + fields_under_root: true + clean_removed: false + close_removed: false + {%- endif %} #----------------------------- Logstash output --------------------------------- output.logstash: diff --git a/salt/filebeat/init.sls b/salt/filebeat/init.sls index 46d6bd780..1a59446b3 100644 --- a/salt/filebeat/init.sls +++ b/salt/filebeat/init.sls @@ -1,4 +1,4 @@ -# Copyright 2014,2015,2016,2017,2018 Security Onion Solutions, LLC + # Copyright 2014,2015,2016,2017,2018 Security Onion Solutions, LLC # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by diff --git a/salt/freqserver/init.sls b/salt/freqserver/init.sls new file mode 100644 index 000000000..783d11b6a --- /dev/null +++ b/salt/freqserver/init.sls @@ -0,0 +1,52 @@ +# Copyright 2014,2015,2016,2017,2018,2019,2020 Security Onion Solutions, LLC + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# Create the user +fservergroup: + group.present: + - name: freqserver + - gid: 935 + +# Add ES user +freqserver: + user.present: + - uid: 935 + - gid: 935 + - home: /opt/so/conf/freqserver + - createhome: False + +# Create the log directory +freqlogdir: + file.directory: + - name: /opt/so/log/freq_server + - user: 935 + - group: 935 + - makedirs: True + +so-freqimage: + cmd.run: + - name: docker pull --disable-content-trust=false docker.io/soshybridhunter/so-freqserver:HH1.0.3 + +so-freq: + docker_container.running: + - require: + - so-freqimage + - image: docker.io/soshybridhunter/so-freqserver:HH1.0.3 + - hostname: freqserver + - name: so-freqserver + - user: freqserver + - binds: + - /opt/so/log/freq_server:/var/log/freq_server:rw + diff --git a/salt/hive/thehive/scripts/hive_init.sh b/salt/hive/thehive/scripts/hive_init.sh index f726ae229..6c5168a66 100755 --- a/salt/hive/thehive/scripts/hive_init.sh +++ b/salt/hive/thehive/scripts/hive_init.sh @@ -16,7 +16,7 @@ hive_init(){ COUNT=0 HIVE_CONNECTED="no" while [[ "$COUNT" -le 240 ]]; do - curl --output /dev/null --silent --head --fail "https://$HIVE_IP:/thehive" + curl --output /dev/null --silent --head --fail -k "https://$HIVE_IP:/thehive" if [ $? -eq 0 ]; then HIVE_CONNECTED="yes" echo "connected!" diff --git a/salt/logstash/conf/conf.enabled.txt.storage b/salt/logstash/conf/conf.enabled.txt.search similarity index 100% rename from salt/logstash/conf/conf.enabled.txt.storage rename to salt/logstash/conf/conf.enabled.txt.search diff --git a/salt/playbook/files/redmine.db b/salt/playbook/files/redmine.db index 7d84b5856..52f171833 100644 Binary files a/salt/playbook/files/redmine.db and b/salt/playbook/files/redmine.db differ diff --git a/salt/strelka/files/backend/backend.yaml b/salt/strelka/files/backend/backend.yaml new file mode 100644 index 000000000..40ea1b5b3 --- /dev/null +++ b/salt/strelka/files/backend/backend.yaml @@ -0,0 +1,423 @@ +{%- set ip = salt['pillar.get']('static:masterip', '') %} +logging_cfg: '/etc/strelka/logging.yaml' +limits: + max_files: 5000 + time_to_live: 900 + max_depth: 15 + distribution: 600 + scanner: 150 +coordinator: + addr: '{{ ip }}:6380' + db: 0 +tasting: + mime_db: null + yara_rules: '/etc/strelka/taste/' +scanners: + 'ScanBase64': + - positive: + filename: '^base64_' + priority: 5 + 'ScanBatch': + - positive: + flavors: + - 'text/x-msdos-batch' + - 'batch_file' + priority: 5 + 'ScanBzip2': + - positive: + flavors: + - 'application/x-bzip2' + - 'bzip2_file' + priority: 5 + 'ScanDocx': + - positive: + flavors: + - 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' + priority: 5 + options: + extract_text: False + 'ScanElf': + - positive: + flavors: + - 'application/x-object' + - 'application/x-executable' + - 'application/x-sharedlib' + - 'application/x-coredump' + - 'elf_file' + priority: 5 + 'ScanEmail': + - positive: + flavors: + - 'application/vnd.ms-outlook' + - 'message/rfc822' + - 'email_file' + priority: 5 + 'ScanEntropy': + - positive: + flavors: + - '*' + priority: 5 + 'ScanExiftool': + - positive: + flavors: + - 'application/msword' + - 'application/vnd.openxmlformats-officedocument' + - 'application/vnd.openxmlformats-officedocument.presentationml.presentation' + - 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' + - 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' + - 'olecf_file' + - 'ooxml_file' + - 'audio/mpeg' + - 'mp3_file' + - 'mhtml_file' + - 'application/pdf' + - 'pdf_file' + - 'text/rtf' + - 'rtf_file' + - 'wordml_file' + - 'application/x-dosexec' + - 'mz_file' + - 'application/x-object' + - 'application/x-executable' + - 'application/x-sharedlib' + - 'application/x-coredump' + - 'elf_file' + - 'lnk_file' + - 'application/x-mach-binary' + - 'macho_file' + - 'image/gif' + - 'gif_file' + - 'image/jpeg' + - 'jpeg_file' + - 'image/png' + - 'png_file' + - 'image/tiff' + - 'type_is_tiff' + - 'image/x-ms-bmp' + - 'bmp_file' + - 'application/x-shockwave-flash' + - 'fws_file' + - 'psd_file' + - 'video/mp4' + - 'video/quicktime' + - 'video/x-msvideo' + - 'avi_file' + - 'video/x-ms-wmv' + - 'wmv_file' + priority: 5 + options: + tmp_directory: '/dev/shm/' + 'ScanGif': + - positive: + flavors: + - 'image/gif' + - 'gif_file' + priority: 5 + 'ScanGzip': + - positive: + flavors: + - 'application/gzip' + - 'application/x-gzip' + - 'gzip_file' + priority: 5 + 'ScanHash': + - positive: + flavors: + - '*' + priority: 5 + 'ScanHeader': + - positive: + flavors: + - '*' + priority: 5 + options: + length: 50 + 'ScanHtml': + - positive: + flavors: + - 'hta_file' + - 'text/html' + - 'html_file' + priority: 5 + options: + parser: "html5lib" + 'ScanIni': + - positive: + filename: '(\.([Cc][Ff][Gg]|[Ii][Nn][Ii])|PROJECT)$' + flavors: + - 'ini_file' + priority: 5 + 'ScanJarManifest': + - positive: + flavors: + - 'jar_manifest_file' + priority: 5 + 'ScanJavascript': + - negative: + flavors: + - 'text/html' + - 'html_file' + positive: + flavors: + - 'javascript_file' + - 'text/javascript' + priority: 5 + options: + beautify: True + 'ScanJpeg': + - positive: + flavors: + - 'image/jpeg' + - 'jpeg_file' + priority: 5 + 'ScanJson': + - positive: + flavors: + - 'application/json' + - 'json_file' + priority: 5 + 'ScanLibarchive': + - positive: + flavors: + - 'application/vnd.ms-cab-compressed' + - 'cab_file' + - 'application/x-7z-compressed' + - '_7zip_file' + - 'application/x-cpio' + - 'cpio_file' + - 'application/x-xar' + - 'xar_file' + - 'arj_file' + - 'iso_file' + - 'application/x-debian-package' + - 'debian_package_file' + priority: 5 + options: + limit: 1000 + 'ScanLzma': + - positive: + flavors: + - 'application/x-lzma' + - 'lzma_file' + - 'application/x-xz' + - 'xz_file' + priority: 5 + 'ScanMacho': + - positive: + flavors: + - 'application/x-mach-binary' + - 'macho_file' + priority: 5 + options: + tmp_directory: '/dev/shm/' + 'ScanMmbot': + - positive: + flavors: + - 'vb_file' + - 'vbscript' + priority: 5 + options: + server: 'strelka_mmrpc_1:33907' + 'ScanOcr': + - positive: + flavors: + - 'image/jpeg' + - 'jpeg_file' + - 'image/png' + - 'png_file' + - 'image/tiff' + - 'type_is_tiff' + - 'image/x-ms-bmp' + - 'bmp_file' + priority: 5 + options: + extract_text: False + tmp_directory: '/dev/shm/' + 'ScanOle': + - positive: + flavors: + - 'application/CDFV2' + - 'application/msword' + - 'olecf_file' + priority: 5 + 'ScanPdf': + - positive: + flavors: + - 'application/pdf' + - 'pdf_file' + priority: 5 + options: + extract_text: False + limit: 2000 + 'ScanPe': + - positive: + flavors: + - 'application/x-dosexec' + - 'mz_file' + priority: 5 + 'ScanPgp': + - positive: + flavors: + - 'application/pgp-keys' + - 'pgp_file' + priority: 5 + 'ScanPhp': + - positive: + flavors: + - 'text/x-php' + - 'php_file' + priority: 5 + 'ScanPkcs7': + - positive: + flavors: + - 'pkcs7_file' + priority: 5 + options: + tmp_directory: '/dev/shm/' + 'ScanPlist': + - positive: + flavors: + - 'bplist_file' + - 'plist_file' + priority: 5 + options: + keys: + - 'KeepAlive' + - 'Label' + - 'NetworkState' + - 'Program' + - 'ProgramArguments' + - 'RunAtLoad' + - 'StartInterval' + 'ScanRar': + - positive: + flavors: + - 'application/x-rar' + - 'rar_file' + priority: 5 + options: + limit: 1000 + 'ScanRpm': + - positive: + flavors: + - 'application/x-rpm' + - 'rpm_file' + priority: 5 + options: + tmp_directory: '/dev/shm/' + 'ScanRtf': + - positive: + flavors: + - 'text/rtf' + - 'rtf_file' + priority: 5 + options: + limit: 1000 + 'ScanRuby': + - positive: + flavors: + - 'text/x-ruby' + priority: 5 + 'ScanSwf': + - positive: + flavors: + - 'application/x-shockwave-flash' + - 'fws_file' + - 'cws_file' + - 'zws_file' + priority: 5 + 'ScanTar': + - positive: + flavors: + - 'application/x-tar' + - 'tar_file' + priority: 5 + options: + limit: 1000 + 'ScanTnef': + - positive: + flavors: + - 'application/vnd.ms-tnef' + - 'tnef_file' + priority: 5 + 'ScanUpx': + - positive: + flavors: + - 'upx_file' + priority: 5 + options: + tmp_directory: '/dev/shm/' + 'ScanUrl': + - negative: + flavors: + - 'javascript_file' + positive: + flavors: + - 'text/plain' + priority: 5 + 'ScanVb': + - positive: + flavors: + - 'vb_file' + - 'vbscript' + priority: 5 + 'ScanVba': + - positive: + flavors: + - 'mhtml_file' + - 'application/msword' + - 'olecf_file' + - 'wordml_file' + priority: 5 + options: + analyze_macros: True + 'ScanX509': + - positive: + flavors: + - 'x509_der_file' + priority: 5 + options: + type: 'der' + - positive: + flavors: + - 'x509_pem_file' + priority: 5 + options: + type: 'pem' + 'ScanXml': + - positive: + flavors: + - 'application/xml' + - 'text/xml' + - 'xml_file' + - 'mso_file' + - 'soap_file' + priority: 5 + 'ScanYara': + - positive: + flavors: + - '*' + priority: 5 + options: + location: '/etc/yara/' + 'ScanZip': + - positive: + flavors: + - 'application/java-archive' + - 'application/zip' + - 'zip_file' + - 'application/vnd.openxmlformats-officedocument' + - 'application/vnd.openxmlformats-officedocument.presentationml.presentation' + - 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' + - 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' + - 'ooxml_file' + priority: 5 + options: + limit: 1000 + password_file: '/etc/strelka/passwords.dat' + 'ScanZlib': + - positive: + flavors: + - 'application/zlib' + - 'zlib_file' + priority: 5 diff --git a/salt/strelka/files/backend/logging.yaml b/salt/strelka/files/backend/logging.yaml new file mode 100644 index 000000000..b21d3c396 --- /dev/null +++ b/salt/strelka/files/backend/logging.yaml @@ -0,0 +1,78 @@ +version: 1 +formatters: + simple: + format: '%(asctime)s - [%(levelname)s] %(name)s [%(module)s.%(funcName)s]: %(message)s' + datefmt: '%Y-%m-%d %H:%M:%S' +handlers: + console: + class: logging.StreamHandler + formatter: simple + stream: ext://sys.stdout +root: + level: DEBUG + handlers: [console] +loggers: + OpenSSL: + propagate: 0 + bs4: + propagate: 0 + bz2: + propagate: 0 + chardet: + propagate: 0 + docx: + propagate: 0 + elftools: + propagate: 0 + email: + propagate: 0 + entropy: + propagate: 0 + esprima: + propagate: 0 + gzip: + propagate: 0 + hashlib: + propagate: 0 + json: + propagate: 0 + libarchive: + propagate: 0 + lxml: + propagate: 0 + lzma: + propagate: 0 + macholibre: + propagate: 0 + olefile: + propagate: 0 + oletools: + propagate: 0 + pdfminer: + propagate: 0 + pefile: + propagate: 0 + pgpdump: + propagate: 0 + pygments: + propagate: 0 + pylzma: + propagate: 0 + rarfile: + propagate: 0 + requests: + propagate: 0 + rpmfile: + propagate: 0 + ssdeep: + propagate: 0 + tarfile: + propagate: 0 + tnefparse: + propagate: 0 + yara: + propagate: 0 + zipfile: + propagate: 0 + zlib: + propagate: 0 diff --git a/salt/strelka/files/backend/passwords.dat b/salt/strelka/files/backend/passwords.dat new file mode 100644 index 000000000..e9541f540 --- /dev/null +++ b/salt/strelka/files/backend/passwords.dat @@ -0,0 +1,2 @@ +infected +password diff --git a/salt/strelka/files/backend/taste/taste.yara b/salt/strelka/files/backend/taste/taste.yara new file mode 100644 index 000000000..15d2dffbb --- /dev/null +++ b/salt/strelka/files/backend/taste/taste.yara @@ -0,0 +1,748 @@ +// Archive Files + +rule _7zip_file +{ + meta: + type = "archive" + strings: + $a = { 37 7A BC AF 27 1C } + condition: + $a at 0 +} + +rule arj_file +{ + meta: + type = "archive" + condition: + uint16(0) == 0xEA60 +} + +rule cab_file +{ + meta: + type = "archive" + strings: + $a = { 4D 53 43 46 00 00 00 00 } + condition: + $a at 0 or + ( uint16(0) == 0x5A4D and $a ) +} + +rule cpio_file +{ + meta: + type = "archive" + strings: + $a = { 30 37 30 37 30 31 } + condition: + $a at 0 +} + +rule iso_file +{ + meta: + type = "archive" + strings: + $a = { 43 44 30 30 31 } + condition: + $a at 0x8001 and $a at 0x8801 and $a at 0x9001 +} + +rule mhtml_file +{ + meta: + type = "archive" + strings: + $a = "MIME-Version: 1.0" + $b = "This document is a Single File Web Page, also known as a Web Archive file" + condition: + $a at 0 and $b +} + +rule rar_file +{ + meta: + type = "archive" + condition: + uint16(0) == 0x6152 and uint8(2) == 0x72 and uint16(3) == 0x1A21 and uint8(5) == 0x07 +} + +rule tar_file +{ + meta: + type = "archive" + strings: + $a = { 75 73 74 61 72 } + condition: + uint16(0) == 0x9D1F or + uint16(0) == 0xA01F or + $a at 257 +} + +rule xar_file +{ + meta: + type = "archive" + condition: + uint32(0) == 0x21726178 +} + +rule zip_file +{ + meta: + type = "archive" + condition: + ( uint32(0) == 0x04034B50 and not uint32(4) == 0x00060014 ) +} + +// Audio Files + +rule mp3_file +{ + meta: + type = "audio" + condition: + uint16(0) == 0x4449 and uint8(2) == 0x33 +} + +// Certificate Files + +rule pkcs7_file +{ + meta: + type = "certificate" + strings: + $a = "-----BEGIN PKCS7-----" + condition: + (uint16(0) == 0x8230 and uint16(4) == 0x0906) or + uint32(0) == 0x09068030 or + $a at 0 +} + +rule x509_der_file +{ + meta: + type = "certificate" + condition: + uint16(0) == 0x8230 and ( uint16(4) == 0x8230 or uint16(4) == 0x8130 ) +} + +rule x509_pem_file +{ + meta: + type = "certificate" + strings: + $a = "-----BEGIN CERTI" + condition: + $a at 0 +} + +// Compressed Files + +rule bzip2_file +{ + meta: + type = "compressed" + condition: + uint16(0) == 0x5A42 and uint8(2) == 0x68 +} + +rule gzip_file +{ + meta: + type = "compressed" + condition: + uint16(0) == 0x8B1F and uint8(2) == 0x08 +} + +rule lzma_file +{ + meta: + type = "compressed" + condition: + uint16(0) == 0x005D and uint8(2) == 0x00 +} + +rule xz_file +{ + meta: + type = "compressed" + condition: + uint32(0) == 0x587A37FD and uint16(4) == 0x005A +} + +// Document Files + +rule doc_subheader_file +{ + meta: + type = "document" + condition: + uint32(0) == 0x00C1A5EC +} + +rule mso_file +{ + meta: + type = "document" + strings: + $a = { 3C 3F 6D 73 6F 2D 61 70 70 6C 69 63 61 74 69 6F 6E 20 } // + condition: + $a at 0 or + $b at 0 or + $c at 0 or + $d at 0 or + $e at 0 or + $f at 0 or + $g at 0 or + $h at 0 or + $i at 0 or + $j at 0 or + $k at 0 or + $l at 0 or + $m at 0 or + $n at 0 +} + +rule json_file +{ + meta: + type = "text" + strings: + $a = { 7B [0-5] 22 } + condition: + $a at 0 +} + +rule php_file +{ + meta: + type = "text" + strings: + $a = { 3c 3f 70 68 70 } + condition: + $a at 0 +} + +rule soap_file +{ + meta: + description = "Simple Object Access Protocol" + type = "text" + strings: + $a = { 3C 73 6F 61 70 65 6E 76 3A 45 6E 76 65 6C 6F 70 65 } // + $c = { 3C 73 74 79 6C 65 53 68 65 65 74 20 78 6D 6C 6E 73 3D } // . +{%- set MASTER = grains['master'] %} +{%- set MASTERIP = salt['pillar.get']('static:masterip', '') %} + +# Strelka config +strelkaconfdir: + file.directory: + - name: /opt/so/conf/strelka + - user: 939 + - group: 939 + - makedirs: True + +# Strelka logs +strelkalogdir: + file.directory: + - name: /opt/so/log/strelka + - user: 939 + - group: 939 + - makedirs: True + +# Sync dynamic config to conf dir +strelkasync: + file.recurse: + - name: /opt/so/conf/strelka/ + - source: salt://strelka/files + - user: 939 + - group: 939 + - template: jinja + +strelkadatadir: + file.directory: + - name: /nsm/strelka + - user: 939 + - group: 939 + - makedirs: True + +strelkastagedir: + file.directory: + - name: /nsm/strelka/processed + - user: 939 + - group: 939 + - makedirs: True + + +so-strelka-frontendimage: + cmd.run: + - name: docker pull --disable-content-trust=false docker.io/soshybridhunter/so-strelka-frontend:HH1.1.5 + +so-strelka-coordinatorimage: + cmd.run: + - name: docker pull --disable-content-trust=false docker.io/redis:5.0.5-alpine3.10 + +so-strelka-gatekeeperimage: + cmd.run: + - name: docker pull --disable-content-trust=false docker.io/redis:5.0.5-alpine3.10 + +so-strelka-backendimage: + cmd.run: + - name: docker pull --disable-content-trust=false docker.io/soshybridhunter/so-strelka-backend:HH1.1.5 + +so-strelka-managerimage: + cmd.run: + - name: docker pull --disable-content-trust=false docker.io/soshybridhunter/so-strelka-manager:HH1.1.5 + +so-strelka-backendimage: + cmd.run: + - name: docker pull --disable-content-trust=false docker.io/soshybridhunter/so-strelka-backend:HH1.1.5 + + +strelka_coordinator: + docker_container.running: + - require: + - so-strelka-coordinatorimage + - image: docker.io/redis:5.0.5-alpine3.10 + - name: so-strelka-coordinator + - command: redis-server --save "" --appendonly no + - port_bindings: + - 0.0.0.0:6380:6379 + +strelka_gatekeeper: + docker_container.running: + - require: + - so-strelka-gatekeeperimage + - image: docker.io/redis:5.0.5-alpine3.10 + - name: so-strelka-gatekeeper + - command: redis-server --save "" --appendonly no --maxmemory-policy allkeys-lru + - port_bindings: + - 0.0.0.0:6381:6379 + +strelka_frontend: + docker_container.running: + - require: + - so-strelka-frontendimage + - image: docker.io/soshybridhunter/so-strelka-frontend:HH1.1.5 + - binds: + - /opt/so/conf/strelka/frontend/:/etc/strelka/:ro + - /opt/so/log/strelka/:/var/log/strelka/:rw + - privileged: True + - name: so-strelka-frontend + - command: strelka-frontend + - port_bindings: + - 0.0.0.0:57314:57314 + +strelka_backend: + docker_container.running: + - require: + - so-strelka-backendimage + - image: docker.io/soshybridhunter/so-strelka-backend:HH1.1.5 + - restart_policy: unless-stopped + - binds: + - /opt/so/conf/strelka/backend/:/etc/strelka/:ro + - /opt/so/conf/strelka/backend/yara:/etc/yara/:ro + - name: so-strelka-backend + - command: strelka-backend + +strelka_manager: + docker_container.running: + - require: + - so-strelka-managerimage + - image: docker.io/soshybridhunter/so-strelka-manager:HH1.1.5 + - binds: + - /opt/so/conf/strelka/manager/:/etc/strelka/:ro + - name: so-strelka-manager + - command: strelka-manager + +strelka_filestream: + docker_container.running: + - require: + - so-strelka-filestreamimage + - image: docker.io/soshybridhunter/so-strelka-filestream:HH1.1.5 + - image: docker.io/wlambert/sfilestream:grpc + - binds: + - /opt/so/conf/strelka/filestream/:/etc/strelka/:ro + - /nsm/strelka:/nsm/strelka + - name: so-strelka-filestream + - command: strelka-filestream diff --git a/salt/suricata/files/threshold.conf.jinja b/salt/suricata/files/threshold.conf.jinja new file mode 100644 index 000000000..45642404a --- /dev/null +++ b/salt/suricata/files/threshold.conf.jinja @@ -0,0 +1,36 @@ +{% set THRESHOLDING = salt['pillar.get']('thresholding', {}) -%} + +{% if THRESHOLDING -%} + + {% for EACH_SID in THRESHOLDING.sids -%} + {% for ACTIONS_LIST in THRESHOLDING.sids[EACH_SID] -%} + {% for EACH_ACTION in ACTIONS_LIST -%} + + {%- if EACH_ACTION == 'threshold' %} +{{ EACH_ACTION }} gen_id {{ ACTIONS_LIST[EACH_ACTION].gen_id }}, sig_id {{ EACH_SID }}, type {{ ACTIONS_LIST[EACH_ACTION].type }}, track {{ ACTIONS_LIST[EACH_ACTION].track }}, count {{ ACTIONS_LIST[EACH_ACTION].count }}, seconds {{ ACTIONS_LIST[EACH_ACTION].seconds }} + + {%- elif EACH_ACTION == 'rate_filter' %} + {%- if ACTIONS_LIST[EACH_ACTION].new_action not in ['drop','reject'] %} +{{ EACH_ACTION }} gen_id {{ ACTIONS_LIST[EACH_ACTION].gen_id }}, sig_id {{ EACH_SID }}, track {{ ACTIONS_LIST[EACH_ACTION].track }}, count {{ ACTIONS_LIST[EACH_ACTION].count }}, seconds {{ ACTIONS_LIST[EACH_ACTION].seconds }}, new_action {{ ACTIONS_LIST[EACH_ACTION].new_action }}, timeout {{ ACTIONS_LIST[EACH_ACTION].timeout }} + {%- else %} +##### Security Onion does not support drop or reject actions for rate_filter +##### {{ EACH_ACTION }} gen_id {{ ACTIONS_LIST[EACH_ACTION].gen_id }}, sig_id {{ EACH_SID }}, track {{ ACTIONS_LIST[EACH_ACTION].track }}, count {{ ACTIONS_LIST[EACH_ACTION].count }}, seconds {{ ACTIONS_LIST[EACH_ACTION].seconds }}, new_action {{ ACTIONS_LIST[EACH_ACTION].new_action }}, timeout {{ ACTIONS_LIST[EACH_ACTION].timeout }} + {%- endif %} + + {%- elif EACH_ACTION == 'suppress' %} + {%- if ACTIONS_LIST[EACH_ACTION].track is defined %} +{{ EACH_ACTION }} gen_id {{ ACTIONS_LIST[EACH_ACTION].gen_id }}, sig_id {{ EACH_SID }}, track {{ ACTIONS_LIST[EACH_ACTION].track }}, ip {{ ACTIONS_LIST[EACH_ACTION].ip }} + {%- else %} +{{ EACH_ACTION }} gen_id {{ ACTIONS_LIST[EACH_ACTION].gen_id }}, sig_id {{ EACH_SID }} + {%- endif %} + + {%- endif %} + + {%- endfor %} + {%- endfor %} + {%- endfor %} + +{%- else %} +##### The thresholding pillar has not been defined + +{%- endif %} diff --git a/salt/suricata/init.sls b/salt/suricata/init.sls index fee02d760..6f08c2704 100644 --- a/salt/suricata/init.sls +++ b/salt/suricata/init.sls @@ -72,6 +72,14 @@ suriconfigsync: - group: 940 - template: jinja +surithresholding: + file.managed: + - name: /opt/so/conf/suricata/threshold.conf + - source: salt://suricata/files/threshold.conf.jinja + - user: 940 + - group: 940 + - template: jinja + so-suricata: docker_container.running: - image: {{ MASTER }}:5000/soshybridhunter/so-suricata:HH{{ VERSION }} @@ -80,9 +88,11 @@ so-suricata: - INTERFACE={{ interface }} - binds: - /opt/so/conf/suricata/suricata.yaml:/etc/suricata/suricata.yaml:ro + - /opt/so/conf/suricata/threshold.conf:/etc/suricata/threshold.conf:ro - /opt/so/conf/suricata/rules:/etc/suricata/rules:ro - /opt/so/log/suricata/:/var/log/suricata/:rw - network_mode: host - watch: - file: /opt/so/conf/suricata/suricata.yaml + - file: surithresholding - file: /opt/so/conf/suricata/rules/ diff --git a/salt/top.sls b/salt/top.sls index 78a39f328..42c26185d 100644 --- a/salt/top.sls +++ b/salt/top.sls @@ -4,6 +4,9 @@ {%- set GRAFANA = salt['pillar.get']('master:grafana', '0') -%} {%- set THEHIVE = salt['pillar.get']('master:thehive', '0') -%} {%- set PLAYBOOK = salt['pillar.get']('master:playbook', '0') -%} +{%- set FREQSERVER = salt['pillar.get']('master:freq', '0') -%} +{%- set DOMAINSTATS = salt['pillar.get']('master:domainstats', '0') -%} + base: '*': - patch.os.schedule @@ -49,6 +52,7 @@ base: - sensoroni - firewall - idstools + - auth {%- if OSQUERY != 0 %} - mysql {%- endif %} @@ -78,7 +82,12 @@ base: {%- if PLAYBOOK != 0 %} - playbook {%- endif %} - + {%- if FREQSERVER != 0 %} + - freqserver + {%- endif %} + {%- if DOMAINSTATS != 0 %} + - domainstats + {%- endif %} 'G@role:so-master': @@ -115,7 +124,12 @@ base: {%- if PLAYBOOK != 0 %} - playbook {%- endif %} - + {%- if FREQSERVER != 0 %} + - freqserver + {%- endif %} + {%- if DOMAINSTATS != 0 %} + - domainstats + {%- endif %} # Search node logic diff --git a/salt/wazuh/files/agent/ossec.conf b/salt/wazuh/files/agent/ossec.conf index 5b02910f9..2a7fe6d6b 100644 --- a/salt/wazuh/files/agent/ossec.conf +++ b/salt/wazuh/files/agent/ossec.conf @@ -179,12 +179,17 @@ syslog /var/ossec/logs/active-responses.log - +{%- if grains['os'] == 'Ubuntu' %} syslog /var/log/auth.log - +{%- else %} + + syslog + /var/log/secure + +{%- endif %} syslog /var/log/syslog diff --git a/salt/wazuh/files/agent/wazuh-register-agent b/salt/wazuh/files/agent/wazuh-register-agent index 4197a5334..12ab7dc8a 100755 --- a/salt/wazuh/files/agent/wazuh-register-agent +++ b/salt/wazuh/files/agent/wazuh-register-agent @@ -31,6 +31,7 @@ USER="foo" PASSWORD="bar" AGENT_NAME=$(hostname) AGENT_IP="{{ip}}" +AGENT_ID=001 display_help() { cat < try to register the agent sleep 10s -register_agent +STATUS=$(curl -s -k -u $USER:$PASSWORD $PROTOCOL://$API_IP:$API_PORT/agents/$AGENT_ID | jq .data.status | sed s'/"//g') +if [[ $STATUS == "Active" ]]; then + echo "Agent $AGENT_ID already registered!" +else + register_agent +fi #remove_agent diff --git a/salt/wazuh/files/wazuh-manager-whitelist b/salt/wazuh/files/wazuh-manager-whitelist new file mode 100644 index 000000000..0cf675f5c --- /dev/null +++ b/salt/wazuh/files/wazuh-manager-whitelist @@ -0,0 +1,33 @@ +{%- set MASTERIP = salt['pillar.get']('static:masterip', '') %} +#!/bin/bash +# +# Copyright 2014,2015,2016,2017,2018,2019,2020 Security Onion Solutions, LLC +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# Check if Wazuh enabled +if grep -q -R "wazuh: 1" /opt/so/saltstack/pillar/*; then + WAZUH_MGR_CFG="/opt/so/wazuh/etc/ossec.conf" + if ! grep -q "{{ MASTERIP }}" $WAZUH_MGR_CFG ; then + DATE=`date` + sed -i 's/<\/ossec_config>//' $WAZUH_MGR_CFG + sed -i '/^$/N;/^\n$/D' $WAZUH_MGR_CFG + echo -e "\n \n {{ MASTERIP }}\n \n" >> $WAZUH_MGR_CFG + echo "Added whitelist entry for {{ MASTERIP }} in $WAZUH_MGR_CFG." + echo + echo "Restarting OSSEC Server..." + /usr/sbin/so-wazuh-restart + fi +fi + diff --git a/salt/wazuh/init.sls b/salt/wazuh/init.sls index cb1f79b56..9623c29ac 100644 --- a/salt/wazuh/init.sls +++ b/salt/wazuh/init.sls @@ -63,6 +63,15 @@ wazuhagentregister: - mode: 755 - template: jinja +wazuhmgrwhitelist: + file.managed: + - name: /usr/sbin/wazuh-manager-whitelist + - source: salt://wazuh/files/wazuh-manager-whitelist + - user: 0 + - group: 0 + - mode: 755 + - template: jinja + so-wazuh: docker_container.running: - image: {{ MASTER }}:5000/soshybridhunter/so-wazuh:HH{{ VERSION }} @@ -82,3 +91,9 @@ registertheagent: - name: /usr/sbin/wazuh-register-agent - cwd: / #- stateful: True + +# Whitelist manager IP +whitelistmanager: + cmd.run: + - name: /usr/sbin/wazuh-manager-whitelist + - cwd: / diff --git a/setup/functions.sh b/setup/functions.sh index 9db6f4a9f..a13ce5475 100644 --- a/setup/functions.sh +++ b/setup/functions.sh @@ -270,9 +270,9 @@ copy_minion_tmp_files() { if [ $INSTALLTYPE == 'MASTERONLY' ] || [ $INSTALLTYPE == 'EVALMODE' ] || [ $INSTALLTYPE == 'HELIXSENSOR' ]; then echo "Copying pillar and salt files in $TMP to /opt/so/saltstack" - cp -Rv $TMP/pillar/ /opt/so/saltstack/pillar/ >> $SETUPLOG 2>&1 + cp -Rv $TMP/pillar/ /opt/so/saltstack/ >> $SETUPLOG 2>&1 if [ -d $TMP/salt ] ; then - cp -Rv $TMP/salt/ /opt/so/saltstack/salt/ >> $SETUPLOG 2>&1 + cp -Rv $TMP/salt/ /opt/so/saltstack/ >> $SETUPLOG 2>&1 fi else echo "scp pillar and salt files in $TMP to master /opt/so/saltstack" @@ -602,7 +602,8 @@ got_root() { install_cleanup() { - echo "install_cleanup called" >> $SETUPLOG 2>&1 + echo "install_cleanup removing the following files:" + ls -lR $TMP # Clean up after ourselves rm -rf /root/installtmp @@ -613,6 +614,8 @@ install_prep() { # Create a tmp space that isn't in /tmp mkdir /root/installtmp + mkdir /root/installtmp/pillar + mkdir /root/installtmp/pillar/minions TMP=/root/installtmp } @@ -652,47 +655,50 @@ ls_heapsize() { master_pillar() { + PILLARFILE=$TMP/pillar/minions/$MINION_ID.sls + # Create the master pillar - touch /opt/so/saltstack/pillar/masters/$MINION_ID.sls - echo "master:" > /opt/so/saltstack/pillar/masters/$MINION_ID.sls - echo " mainip: $MAINIP" >> /opt/so/saltstack/pillar/masters/$MINION_ID.sls - echo " mainint: $MAININT" >> /opt/so/saltstack/pillar/masters/$MINION_ID.sls - echo " esheap: $ES_HEAP_SIZE" >> /opt/so/saltstack/pillar/masters/$MINION_ID.sls - echo " esclustername: {{ grains.host }}" >> /opt/so/saltstack/pillar/masters/$MINION_ID.sls + echo "master:" >> $PILLARFILE + echo " mainip: $MAINIP" >> $PILLARFILE + echo " mainint: $MAININT" >> $PILLARFILE + echo " esheap: $ES_HEAP_SIZE" >> $PILLARFILE + echo " esclustername: {{ grains.host }}" >> $PILLARFILE if [ $INSTALLTYPE == 'EVALMODE' ] || [ $INSTALLTYPE == 'HELIXSENSOR' ]; then - echo " freq: 0" >> /opt/so/saltstack/pillar/masters/$MINION_ID.sls - echo " domainstats: 0" >> /opt/so/saltstack/pillar/masters/$MINION_ID.sls - echo " ls_pipeline_batch_size: 125" >> /opt/so/saltstack/pillar/masters/$MINION_ID.sls - echo " ls_input_threads: 1" >> /opt/so/saltstack/pillar/masters/$MINION_ID.sls - echo " ls_batch_count: 125" >> /opt/so/saltstack/pillar/masters/$MINION_ID.sls - echo " mtu: 1500" >> /opt/so/saltstack/pillar/masters/$MINION_ID.sls + echo " freq: 0" >> $PILLARFILE + echo " domainstats: 0" >> $PILLARFILE + echo " ls_pipeline_batch_size: 125" >> $PILLARFILE + echo " ls_input_threads: 1" >> $PILLARFILE + echo " ls_batch_count: 125" >> $PILLARFILE + echo " mtu: 1500" >> $PILLARFILE else - echo " freq: 0" >> /opt/so/saltstack/pillar/masters/$MINION_ID.sls - echo " domainstats: 0" >> /opt/so/saltstack/pillar/masters/$MINION_ID.sls + echo " freq: 0" >> $PILLARFILE + echo " domainstats: 0" >> $PILLARFILE fi if [ $INSTALLTYPE == 'HELIXSENSOR' ]; then - echo " lsheap: 1000m" >> /opt/so/saltstack/pillar/masters/$MINION_ID.sls + echo " lsheap: 1000m" >> $PILLARFILE else - echo " lsheap: $LS_HEAP_SIZE" >> /opt/so/saltstack/pillar/masters/$MINION_ID.sls + echo " lsheap: $LS_HEAP_SIZE" >> $PILLARFILE fi - echo " lsaccessip: 127.0.0.1" >> /opt/so/saltstack/pillar/masters/$MINION_ID.sls - echo " elastalert: 1" >> /opt/so/saltstack/pillar/masters/$MINION_ID.sls - echo " ls_pipeline_workers: $CPUCORES" >> /opt/so/saltstack/pillar/masters/$MINION_ID.sls - echo " nids_rules: $RULESETUP" >> /opt/so/saltstack/pillar/masters/$MINION_ID.sls - echo " oinkcode: $OINKCODE" >> /opt/so/saltstack/pillar/masters/$MINION_ID.sls - #echo " access_key: $ACCESS_KEY" >> /opt/so/saltstack/pillar/masters/$MINION_ID.sls - #echo " access_secret: $ACCESS_SECRET" >> /opt/so/saltstack/pillar/masters/$MINION_ID.sls - echo " es_port: $NODE_ES_PORT" >> /opt/so/saltstack/pillar/masters/$MINION_ID.sls - echo " log_size_limit: $LOG_SIZE_LIMIT" >> /opt/so/saltstack/pillar/masters/$MINION_ID.sls - echo " cur_close_days: $CURCLOSEDAYS" >> /opt/so/saltstack/pillar/masters/$MINION_ID.sls - #echo " mysqlpass: $MYSQLPASS" >> /opt/so/saltstack/pillar/masters/$MINION_ID.sls - #echo " fleetpass: $FLEETPASS" >> /opt/so/saltstack/pillar/masters/$MINION_ID.sls - echo " grafana: $GRAFANA" >> /opt/so/saltstack/pillar/masters/$MINION_ID.sls - echo " osquery: $OSQUERY" >> /opt/so/saltstack/pillar/masters/$MINION_ID.sls - echo " wazuh: $WAZUH" >> /opt/so/saltstack/pillar/masters/$MINION_ID.sls - echo " thehive: $THEHIVE" >> /opt/so/saltstack/pillar/masters/$MINION_ID.sls - echo " playbook: $PLAYBOOK" >> /opt/so/saltstack/pillar/masters/$MINION_ID.sls + echo " lsaccessip: 127.0.0.1" >> $PILLARFILE + echo " elastalert: 1" >> $PILLARFILE + echo " ls_pipeline_workers: $CPUCORES" >> $PILLARFILE + echo " nids_rules: $RULESETUP" >> $PILLARFILE + echo " oinkcode: $OINKCODE" >> $PILLARFILE + #echo " access_key: $ACCESS_KEY" >> $PILLARFILE + #echo " access_secret: $ACCESS_SECRET" >> $PILLARFILE + echo " es_port: $NODE_ES_PORT" >> $PILLARFILE + echo " log_size_limit: $LOG_SIZE_LIMIT" >> $PILLARFILE + echo " cur_close_days: $CURCLOSEDAYS" >> $PILLARFILE + #echo " mysqlpass: $MYSQLPASS" >> $PILLARFILE + #echo " fleetpass: $FLEETPASS" >> $PILLARFILE + echo " grafana: $GRAFANA" >> $PILLARFILE + echo " osquery: $OSQUERY" >> $PILLARFILE + echo " wazuh: $WAZUH" >> $PILLARFILE + echo " thehive: $THEHIVE" >> $PILLARFILE + echo " playbook: $PLAYBOOK" >> $PILLARFILE + echo "" >> $PILLARFILE + } master_static() { @@ -753,53 +759,39 @@ network_setup() { node_pillar() { - NODEPILLARPATH=$TMP/pillar/nodes - if [ ! -d $NODEPILLARPATH ]; then - mkdir -p $NODEPILLARPATH - fi + PILLARFILE=$TMP/pillar/minions/$MINION_ID.sls # Create the node pillar - touch $NODEPILLARPATH/$MINION_ID.sls - echo "node:" > $NODEPILLARPATH/$MINION_ID.sls - echo " mainip: $MAINIP" >> $NODEPILLARPATH/$MINION_ID.sls - echo " mainint: $MAININT" >> $NODEPILLARPATH/$MINION_ID.sls - echo " esheap: $NODE_ES_HEAP_SIZE" >> $NODEPILLARPATH/$MINION_ID.sls - echo " esclustername: {{ grains.host }}" >> $NODEPILLARPATH/$MINION_ID.sls - echo " lsheap: $NODE_LS_HEAP_SIZE" >> $NODEPILLARPATH/$MINION_ID.sls - echo " ls_pipeline_workers: $LSPIPELINEWORKERS" >> $NODEPILLARPATH/$MINION_ID.sls - echo " ls_pipeline_batch_size: $LSPIPELINEBATCH" >> $NODEPILLARPATH/$MINION_ID.sls - echo " ls_input_threads: $LSINPUTTHREADS" >> $NODEPILLARPATH/$MINION_ID.sls - echo " ls_batch_count: $LSINPUTBATCHCOUNT" >> $NODEPILLARPATH/$MINION_ID.sls - echo " es_shard_count: $SHARDCOUNT" >> $NODEPILLARPATH/$MINION_ID.sls - echo " node_type: $NODETYPE" >> $NODEPILLARPATH/$MINION_ID.sls - echo " es_port: $NODE_ES_PORT" >> $NODEPILLARPATH/$MINION_ID.sls - echo " log_size_limit: $LOG_SIZE_LIMIT" >> $NODEPILLARPATH/$MINION_ID.sls - echo " cur_close_days: $CURCLOSEDAYS" >> $NODEPILLARPATH/$MINION_ID.sls + echo "node:" >> $PILLARFILE + echo " mainip: $MAINIP" >> $PILLARFILE + echo " mainint: $MAININT" >> $PILLARFILE + echo " esheap: $NODE_ES_HEAP_SIZE" >> $PILLARFILE + echo " esclustername: {{ grains.host }}" >> $PILLARFILE + echo " lsheap: $NODE_LS_HEAP_SIZE" >> $PILLARFILE + echo " ls_pipeline_workers: $LSPIPELINEWORKERS" >> $PILLARFILE + echo " ls_pipeline_batch_size: $LSPIPELINEBATCH" >> $PILLARFILE + echo " ls_input_threads: $LSINPUTTHREADS" >> $PILLARFILE + echo " ls_batch_count: $LSINPUTBATCHCOUNT" >> $PILLARFILE + echo " es_shard_count: $SHARDCOUNT" >> $PILLARFILE + echo " node_type: $NODETYPE" >> $PILLARFILE + echo " es_port: $NODE_ES_PORT" >> $PILLARFILE + echo " log_size_limit: $LOG_SIZE_LIMIT" >> $PILLARFILE + echo " cur_close_days: $CURCLOSEDAYS" >> $PILLARFILE + echo "" >> $PILLARFILE } patch_pillar() { - case $INSTALLTYPE in - MASTERONLY | EVALMODE | HELIXSENSOR) - PATCHPILLARPATH=/opt/so/saltstack/pillar/masters - ;; - SENSORONLY) - PATCHPILLARPATH=$SENSORPILLARPATH - ;; - SEARCHNODE | PARSINGNODE | HOTNODE | WARMNODE) - PATCHPILLARPATH=$NODEPILLARPATH - ;; - esac - - - echo "" >> $PATCHPILLARPATH/$MINION_ID.sls - echo "patch:" >> $PATCHPILLARPATH/$MINION_ID.sls - echo " os:" >> $PATCHPILLARPATH/$MINION_ID.sls - echo " schedule_name: $PATCHSCHEDULENAME" >> $PATCHPILLARPATH/$MINION_ID.sls - echo " enabled: True" >> $PATCHPILLARPATH/$MINION_ID.sls - echo " splay: 300" >> $PATCHPILLARPATH/$MINION_ID.sls + PILLARFILE=$TMP/pillar/minions/$MINION_ID.sls + echo "" >> $PILLARFILE + echo "patch:" >> $PILLARFILE + echo " os:" >> $PILLARFILE + echo " schedule_name: $PATCHSCHEDULENAME" >> $PILLARFILE + echo " enabled: True" >> $PILLARFILE + echo " splay: 300" >> $PILLARFILE + echo "" >> $PILLARFILE } @@ -1163,51 +1155,44 @@ salt_install_mysql_deps() { } sensor_pillar() { - if [ $INSTALLTYPE == 'HELIXSENSOR' ]; then - SENSORPILLARPATH=/opt/so/saltstack/pillar/sensors - mkdir -p $TMP - mkdir -p $SENSORPILLARPATH - else - SENSORPILLARPATH=$TMP/pillar/sensors - fi - if [ ! -d $SENSORPILLARPATH ]; then - mkdir -p $SENSORPILLARPATH - fi + + PILLARFILE=$TMP/pillar/minions/$MINION_ID.sls # Create the sensor pillar - touch $SENSORPILLARPATH/$MINION_ID.sls - echo "sensor:" > $SENSORPILLARPATH/$MINION_ID.sls - echo " interface: bond0" >> $SENSORPILLARPATH/$MINION_ID.sls - echo " mainip: $MAINIP" >> $SENSORPILLARPATH/$MINION_ID.sls - echo " mainint: $MAININT" >> $SENSORPILLARPATH/$MINION_ID.sls + touch $PILLARFILE + echo "sensor:" >> $PILLARFILE + echo " interface: bond0" >> $PILLARFILE + echo " mainip: $MAINIP" >> $PILLARFILE + echo " mainint: $MAININT" >> $PILLARFILE if [ $NSMSETUP == 'ADVANCED' ]; then - echo " bro_pins:" >> $SENSORPILLARPATH/$MINION_ID.sls + echo " bro_pins:" >> $PILLARFILE for PIN in $BROPINS; do PIN=$(echo $PIN | cut -d\" -f2) - echo " - $PIN" >> $SENSORPILLARPATH/$MINION_ID.sls + echo " - $PIN" >> $PILLARFILE done - echo " suripins:" >> $SENSORPILLARPATH/$MINION_ID.sls + echo " suripins:" >> $PILLARFILE for SPIN in $SURIPINS; do SPIN=$(echo $SPIN | cut -d\" -f2) - echo " - $SPIN" >> $SENSORPILLARPATH/$MINION_ID.sls + echo " - $SPIN" >> $PILLARFILE done elif [ $INSTALLTYPE == 'HELIXSENSOR' ]; then - echo " bro_lbprocs: $LBPROCS" >> $SENSORPILLARPATH/$MINION_ID.sls - echo " suriprocs: $LBPROCS" >> $SENSORPILLARPATH/$MINION_ID.sls + echo " bro_lbprocs: $LBPROCS" >> $PILLARFILE + echo " suriprocs: $LBPROCS" >> $PILLARFILE else - echo " bro_lbprocs: $BASICBRO" >> $SENSORPILLARPATH/$MINION_ID.sls - echo " suriprocs: $BASICSURI" >> $SENSORPILLARPATH/$MINION_ID.sls + echo " bro_lbprocs: $BASICBRO" >> $PILLARFILE + echo " suriprocs: $BASICSURI" >> $PILLARFILE fi - echo " brobpf:" >> $SENSORPILLARPATH/$MINION_ID.sls - echo " pcapbpf:" >> $SENSORPILLARPATH/$MINION_ID.sls - echo " nidsbpf:" >> $SENSORPILLARPATH/$MINION_ID.sls - echo " master: $MSRV" >> $SENSORPILLARPATH/$MINION_ID.sls - echo " mtu: $MTU" >> $SENSORPILLARPATH/$MINION_ID.sls + echo " brobpf:" >> $PILLARFILE + echo " pcapbpf:" >> $PILLARFILE + echo " nidsbpf:" >> $PILLARFILE + echo " master: $MSRV" >> $PILLARFILE + echo " mtu: $MTU" >> $PILLARFILE if [ $HNSENSOR != 'inherit' ]; then - echo " hnsensor: $HNSENSOR" >> $SENSORPILLARPATH/$MINION_ID.sls + echo " hnsensor: $HNSENSOR" >> $PILLARFILE fi - echo " access_key: $ACCESS_KEY" >> $SENSORPILLARPATH/$MINION_ID.sls - echo " access_secret: $ACCESS_SECRET" >> $SENSORPILLARPATH/$MINION_ID.sls + echo " access_key: $ACCESS_KEY" >> $PILLARFILE + echo " access_secret: $ACCESS_SECRET" >> $PILLARFILE + echo "" >> $PILLARFILE } diff --git a/setup/so-setup.sh b/setup/so-setup.sh index 53e5ad0bd..6059c5dd9 100644 --- a/setup/so-setup.sh +++ b/setup/so-setup.sh @@ -663,6 +663,7 @@ if (whiptail_you_sure) ; then echo -e "XXX\n95\nSetting checkin to run on boot... \nXXX" checkin_at_boot >> $SETUPLOG 2>&1 echo -e "XX\n97\nFinishing touches... \nXXX" + salt-call state.apply auth >> $SETUPLOG 2>&1 filter_unused_nics >> $SETUPLOG 2>&1 network_setup >> $SETUPLOG 2>&1 echo -e "XXX\n98\nVerifying Setup... \nXXX" diff --git a/setup/whiptail.sh b/setup/whiptail.sh index 2d48e890c..a3bee17ea 100644 --- a/setup/whiptail.sh +++ b/setup/whiptail.sh @@ -90,7 +90,7 @@ whiptail_cancel() { whiptail --title "Security Onion Setup" --msgbox "Cancelling Setup. No changes have been made." 8 75 if [ -d "/root/installtmp" ]; then echo "/root/installtmp exists" >> $SETUPLOG 2>&1 - install_cleanup + install_cleanup >> $SETUPLOG 2>&1 echo "/root/installtmp removed" >> $SETUPLOG 2>&1 fi exit @@ -685,14 +685,14 @@ whiptail_set_hostname() { whiptail_setup_complete() { whiptail --title "Security Onion Setup" --msgbox "Finished installing this as an $INSTALLTYPE. Press Enter to reboot." 8 75 - install_cleanup + install_cleanup >> $SETUPLOG 2>&1 } whiptail_setup_failed() { whiptail --title "Security Onion Setup" --msgbox "Install had a problem. Please see $SETUPLOG for details. Press Enter to reboot." 8 75 - install_cleanup + install_cleanup >> $SETUPLOG 2>&1 }