From 60d284518584dc59c24f2828559894c2d78bf801 Mon Sep 17 00:00:00 2001 From: Mike Reeves Date: Wed, 7 Aug 2019 13:49:43 -0400 Subject: [PATCH 01/73] 1.1.0 updates --- salt/bro/cron/packetloss.sh | 2 +- salt/common/tools/sbin/{so-brologs => so-bro-logs} | 0 salt/common/tools/sbin/{so-getparsed => so-get-parsed} | 0 salt/common/tools/sbin/{so-getunparsed => so-get-unparsed} | 0 salt/common/tools/sbin/{so-listindex => so-list-index} | 0 salt/sensoroni/init.sls | 4 ++-- 6 files changed, 3 insertions(+), 3 deletions(-) rename salt/common/tools/sbin/{so-brologs => so-bro-logs} (100%) rename salt/common/tools/sbin/{so-getparsed => so-get-parsed} (100%) rename salt/common/tools/sbin/{so-getunparsed => so-get-unparsed} (100%) rename salt/common/tools/sbin/{so-listindex => so-list-index} (100%) diff --git a/salt/bro/cron/packetloss.sh b/salt/bro/cron/packetloss.sh index 56dc7b771..22013cbc6 100644 --- a/salt/bro/cron/packetloss.sh +++ b/salt/bro/cron/packetloss.sh @@ -1,2 +1,2 @@ #!/bin/bash -/usr/bin/docker exec so-bro /opt/bro/bin/broctl netstats | awk -F '[ =]' '{RCVD += $5;DRP += $7;TTL += $9} END { print "rcvd: " RCVD, "dropped: " DRP, "total: " TTL}' >> /nsm/bro/logs/packetloss.log +/usr/bin/docker exec so-bro /opt/bro/bin/broctl netstats | awk '{print $(NF-2),$(NF-1),$NF}' | awk -F '[ =]' '{RCVD += $2;DRP += $4;TTL += $6} END { print "rcvd: " RCVD, "dropped: " DRP, "total: " TTL}' diff --git a/salt/common/tools/sbin/so-brologs b/salt/common/tools/sbin/so-bro-logs similarity index 100% rename from salt/common/tools/sbin/so-brologs rename to salt/common/tools/sbin/so-bro-logs diff --git a/salt/common/tools/sbin/so-getparsed b/salt/common/tools/sbin/so-get-parsed similarity index 100% rename from salt/common/tools/sbin/so-getparsed rename to salt/common/tools/sbin/so-get-parsed diff --git a/salt/common/tools/sbin/so-getunparsed b/salt/common/tools/sbin/so-get-unparsed similarity index 100% rename from salt/common/tools/sbin/so-getunparsed rename to salt/common/tools/sbin/so-get-unparsed diff --git a/salt/common/tools/sbin/so-listindex b/salt/common/tools/sbin/so-list-index similarity index 100% rename from salt/common/tools/sbin/so-listindex rename to salt/common/tools/sbin/so-list-index diff --git a/salt/sensoroni/init.sls b/salt/sensoroni/init.sls index 9c6cf1906..2c06ba7a8 100644 --- a/salt/sensoroni/init.sls +++ b/salt/sensoroni/init.sls @@ -29,13 +29,13 @@ sensoronisync: so-sensoroniimage: cmd.run: - - name: docker pull --disable-content-trust=false soshybridhunter/so-sensoroni:HH1.1.0 + - name: docker pull --disable-content-trust=false soshybridhunter/so-sensoroni:HH1.1.1 so-sensoroni: docker_container.running: - require: - so-sensoroniimage - - image: soshybridhunter/so-sensoroni:HH1.1.0 + - image: soshybridhunter/so-sensoroni:HH1.1.1 - hostname: sensoroni - name: so-sensoroni - binds: From 4e41a8ef0a82941befa5771814c2942a9712a861 Mon Sep 17 00:00:00 2001 From: Mike Reeves Date: Wed, 7 Aug 2019 14:53:40 -0400 Subject: [PATCH 02/73] Bro Module - Fix version to 1.1.0 --- salt/bro/init.sls | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/salt/bro/init.sls b/salt/bro/init.sls index 734255536..f406558be 100644 --- a/salt/bro/init.sls +++ b/salt/bro/init.sls @@ -125,13 +125,13 @@ localbrosync: so-broimage: cmd.run: - - name: docker pull --disable-content-trust=false soshybridhunter/so-bro:HH1.1.0 + - name: docker pull --disable-content-trust=false soshybridhunter/so-bro:HH1.1.1 so-bro: docker_container.running: - require: - so-broimage - - image: soshybridhunter/so-bro:HH1.1.0 + - image: soshybridhunter/so-bro:HH1.1.1 - privileged: True - binds: - /nsm/bro/logs:/nsm/bro/logs:rw From 7688691dbcb9d46d5fbfc2497f1e545a211d8aed Mon Sep 17 00:00:00 2001 From: Mike Reeves Date: Wed, 7 Aug 2019 15:00:22 -0400 Subject: [PATCH 03/73] Bro Module - redirect packet loss to file --- salt/bro/cron/packetloss.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/salt/bro/cron/packetloss.sh b/salt/bro/cron/packetloss.sh index 22013cbc6..744fd09f4 100644 --- a/salt/bro/cron/packetloss.sh +++ b/salt/bro/cron/packetloss.sh @@ -1,2 +1,2 @@ #!/bin/bash -/usr/bin/docker exec so-bro /opt/bro/bin/broctl netstats | awk '{print $(NF-2),$(NF-1),$NF}' | awk -F '[ =]' '{RCVD += $2;DRP += $4;TTL += $6} END { print "rcvd: " RCVD, "dropped: " DRP, "total: " TTL}' +/usr/bin/docker exec so-bro /opt/bro/bin/broctl netstats | awk '{print $(NF-2),$(NF-1),$NF}' | awk -F '[ =]' '{RCVD += $2;DRP += $4;TTL += $6} END { print "rcvd: " RCVD, "dropped: " DRP, "total: " TTL}' >> /nsm/bro/logs/packetloss.log From e36b178e1c844d68322f6ed3809cc806045a932d Mon Sep 17 00:00:00 2001 From: Mike Reeves Date: Tue, 13 Aug 2019 09:27:38 -0400 Subject: [PATCH 04/73] Filebeat Module - Change logging to error --- salt/filebeat/etc/filebeat.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/salt/filebeat/etc/filebeat.yml b/salt/filebeat/etc/filebeat.yml index 67fd596c5..748d6658f 100644 --- a/salt/filebeat/etc/filebeat.yml +++ b/salt/filebeat/etc/filebeat.yml @@ -187,7 +187,7 @@ output.logstash: # Sets log level. The default log level is info. # Available log levels are: error, warning, info, debug -logging.level: debug +logging.level: error # Enable debug output for selected components. To enable all selectors use ["*"] # Other available selectors are "beat", "publish", "service" From a9f592a53bd774c251d08c370968afb953007651 Mon Sep 17 00:00:00 2001 From: Mike Reeves Date: Tue, 13 Aug 2019 09:37:41 -0400 Subject: [PATCH 05/73] Filebeat Module - Move logging to the top --- salt/filebeat/etc/filebeat.yml | 105 +++++++++++++++++---------------- 1 file changed, 53 insertions(+), 52 deletions(-) diff --git a/salt/filebeat/etc/filebeat.yml b/salt/filebeat/etc/filebeat.yml index 748d6658f..7089f85ea 100644 --- a/salt/filebeat/etc/filebeat.yml +++ b/salt/filebeat/etc/filebeat.yml @@ -6,6 +6,59 @@ name: {{ HOSTNAME }} +#================================ Logging ====================================== +# There are four options for the log output: file, stderr, syslog, eventlog +# The file output is the default. + +# Sets log level. The default log level is info. +# Available log levels are: error, warning, info, debug +logging.level: error + +# Enable debug output for selected components. To enable all selectors use ["*"] +# Other available selectors are "beat", "publish", "service" +# Multiple selectors can be chained. +#logging.selectors: [ ] + +# Send all logging output to syslog. The default is false. +#logging.to_syslog: false + +# Send all logging output to Windows Event Logs. The default is false. +#logging.to_eventlog: false + +# If enabled, filebeat periodically logs its internal metrics that have changed +# in the last period. For each metric that changed, the delta from the value at +# the beginning of the period is logged. Also, the total values for +# all non-zero internal metrics are logged on shutdown. The default is true. +#logging.metrics.enabled: true + +# The period after which to log the internal metrics. The default is 30s. +#logging.metrics.period: 30s + +# Logging to rotating files. Set logging.to_files to false to disable logging to +# files. +logging.to_files: true +logging.files: + # Configure the path where the logs are written. The default is the logs directory + # under the home path (the binary location). + path: /var/log/filebeat + + # The name of the files where the logs are written to. + name: filebeat.log + + # Configure log file size limit. If limit is reached, log file will be + # automatically rotated + rotateeverybytes: 10485760 # = 10MB + + # Number of rotated log files to keep. Oldest files will be deleted first. + keepfiles: 7 + + # The permissions mask to apply when rotating log files. The default value is 0600. + # Must be a valid Unix-style file permissions mask expressed in octal notation. + #permissions: 0600 + +# Set to true to log messages in json format. +#logging.json: false + #========================== Modules configuration ============================ filebeat.modules: #=========================== Filebeat prospectors ============================= @@ -181,58 +234,6 @@ output.logstash: -#================================ Logging ====================================== -# There are four options for the log output: file, stderr, syslog, eventlog -# The file output is the default. - -# Sets log level. The default log level is info. -# Available log levels are: error, warning, info, debug -logging.level: error - -# Enable debug output for selected components. To enable all selectors use ["*"] -# Other available selectors are "beat", "publish", "service" -# Multiple selectors can be chained. -#logging.selectors: [ ] - -# Send all logging output to syslog. The default is false. -#logging.to_syslog: false - -# Send all logging output to Windows Event Logs. The default is false. -#logging.to_eventlog: false - -# If enabled, filebeat periodically logs its internal metrics that have changed -# in the last period. For each metric that changed, the delta from the value at -# the beginning of the period is logged. Also, the total values for -# all non-zero internal metrics are logged on shutdown. The default is true. -#logging.metrics.enabled: true - -# The period after which to log the internal metrics. The default is 30s. -#logging.metrics.period: 30s - -# Logging to rotating files. Set logging.to_files to false to disable logging to -# files. -logging.to_files: true -logging.files: - # Configure the path where the logs are written. The default is the logs directory - # under the home path (the binary location). - path: /var/log/filebeat - - # The name of the files where the logs are written to. - name: filebeat.log - - # Configure log file size limit. If limit is reached, log file will be - # automatically rotated - rotateeverybytes: 10485760 # = 10MB - - # Number of rotated log files to keep. Oldest files will be deleted first. - keepfiles: 7 - - # The permissions mask to apply when rotating log files. The default value is 0600. - # Must be a valid Unix-style file permissions mask expressed in octal notation. - #permissions: 0600 - -# Set to true to log messages in json format. -#logging.json: false #============================== Xpack Monitoring ===================================== From 5ca2db8407c0b46f57d6c8fd732d67317dc757d9 Mon Sep 17 00:00:00 2001 From: Mike Reeves Date: Tue, 13 Aug 2019 10:07:40 -0400 Subject: [PATCH 06/73] Filebeat Module - Create Log dir to fix permissions --- salt/filebeat/init.sls | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/salt/filebeat/init.sls b/salt/filebeat/init.sls index f14e71772..e7c707bc7 100644 --- a/salt/filebeat/init.sls +++ b/salt/filebeat/init.sls @@ -23,6 +23,13 @@ filebeatetcdir: - group: 939 - makedirs: True +filebeatlogdir: + file.directory: + - name: /opt/so/log/filebeat + - user: 939 + - group: 939 + - makedirs: True + filebeatpkidir: file.directory: - name: /opt/so/conf/filebeat/etc/pki From f1ae2617c2ef4a88b472d2790d72608212b9c26f Mon Sep 17 00:00:00 2001 From: Mike Reeves Date: Wed, 14 Aug 2019 08:44:54 -0400 Subject: [PATCH 07/73] Filebeat Module - Change log dir mapping --- salt/filebeat/etc/filebeat.yml | 2 +- salt/filebeat/init.sls | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/salt/filebeat/etc/filebeat.yml b/salt/filebeat/etc/filebeat.yml index 7089f85ea..51a751105 100644 --- a/salt/filebeat/etc/filebeat.yml +++ b/salt/filebeat/etc/filebeat.yml @@ -40,7 +40,7 @@ logging.to_files: true logging.files: # Configure the path where the logs are written. The default is the logs directory # under the home path (the binary location). - path: /var/log/filebeat + #path: /var/log/filebeat # The name of the files where the logs are written to. name: filebeat.log diff --git a/salt/filebeat/init.sls b/salt/filebeat/init.sls index e7c707bc7..b7597730c 100644 --- a/salt/filebeat/init.sls +++ b/salt/filebeat/init.sls @@ -69,7 +69,7 @@ so-filebeat: - user: root - extra_hosts: {{ MASTER }}:{{ MASTERIP }} - binds: - - /opt/so/log/filebeat:/var/log/filebeat:rw + - /opt/so/log/filebeat:/usr/share/filebeat/logs:rw - /opt/so/conf/filebeat/etc/filebeat.yml:/usr/share/filebeat/filebeat.yml:ro - /nsm/bro:/nsm/bro:ro - /opt/so/log/suricata:/suricata:ro From 8dbb5de55dbb420fc3bffe3468ade46df11027eb Mon Sep 17 00:00:00 2001 From: William Wernert Date: Wed, 14 Aug 2019 12:09:03 -0400 Subject: [PATCH 08/73] Preliminary fix for packet capture loss Interface offloading was not being turned off during setup --- install_scripts/disable-checksum-offload.sh | 9 +++++++++ so-setup-network.sh | 11 ++++++++--- 2 files changed, 17 insertions(+), 3 deletions(-) create mode 100644 install_scripts/disable-checksum-offload.sh diff --git a/install_scripts/disable-checksum-offload.sh b/install_scripts/disable-checksum-offload.sh new file mode 100644 index 000000000..0af7bdbf9 --- /dev/null +++ b/install_scripts/disable-checksum-offload.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +if [ "$NM_DISPATCHER_ACTION" == "pre-up" ]; then + if ["$DEVICE_IFACE" !== "$MAININT"]; then + for i in rx tx sg tso ufo gso gro lro; do + ethtool -K $DEVICE_IFACE $i off; + done + fii +fi \ No newline at end of file diff --git a/so-setup-network.sh b/so-setup-network.sh index 24a1ddf5b..a12259011 100644 --- a/so-setup-network.sh +++ b/so-setup-network.sh @@ -246,15 +246,15 @@ copy_ssh_key() { } -create_bond_nmcli() { +network_setup() { echo "Setting up Bond" >> $SETUPLOG 2>&1 # Set the MTU - if [ $NSMSETUP != 'ADVANCED' ]; then + if [ "$NSMSETUP" != 'ADVANCED' ]; then MTU=1500 fi -# Create the bond interface + # Create the bond interface nmcli con add ifname bond0 con-name "bond0" type bond mode 0 -- \ ipv4.method disabled \ ipv6.method link-local \ @@ -271,6 +271,11 @@ create_bond_nmcli() { # Bring the slave interface up nmcli con up bond0-slave-$BONDNIC >> $SETUPLOG 2>&1 done + + sed -i "s/\$MAININT/${MAININT}/g" ./install_scripts/disable-checksum-offload.sh >> $SETUPLOG 2>&1 + + # Copy the checksum offload script to prevent issues with packet capture + cp ./install_scripts/disable-checksum-offload.sh /etc/NetworkManager/dispatcher.d/disable-checksum-offload.sh >> $SETUPLOG 2>&1 } detect_os() { From 75ab90d5e8b58ce4714fe0b113bedec1c2d33e92 Mon Sep 17 00:00:00 2001 From: William Wernert Date: Wed, 14 Aug 2019 12:24:23 -0400 Subject: [PATCH 09/73] Further fixes for network offloading --- install_scripts/disable-checksum-offload.sh | 2 +- so-setup-network.sh | 39 +++++++++++---------- 2 files changed, 22 insertions(+), 19 deletions(-) diff --git a/install_scripts/disable-checksum-offload.sh b/install_scripts/disable-checksum-offload.sh index 0af7bdbf9..9cc0b5d5b 100644 --- a/install_scripts/disable-checksum-offload.sh +++ b/install_scripts/disable-checksum-offload.sh @@ -5,5 +5,5 @@ if [ "$NM_DISPATCHER_ACTION" == "pre-up" ]; then for i in rx tx sg tso ufo gso gro lro; do ethtool -K $DEVICE_IFACE $i off; done - fii + fi fi \ No newline at end of file diff --git a/so-setup-network.sh b/so-setup-network.sh index a12259011..13906311d 100644 --- a/so-setup-network.sh +++ b/so-setup-network.sh @@ -255,25 +255,28 @@ network_setup() { fi # Create the bond interface - nmcli con add ifname bond0 con-name "bond0" type bond mode 0 -- \ - ipv4.method disabled \ - ipv6.method link-local \ - ethernet.mtu $MTU \ - connection.autoconnect "yes" >> $SETUPLOG 2>&1 + nmcli con add ifname bond0 con-name "bond0" type bond mode 0 -- \ + ipv4.method disabled \ + ipv6.method link-local \ + ethernet.mtu $MTU \ + connection.autoconnect "yes" >> $SETUPLOG 2>&1 - for BNIC in ${BNICS[@]}; do - # Strip the quotes from the NIC names - BONDNIC="$(echo -e "${BNIC}" | tr -d '"')" - # Create the slave interface and assign it to the bond - nmcli con add type ethernet ifname $BONDNIC con-name "bond0-slave-$BONDNIC" master bond0 -- \ - ethernet.mtu $MTU \ - connection.autoconnect "yes" >> $SETUPLOG 2>&1 - # Bring the slave interface up - nmcli con up bond0-slave-$BONDNIC >> $SETUPLOG 2>&1 + for BNIC in ${BNICS[@]}; do + # Strip the quotes from the NIC names + BONDNIC="$(echo -e "${BNIC}" | tr -d '"')" + # Turn off various offloading settings for the interface + for i in rx tx sg tso ufo gso gro lro; do + ethtool -K $BONDNIC $i off >> $SETUPLOG 2>&1 done - + # Create the slave interface and assign it to the bond + nmcli con add type ethernet ifname $BONDNIC con-name "bond0-slave-$BONDNIC" master bond0 -- \ + ethernet.mtu $MTU \ + connection.autoconnect "yes" >> $SETUPLOG 2>&1 + # Bring the slave interface up + nmcli con up bond0-slave-$BONDNIC >> $SETUPLOG 2>&1 + done + # Replace the variable string in the network script sed -i "s/\$MAININT/${MAININT}/g" ./install_scripts/disable-checksum-offload.sh >> $SETUPLOG 2>&1 - # Copy the checksum offload script to prevent issues with packet capture cp ./install_scripts/disable-checksum-offload.sh /etc/NetworkManager/dispatcher.d/disable-checksum-offload.sh >> $SETUPLOG 2>&1 } @@ -1688,7 +1691,7 @@ if (whiptail_you_sure); then echo -e "XXX\n0\nSetting Initial Firewall Policy... \nXXX" set_initial_firewall_policy >> $SETUPLOG 2>&1 echo -e "XXX\n3\nCreating Bond Interface... \nXXX" - create_bond_nmcli >> $SETUPLOG 2>&1 + network_setup >> $SETUPLOG 2>&1 echo -e "XXX\n4\nGenerating Sensor Pillar... \nXXX" sensor_pillar >> $SETUPLOG 2>&1 echo -e "XXX\n5\nInstalling Salt Components... \nXXX" @@ -1778,7 +1781,7 @@ if (whiptail_you_sure); then { sleep 0.5 echo -e "XXX\n0\nCreating Bond Interface... \nXXX" - create_bond_nmcli >> $SETUPLOG 2>&1 + network_setup >> $SETUPLOG 2>&1 echo -e "XXX\n1\nInstalling saltstack... \nXXX" saltify >> $SETUPLOG 2>&1 echo -e "XXX\n3\nInstalling docker... \nXXX" From a1998a8aa21ec0e3340a4b46dc85c92ba7d9d509 Mon Sep 17 00:00:00 2001 From: Wes Lambert Date: Mon, 9 Sep 2019 20:23:37 +0000 Subject: [PATCH 10/73] update to allow use of custom modules and local config --- salt/elastalert/init.sls | 57 ++++++++++++++++++++++++++++------------ 1 file changed, 40 insertions(+), 17 deletions(-) diff --git a/salt/elastalert/init.sls b/salt/elastalert/init.sls index 301aa9459..4250165b5 100644 --- a/salt/elastalert/init.sls +++ b/salt/elastalert/init.sls @@ -64,20 +64,42 @@ elastarules: - group: 939 - makedirs: True -#elastaconfdir: -# file.directory: -# - name: /opt/so/conf/elastalert -# - user: 933 -# - group: 939 -# - makedirs: True +elastaconfdir: + file.directory: + - name: /opt/so/conf/elastalert + - user: 933 + - group: 939 + - makedirs: True -#elastaconf: -# file.managed: -# - name: /opt/so/conf/elastalert/config.yaml -# - source: salt://elastalert/files/config.yaml -# - user: 933 -# - group: 939 -# - template: jinja +elastasomodulesdir: + file.directory: + - name: /opt/so/conf/elastalert/modules/so + - user: 933 + - group: 939 + - makedirs: True + +elastacustmodulesdir: + file.directory: + - name: /opt/so/conf/elastalert/modules/custom + - user: 933 + - group: 939 + - makedirs: True + +elastasomodulesync: + file.recurse: + - name: /opt/so/conf/elastalert/modules/so + - source: salt://elastalert/files/modules/so + - user: 933 + - group: 939 + - makedirs: True + +elastaconf: + file.managed: + - name: /opt/so/conf/elastalert/elastalert_config.yaml + - source: salt://elastalert/files/elastalert_config.yaml + - user: 933 + - group: 939 + - template: jinja so-elastalertimage: cmd.run: @@ -93,15 +115,16 @@ so-elastalert: - user: elastalert - detach: True - binds: -# - /opt/so/conf/elastalert/config.yaml:/etc/elastalert/conf/elastalert_config.yaml:ro - /opt/so/rules/elastalert:/etc/elastalert/rules/:ro - /opt/so/log/elastalert:/var/log/elastalert:rw + - /opt/so/conf/elastalert/modules:/opt/elastalert/elastalert/modules:ro + - /opt/so/conf/elastalert/elastalert_config.yaml:/etc/elastalert/conf/elastalert_config.yaml:ro - environment: - - ELASTICSEARCH_HOST: {{ esip }} - - ELASTICSEARCH_PORT: {{ esport }} + #- ELASTICSEARCH_HOST: {{ esip }} + #- ELASTICSEARCH_PORT: {{ esport }} - ELASTALERT_CONFIG: /etc/elastalert/conf/elastalert_config.yaml - ELASTALERT_SUPERVISOR_CONF: /etc/elastalert/conf/elastalert_supervisord.conf - - RULES_DIRECTORY: /etc/elastalert/rules/ + #- RULES_DIRECTORY: /etc/elastalert/rules/ - LOG_DIR: /var/log/elastalert {% endif %} From 3f07d7de91be41661ff9f12c9539cd321fdb4985 Mon Sep 17 00:00:00 2001 From: Wes Lambert Date: Mon, 9 Sep 2019 20:28:31 +0000 Subject: [PATCH 11/73] add files --- salt/elastalert/files/elastalert_config.yaml | 79 +++++++++++++ .../files/modules/so/hivealerter.py | 108 ++++++++++++++++++ 2 files changed, 187 insertions(+) create mode 100644 salt/elastalert/files/elastalert_config.yaml create mode 100644 salt/elastalert/files/modules/so/hivealerter.py diff --git a/salt/elastalert/files/elastalert_config.yaml b/salt/elastalert/files/elastalert_config.yaml new file mode 100644 index 000000000..6a918093b --- /dev/null +++ b/salt/elastalert/files/elastalert_config.yaml @@ -0,0 +1,79 @@ +{% set esip = salt['pillar.get']('master:mainip', '') %} +{% set esport = salt['pillar.get']('master:es_port', '') %} +# This is the folder that contains the rule yaml files +# Any .yaml file will be loaded as a rule +rules_folder: /etc/elastalert/rules/ + +# Sets whether or not ElastAlert should recursively descend +# the rules directory - true or false +scan_subdirectories: true + +# How often ElastAlert will query Elasticsearch +# The unit can be anything from weeks to seconds +run_every: + minutes: 1 + +# ElastAlert will buffer results from the most recent +# period of time, in case some log sources are not in real time +buffer_time: + minutes: 1 + +# The maximum time between queries for ElastAlert to start at the most recently +# run query. When ElastAlert starts, for each rule, it will search elastalert_metadata +# for the most recently run query and start from that time, unless it is older than +# old_query_limit, in which case it will start from the present time. The default is one week. +old_query_limit: + minutes: 5 + +# The Elasticsearch hostname for metadata writeback +# Note that every rule can have its own Elasticsearch host +es_host: {{ esip }} + +# The Elasticsearch port +es_port: {{ esport }} + +# Sets timeout for connecting to and reading from es_host +es_conn_timeout: 60 + +# The maximum number of documents that will be downloaded from Elasticsearch in +# a single query. The default is 10,000, and if you expect to get near this number, +# consider using use_count_query for the rule. If this limit is reached, ElastAlert +# will scroll through pages the size of max_query_size until processing all results. +max_query_size: 5000 + +# The AWS region to use. Set this when using AWS-managed elasticsearch +#aws_region: us-east-1 + +# The AWS profile to use. Use this if you are using an aws-cli profile. +# See http://docs.aws.amazon.com/cli/latest/userguide/cli-chap-getting-started.html +# for details +#profile: test + +# Optional URL prefix for Elasticsearch +#es_url_prefix: elasticsearch + +# Connect with TLS to Elasticsearch +#use_ssl: True + +# Verify TLS certificates +#verify_certs: True + +# GET request with body is the default option for Elasticsearch. +# If it fails for some reason, you can pass 'GET', 'POST' or 'source'. +# See http://elasticsearch-py.readthedocs.io/en/master/connection.html?highlight=send_get_body_as#transport +# for details +#es_send_get_body_as: GET + +# Option basic-auth username and password for Elasticsearch +#es_username: someusername +#es_password: somepassword + +# The index on es_host which is used for metadata storage +# This can be a unmapped index, but it is recommended that you run +# elastalert-create-index to set a mapping +writeback_index: elastalert_status + +# If an alert fails for some reason, ElastAlert will retry +# sending the alert until this time period has elapsed +alert_time_limit: + days: 2 diff --git a/salt/elastalert/files/modules/so/hivealerter.py b/salt/elastalert/files/modules/so/hivealerter.py new file mode 100644 index 000000000..fbe4d6aac --- /dev/null +++ b/salt/elastalert/files/modules/so/hivealerter.py @@ -0,0 +1,108 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals +import uuid + +from elastalert.alerts import Alerter +from thehive4py.api import TheHiveApi +from thehive4py.models import Alert, AlertArtifact, CustomFieldHelper + + +class HiveAlerter(Alerter): + """ + Use matched data to create alerts containing observables in an instance of TheHive + """ + + required_options = set(['hive_connection', 'hive_alert_config']) + + def get_aggregation_summary_text(self, matches): + text = super(HiveAlerter, self).get_aggregation_summary_text(matches) + if text: + text = u'```\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.iteritems(): + 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.iteritems(): + if alert_config_field == 'customFields': + custom_fields = CustomFieldHelper() + for cf_key, cf_value in alert_config_value.iteritems(): + 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, basestring): + 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.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_apikey', ''), + proxies=connection_details.get('hive_proxies', {'http': '', 'https': ''}), + cert=connection_details.get('hive_verify', False)) + + 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 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 + 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', '') + } From 30d732e18f53920f5a60440b2403f2a163bbb0bd Mon Sep 17 00:00:00 2001 From: Wes Lambert Date: Wed, 18 Sep 2019 19:37:47 +0000 Subject: [PATCH 12/73] sync default Elastalert rules --- salt/elastalert/files/rules/so/nids2hive.yaml | 45 +++++++++++++++++++ salt/elastalert/init.sls | 8 ++++ 2 files changed, 53 insertions(+) create mode 100644 salt/elastalert/files/rules/so/nids2hive.yaml diff --git a/salt/elastalert/files/rules/so/nids2hive.yaml b/salt/elastalert/files/rules/so/nids2hive.yaml new file mode 100644 index 000000000..e5e3a7111 --- /dev/null +++ b/salt/elastalert/files/rules/so/nids2hive.yaml @@ -0,0 +1,45 @@ +{% set hivehost = salt['pillar.get']('static:masterip', '') %} %} +{% set hivekey = salt['pillar.get']('static:hivekey', '') %} +# hive.yaml +# Elastalert rule to forward IDS alerts from Security Onion to a specified TheHive instance. +# +es_host: elasticsearch +es_port: 9200 +name: TheHive - New IDS Alert! +type: frequency +index: "*:logstash-ids*" +num_events: 1 +timeframe: + minutes: 10 +buffer_time: + minutes: 10 +allow_buffer_time_overlap: true + +filter: +- term: + event_type: "ids" + +alert: elastalert.modules.so.hivealerter + +hive_connection: + hive_host: {{hivehost}} + hive_apikey: {{hivekey}} + +hive_proxies: + http: '' + https: '' + +hive_alert_config: + title: '{rule[name]} -- {match[alert]}' + type: 'external' + source: 'SecurityOnion' + description: '{match[message]}' + severity: 2 + tags: ['elastalert, SecurityOnion'] + tlp: 3 + status: 'New' + follow: True + +hive_observable_data_mapping: + - ip: '{match[source_ip]}' + - ip: '{match[destination_ip]}' diff --git a/salt/elastalert/init.sls b/salt/elastalert/init.sls index 4250165b5..2dd06f200 100644 --- a/salt/elastalert/init.sls +++ b/salt/elastalert/init.sls @@ -93,6 +93,14 @@ elastasomodulesync: - group: 939 - makedirs: True +elastarulesync: + file.recurse: + - name: /opt/so/rules/elastalert + - source: salt://elastalert/files/rules + - user: 933 + - group: 939 + - template: jinja + elastaconf: file.managed: - name: /opt/so/conf/elastalert/elastalert_config.yaml From 1f8fd7ddd18a730eda0b760277780c0d8a2cdf6a Mon Sep 17 00:00:00 2001 From: Wes Lambert Date: Wed, 18 Sep 2019 19:42:02 +0000 Subject: [PATCH 13/73] fix typo --- salt/elastalert/files/rules/so/nids2hive.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/salt/elastalert/files/rules/so/nids2hive.yaml b/salt/elastalert/files/rules/so/nids2hive.yaml index e5e3a7111..1d4b4ee39 100644 --- a/salt/elastalert/files/rules/so/nids2hive.yaml +++ b/salt/elastalert/files/rules/so/nids2hive.yaml @@ -1,4 +1,4 @@ -{% set hivehost = salt['pillar.get']('static:masterip', '') %} %} +{% set hivehost = salt['pillar.get']('static:masterip', '') %} {% set hivekey = salt['pillar.get']('static:hivekey', '') %} # hive.yaml # Elastalert rule to forward IDS alerts from Security Onion to a specified TheHive instance. From 9a53cfd5ffb504eca3cff0a735056de440971994 Mon Sep 17 00:00:00 2001 From: Wes Lambert Date: Wed, 18 Sep 2019 19:47:39 +0000 Subject: [PATCH 14/73] update path --- salt/elastalert/init.sls | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/salt/elastalert/init.sls b/salt/elastalert/init.sls index 2dd06f200..b17e657ca 100644 --- a/salt/elastalert/init.sls +++ b/salt/elastalert/init.sls @@ -96,7 +96,7 @@ elastasomodulesync: elastarulesync: file.recurse: - name: /opt/so/rules/elastalert - - source: salt://elastalert/files/rules + - source: salt://elastalert/files/rules/so - user: 933 - group: 939 - template: jinja From 9a4eadc9676f55895ded6bae3dc4cd6d0e164ee6 Mon Sep 17 00:00:00 2001 From: Josh Brower Date: Thu, 19 Sep 2019 08:30:33 -0400 Subject: [PATCH 15/73] Add rule_signature mapping --- salt/logstash/etc/logstash-template.json | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/salt/logstash/etc/logstash-template.json b/salt/logstash/etc/logstash-template.json index 53c418d39..44e519842 100644 --- a/salt/logstash/etc/logstash-template.json +++ b/salt/logstash/etc/logstash-template.json @@ -2675,6 +2675,14 @@ "rule_number":{ "type":"long" }, + "rule_signature":{ + "type":"text", + "fields":{ + "keyword":{ + "type":"keyword" + } + } + }, "rule_type":{ "type":"text", "fields":{ From a9113a99a697b24fd5eeae30e458493af6bfb7c4 Mon Sep 17 00:00:00 2001 From: Mike Reeves Date: Thu, 19 Sep 2019 08:52:44 -0400 Subject: [PATCH 16/73] cmd.script cleanup --- salt/hive/init.sls | 3 ++- salt/utility/init.sls | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/salt/hive/init.sls b/salt/hive/init.sls index 3fc364e4e..3f8d5e04e 100644 --- a/salt/hive/init.sls +++ b/salt/hive/init.sls @@ -97,8 +97,9 @@ so-thehive: - /opt/so/conf/hive/etc/application.conf:/opt/thehive/conf/application.conf:ro - port_bindings: - 0.0.0.0:9000:9000 - + hivescript: cmd.script: - source: salt://hive/thehive/scripts/hive_init.sh + - cwd: /root - template: jinja diff --git a/salt/utility/init.sls b/salt/utility/init.sls index 845da59c7..07996f3e6 100644 --- a/salt/utility/init.sls +++ b/salt/utility/init.sls @@ -5,6 +5,7 @@ crossclusterson: cmd.script: - shell: /bin/bash + - cwd: /root - runas: socore - source: salt://utility/bin/crossthestreams.sh - template: jinja @@ -15,6 +16,7 @@ crossclusterson: fixsearch: cmd.script: - shell: /bin/bash + - cwd: /root - runas: socore - source: salt://utility/bin/eval.sh - template: jinja From b68391acd09a4b8994222771bee6372f5dbe58f5 Mon Sep 17 00:00:00 2001 From: Mike Reeves Date: Thu, 19 Sep 2019 10:22:10 -0400 Subject: [PATCH 17/73] cmd.script - Fix location --- salt/hive/init.sls | 2 +- salt/utility/init.sls | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/salt/hive/init.sls b/salt/hive/init.sls index 3f8d5e04e..c72123d2a 100644 --- a/salt/hive/init.sls +++ b/salt/hive/init.sls @@ -101,5 +101,5 @@ so-thehive: hivescript: cmd.script: - source: salt://hive/thehive/scripts/hive_init.sh - - cwd: /root + - cwd: /opt/so - template: jinja diff --git a/salt/utility/init.sls b/salt/utility/init.sls index 07996f3e6..d4ff00b3b 100644 --- a/salt/utility/init.sls +++ b/salt/utility/init.sls @@ -5,7 +5,7 @@ crossclusterson: cmd.script: - shell: /bin/bash - - cwd: /root + - cwd: /opt/so - runas: socore - source: salt://utility/bin/crossthestreams.sh - template: jinja @@ -16,7 +16,7 @@ crossclusterson: fixsearch: cmd.script: - shell: /bin/bash - - cwd: /root + - cwd: /opt/so - runas: socore - source: salt://utility/bin/eval.sh - template: jinja From 06cc8e723672d359732ad54cdd1dbf5c16762c63 Mon Sep 17 00:00:00 2001 From: Mike Reeves Date: Thu, 19 Sep 2019 13:44:28 -0400 Subject: [PATCH 18/73] OSSEC Module - Fix User Creation --- salt/wazuh/init.sls | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/salt/wazuh/init.sls b/salt/wazuh/init.sls index 4ff937c08..0369fdc18 100644 --- a/salt/wazuh/init.sls +++ b/salt/wazuh/init.sls @@ -5,6 +5,7 @@ ossecgroup: group.present: - name: ossec - gid: 945 + - allow_gid_change: True # Add ossecm user ossecm: @@ -13,6 +14,8 @@ ossecm: - gid: 945 - home: /opt/so/wazuh - createhome: False + - allow_uid_change: True + - allow_gid_change: True # Add ossecr user ossecr: @@ -21,6 +24,8 @@ ossecr: - gid: 945 - home: /opt/so/wazuh - createhome: False + - allow_uid_change: True + - allow_gid_change: True # Add ossec user ossec: @@ -29,6 +34,8 @@ ossec: - gid: 945 - home: /opt/so/wazuh - createhome: False + - allow_uid_change: True + - allow_gid_change: True # Add wazuh agent wazuhpkgs: From 50c074bb4ec342c0a98fd85090cc6619838e32ac Mon Sep 17 00:00:00 2001 From: Mike Reeves Date: Thu, 19 Sep 2019 15:46:46 -0400 Subject: [PATCH 19/73] Logstash Module - Add more watches --- salt/logstash/init.sls | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/salt/logstash/init.sls b/salt/logstash/init.sls index 302598a45..feec09afc 100644 --- a/salt/logstash/init.sls +++ b/salt/logstash/init.sls @@ -193,3 +193,7 @@ so-logstash: {%- endif %} - watch: - file: /opt/so/conf/logstash/etc + - file: /opt/so/conf/logstash/conf.enabled.txt + - file: /opt/so/conf/logstash/custom + - file: /opt/so/conf/logstash/rulesets + - file: /opt/so/conf/logstash/dynamic From 6d14a94765c72138f104bc5185cd61de06dac285 Mon Sep 17 00:00:00 2001 From: Mike Reeves Date: Fri, 20 Sep 2019 16:31:23 -0400 Subject: [PATCH 20/73] Logstash Module - Fix watch --- salt/logstash/init.sls | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/salt/logstash/init.sls b/salt/logstash/init.sls index feec09afc..f1b41627b 100644 --- a/salt/logstash/init.sls +++ b/salt/logstash/init.sls @@ -195,5 +195,5 @@ so-logstash: - file: /opt/so/conf/logstash/etc - file: /opt/so/conf/logstash/conf.enabled.txt - file: /opt/so/conf/logstash/custom - - file: /opt/so/conf/logstash/rulesets + #- file: /opt/so/conf/logstash/rulesets - file: /opt/so/conf/logstash/dynamic From 5419bd6f088cce284b3a16854e2641b2379d3e01 Mon Sep 17 00:00:00 2001 From: Wes Lambert Date: Mon, 23 Sep 2019 14:43:14 +0000 Subject: [PATCH 21/73] update config for Elastalert --- salt/elastalert/files/modules/so/thehive.py | 108 ++++++++++++++++++ salt/elastalert/files/rules/so/nids2hive.yaml | 5 +- salt/elastalert/init.sls | 12 +- 3 files changed, 117 insertions(+), 8 deletions(-) create mode 100644 salt/elastalert/files/modules/so/thehive.py diff --git a/salt/elastalert/files/modules/so/thehive.py b/salt/elastalert/files/modules/so/thehive.py new file mode 100644 index 000000000..d78a8d050 --- /dev/null +++ b/salt/elastalert/files/modules/so/thehive.py @@ -0,0 +1,108 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals +import uuid + +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 + """ + + required_options = set(['hive_connection', 'hive_alert_config']) + + def get_aggregation_summary_text(self, matches): + text = super(HiveAlerter, self).get_aggregation_summary_text(matches) + if text: + text = u'```\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.iteritems(): + 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.iteritems(): + if alert_config_field == 'customFields': + custom_fields = CustomFieldHelper() + for cf_key, cf_value in alert_config_value.iteritems(): + 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, basestring): + 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.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_apikey', ''), + proxies=connection_details.get('hive_proxies', {'http': '', 'https': ''}), + cert=connection_details.get('hive_verify', False)) + + 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 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 + 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/elastalert/files/rules/so/nids2hive.yaml b/salt/elastalert/files/rules/so/nids2hive.yaml index 1d4b4ee39..ab0624e13 100644 --- a/salt/elastalert/files/rules/so/nids2hive.yaml +++ b/salt/elastalert/files/rules/so/nids2hive.yaml @@ -1,9 +1,10 @@ +{% set es = salt['pillar.get']('static:masterip', '') %} {% set hivehost = salt['pillar.get']('static:masterip', '') %} {% set hivekey = salt['pillar.get']('static:hivekey', '') %} # hive.yaml # Elastalert rule to forward IDS alerts from Security Onion to a specified TheHive instance. # -es_host: elasticsearch +es_host: {{es}} es_port: 9200 name: TheHive - New IDS Alert! type: frequency @@ -19,7 +20,7 @@ filter: - term: event_type: "ids" -alert: elastalert.modules.so.hivealerter +alert: modules.so.thehive.TheHiveAlerter hive_connection: hive_host: {{hivehost}} diff --git a/salt/elastalert/init.sls b/salt/elastalert/init.sls index b17e657ca..8e8b32ae6 100644 --- a/salt/elastalert/init.sls +++ b/salt/elastalert/init.sls @@ -111,13 +111,13 @@ elastaconf: so-elastalertimage: cmd.run: - - name: docker pull --disable-content-trust=false soshybridhunter/so-elastalert:HH1.1.0 + - name: docker pull --disable-content-trust=false soshybridhunter/so-elastalert:HH1.1.1 so-elastalert: docker_container.running: - require: - so-elastalertimage - - image: soshybridhunter/so-elastalert:HH1.1.0 + - image: soshybridhunter/so-elastalert:HH1.1.1 - hostname: elastalert - name: so-elastalert - user: elastalert @@ -125,14 +125,14 @@ so-elastalert: - binds: - /opt/so/rules/elastalert:/etc/elastalert/rules/:ro - /opt/so/log/elastalert:/var/log/elastalert:rw - - /opt/so/conf/elastalert/modules:/opt/elastalert/elastalert/modules:ro + - /opt/so/conf/elastalert/modules/:/opt/elastalert/modules/:ro - /opt/so/conf/elastalert/elastalert_config.yaml:/etc/elastalert/conf/elastalert_config.yaml:ro - environment: - #- ELASTICSEARCH_HOST: {{ esip }} - #- ELASTICSEARCH_PORT: {{ esport }} + - ELASTICSEARCH_HOST: {{ esip }} + - ELASTICSEARCH_PORT: {{ esport }} - ELASTALERT_CONFIG: /etc/elastalert/conf/elastalert_config.yaml - ELASTALERT_SUPERVISOR_CONF: /etc/elastalert/conf/elastalert_supervisord.conf - #- RULES_DIRECTORY: /etc/elastalert/rules/ + - RULES_DIRECTORY: /etc/elastalert/rules/ - LOG_DIR: /var/log/elastalert {% endif %} From 965ee6f922f2085a2a1bc39027409270fac95338 Mon Sep 17 00:00:00 2001 From: Wes Lambert Date: Mon, 23 Sep 2019 14:43:54 +0000 Subject: [PATCH 22/73] remove duplicate alerter --- .../files/modules/so/hivealerter.py | 108 ------------------ 1 file changed, 108 deletions(-) delete mode 100644 salt/elastalert/files/modules/so/hivealerter.py diff --git a/salt/elastalert/files/modules/so/hivealerter.py b/salt/elastalert/files/modules/so/hivealerter.py deleted file mode 100644 index fbe4d6aac..000000000 --- a/salt/elastalert/files/modules/so/hivealerter.py +++ /dev/null @@ -1,108 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals -import uuid - -from elastalert.alerts import Alerter -from thehive4py.api import TheHiveApi -from thehive4py.models import Alert, AlertArtifact, CustomFieldHelper - - -class HiveAlerter(Alerter): - """ - Use matched data to create alerts containing observables in an instance of TheHive - """ - - required_options = set(['hive_connection', 'hive_alert_config']) - - def get_aggregation_summary_text(self, matches): - text = super(HiveAlerter, self).get_aggregation_summary_text(matches) - if text: - text = u'```\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.iteritems(): - 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.iteritems(): - if alert_config_field == 'customFields': - custom_fields = CustomFieldHelper() - for cf_key, cf_value in alert_config_value.iteritems(): - 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, basestring): - 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.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_apikey', ''), - proxies=connection_details.get('hive_proxies', {'http': '', 'https': ''}), - cert=connection_details.get('hive_verify', False)) - - 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 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 - 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', '') - } From 8472b24a67938b68cf804524d08824fe15ab3b7f Mon Sep 17 00:00:00 2001 From: doug Date: Mon, 23 Sep 2019 16:04:23 -0400 Subject: [PATCH 23/73] parse Bro logs using Elasticsearch ingest node --- salt/elasticsearch/files/ingest/bro_common | 9 ++ .../elasticsearch/files/ingest/bro_common_ssl | 58 +++++++++++++ salt/elasticsearch/files/ingest/bro_conn | 48 +++++++++++ salt/elasticsearch/files/ingest/bro_dce_rpc | 20 +++++ salt/elasticsearch/files/ingest/bro_dhcp | 20 +++++ salt/elasticsearch/files/ingest/bro_dnp3 | 19 +++++ salt/elasticsearch/files/ingest/bro_dns | 35 ++++++++ salt/elasticsearch/files/ingest/bro_dpd | 19 +++++ salt/elasticsearch/files/ingest/bro_files | 32 +++++++ salt/elasticsearch/files/ingest/bro_ftp | 33 +++++++ salt/elasticsearch/files/ingest/bro_http | 42 +++++++++ salt/elasticsearch/files/ingest/bro_intel | 29 +++++++ salt/elasticsearch/files/ingest/bro_irc | 25 ++++++ salt/elasticsearch/files/ingest/bro_kerberos | 30 +++++++ salt/elasticsearch/files/ingest/bro_modbus | 18 ++++ salt/elasticsearch/files/ingest/bro_mysql | 21 +++++ salt/elasticsearch/files/ingest/bro_notice | 36 ++++++++ salt/elasticsearch/files/ingest/bro_ntlm | 24 ++++++ salt/elasticsearch/files/ingest/bro_pe | 23 +++++ salt/elasticsearch/files/ingest/bro_radius | 25 ++++++ salt/elasticsearch/files/ingest/bro_rdp | 31 +++++++ salt/elasticsearch/files/ingest/bro_rfb | 26 ++++++ .../elasticsearch/files/ingest/bro_signatures | 22 +++++ salt/elasticsearch/files/ingest/bro_sip | 37 ++++++++ salt/elasticsearch/files/ingest/bro_smb_files | 31 +++++++ .../files/ingest/bro_smb_mapping | 21 +++++ salt/elasticsearch/files/ingest/bro_smtp | 38 +++++++++ salt/elasticsearch/files/ingest/bro_snmp | 25 ++++++ salt/elasticsearch/files/ingest/bro_socks | 28 ++++++ salt/elasticsearch/files/ingest/bro_software | 23 +++++ salt/elasticsearch/files/ingest/bro_ssh | 40 +++++++++ salt/elasticsearch/files/ingest/bro_ssl | 33 +++++++ salt/elasticsearch/files/ingest/bro_syslog | 21 +++++ salt/elasticsearch/files/ingest/bro_tunnels | 18 ++++ salt/elasticsearch/files/ingest/bro_weird | 20 +++++ salt/elasticsearch/files/ingest/bro_x509 | 44 ++++++++++ salt/elasticsearch/files/ingest/common | 52 ++++++++++++ salt/elasticsearch/files/ingest/common_nids | 17 ++++ salt/elasticsearch/files/ingest/ossec | 53 ++++++++++++ salt/elasticsearch/files/ingest/sguild_nids | 25 ++++++ salt/elasticsearch/files/ingest/snort | 21 +++++ .../files/so-elasticsearch-pipelines | 52 ++++++++++++ salt/elasticsearch/init.sls | 4 + salt/logstash/conf/conf.enabled.txt.parser | 85 ++++++++++--------- salt/logstash/conf/conf.enabled.txt.so-eval | 77 ++++++++--------- salt/logstash/conf/conf.enabled.txt.storage | 77 ++++++++--------- .../files/dynamic/9000_output_bro.conf | 1 + so-setup-network.sh | 10 +-- 48 files changed, 1375 insertions(+), 123 deletions(-) create mode 100644 salt/elasticsearch/files/ingest/bro_common create mode 100644 salt/elasticsearch/files/ingest/bro_common_ssl create mode 100644 salt/elasticsearch/files/ingest/bro_conn create mode 100644 salt/elasticsearch/files/ingest/bro_dce_rpc create mode 100644 salt/elasticsearch/files/ingest/bro_dhcp create mode 100644 salt/elasticsearch/files/ingest/bro_dnp3 create mode 100644 salt/elasticsearch/files/ingest/bro_dns create mode 100644 salt/elasticsearch/files/ingest/bro_dpd create mode 100644 salt/elasticsearch/files/ingest/bro_files create mode 100644 salt/elasticsearch/files/ingest/bro_ftp create mode 100644 salt/elasticsearch/files/ingest/bro_http create mode 100644 salt/elasticsearch/files/ingest/bro_intel create mode 100644 salt/elasticsearch/files/ingest/bro_irc create mode 100644 salt/elasticsearch/files/ingest/bro_kerberos create mode 100644 salt/elasticsearch/files/ingest/bro_modbus create mode 100644 salt/elasticsearch/files/ingest/bro_mysql create mode 100644 salt/elasticsearch/files/ingest/bro_notice create mode 100644 salt/elasticsearch/files/ingest/bro_ntlm create mode 100644 salt/elasticsearch/files/ingest/bro_pe create mode 100644 salt/elasticsearch/files/ingest/bro_radius create mode 100644 salt/elasticsearch/files/ingest/bro_rdp create mode 100644 salt/elasticsearch/files/ingest/bro_rfb create mode 100644 salt/elasticsearch/files/ingest/bro_signatures create mode 100644 salt/elasticsearch/files/ingest/bro_sip create mode 100644 salt/elasticsearch/files/ingest/bro_smb_files create mode 100644 salt/elasticsearch/files/ingest/bro_smb_mapping create mode 100644 salt/elasticsearch/files/ingest/bro_smtp create mode 100644 salt/elasticsearch/files/ingest/bro_snmp create mode 100644 salt/elasticsearch/files/ingest/bro_socks create mode 100644 salt/elasticsearch/files/ingest/bro_software create mode 100644 salt/elasticsearch/files/ingest/bro_ssh create mode 100644 salt/elasticsearch/files/ingest/bro_ssl create mode 100644 salt/elasticsearch/files/ingest/bro_syslog create mode 100644 salt/elasticsearch/files/ingest/bro_tunnels create mode 100644 salt/elasticsearch/files/ingest/bro_weird create mode 100644 salt/elasticsearch/files/ingest/bro_x509 create mode 100644 salt/elasticsearch/files/ingest/common create mode 100644 salt/elasticsearch/files/ingest/common_nids create mode 100644 salt/elasticsearch/files/ingest/ossec create mode 100644 salt/elasticsearch/files/ingest/sguild_nids create mode 100644 salt/elasticsearch/files/ingest/snort create mode 100755 salt/elasticsearch/files/so-elasticsearch-pipelines diff --git a/salt/elasticsearch/files/ingest/bro_common b/salt/elasticsearch/files/ingest/bro_common new file mode 100644 index 000000000..98618ce56 --- /dev/null +++ b/salt/elasticsearch/files/ingest/bro_common @@ -0,0 +1,9 @@ +{ + "description" : "bro_common", + "processors" : [ + { "rename": { "field": "@timestamp", "target_field": "timestamp", "ignore_missing": true } }, + { "date": { "field": "message2.ts", "target_field": "@timestamp", "formats": ["ISO8601", "UNIX"], "ignore_failure": true } }, + { "remove": { "field": "message2.ts", "ignore_failure": true } }, + { "pipeline": { "name": "common" } } + ] +} diff --git a/salt/elasticsearch/files/ingest/bro_common_ssl b/salt/elasticsearch/files/ingest/bro_common_ssl new file mode 100644 index 000000000..faf1666ac --- /dev/null +++ b/salt/elasticsearch/files/ingest/bro_common_ssl @@ -0,0 +1,58 @@ +{ + "description" : "bro_common_ssl", + "processors" : [ + { + "kv": { + "field": "certificate_issuer", + "field_split": ",", + "value_split": "=", + "ignore_missing": true, + "ignore_failure": true, + "include_keys": [ "CN", "C", "O", "OU", "ST", "SN", "L", "DC", "GN", "pseudonym", "serialNumber", "title", "initials" ] + } + }, + { "rename":{ "field": "CN", "target_field": "issuer_common_name", "ignore_failure": true } }, + { "rename":{ "field": "C", "target_field": "issuer_country_code", "ignore_failure": true } }, + { "rename":{ "field": "O", "target_field": "issuer_organization", "ignore_failure": true } }, + { "rename":{ "field": "OU", "target_field": "issuer_organization_unit", "ignore_failure": true } }, + { "rename":{ "field": "ST", "target_field": "issuer_state", "ignore_failure": true } }, + { "rename":{ "field": "SN", "target_field": "issuer_surname", "ignore_failure": true } }, + { "rename":{ "field": "L", "target_field": "issuer_locality", "ignore_failure": true } }, + { "rename":{ "field": "DC", "target_field": "issuer_distinguised_name", "ignore_failure": true } }, + { "rename":{ "field": "GN", "target_field": "issuer_given_name", "ignore_failure": true } }, + { "rename":{ "field": "pseudonym", "target_field": "issuer_pseudonym", "ignore_failure": true } }, + { "rename":{ "field": "serialNumber", "target_field": "issuer_serial_number", "ignore_failure": true } }, + { "rename":{ "field": "title", "target_field": "issuer_title", "ignore_failure": true } }, + { "rename":{ "field": "initials", "target_field": "issuer_initials", "ignore_failure": true } }, + { + "kv": { + "field": "certificate_subject", + "field_split": ",", + "value_split": "=", + "ignore_missing": true, + "ignore_failure": true, + "include_keys": [ "CN", "C", "O", "OU", "ST", "SN", "L", "GN", "pseudonym", "serialNumber", "title", "initials" ] + } + }, + { "rename":{ "field": "CN", "target_field": "certificate_common_name", "ignore_failure": true } }, + { "rename":{ "field": "C", "target_field": "certificate_country_code", "ignore_failure": true } }, + { "rename":{ "field": "O", "target_field": "certificate_organization", "ignore_failure": true } }, + { "rename":{ "field": "OU", "target_field": "certificate_organization_unit","ignore_failure": true } }, + { "rename":{ "field": "ST", "target_field": "certificate_state", "ignore_failure": true } }, + { "rename":{ "field": "SN", "target_field": "certificate_surname", "ignore_failure": true } }, + { "rename":{ "field": "L", "target_field": "certificate_locality", "ignore_failure": true } }, + { "rename":{ "field": "GN", "target_field": "certificate_given_name", "ignore_failure": true } }, + { "rename":{ "field": "pseudonym", "target_field": "certificate_pseudonym", "ignore_failure": true } }, + { "rename":{ "field": "serialNumber", "target_field": "certificate_serial_number", "ignore_failure": true } }, + { "rename":{ "field": "title", "target_field": "certificate_title", "ignore_failure": true } }, + { "rename":{ "field": "initials", "target_field": "certificate_initials", "ignore_failure": true } }, + { "script":{ "lang": "painless", "source": "ctx.certificate_common_name_length = ctx.certificate_common_name.length()", "ignore_failure": true } }, + { "script":{ "lang": "painless", "source": "ctx.issuer_common_name_length = ctx.issuer_common_name.length()", "ignore_failure": true } }, + { "script":{ "lang": "painless", "source": "ctx.server_name_length = ctx.server_name.length()", "ignore_failure": true } }, + { + "pipeline": { + "name": "bro_common" + } + } + ] +} diff --git a/salt/elasticsearch/files/ingest/bro_conn b/salt/elasticsearch/files/ingest/bro_conn new file mode 100644 index 000000000..b12be156e --- /dev/null +++ b/salt/elasticsearch/files/ingest/bro_conn @@ -0,0 +1,48 @@ +{ + "description" : "bro_conn", + "processors" : [ + { "json": { "field": "message", "target_field": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.uid", "target_field": "uid", "ignore_missing": true } }, + { "dot_expander": { "field": "id.orig_h", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.orig_h", "target_field": "source_ip", "ignore_missing": true } }, + { "dot_expander": { "field": "id.orig_p", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.orig_p", "target_field": "source_port", "ignore_missing": true } }, + { "dot_expander": { "field": "id.resp_h", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.resp_h", "target_field": "destination_ip", "ignore_missing": true } }, + { "dot_expander": { "field": "id.resp_p", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.resp_p", "target_field": "destination_port", "ignore_missing": true } }, + { "rename": { "field": "message2.proto", "target_field": "protocol", "ignore_missing": true } }, + { "rename": { "field": "message2.service", "target_field": "service", "ignore_missing": true } }, + { "rename": { "field": "message2.duration", "target_field": "duration", "ignore_missing": true } }, + { "rename": { "field": "message2.orig_bytes", "target_field": "original_bytes", "ignore_missing": true } }, + { "rename": { "field": "message2.resp_bytes", "target_field": "respond_bytes", "ignore_missing": true } }, + { "rename": { "field": "message2.conn_state", "target_field": "connection_state", "ignore_missing": true } }, + { "rename": { "field": "message2.local_orig", "target_field": "local_orig", "ignore_missing": true } }, + { "rename": { "field": "message2.local_resp", "target_field": "local_respond", "ignore_missing": true } }, + { "rename": { "field": "message2.missed_bytes", "target_field": "missed_bytes", "ignore_missing": true } }, + { "rename": { "field": "message2.history", "target_field": "history", "ignore_missing": true } }, + { "rename": { "field": "message2.orig_pkts", "target_field": "original_packets", "ignore_missing": true } }, + { "rename": { "field": "message2.orig_ip_bytes", "target_field": "original_ip_bytes", "ignore_missing": true } }, + { "rename": { "field": "message2.resp_pkts", "target_field": "respond_packets", "ignore_missing": true } }, + { "rename": { "field": "message2.resp_ip_bytes", "target_field": "respond_ip_bytes", "ignore_missing": true } }, + { "rename": { "field": "message2.tunnel_parents", "target_field": "tunnel_parents", "ignore_missing": true } }, + { "rename": { "field": "message2.orig_cc", "target_field": "original_country_code","ignore_missing": true } }, + { "rename": { "field": "message2.resp_cc", "target_field": "respond_country_code", "ignore_missing": true } }, + { "rename": { "field": "message2.sensorname", "target_field": "sensor_name", "ignore_missing": true } }, + { "script": { "lang": "painless", "source": "ctx.total_bytes = (ctx.original_bytes + ctx.respond_bytes)", "ignore_failure": true } }, + { "set": { "if": "ctx.connection_state == 'S0'", "field": "connection_state_description", "value": "Connection attempt seen, no reply" } }, + { "set": { "if": "ctx.connection_state == 'S1'", "field": "connection_state_description", "value": "Connection established, not terminated" } }, + { "set": { "if": "ctx.connection_state == 'S2'", "field": "connection_state_description", "value": "Connection established and close attempt by originator seen (but no reply from responder)" } }, + { "set": { "if": "ctx.connection_state == 'S3'", "field": "connection_state_description", "value": "Connection established and close attempt by responder seen (but no reply from originator)" } }, + { "set": { "if": "ctx.connection_state == 'SF'", "field": "connection_state_description", "value": "Normal SYN/FIN completion" } }, + { "set": { "if": "ctx.connection_state == 'REJ'", "field": "connection_state_description", "value": "Connection attempt rejected" } }, + { "set": { "if": "ctx.connection_state == 'RSTO'", "field": "connection_state_description", "value": "Connection established, originator aborted (sent a RST)" } }, + { "set": { "if": "ctx.connection_state == 'RSTR'", "field": "connection_state_description", "value": "Established, responder aborted" } }, + { "set": { "if": "ctx.connection_state == 'RSTOS0'","field": "connection_state_description", "value": "Originator sent a SYN followed by a RST, we never saw a SYN-ACK from the responder" } }, + { "set": { "if": "ctx.connection_state == 'RSTRH'", "field": "connection_state_description", "value": "Responder sent a SYN ACK followed by a RST, we never saw a SYN from the (purported) originator" } }, + { "set": { "if": "ctx.connection_state == 'SH'", "field": "connection_state_description", "value": "Originator sent a SYN followed by a FIN, we never saw a SYN ACK from the responder (hence the connection was 'half' open)" } }, + { "set": { "if": "ctx.connection_state == 'SHR'", "field": "connection_state_description", "value": "Responder sent a SYN ACK followed by a FIN, we never saw a SYN from the originator" } }, + { "set": { "if": "ctx.connection_state == 'OTH'", "field": "connection_state_description", "value": "No SYN seen, just midstream traffic (a 'partial connection' that was not later closed)" } }, + { "pipeline": { "name": "bro_common" } } + ] +} diff --git a/salt/elasticsearch/files/ingest/bro_dce_rpc b/salt/elasticsearch/files/ingest/bro_dce_rpc new file mode 100644 index 000000000..105905245 --- /dev/null +++ b/salt/elasticsearch/files/ingest/bro_dce_rpc @@ -0,0 +1,20 @@ +{ + "description" : "bro_dce_rpc", + "processors" : [ + { "json": { "field": "message", "target_field": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.uid", "target_field": "uid", "ignore_missing": true } }, + { "dot_expander": { "field": "id.orig_h", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.orig_h", "target_field": "source_ip", "ignore_missing": true } }, + { "dot_expander": { "field": "id.orig_p", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.orig_p", "target_field": "source_port", "ignore_missing": true } }, + { "dot_expander": { "field": "id.resp_h", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.resp_h", "target_field": "destination_ip", "ignore_missing": true } }, + { "dot_expander": { "field": "id.resp_p", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.resp_p", "target_field": "destination_port", "ignore_missing": true } }, + { "rename": { "field": "message2.rtt", "target_field": "rtt", "ignore_missing": true } }, + { "rename": { "field": "message2.named_pipe", "target_field": "named_pipe", "ignore_missing": true } }, + { "rename": { "field": "message2.endpoint", "target_field": "endpoint", "ignore_missing": true } }, + { "rename": { "field": "message2.operation", "target_field": "operation", "ignore_missing": true } }, + { "pipeline": { "name": "bro_common" } } + ] +} diff --git a/salt/elasticsearch/files/ingest/bro_dhcp b/salt/elasticsearch/files/ingest/bro_dhcp new file mode 100644 index 000000000..010d0f85b --- /dev/null +++ b/salt/elasticsearch/files/ingest/bro_dhcp @@ -0,0 +1,20 @@ +{ + "description" : "bro_dhcp", + "processors" : [ + { "json": { "field": "message", "target_field": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.uids", "target_field": "uid", "ignore_missing": true } }, + { "rename": { "field": "message2.mac", "target_field": "mac", "ignore_missing": true } }, + { "rename": { "field": "message2.assigned_ip", "target_field": "assigned_ip", "ignore_missing": true } }, + { "rename": { "field": "message2.lease_time", "target_field": "lease_time", "ignore_missing": true } }, + { "rename": { "field": "message2.trans_id", "target_field": "transaction_id", "ignore_missing": true } }, + { "rename": { "field": "message2.assigned_addr", "target_field": "assigned_ip", "ignore_missing": true } }, + { "rename": { "field": "message2.client_addr", "target_field": "source_ip", "ignore_missing": true } }, + { "rename": { "field": "message2.server_addr", "target_field": "destination_ip", "ignore_missing": true } }, + { "rename": { "field": "message2.requested_addr", "target_field": "requested_ip", "ignore_missing": true } }, + { "rename": { "field": "message2.domain", "target_field": "domain_name", "ignore_missing": true } }, + { "rename": { "field": "message2.host_name", "target_field": "hostname", "ignore_missing": true } }, + { "rename": { "field": "message2.duration", "target_field": "duration", "ignore_missing": true } }, + { "rename": { "field": "message2.msg_types", "target_field": "message_types", "ignore_missing": true } }, + { "pipeline": { "name": "bro_common" } } + ] +} diff --git a/salt/elasticsearch/files/ingest/bro_dnp3 b/salt/elasticsearch/files/ingest/bro_dnp3 new file mode 100644 index 000000000..bebb85ecb --- /dev/null +++ b/salt/elasticsearch/files/ingest/bro_dnp3 @@ -0,0 +1,19 @@ +{ + "description" : "bro_dnp3", + "processors" : [ + { "json": { "field": "message", "target_field": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.uid", "target_field": "uid", "ignore_missing": true } }, + { "dot_expander": { "field": "id.orig_h", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.orig_h", "target_field": "source_ip", "ignore_missing": true } }, + { "dot_expander": { "field": "id.orig_p", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.orig_p", "target_field": "source_port", "ignore_missing": true } }, + { "dot_expander": { "field": "id.resp_h", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.resp_h", "target_field": "destination_ip", "ignore_missing": true } }, + { "dot_expander": { "field": "id.resp_p", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.resp_p", "target_field": "destination_port", "ignore_missing": true } }, + { "rename": { "field": "message2.fc_request", "target_field": "fc_request", "ignore_missing": true } }, + { "rename": { "field": "message2.fc_reply", "target_field": "fc_reply", "ignore_missing": true } }, + { "rename": { "field": "message2.iin", "target_field": "iin", "ignore_missing": true } }, + { "pipeline": { "name": "bro_common" } } + ] +} diff --git a/salt/elasticsearch/files/ingest/bro_dns b/salt/elasticsearch/files/ingest/bro_dns new file mode 100644 index 000000000..be8d59294 --- /dev/null +++ b/salt/elasticsearch/files/ingest/bro_dns @@ -0,0 +1,35 @@ +{ + "description" : "bro_dns", + "processors" : [ + { "json": { "field": "message", "target_field": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.uid", "target_field": "uid", "ignore_missing": true } }, + { "dot_expander": { "field": "id.orig_h", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.orig_h", "target_field": "source_ip", "ignore_missing": true } }, + { "dot_expander": { "field": "id.orig_p", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.orig_p", "target_field": "source_port", "ignore_missing": true } }, + { "dot_expander": { "field": "id.resp_h", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.resp_h", "target_field": "destination_ip", "ignore_missing": true } }, + { "dot_expander": { "field": "id.resp_p", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.resp_p", "target_field": "destination_port", "ignore_missing": true } }, + { "rename": { "field": "message2.proto", "target_field": "protocol", "ignore_missing": true } }, + { "rename": { "field": "message2.trans_id", "target_field": "transaction_id", "ignore_missing": true } }, + { "rename": { "field": "message2.rtt", "target_field": "rtt", "ignore_missing": true } }, + { "rename": { "field": "message2.query", "target_field": "query", "ignore_missing": true } }, + { "rename": { "field": "message2.qclass", "target_field": "query_class", "ignore_missing": true } }, + { "rename": { "field": "message2.qclass_name", "target_field": "query_class_name", "ignore_missing": true } }, + { "rename": { "field": "message2.qtype", "target_field": "query_type", "ignore_missing": true } }, + { "rename": { "field": "message2.qtype_name", "target_field": "query_type_name", "ignore_missing": true } }, + { "rename": { "field": "message2.rcode", "target_field": "rcode", "ignore_missing": true } }, + { "rename": { "field": "message2.rcode_name", "target_field": "rcode_name", "ignore_missing": true } }, + { "rename": { "field": "message2.AA", "target_field": "aa", "ignore_missing": true } }, + { "rename": { "field": "message2.TC", "target_field": "tc", "ignore_missing": true } }, + { "rename": { "field": "message2.RD", "target_field": "rd", "ignore_missing": true } }, + { "rename": { "field": "message2.RA", "target_field": "ra", "ignore_missing": true } }, + { "rename": { "field": "message2.Z", "target_field": "z", "ignore_missing": true } }, + { "rename": { "field": "message2.answers", "target_field": "answers", "ignore_missing": true } }, + { "rename": { "field": "message2.TTLs", "target_field": "ttls", "ignore_missing": true } }, + { "rename": { "field": "message2.rejected", "target_field": "rejected", "ignore_missing": true } }, + { "script": { "lang": "painless", "source": "ctx.query_length = ctx.query.length()", "ignore_failure": true } }, + { "pipeline": { "name": "bro_common" } } + ] +} diff --git a/salt/elasticsearch/files/ingest/bro_dpd b/salt/elasticsearch/files/ingest/bro_dpd new file mode 100644 index 000000000..caf66d39e --- /dev/null +++ b/salt/elasticsearch/files/ingest/bro_dpd @@ -0,0 +1,19 @@ +{ + "description" : "bro_dpd", + "processors" : [ + { "json": { "field": "message", "target_field": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.uid", "target_field": "uid", "ignore_missing": true } }, + { "dot_expander": { "field": "id.orig_h", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.orig_h", "target_field": "source_ip", "ignore_missing": true } }, + { "dot_expander": { "field": "id.orig_p", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.orig_p", "target_field": "source_port", "ignore_missing": true } }, + { "dot_expander": { "field": "id.resp_h", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.resp_h", "target_field": "destination_ip", "ignore_missing": true } }, + { "dot_expander": { "field": "id.resp_p", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.resp_p", "target_field": "destination_port", "ignore_missing": true } }, + { "rename": { "field": "message2.proto", "target_field": "protocol", "ignore_missing": true } }, + { "rename": { "field": "message2.analyzer", "target_field": "analyzer", "ignore_missing": true } }, + { "rename": { "field": "message2.failure_reason", "target_field": "failure_reason", "ignore_missing": true } }, + { "pipeline": { "name": "bro_common" } } + ] +} diff --git a/salt/elasticsearch/files/ingest/bro_files b/salt/elasticsearch/files/ingest/bro_files new file mode 100644 index 000000000..4337b75f2 --- /dev/null +++ b/salt/elasticsearch/files/ingest/bro_files @@ -0,0 +1,32 @@ +{ + "description" : "bro_files", + "processors" : [ + { "json": { "field": "message", "target_field": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.fuid", "target_field": "fuid", "ignore_missing": true } }, + { "rename": { "field": "message2.tx_hosts", "target_field": "file_ip", "ignore_missing": true } }, + { "rename": { "field": "message2.rx_hosts.0", "target_field": "destination_ip", "ignore_missing": true } }, + { "remove": { "field": "message2.rx_hosts", "ignore_missing": true } }, + { "rename": { "field": "message2.conn_uids", "target_field": "uid", "ignore_missing": true } }, + { "remove": { "field": "source", "ignore_missing": true } }, + { "rename": { "field": "message2.source", "target_field": "source", "ignore_missing": true } }, + { "rename": { "field": "message2.depth", "target_field": "depth", "ignore_missing": true } }, + { "rename": { "field": "message2.analyzers", "target_field": "analyzer", "ignore_missing": true } }, + { "rename": { "field": "message2.mime_type", "target_field": "mimetype", "ignore_missing": true } }, + { "rename": { "field": "message2.filename", "target_field": "file_name", "ignore_missing": true } }, + { "rename": { "field": "message2.duration", "target_field": "duration", "ignore_missing": true } }, + { "rename": { "field": "message2.local_orig", "target_field": "local_orig", "ignore_missing": true } }, + { "rename": { "field": "message2.is_orig", "target_field": "is_orig", "ignore_missing": true } }, + { "rename": { "field": "message2.seen_bytes", "target_field": "seen_bytes", "ignore_missing": true } }, + { "rename": { "field": "message2.total_bytes", "target_field": "total_bytes", "ignore_missing": true } }, + { "rename": { "field": "message2.missing_bytes", "target_field": "missing_bytes", "ignore_missing": true } }, + { "rename": { "field": "message2.overflow_bytes", "target_field": "overflow_bytes", "ignore_missing": true } }, + { "rename": { "field": "message2.timedout", "target_field": "timed_out", "ignore_missing": true } }, + { "rename": { "field": "message2.parent_fuid", "target_field": "parent_fuid", "ignore_missing": true } }, + { "rename": { "field": "message2.md5", "target_field": "md5", "ignore_missing": true } }, + { "rename": { "field": "message2.sha1", "target_field": "sha1", "ignore_missing": true } }, + { "rename": { "field": "message2.extracted", "target_field": "extracted", "ignore_missing": true } }, + { "rename": { "field": "message2.extracted_cutoff", "target_field": "extracted_cutoff", "ignore_missing": true } }, + { "rename": { "field": "message2.extracted_size", "target_field": "extracted_size", "ignore_missing": true } }, + { "pipeline": { "name": "bro_common" } } + ] +} diff --git a/salt/elasticsearch/files/ingest/bro_ftp b/salt/elasticsearch/files/ingest/bro_ftp new file mode 100644 index 000000000..34775072d --- /dev/null +++ b/salt/elasticsearch/files/ingest/bro_ftp @@ -0,0 +1,33 @@ +{ + "description" : "bro_http", + "processors" : [ + { "json": { "field": "message", "target_field": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.uid", "target_field": "uid", "ignore_missing": true } }, + { "dot_expander": { "field": "id.orig_h", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.orig_h", "target_field": "source_ip", "ignore_missing": true } }, + { "dot_expander": { "field": "id.orig_p", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.orig_p", "target_field": "source_port", "ignore_missing": true } }, + { "dot_expander": { "field": "id.resp_h", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.resp_h", "target_field": "destination_ip", "ignore_missing": true } }, + { "dot_expander": { "field": "id.resp_p", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.resp_p", "target_field": "destination_port", "ignore_missing": true } }, + { "rename": { "field": "message2.user", "target_field": "username", "ignore_missing": true } }, + { "rename": { "field": "message2.password", "target_field": "password", "ignore_missing": true } }, + { "rename": { "field": "message2.command", "target_field": "ftp_command", "ignore_missing": true } }, + { "rename": { "field": "message2.arg", "target_field": "ftp_argument", "ignore_missing": true } }, + { "rename": { "field": "message2.mime_type", "target_field": "mimetype", "ignore_missing": true } }, + { "rename": { "field": "message2.file_size", "target_field": "file_size", "ignore_missing": true } }, + { "rename": { "field": "message2.reply_code", "target_field": "reply_code", "ignore_missing": true } }, + { "rename": { "field": "message2.reply_msg", "target_field": "reply_message", "ignore_missing": true } }, + { "dot_expander": { "field": "data_channel.passive", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.data_channel.passive","target_field": "data_channel_passive", "ignore_missing": true } }, + { "dot_expander": { "field": "data_channel.orig_h", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.data_channel.orig_h","target_field": "data_channel_source_ip", "ignore_missing": true } }, + { "dot_expander": { "field": "data_channel.resp_h", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.data_channel.resp_h","target_field": "data_channel_destination_ip", "ignore_missing": true } }, + { "dot_expander": { "field": "data_channel.resp_p", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.data_channel.resp_p","target_field": "data_channel_destination_port", "ignore_missing": true } }, + { "rename": { "field": "message2.fuid", "target_field": "fuid", "ignore_missing": true } }, + { "pipeline": { "name": "bro_common" } } + ] +} diff --git a/salt/elasticsearch/files/ingest/bro_http b/salt/elasticsearch/files/ingest/bro_http new file mode 100644 index 000000000..842a12bc9 --- /dev/null +++ b/salt/elasticsearch/files/ingest/bro_http @@ -0,0 +1,42 @@ +{ + "description" : "bro_http", + "processors" : [ + { "json": { "field": "message", "target_field": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.uid", "target_field": "uid", "ignore_missing": true } }, + { "dot_expander": { "field": "id.orig_h", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.orig_h", "target_field": "source_ip", "ignore_missing": true } }, + { "dot_expander": { "field": "id.orig_p", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.orig_p", "target_field": "source_port", "ignore_missing": true } }, + { "dot_expander": { "field": "id.resp_h", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.resp_h", "target_field": "destination_ip", "ignore_missing": true } }, + { "dot_expander": { "field": "id.resp_p", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.resp_p", "target_field": "destination_port", "ignore_missing": true } }, + { "rename": { "field": "message2.trans_depth", "target_field": "trans_depth", "ignore_missing": true } }, + { "rename": { "field": "message2.method", "target_field": "method", "ignore_missing": true } }, + { "rename": { "field": "message2.host", "target_field": "virtual_host", "ignore_missing": true } }, + { "rename": { "field": "message2.uri", "target_field": "uri", "ignore_missing": true } }, + { "rename": { "field": "message2.referrer", "target_field": "referrer", "ignore_missing": true } }, + { "rename": { "field": "message2.version", "target_field": "version", "ignore_missing": true } }, + { "rename": { "field": "message2.user_agent", "target_field": "useragent", "ignore_missing": true } }, + { "rename": { "field": "message2.request_body_len", "target_field": "request_body_length", "ignore_missing": true } }, + { "rename": { "field": "message2.response_body_len","target_field": "response_body_length", "ignore_missing": true } }, + { "rename": { "field": "message2.status_code", "target_field": "status_code", "ignore_missing": true } }, + { "rename": { "field": "message2.status_msg", "target_field": "status_message", "ignore_missing": true } }, + { "rename": { "field": "message2.info_code", "target_field": "info_code", "ignore_missing": true } }, + { "rename": { "field": "message2.info_msg", "target_field": "info_message", "ignore_missing": true } }, + { "remove": { "field": "message2.tags", "ignore_failure": true } }, + { "rename": { "field": "message2.username", "target_field": "user", "ignore_missing": true } }, + { "rename": { "field": "message2.password", "target_field": "password", "ignore_missing": true } }, + { "rename": { "field": "message2.proxied", "target_field": "proxied", "ignore_missing": true } }, + { "rename": { "field": "message2.orig_fuids", "target_field": "orig_fuids", "ignore_missing": true } }, + { "rename": { "field": "message2.orig_filenames", "target_field": "orig_filenames", "ignore_missing": true } }, + { "rename": { "field": "message2.orig_mime_types", "target_field": "orig_mime_types", "ignore_missing": true } }, + { "rename": { "field": "message2.resp_fuids", "target_field": "resp_fuids", "ignore_missing": true } }, + { "rename": { "field": "message2.resp_filenames", "target_field": "resp_filenames", "ignore_missing": true } }, + { "rename": { "field": "message2.resp_mime_types", "target_field": "resp_mime_types", "ignore_missing": true } }, + { "script": { "lang": "painless", "source": "ctx.uri_length = ctx.uri.length()", "ignore_failure": true } }, + { "script": { "lang": "painless", "source": "ctx.useragent_length = ctx.useragent.length()", "ignore_failure": true } }, + { "script": { "lang": "painless", "source": "ctx.virtual_host_length = ctx.virtual_host.length()", "ignore_failure": true } }, + { "pipeline": { "name": "bro_common" } } + ] +} diff --git a/salt/elasticsearch/files/ingest/bro_intel b/salt/elasticsearch/files/ingest/bro_intel new file mode 100644 index 000000000..20bf90c5a --- /dev/null +++ b/salt/elasticsearch/files/ingest/bro_intel @@ -0,0 +1,29 @@ +{ + "description" : "bro_intel", + "processors" : [ + { "json": { "field": "message", "target_field": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.uid", "target_field": "uid", "ignore_missing": true } }, + { "dot_expander": { "field": "id.orig_h", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.orig_h", "target_field": "source_ip", "ignore_missing": true } }, + { "dot_expander": { "field": "id.orig_p", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.orig_p", "target_field": "source_port", "ignore_missing": true } }, + { "dot_expander": { "field": "id.resp_h", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.resp_h", "target_field": "destination_ip", "ignore_missing": true } }, + { "dot_expander": { "field": "id.resp_p", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.resp_p", "target_field": "destination_port", "ignore_missing": true } }, + { "dot_expander": { "field": "seen.indicator", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.seen.indicator", "target_field": "indicator", "ignore_missing": true } }, + { "dot_expander": { "field": "seen.indicator_type", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.seen.indicator_type", "target_field": "indicator_type", "ignore_missing": true } }, + { "dot_expander": { "field": "seen.where", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.seen.where", "target_field": "seen_where", "ignore_missing": true } }, + { "dot_expander": { "field": "seen.node", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.seen.node", "target_field": "seen_node", "ignore_missing": true } }, + { "rename": { "field": "message2.matched", "target_field": "matched", "ignore_missing": true } }, + { "rename": { "field": "message2.sources", "target_field": "sources", "ignore_missing": true } }, + { "rename": { "field": "message2.fuid", "target_field": "fuid", "ignore_missing": true } }, + { "rename": { "field": "message2.file_mime_type", "target_field": "mimetype", "ignore_missing": true } }, + { "rename": { "field": "message2.file_desc", "target_field": "file_description", "ignore_missing": true } }, + { "pipeline": { "name": "bro_common" } } + ] +} diff --git a/salt/elasticsearch/files/ingest/bro_irc b/salt/elasticsearch/files/ingest/bro_irc new file mode 100644 index 000000000..c2a5ba22d --- /dev/null +++ b/salt/elasticsearch/files/ingest/bro_irc @@ -0,0 +1,25 @@ +{ + "description" : "bro_irc", + "processors" : [ + { "json": { "field": "message", "target_field": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.uid", "target_field": "uid", "ignore_missing": true } }, + { "dot_expander": { "field": "id.orig_h", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.orig_h", "target_field": "source_ip", "ignore_missing": true } }, + { "dot_expander": { "field": "id.orig_p", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.orig_p", "target_field": "source_port", "ignore_missing": true } }, + { "dot_expander": { "field": "id.resp_h", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.resp_h", "target_field": "destination_ip", "ignore_missing": true } }, + { "dot_expander": { "field": "id.resp_p", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.resp_p", "target_field": "destination_port", "ignore_missing": true } }, + { "rename": { "field": "message2.nick", "target_field": "nick", "ignore_missing": true } }, + { "rename": { "field": "message2.user", "target_field": "irc_username", "ignore_missing": true } }, + { "rename": { "field": "message2.command", "target_field": "irc_command", "ignore_missing": true } }, + { "rename": { "field": "message2.value", "target_field": "value", "ignore_missing": true } }, + { "rename": { "field": "message2.addl", "target_field": "additional_info", "ignore_missing": true } }, + { "rename": { "field": "message2.dcc_file_name", "target_field": "dcc_file_name", "ignore_missing": true } }, + { "rename": { "field": "message2.dcc_file_size", "target_field": "dcc_file_size", "ignore_missing": true } }, + { "rename": { "field": "message2.dcc_mime_type", "target_field": "dcc_mime_type", "ignore_missing": true } }, + { "rename": { "field": "message2.fuid", "target_field": "fuid", "ignore_missing": true } }, + { "pipeline": { "name": "bro_common" } } + ] +} diff --git a/salt/elasticsearch/files/ingest/bro_kerberos b/salt/elasticsearch/files/ingest/bro_kerberos new file mode 100644 index 000000000..b338b5c96 --- /dev/null +++ b/salt/elasticsearch/files/ingest/bro_kerberos @@ -0,0 +1,30 @@ +{ + "description" : "bro_kerberos", + "processors" : [ + { "json": { "field": "message", "target_field": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.uid", "target_field": "uid", "ignore_missing": true } }, + { "dot_expander": { "field": "id.orig_h", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.orig_h", "target_field": "source_ip", "ignore_missing": true } }, + { "dot_expander": { "field": "id.orig_p", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.orig_p", "target_field": "source_port", "ignore_missing": true } }, + { "dot_expander": { "field": "id.resp_h", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.resp_h", "target_field": "destination_ip", "ignore_missing": true } }, + { "dot_expander": { "field": "id.resp_p", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.resp_p", "target_field": "destination_port", "ignore_missing": true } }, + { "rename": { "field": "message2.request_type", "target_field": "request_type", "ignore_missing": true } }, + { "rename": { "field": "message2.client", "target_field": "client", "ignore_missing": true } }, + { "rename": { "field": "message2.service", "target_field": "service", "ignore_missing": true } }, + { "rename": { "field": "message2.success", "target_field": "kerberos_success", "ignore_missing": true } }, + { "rename": { "field": "message2.error_msg", "target_field": "error_message", "ignore_missing": true } }, + { "rename": { "field": "message2.from", "target_field": "valid_from", "ignore_missing": true } }, + { "rename": { "field": "message2.till", "target_field": "valid_till", "ignore_missing": true } }, + { "rename": { "field": "message2.cipher", "target_field": "cipher", "ignore_missing": true } }, + { "rename": { "field": "message2.forwardable", "target_field": "forwardable", "ignore_missing": true } }, + { "rename": { "field": "message2.renewable", "target_field": "renewable", "ignore_missing": true } }, + { "rename": { "field": "message2.client_cert_subject", "target_field": "client_certificate_subject", "ignore_missing": true } }, + { "rename": { "field": "message2.client_cert_fuid", "target_field": "client_certificate_fuid", "ignore_missing": true } }, + { "rename": { "field": "message2.server_cert_subject", "target_field": "server_certificate_subject", "ignore_missing": true } }, + { "rename": { "field": "message2.server_cert_fuid", "target_field": "server_certificate_fuid", "ignore_missing": true } }, + { "pipeline": { "name": "bro_common" } } + ] +} diff --git a/salt/elasticsearch/files/ingest/bro_modbus b/salt/elasticsearch/files/ingest/bro_modbus new file mode 100644 index 000000000..10e7c271a --- /dev/null +++ b/salt/elasticsearch/files/ingest/bro_modbus @@ -0,0 +1,18 @@ +{ + "description" : "bro_modbus", + "processors" : [ + { "json": { "field": "message", "target_field": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.uid", "target_field": "uid", "ignore_missing": true } }, + { "dot_expander": { "field": "id.orig_h", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.orig_h", "target_field": "source_ip", "ignore_missing": true } }, + { "dot_expander": { "field": "id.orig_p", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.orig_p", "target_field": "source_port", "ignore_missing": true } }, + { "dot_expander": { "field": "id.resp_h", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.resp_h", "target_field": "destination_ip", "ignore_missing": true } }, + { "dot_expander": { "field": "id.resp_p", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.resp_p", "target_field": "destination_port", "ignore_missing": true } }, + { "rename": { "field": "message2.func", "target_field": "function", "ignore_missing": true } }, + { "rename": { "field": "message2.exception", "target_field": "exception", "ignore_missing": true } }, + { "pipeline": { "name": "bro_common" } } + ] +} diff --git a/salt/elasticsearch/files/ingest/bro_mysql b/salt/elasticsearch/files/ingest/bro_mysql new file mode 100644 index 000000000..a01d57da2 --- /dev/null +++ b/salt/elasticsearch/files/ingest/bro_mysql @@ -0,0 +1,21 @@ +{ + "description" : "bro_mysql", + "processors" : [ + { "json": { "field": "message", "target_field": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.uid", "target_field": "uid", "ignore_missing": true } }, + { "dot_expander": { "field": "id.orig_h", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.orig_h", "target_field": "source_ip", "ignore_missing": true } }, + { "dot_expander": { "field": "id.orig_p", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.orig_p", "target_field": "source_port", "ignore_missing": true } }, + { "dot_expander": { "field": "id.resp_h", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.resp_h", "target_field": "destination_ip", "ignore_missing": true } }, + { "dot_expander": { "field": "id.resp_p", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.resp_p", "target_field": "destination_port", "ignore_missing": true } }, + { "rename": { "field": "message2.cmd", "target_field": "mysql_command", "ignore_missing": true } }, + { "rename": { "field": "message2.arg", "target_field": "mysql_argument", "ignore_missing": true } }, + { "rename": { "field": "message2.success", "target_field": "mysql_success", "ignore_missing": true } }, + { "rename": { "field": "message2.rows", "target_field": "rows", "ignore_missing": true } }, + { "rename": { "field": "message2.response", "target_field": "response", "ignore_missing": true } }, + { "pipeline": { "name": "bro_common" } } + ] +} diff --git a/salt/elasticsearch/files/ingest/bro_notice b/salt/elasticsearch/files/ingest/bro_notice new file mode 100644 index 000000000..6e43448d5 --- /dev/null +++ b/salt/elasticsearch/files/ingest/bro_notice @@ -0,0 +1,36 @@ +{ + "description" : "bro_notice", + "processors" : [ + { "json": { "field": "message", "target_field": "message2", "ignore_failure": true } }, + { "remove": { "field": "message2.dst", "ignore_failure": true } }, + { "remove": { "field": "message2.src", "ignore_failure": true } }, + { "rename": { "field": "message2.uid", "target_field": "uid", "ignore_missing": true } }, + { "dot_expander": { "field": "id.orig_h", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.orig_h", "target_field": "source_ip", "ignore_missing": true } }, + { "dot_expander": { "field": "id.orig_p", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.orig_p", "target_field": "source_port", "ignore_missing": true } }, + { "dot_expander": { "field": "id.resp_h", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.resp_h", "target_field": "destination_ip", "ignore_missing": true } }, + { "dot_expander": { "field": "id.resp_p", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.resp_p", "target_field": "destination_port", "ignore_missing": true } }, + { "rename": { "field": "message2.fuid", "target_field": "fuid", "ignore_missing": true } }, + { "rename": { "field": "message2.mime", "target_field": "file_mime_type", "ignore_missing": true } }, + { "rename": { "field": "message2.desc", "target_field": "file_description", "ignore_missing": true } }, + { "rename": { "field": "message2.proto", "target_field": "protocol", "ignore_missing": true } }, + { "rename": { "field": "message2.note", "target_field": "note", "ignore_missing": true } }, + { "rename": { "field": "message2.msg", "target_field": "msg", "ignore_missing": true } }, + { "rename": { "field": "message2.sub", "target_field": "sub_msg", "ignore_missing": true } }, + { "rename": { "field": "message2.p", "target_field": "p", "ignore_missing": true } }, + { "rename": { "field": "message2.n", "target_field": "n", "ignore_missing": true } }, + { "rename": { "field": "message2.peer_descr", "target_field": "peer_description", "ignore_missing": true } }, + { "rename": { "field": "message2.actions", "target_field": "action", "ignore_missing": true } }, + { "rename": { "field": "message2.suppress_for", "target_field": "suppress_for", "ignore_missing": true } }, + { "rename": { "field": "message2.dropped", "target_field": "dropped", "ignore_missing": true } }, + { "rename": { "field": "message2.destination_country_code", "target_field": "destination_country_code", "ignore_missing": true } }, + { "rename": { "field": "message2.destination_region", "target_field": "destination_region", "ignore_missing": true } }, + { "rename": { "field": "message2.destination_city", "target_field": "destination_city", "ignore_missing": true } }, + { "rename": { "field": "message2.destination_latitude", "target_field": "destination_latitude", "ignore_missing": true } }, + { "rename": { "field": "message2.destination_longitude", "target_field": "destination_longitude", "ignore_missing": true } }, + { "pipeline": { "name": "bro_common" } } + ] +} diff --git a/salt/elasticsearch/files/ingest/bro_ntlm b/salt/elasticsearch/files/ingest/bro_ntlm new file mode 100644 index 000000000..a3d130343 --- /dev/null +++ b/salt/elasticsearch/files/ingest/bro_ntlm @@ -0,0 +1,24 @@ +{ + "description" : "bro_ntlm", + "processors" : [ + { "json": { "field": "message", "target_field": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.uid", "target_field": "uid", "ignore_missing": true } }, + { "dot_expander": { "field": "id.orig_h", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.orig_h", "target_field": "source_ip", "ignore_missing": true } }, + { "dot_expander": { "field": "id.orig_p", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.orig_p", "target_field": "source_port", "ignore_missing": true } }, + { "dot_expander": { "field": "id.resp_h", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.resp_h", "target_field": "destination_ip", "ignore_missing": true } }, + { "dot_expander": { "field": "id.resp_p", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.resp_p", "target_field": "destination_port", "ignore_missing": true } }, + { "rename": { "field": "message2.hostname", "target_field": "hostname", "ignore_missing": true } }, + { "rename": { "field": "message2.domainname", "target_field": "domain_name", "ignore_missing": true } }, + { "rename": { "field": "message2.success", "target_field": "ntlm_success", "ignore_missing": true } }, + { "rename": { "field": "message2.status", "target_field": "status", "ignore_missing": true } }, + { "rename": { "field": "message2.username", "target_field": "username", "ignore_missing": true } }, + { "rename": { "field": "message2.server_dns_computer_name", "target_field": "server_dns_computer_name", "ignore_missing": true } }, + { "rename": { "field": "message2.server_nb_computer_name", "target_field": "server_nb_computer_name", "ignore_missing": true } }, + { "rename": { "field": "message2.server_tree_name", "target_field": "server_tree_name", "ignore_missing": true } }, + { "pipeline": { "name": "bro_common" } } + ] +} diff --git a/salt/elasticsearch/files/ingest/bro_pe b/salt/elasticsearch/files/ingest/bro_pe new file mode 100644 index 000000000..2597d3e26 --- /dev/null +++ b/salt/elasticsearch/files/ingest/bro_pe @@ -0,0 +1,23 @@ +{ + "description" : "bro_pe", + "processors" : [ + { "json": { "field": "message", "target_field": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id", "target_field": "fuid", "ignore_missing": true } }, + { "rename": { "field": "message2.machine", "target_field": "machine", "ignore_missing": true } }, + { "rename": { "field": "message2.compile_ts", "target_field": "compile_ts", "ignore_missing": true } }, + { "rename": { "field": "message2.os", "target_field": "os", "ignore_missing": true } }, + { "rename": { "field": "message2.subsystem", "target_field": "subsystem", "ignore_missing": true } }, + { "rename": { "field": "message2.is_exe", "target_field": "is_exe", "ignore_missing": true } }, + { "rename": { "field": "message2.is_64bit", "target_field": "is_64bit", "ignore_missing": true } }, + { "rename": { "field": "message2.uses_aslr", "target_field": "uses_aslr", "ignore_missing": true } }, + { "rename": { "field": "message2.uses_dep", "target_field": "uses_dep", "ignore_missing": true } }, + { "rename": { "field": "message2.uses_code_integrity","target_field": "uses_code_integrity","ignore_missing": true } }, + { "rename": { "field": "message2.uses_seh", "target_field": "uses_seh", "ignore_missing": true } }, + { "rename": { "field": "message2.has_import_table", "target_field": "has_import_table", "ignore_missing": true } }, + { "rename": { "field": "message2.has_export_table", "target_field": "has_export_table", "ignore_missing": true } }, + { "rename": { "field": "message2.has_cert_table", "target_field": "has_cert_table", "ignore_missing": true } }, + { "rename": { "field": "message2.has_debug_data", "target_field": "has_debug_data", "ignore_missing": true } }, + { "rename": { "field": "message2.section_names", "target_field": "section_names", "ignore_missing": true } }, + { "pipeline": { "name": "bro_common" } } + ] +} diff --git a/salt/elasticsearch/files/ingest/bro_radius b/salt/elasticsearch/files/ingest/bro_radius new file mode 100644 index 000000000..c333711d6 --- /dev/null +++ b/salt/elasticsearch/files/ingest/bro_radius @@ -0,0 +1,25 @@ +{ + "description" : "bro_radius", + "processors" : [ + { "json": { "field": "message", "target_field": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.uid", "target_field": "uid", "ignore_missing": true } }, + { "dot_expander": { "field": "id.orig_h", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.orig_h", "target_field": "source_ip", "ignore_missing": true } }, + { "dot_expander": { "field": "id.orig_p", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.orig_p", "target_field": "source_port", "ignore_missing": true } }, + { "dot_expander": { "field": "id.resp_h", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.resp_h", "target_field": "destination_ip", "ignore_missing": true } }, + { "dot_expander": { "field": "id.resp_p", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.resp_p", "target_field": "destination_port", "ignore_missing": true } }, + { "rename": { "field": "message2.username", "target_field": "username", "ignore_missing": true } }, + { "rename": { "field": "message2.mac", "target_field": "mac", "ignore_missing": true } }, + { "rename": { "field": "message2.framed_addr", "target_field": "framed_addr", "ignore_missing": true } }, + { "rename": { "field": "message2.remote_ip", "target_field": "remote_ip", "ignore_missing": true } }, + { "rename": { "field": "message2.connect_info", "target_field": "connect_info", "ignore_missing": true } }, + { "rename": { "field": "message2.reply_msg", "target_field": "reply_message", "ignore_missing": true } }, + { "rename": { "field": "message2.result", "target_field": "result", "ignore_missing": true } }, + { "remove": { "field": "message2.ttl", "ignore_failure": true } }, + { "rename": { "field": "message2.logged", "target_field": "logged", "ignore_missing": true } }, + { "pipeline": { "name": "bro_common" } } + ] +} diff --git a/salt/elasticsearch/files/ingest/bro_rdp b/salt/elasticsearch/files/ingest/bro_rdp new file mode 100644 index 000000000..b3cf206a5 --- /dev/null +++ b/salt/elasticsearch/files/ingest/bro_rdp @@ -0,0 +1,31 @@ +{ + "description" : "bro_rdp", + "processors" : [ + { "json": { "field": "message", "target_field": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.uid", "target_field": "uid", "ignore_missing": true } }, + { "dot_expander": { "field": "id.orig_h", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.orig_h", "target_field": "source_ip", "ignore_missing": true } }, + { "dot_expander": { "field": "id.orig_p", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.orig_p", "target_field": "source_port", "ignore_missing": true } }, + { "dot_expander": { "field": "id.resp_h", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.resp_h", "target_field": "destination_ip", "ignore_missing": true } }, + { "dot_expander": { "field": "id.resp_p", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.resp_p", "target_field": "destination_port", "ignore_missing": true } }, + { "rename": { "field": "message2.cookie", "target_field": "cookie", "ignore_missing": true } }, + { "rename": { "field": "message2.result", "target_field": "result", "ignore_missing": true } }, + { "rename": { "field": "message2.security_protocol","target_field": "security_protocol", "ignore_missing": true } }, + { "rename": { "field": "message2.keyboard_layout", "target_field": "keyboard_layout", "ignore_missing": true } }, + { "rename": { "field": "message2.client_build", "target_field": "client_build", "ignore_missing": true } }, + { "rename": { "field": "message2.client_name", "target_field": "client_name", "ignore_missing": true } }, + { "rename": { "field": "message2.client_dig_product_id", "target_field": "client_digital_product_id", "ignore_missing": true } }, + { "rename": { "field": "message2.desktop_width", "target_field": "desktop_width", "ignore_missing": true } }, + { "rename": { "field": "message2.desktop_height", "target_field": "desktop_height", "ignore_missing": true } }, + { "rename": { "field": "message2.requested_color_depth", "target_field": "requested_color_depth", "ignore_missing": true } }, + { "rename": { "field": "message2.cert_type", "target_field": "certificate_type", "ignore_missing": true } }, + { "rename": { "field": "message2.cert_count", "target_field": "certificate_count", "ignore_missing": true } }, + { "rename": { "field": "message2.cert_permanent", "target_field": "certificate_permanent","ignore_missing": true } }, + { "rename": { "field": "message2.encryption_level", "target_field": "encryption_level", "ignore_missing": true } }, + { "rename": { "field": "message2.encryption_method","target_field": "encryption_method", "ignore_missing": true } }, + { "pipeline": { "name": "bro_common" } } + ] +} diff --git a/salt/elasticsearch/files/ingest/bro_rfb b/salt/elasticsearch/files/ingest/bro_rfb new file mode 100644 index 000000000..8f3cc86e7 --- /dev/null +++ b/salt/elasticsearch/files/ingest/bro_rfb @@ -0,0 +1,26 @@ +{ + "description" : "bro_rfb", + "processors" : [ + { "json": { "field": "message", "target_field": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.uid", "target_field": "uid", "ignore_missing": true } }, + { "dot_expander": { "field": "id.orig_h", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.orig_h", "target_field": "source_ip", "ignore_missing": true } }, + { "dot_expander": { "field": "id.orig_p", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.orig_p", "target_field": "source_port", "ignore_missing": true } }, + { "dot_expander": { "field": "id.resp_h", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.resp_h", "target_field": "destination_ip", "ignore_missing": true } }, + { "dot_expander": { "field": "id.resp_p", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.resp_p", "target_field": "destination_port", "ignore_missing": true } }, + { "rename": { "field": "message2.client_major_version", "target_field": "client_major_version", "ignore_missing": true } }, + { "rename": { "field": "message2.client_minor_version", "target_field": "client_minor_version", "ignore_missing": true } }, + { "rename": { "field": "message2.server_major_version", "target_field": "server_major_version", "ignore_missing": true } }, + { "rename": { "field": "message2.server_minor_version", "target_field": "server_minor_version", "ignore_missing": true } }, + { "rename": { "field": "message2.authentication_method", "target_field": "authentication_method","ignore_missing": true } }, + { "rename": { "field": "message2.auth", "target_field": "auth", "ignore_missing": true } }, + { "rename": { "field": "message2.share_flag", "target_field": "share_flag", "ignore_missing": true } }, + { "rename": { "field": "message2.desktop_name", "target_field": "desktop_name", "ignore_missing": true } }, + { "rename": { "field": "message2.width", "target_field": "width", "ignore_missing": true } }, + { "rename": { "field": "message2.height", "target_field": "height", "ignore_missing": true } }, + { "pipeline": { "name": "bro_common" } } + ] +} diff --git a/salt/elasticsearch/files/ingest/bro_signatures b/salt/elasticsearch/files/ingest/bro_signatures new file mode 100644 index 000000000..5dd3d9924 --- /dev/null +++ b/salt/elasticsearch/files/ingest/bro_signatures @@ -0,0 +1,22 @@ +{ + "description" : "bro_signatures", + "processors" : [ + { "json": { "field": "message", "target_field": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.uid", "target_field": "uid", "ignore_missing": true } }, + { "dot_expander": { "field": "id.orig_h", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.orig_h", "target_field": "source_ip", "ignore_missing": true } }, + { "dot_expander": { "field": "id.orig_p", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.orig_p", "target_field": "source_port", "ignore_missing": true } }, + { "dot_expander": { "field": "id.resp_h", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.resp_h", "target_field": "destination_ip", "ignore_missing": true } }, + { "dot_expander": { "field": "id.resp_p", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.resp_p", "target_field": "destination_port", "ignore_missing": true } }, + { "rename": { "field": "message2.note", "target_field": "note", "ignore_missing": true } }, + { "rename": { "field": "message2.sig_id", "target_field": "signature_id", "ignore_missing": true } }, + { "rename": { "field": "message2.event_msg", "target_field": "event_message", "ignore_missing": true } }, + { "rename": { "field": "message2.sub_msg", "target_field": "sub_message", "ignore_missing": true } }, + { "rename": { "field": "message2.sig_count", "target_field": "signature_count", "ignore_missing": true } }, + { "rename": { "field": "message2.host_count", "target_field": "host_count", "ignore_missing": true } }, + { "pipeline": { "name": "bro_common" } } + ] +} diff --git a/salt/elasticsearch/files/ingest/bro_sip b/salt/elasticsearch/files/ingest/bro_sip new file mode 100644 index 000000000..3a8b00d62 --- /dev/null +++ b/salt/elasticsearch/files/ingest/bro_sip @@ -0,0 +1,37 @@ +{ + "description" : "bro_sip", + "processors" : [ + { "json": { "field": "message", "target_field": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.uid", "target_field": "uid", "ignore_missing": true } }, + { "dot_expander": { "field": "id.orig_h", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.orig_h", "target_field": "source_ip", "ignore_missing": true } }, + { "dot_expander": { "field": "id.orig_p", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.orig_p", "target_field": "source_port", "ignore_missing": true } }, + { "dot_expander": { "field": "id.resp_h", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.resp_h", "target_field": "destination_ip", "ignore_missing": true } }, + { "dot_expander": { "field": "id.resp_p", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.resp_p", "target_field": "destination_port", "ignore_missing": true } }, + { "rename": { "field": "message2.trans_depth", "target_field": "trans_depth", "ignore_missing": true } }, + { "rename": { "field": "message2.method", "target_field": "method", "ignore_missing": true } }, + { "rename": { "field": "message2.uri", "target_field": "uri", "ignore_missing": true } }, + { "rename": { "field": "message2.date", "target_field": "date", "ignore_missing": true } }, + { "rename": { "field": "message2.request_from", "target_field": "request_from", "ignore_missing": true } }, + { "rename": { "field": "message2.request_to", "target_field": "request_to", "ignore_missing": true } }, + { "rename": { "field": "message2.response_from", "target_field": "response_from", "ignore_missing": true } }, + { "rename": { "field": "message2.response_to", "target_field": "response_to", "ignore_missing": true } }, + { "rename": { "field": "message2.reply_to", "target_field": "reply_to", "ignore_missing": true } }, + { "rename": { "field": "message2.call_id", "target_field": "call_id", "ignore_missing": true } }, + { "rename": { "field": "message2.seq", "target_field": "seq", "ignore_missing": true } }, + { "rename": { "field": "message2.subject", "target_field": "subject", "ignore_missing": true } }, + { "rename": { "field": "message2.request_path", "target_field": "request_path", "ignore_missing": true } }, + { "rename": { "field": "message2.response_path", "target_field": "response_path", "ignore_missing": true } }, + { "rename": { "field": "message2.user_agent", "target_field": "user_agent", "ignore_missing": true } }, + { "rename": { "field": "message2.status_code", "target_field": "status_code", "ignore_missing": true } }, + { "rename": { "field": "message2.status_msg", "target_field": "status_msg", "ignore_missing": true } }, + { "rename": { "field": "message2.warning", "target_field": "warning", "ignore_missing": true } }, + { "rename": { "field": "message2.request_body_len", "target_field": "request_body_length", "ignore_missing": true } }, + { "rename": { "field": "message2.response_body_len","target_field": "response_body_length", "ignore_missing": true } }, + { "rename": { "field": "message2.content_type", "target_field": "content_type", "ignore_missing": true } }, + { "pipeline": { "name": "bro_common" } } + ] +} diff --git a/salt/elasticsearch/files/ingest/bro_smb_files b/salt/elasticsearch/files/ingest/bro_smb_files new file mode 100644 index 000000000..83ba8bd67 --- /dev/null +++ b/salt/elasticsearch/files/ingest/bro_smb_files @@ -0,0 +1,31 @@ +{ + "description" : "bro_smb_files", + "processors" : [ + { "json": { "field": "message", "target_field": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.uid", "target_field": "uid", "ignore_missing": true } }, + { "dot_expander": { "field": "id.orig_h", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.orig_h", "target_field": "source_ip", "ignore_missing": true } }, + { "dot_expander": { "field": "id.orig_p", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.orig_p", "target_field": "source_port", "ignore_missing": true } }, + { "dot_expander": { "field": "id.resp_h", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.resp_h", "target_field": "destination_ip", "ignore_missing": true } }, + { "dot_expander": { "field": "id.resp_p", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.resp_p", "target_field": "destination_port", "ignore_missing": true } }, + { "rename": { "field": "message2.fuid", "target_field": "fuid", "ignore_missing": true } }, + { "rename": { "field": "message2.action", "target_field": "action", "ignore_missing": true } }, + { "remove": { "field": "path", "ignore_failure": true } }, + { "rename": { "field": "message2.path", "target_field": "path", "ignore_missing": true } }, + { "rename": { "field": "message2.name", "target_field": "name", "ignore_missing": true } }, + { "rename": { "field": "message2.size", "target_field": "size", "ignore_missing": true } }, + { "rename": { "field": "message2.prev_name", "target_field": "prev_name", "ignore_missing": true } }, + { "dot_expander": { "field": "times.modified", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.times.modified", "target_field": "times_modified", "ignore_missing": true } }, + { "dot_expander": { "field": "times.accessed", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.times.accessed", "target_field": "times_accessed", "ignore_missing": true } }, + { "dot_expander": { "field": "times.created", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.times.created", "target_field": "times_created", "ignore_missing": true } }, + { "dot_expander": { "field": "times.changed", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.times.changed", "target_field": "times_changed", "ignore_missing": true } }, + { "pipeline": { "name": "bro_common" } } + ] +} diff --git a/salt/elasticsearch/files/ingest/bro_smb_mapping b/salt/elasticsearch/files/ingest/bro_smb_mapping new file mode 100644 index 000000000..e1b6b5dfb --- /dev/null +++ b/salt/elasticsearch/files/ingest/bro_smb_mapping @@ -0,0 +1,21 @@ +{ + "description" : "bro_smb_files", + "processors" : [ + { "json": { "field": "message", "target_field": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.uid", "target_field": "uid", "ignore_missing": true } }, + { "dot_expander": { "field": "id.orig_h", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.orig_h", "target_field": "source_ip", "ignore_missing": true } }, + { "dot_expander": { "field": "id.orig_p", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.orig_p", "target_field": "source_port", "ignore_missing": true } }, + { "dot_expander": { "field": "id.resp_h", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.resp_h", "target_field": "destination_ip", "ignore_missing": true } }, + { "dot_expander": { "field": "id.resp_p", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.resp_p", "target_field": "destination_port", "ignore_missing": true } }, + { "remove": { "field": "path", "ignore_failure": true } }, + { "rename": { "field": "message2.path", "target_field": "path", "ignore_missing": true } }, + { "rename": { "field": "message2.service", "target_field": "service", "ignore_missing": true } }, + { "rename": { "field": "message2.native_file_system", "target_field": "native_file_system", "ignore_missing": true } }, + { "rename": { "field": "message2.share_type", "target_field": "share_type", "ignore_missing": true } }, + { "pipeline": { "name": "bro_common" } } + ] +} diff --git a/salt/elasticsearch/files/ingest/bro_smtp b/salt/elasticsearch/files/ingest/bro_smtp new file mode 100644 index 000000000..4bd85a293 --- /dev/null +++ b/salt/elasticsearch/files/ingest/bro_smtp @@ -0,0 +1,38 @@ +{ + "description" : "bro_smtp", + "processors" : [ + { "json": { "field": "message", "target_field": "message2", "ignore_failure": true } }, + { "remove": { "field": "path", "ignore_failure": true } }, + { "rename": { "field": "message2.uid", "target_field": "uid", "ignore_missing": true } }, + { "dot_expander": { "field": "id.orig_h", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.orig_h", "target_field": "source_ip", "ignore_missing": true } }, + { "dot_expander": { "field": "id.orig_p", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.orig_p", "target_field": "source_port", "ignore_missing": true } }, + { "dot_expander": { "field": "id.resp_h", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.resp_h", "target_field": "destination_ip", "ignore_missing": true } }, + { "dot_expander": { "field": "id.resp_p", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.resp_p", "target_field": "destination_port", "ignore_missing": true } }, + { "rename": { "field": "message2.trans_depth", "target_field": "trans_depth", "ignore_missing": true } }, + { "rename": { "field": "message2.helo", "target_field": "helo", "ignore_missing": true } }, + { "rename": { "field": "message2.mailfrom", "target_field": "mail_from", "ignore_missing": true } }, + { "rename": { "field": "message2.rcptto", "target_field": "recipient_to", "ignore_missing": true } }, + { "rename": { "field": "message2.date", "target_field": "mail_date", "ignore_missing": true } }, + { "rename": { "field": "message2.from", "target_field": "from", "ignore_missing": true } }, + { "rename": { "field": "message2.to", "target_field": "to", "ignore_missing": true } }, + { "rename": { "field": "message2.cc", "target_field": "cc", "ignore_missing": true } }, + { "rename": { "field": "message2.reply_to", "target_field": "reply_to", "ignore_missing": true } }, + { "rename": { "field": "message2.msg_id", "target_field": "message_id", "ignore_missing": true } }, + { "rename": { "field": "message2.in_reply_to", "target_field": "in_reply_to", "ignore_missing": true } }, + { "rename": { "field": "message2.subject", "target_field": "subject", "ignore_missing": true } }, + { "rename": { "field": "message2.x_originating_ip", "target_field": "x_originating_ip", "ignore_missing": true } }, + { "rename": { "field": "message2.first_received", "target_field": "first_received", "ignore_missing": true } }, + { "rename": { "field": "message2.second_received", "target_field": "second_received", "ignore_missing": true } }, + { "rename": { "field": "message2.last_reply", "target_field": "last_reply", "ignore_missing": true } }, + { "rename": { "field": "message2.path", "target_field": "path", "ignore_missing": true } }, + { "rename": { "field": "message2.user_agent", "target_field": "useragent", "ignore_missing": true } }, + { "rename": { "field": "message2.tls", "target_field": "tls", "ignore_missing": true } }, + { "rename": { "field": "message2.fuids", "target_field": "fuids", "ignore_missing": true } }, + { "rename": { "field": "message2.is_webmail", "target_field": "is_webmail", "ignore_missing": true } }, + { "pipeline": { "name": "bro_common" } } + ] +} diff --git a/salt/elasticsearch/files/ingest/bro_snmp b/salt/elasticsearch/files/ingest/bro_snmp new file mode 100644 index 000000000..bec88c1af --- /dev/null +++ b/salt/elasticsearch/files/ingest/bro_snmp @@ -0,0 +1,25 @@ +{ + "description" : "bro_snmp", + "processors" : [ + { "json": { "field": "message", "target_field": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.uid", "target_field": "uid", "ignore_missing": true } }, + { "dot_expander": { "field": "id.orig_h", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.orig_h", "target_field": "source_ip", "ignore_missing": true } }, + { "dot_expander": { "field": "id.orig_p", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.orig_p", "target_field": "source_port", "ignore_missing": true } }, + { "dot_expander": { "field": "id.resp_h", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.resp_h", "target_field": "destination_ip", "ignore_missing": true } }, + { "dot_expander": { "field": "id.resp_p", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.resp_p", "target_field": "destination_port", "ignore_missing": true } }, + { "rename": { "field": "message2.duration", "target_field": "duration", "ignore_missing": true } }, + { "rename": { "field": "message2.version", "target_field": "version", "ignore_missing": true } }, + { "rename": { "field": "message2.community", "target_field": "community", "ignore_missing": true } }, + { "rename": { "field": "message2.get_requests", "target_field": "get_requests", "ignore_missing": true } }, + { "rename": { "field": "message2.get_bulk_requests","target_field": "get_bulk_requests", "ignore_missing": true } }, + { "rename": { "field": "message2.get_responses", "target_field": "get_responses", "ignore_missing": true } }, + { "rename": { "field": "message2.set_requests", "target_field": "set_requests", "ignore_missing": true } }, + { "rename": { "field": "message2.display_string", "target_field": "display_string", "ignore_missing": true } }, + { "rename": { "field": "message2.up_since", "target_field": "up_since", "ignore_missing": true } }, + { "pipeline": { "name": "bro_common" } } + ] +} diff --git a/salt/elasticsearch/files/ingest/bro_socks b/salt/elasticsearch/files/ingest/bro_socks new file mode 100644 index 000000000..38c5dd528 --- /dev/null +++ b/salt/elasticsearch/files/ingest/bro_socks @@ -0,0 +1,28 @@ +{ + "description" : "bro_socks", + "processors" : [ + { "json": { "field": "message", "target_field": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.uid", "target_field": "uid", "ignore_missing": true } }, + { "dot_expander": { "field": "id.orig_h", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.orig_h", "target_field": "source_ip", "ignore_missing": true } }, + { "dot_expander": { "field": "id.orig_p", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.orig_p", "target_field": "source_port", "ignore_missing": true } }, + { "dot_expander": { "field": "id.resp_h", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.resp_h", "target_field": "destination_ip", "ignore_missing": true } }, + { "dot_expander": { "field": "id.resp_p", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.resp_p", "target_field": "destination_port", "ignore_missing": true } }, + { "rename": { "field": "message2.version", "target_field": "version", "ignore_missing": true } }, + { "rename": { "field": "message2.user", "target_field": "user", "ignore_missing": true } }, + { "rename": { "field": "message2.password", "target_field": "password", "ignore_missing": true } }, + { "rename": { "field": "message2.status", "target_field": "status", "ignore_missing": true } }, + { "rename": { "field": "message2.request_host", "target_field": "request_host", "ignore_missing": true } }, + { "dot_expander": { "field": "request.name", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.request.name", "target_field": "request_name", "ignore_missing": true } }, + { "rename": { "field": "message2.request_p", "target_field": "request_port", "ignore_missing": true } }, + { "dot_expander": { "field": "bound.host", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.bound.host", "target_field": "bound_host", "ignore_missing": true } }, + { "rename": { "field": "message2.bound_name", "target_field": "bound_name", "ignore_missing": true } }, + { "rename": { "field": "message2.bound_p", "target_field": "bound_port", "ignore_missing": true } }, + { "pipeline": { "name": "bro_common" } } + ] +} diff --git a/salt/elasticsearch/files/ingest/bro_software b/salt/elasticsearch/files/ingest/bro_software new file mode 100644 index 000000000..e742fda9e --- /dev/null +++ b/salt/elasticsearch/files/ingest/bro_software @@ -0,0 +1,23 @@ +{ + "description" : "bro_software", + "processors" : [ + { "json": { "field": "message", "target_field": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.uid", "target_field": "uid", "ignore_missing": true } }, + { "dot_expander": { "field": "version.major", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.version.major", "target_field": "version_major", "ignore_missing": true } }, + { "dot_expander": { "field": "version.minor", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.version.minor", "target_field": "version_minor", "ignore_missing": true } }, + { "dot_expander": { "field": "version.minor2", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.version.minor2", "target_field": "version_minor2", "ignore_missing": true } }, + { "dot_expander": { "field": "version.minor3", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.version.minor3", "target_field": "version_minor3", "ignore_missing": true } }, + { "dot_expander": { "field": "version.addl", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.version.addl", "target_field": "version_additional_info", "ignore_missing": true } }, + { "rename": { "field": "message2.host", "target_field": "source_ip", "ignore_missing": true } }, + { "rename": { "field": "message2.host_p", "target_field": "source_port", "ignore_missing": true } }, + { "rename": { "field": "message2.software_type", "target_field": "software_type", "ignore_missing": true } }, + { "rename": { "field": "message2.name", "target_field": "name", "ignore_missing": true } }, + { "rename": { "field": "message2.unparsed_version", "target_field": "unparsed_version", "ignore_missing": true } }, + { "pipeline": { "name": "bro_common" } } + ] +} diff --git a/salt/elasticsearch/files/ingest/bro_ssh b/salt/elasticsearch/files/ingest/bro_ssh new file mode 100644 index 000000000..7df949503 --- /dev/null +++ b/salt/elasticsearch/files/ingest/bro_ssh @@ -0,0 +1,40 @@ +{ + "description" : "bro_conn", + "processors" : [ + { "json": { "field": "message", "target_field": "message2", "ignore_failure": true } }, + { "dot_expander": { "field": "id.orig_h", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.orig_h", "target_field": "source_ip", "ignore_missing": true } }, + { "dot_expander": { "field": "id.orig_p", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.orig_p", "target_field": "source_port", "ignore_missing": true } }, + { "dot_expander": { "field": "id.resp_h", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.resp_h", "target_field": "destination_ip", "ignore_missing": true } }, + { "dot_expander": { "field": "id.resp_p", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.resp_p", "target_field": "destination_port", "ignore_missing": true } }, + { "rename": { "field": "message2.version", "target_field": "version", "ignore_missing": true } }, + { "rename": { "field": "message2.uid", "target_field": "uid", "ignore_missing": true } }, + { "rename": { "field": "message2.hassh", "target_field": "hassh", "ignore_missing": true } }, + { "rename": { "field": "message2.auth_success", "target_field": "authentication_success", "ignore_missing": true } }, + { "rename": { "field": "message2.auth_attempts", "target_field": "authentication_attempts", "ignore_missing": true } }, + { "rename": { "field": "message2.direction", "target_field": "direction", "ignore_missing": true } }, + { "rename": { "field": "message2.client", "target_field": "client", "ignore_missing": true } }, + { "rename": { "field": "message2.server", "target_field": "server", "ignore_missing": true } }, + { "rename": { "field": "message2.cipher_alg", "target_field": "cipher_algorithm", "ignore_missing": true } }, + { "rename": { "field": "message2.compression_alg", "target_field": "compression_algorithm", "ignore_missing": true } }, + { "rename": { "field": "message2.cshka", "target_field": "client_host_key_algorithms", "ignore_missing": true } }, + { "rename": { "field": "message2.host_key_alg", "target_field": "host_key_algorithm", "ignore_missing": true } }, + { "rename": { "field": "message2.hasshAlgorithms", "target_field": "hassh_algorithms", "ignore_missing": true } }, + { "rename": { "field": "message2.hasshServer", "target_field": "hassh_server", "ignore_missing": true } }, + { "rename": { "field": "message2.hasshVersion", "target_field": "hassh_version", "ignore_missing": true } }, + { "rename": { "field": "message2.kex_alg", "target_field": "kex_algorithm", "ignore_missing": true } }, + { "rename": { "field": "message2.mac_alg", "target_field": "mac_algorithm", "ignore_missing": true } }, + { "rename": { "field": "message2.sshka", "target_field": "server_host_key_algorithms", "ignore_missing": true } }, + { "rename": { "field": "message2.host_key", "target_field": "host_key", "ignore_missing": true } }, + { "rename": { "field": "message2.destination_region", "target_field": "destination_region", "ignore_missing": true } }, + { "rename": { "field": "message2.destination_city", "target_field": "destination_city", "ignore_missing": true } }, + { "rename": { "field": "message2.destination_latitude", "target_field": "destination_latitude", "ignore_missing": true } }, + { "rename": { "field": "message2.destination_longitude", "target_field": "destination_longitude", "ignore_missing": true } }, + { "rename": { "field": "message2.destination_country_code", "target_field": "destination_country_code", "ignore_missing": true } }, + { "rename": { "field": "message2.hasshServerAlgorithms", "target_field": "hassh_server_algorithms", "ignore_missing": true } }, + { "pipeline": { "name": "bro_common" } } + ] +} diff --git a/salt/elasticsearch/files/ingest/bro_ssl b/salt/elasticsearch/files/ingest/bro_ssl new file mode 100644 index 000000000..04d0fc8ec --- /dev/null +++ b/salt/elasticsearch/files/ingest/bro_ssl @@ -0,0 +1,33 @@ +{ + "description" : "bro_ssl", + "processors" : [ + { "json": { "field": "message", "target_field": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.uid", "target_field": "uid", "ignore_missing": true } }, + { "dot_expander": { "field": "id.orig_h", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.orig_h", "target_field": "source_ip", "ignore_missing": true } }, + { "dot_expander": { "field": "id.orig_p", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.orig_p", "target_field": "source_port", "ignore_missing": true } }, + { "dot_expander": { "field": "id.resp_h", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.resp_h", "target_field": "destination_ip", "ignore_missing": true } }, + { "dot_expander": { "field": "id.resp_p", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.resp_p", "target_field": "destination_port", "ignore_missing": true } }, + { "rename": { "field": "message2.version", "target_field": "version", "ignore_missing": true } }, + { "rename": { "field": "message2.cipher", "target_field": "cipher", "ignore_missing": true } }, + { "rename": { "field": "message2.curve", "target_field": "curve", "ignore_missing": true } }, + { "rename": { "field": "message2.server_name", "target_field": "server_name", "ignore_missing": true } }, + { "rename": { "field": "message2.resumed", "target_field": "resumed", "ignore_missing": true } }, + { "rename": { "field": "message2.last_alert", "target_field": "last_alert", "ignore_missing": true } }, + { "rename": { "field": "message2.next_protocol", "target_field": "next_protocol", "ignore_missing": true } }, + { "rename": { "field": "message2.established", "target_field": "established", "ignore_missing": true } }, + { "rename": { "field": "message2.cert_chain_fuids", "target_field": "certificate_chain_fuids", "ignore_missing": true } }, + { "rename": { "field": "message2.client_cert_chain_fuids", "target_field": "client_certificate_chain_fuids", "ignore_missing": true } }, + { "rename": { "field": "message2.subject", "target_field": "certificate_subject", "ignore_missing": true } }, + { "rename": { "field": "message2.issuer", "target_field": "certificate_issuer", "ignore_missing": true } }, + { "rename": { "field": "message2.client_subject", "target_field": "client_subject", "ignore_missing": true } }, + { "rename": { "field": "message2.client_issuer", "target_field": "client_issuer", "ignore_missing": true } }, + { "rename": { "field": "message2.validation_status","target_field": "validation_status", "ignore_missing": true } }, + { "rename": { "field": "message2.ja3", "target_field": "ja3", "ignore_missing": true } }, + { "rename": { "field": "message2.ja3s", "target_field": "ja3s", "ignore_missing": true } }, + { "pipeline": { "name": "bro_common_ssl" } } + ] +} diff --git a/salt/elasticsearch/files/ingest/bro_syslog b/salt/elasticsearch/files/ingest/bro_syslog new file mode 100644 index 000000000..9599b435c --- /dev/null +++ b/salt/elasticsearch/files/ingest/bro_syslog @@ -0,0 +1,21 @@ +{ + "description" : "bro_syslog", + "processors" : [ + { "json": { "field": "message", "target_field": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.uid", "target_field": "uid", "ignore_missing": true } }, + { "dot_expander": { "field": "id.orig_h", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.orig_h", "target_field": "source_ip", "ignore_missing": true } }, + { "dot_expander": { "field": "id.orig_p", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.orig_p", "target_field": "source_port", "ignore_missing": true } }, + { "dot_expander": { "field": "id.resp_h", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.resp_h", "target_field": "destination_ip", "ignore_missing": true } }, + { "dot_expander": { "field": "id.resp_p", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.resp_p", "target_field": "destination_port", "ignore_missing": true } }, + { "rename": { "field": "message2.proto", "target_field": "protocol", "ignore_missing": true } }, + { "rename": { "field": "message2.facility", "target_field": "facility", "ignore_missing": true } }, + { "rename": { "field": "message2.severity", "target_field": "severity", "ignore_missing": true } }, + { "remove": { "field": "message", "ignore_failure": true } }, + { "rename": { "field": "message2.message", "target_field": "message", "ignore_missing": true } }, + { "pipeline": { "name": "bro_common" } } + ] +} diff --git a/salt/elasticsearch/files/ingest/bro_tunnels b/salt/elasticsearch/files/ingest/bro_tunnels new file mode 100644 index 000000000..50c12518f --- /dev/null +++ b/salt/elasticsearch/files/ingest/bro_tunnels @@ -0,0 +1,18 @@ +{ + "description" : "bro_tunnels", + "processors" : [ + { "json": { "field": "message", "target_field": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.uid", "target_field": "uid", "ignore_missing": true } }, + { "dot_expander": { "field": "id.orig_h", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.orig_h", "target_field": "source_ip", "ignore_missing": true } }, + { "dot_expander": { "field": "id.orig_p", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.orig_p", "target_field": "source_port", "ignore_missing": true } }, + { "dot_expander": { "field": "id.resp_h", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.resp_h", "target_field": "destination_ip", "ignore_missing": true } }, + { "dot_expander": { "field": "id.resp_p", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.resp_p", "target_field": "destination_port", "ignore_missing": true } }, + { "rename": { "field": "message2.tunnel_type", "target_field": "tunnel_type", "ignore_missing": true } }, + { "rename": { "field": "message2.action", "target_field": "action", "ignore_missing": true } }, + { "pipeline": { "name": "bro_common" } } + ] +} diff --git a/salt/elasticsearch/files/ingest/bro_weird b/salt/elasticsearch/files/ingest/bro_weird new file mode 100644 index 000000000..b471f5e75 --- /dev/null +++ b/salt/elasticsearch/files/ingest/bro_weird @@ -0,0 +1,20 @@ +{ + "description" : "bro_weird", + "processors" : [ + { "json": { "field": "message", "target_field": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.uid", "target_field": "uid", "ignore_missing": true } }, + { "dot_expander": { "field": "id.orig_h", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.orig_h", "target_field": "source_ip", "ignore_missing": true } }, + { "dot_expander": { "field": "id.orig_p", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.orig_p", "target_field": "source_port", "ignore_missing": true } }, + { "dot_expander": { "field": "id.resp_h", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.resp_h", "target_field": "destination_ip", "ignore_missing": true } }, + { "dot_expander": { "field": "id.resp_p", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id.resp_p", "target_field": "destination_port", "ignore_missing": true } }, + { "rename": { "field": "message2.name", "target_field": "name", "ignore_missing": true } }, + { "rename": { "field": "message2.addl", "target_field": "additional_info", "ignore_missing": true } }, + { "rename": { "field": "message2.notice", "target_field": "notice", "ignore_missing": true } }, + { "rename": { "field": "message2.peer", "target_field": "peer", "ignore_missing": true } }, + { "pipeline": { "name": "bro_common" } } + ] +} diff --git a/salt/elasticsearch/files/ingest/bro_x509 b/salt/elasticsearch/files/ingest/bro_x509 new file mode 100644 index 000000000..56e905347 --- /dev/null +++ b/salt/elasticsearch/files/ingest/bro_x509 @@ -0,0 +1,44 @@ +{ + "description" : "bro_x509", + "processors" : [ + { "json": { "field": "message", "target_field": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id", "target_field": "id", "ignore_missing": true } }, + { "dot_expander": { "field": "certificate.version", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.certificate.version", "target_field": "certificate_version", "ignore_missing": true } }, + { "dot_expander": { "field": "certificate.serial", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.certificate.serial", "target_field": "certificate_serial", "ignore_missing": true } }, + { "dot_expander": { "field": "certificate.subject", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.certificate.subject", "target_field": "certificate_subject", "ignore_missing": true } }, + { "dot_expander": { "field": "certificate.issuer", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.certificate.issuer", "target_field": "certificate_issuer", "ignore_missing": true } }, + { "dot_expander": { "field": "certificate.not_valid_before", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.certificate.not_valid_before", "target_field": "certificate_not_valid_before", "ignore_missing": true } }, + { "dot_expander": { "field": "certificate.not_valid_after", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.certificate.not_valid_after", "target_field": "certificate_not_valid_after", "ignore_missing": true } }, + { "dot_expander": { "field": "certificate.key_alg", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.certificate.key_alg", "target_field": "certificate_key_algorithm", "ignore_missing": true } }, + { "dot_expander": { "field": "certificate.sig_alg", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.certificate.sig_alg", "target_field": "certificate_signing_algorithm", "ignore_missing": true } }, + { "dot_expander": { "field": "certificate.key_type", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.certificate.key_type", "target_field": "certificate_key_type", "ignore_missing": true } }, + { "dot_expander": { "field": "certificate.key_length", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.certificate.key_length", "target_field": "certificate_key_length", "ignore_missing": true } }, + { "dot_expander": { "field": "certificate.exponent", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.certificate.exponent", "target_field": "certificate_exponent", "ignore_missing": true } }, + { "dot_expander": { "field": "certificate.curve", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.certificate.curve", "target_field": "certificate_curve", "ignore_missing": true } }, + { "dot_expander": { "field": "san.dns", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.san.dns", "target_field": "san_dns", "ignore_missing": true } }, + { "dot_expander": { "field": "san.uri", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.san.uri", "target_field": "san_uri", "ignore_missing": true } }, + { "dot_expander": { "field": "san.email", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.san.email", "target_field": "san_email", "ignore_missing": true } }, + { "dot_expander": { "field": "san.ip", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.san.ip", "target_field": "san_ip", "ignore_missing": true } }, + { "dot_expander": { "field": "basic_constraints.ca", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.basic_constraints.ca", "target_field": "basic_constraints_ca", "ignore_missing": true } }, + { "dot_expander": { "field": "basic_constraints.path_length", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.basic_constraints.path_length", "target_field": "basic_constraints_path_length", "ignore_missing": true } }, + { "pipeline": { "name": "bro_common_ssl" } } + ] +} diff --git a/salt/elasticsearch/files/ingest/common b/salt/elasticsearch/files/ingest/common new file mode 100644 index 000000000..ed227258e --- /dev/null +++ b/salt/elasticsearch/files/ingest/common @@ -0,0 +1,52 @@ +{ + "description" : "common", + "processors" : [ + { + "rename": { + "field": "type", + "target_field": "event_type", + "ignore_missing": true + } + }, + { + "geoip": { + "field": "destination_ip", + "target_field": "destination_geo", + "database_file": "GeoLite2-City.mmdb", + "ignore_missing": true, + "properties": ["ip", "country_iso_code", "country_name", "continent_name", "region_iso_code", "region_name", "city_name", "timezone", "location"] + } + }, + { + "geoip": { + "field": "source_ip", + "target_field": "source_geo", + "database_file": "GeoLite2-City.mmdb", + "ignore_missing": true, + "properties": ["ip", "country_iso_code", "country_name", "continent_name", "region_iso_code", "region_name", "city_name", "timezone", "location"] + } + }, + { + "split": { + "field": "_index", + "target_field": "index_name_prefix", + "separator": "-" + } + }, + { + "date_index_name": { + "field": "@timestamp", + "index_name_prefix": "{{index_name_prefix.0}}-{{index_name_prefix.1}}-", + "date_rounding": "d", + "ignore_failure": true, + "index_name_format": "yyyy.MM.dd" + } + }, + { + "remove": { + "field": "index_name_prefix", + "ignore_failure": true + } + } + ] +} diff --git a/salt/elasticsearch/files/ingest/common_nids b/salt/elasticsearch/files/ingest/common_nids new file mode 100644 index 000000000..4fffab7c1 --- /dev/null +++ b/salt/elasticsearch/files/ingest/common_nids @@ -0,0 +1,17 @@ +{ + "description" : "common_nids", + "processors" : [ + { "convert": { "field": "sid", "type": "integer" } }, + { "set": { "if": "ctx.sid < 1000000", "field": "signature_info", "value": "https://www.snort.org/search?query={{gid}}-{{sid}}" } }, + { "set": { "if": "ctx.sid > 1999999", "field": "signature_info", "value": "https://doc.emergingthreats.net/{{sid}}" } }, + { "remove": { "if": "ctx.sid > 2999999", "field": "signature_info" } }, + { "set": { "if": "ctx.priority == '1'", "field": "severity", "value": "High" } }, + { "set": { "if": "ctx.priority == '2'", "field": "severity", "value": "Medium" } }, + { "set": { "if": "ctx.priority == '3'", "field": "severity", "value": "Low" } }, + { "dissect": { "field": "alert", "pattern" : "%{rule_type} %{category} ", "ignore_failure": true } }, + { "set": { "if": "ctx.rule_type == 'GPL'", "field": "rule_type", "value": "Snort GPL" } }, + { "set": { "if": "ctx.rule_type == 'ET'", "field": "rule_type", "value": "Emerging Threats" } }, + { "lowercase": { "field": "category", "ignore_failure": true } }, + { "pipeline": { "name": "common" } } + ] +} diff --git a/salt/elasticsearch/files/ingest/ossec b/salt/elasticsearch/files/ingest/ossec new file mode 100644 index 000000000..2b6d19370 --- /dev/null +++ b/salt/elasticsearch/files/ingest/ossec @@ -0,0 +1,53 @@ +{ + "description" : "ossec", + "processors" : [ + { "json": { "field": "message", "target_field": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.agent", "target_field": "agent", "ignore_missing": true } }, + { "rename": { "field": "message2.data", "target_field": "data", "ignore_missing": true } }, + { "rename": { "field": "message2.decoder", "target_field": "decoder", "ignore_missing": true } }, + { "rename": { "field": "message2.full_log", "target_field": "full_log", "ignore_missing": true } }, + { "rename": { "field": "message2.id", "target_field": "id", "ignore_missing": true } }, + { "rename": { "field": "message2.location", "target_field": "location", "ignore_missing": true } }, + { "rename": { "field": "message2.manager", "target_field": "manager", "ignore_missing": true } }, + { "rename": { "field": "message2.predecoder", "target_field": "predecoder", "ignore_missing": true } }, + { "rename": { "field": "message2.timestamp", "target_field": "timestamp", "ignore_missing": true } }, + { "rename": { "field": "message2.rule", "target_field": "wazuh-rule", "ignore_missing": true } }, + { "rename": { "field": "data.command", "target_field": "command", "ignore_missing": true } }, + { "rename": { "field": "data.dstip", "target_field": "destination_ip", "ignore_missing": true } }, + { "rename": { "field": "data.dstport", "target_field": "destination_port", "ignore_missing": true } }, + { "rename": { "field": "data.dstuser", "target_field": "escalated_user", "ignore_missing": true } }, + { "rename": { "field": "data.srcip", "target_field": "source_ip", "ignore_missing": true } }, + { "rename": { "field": "data.srcuser", "target_field": "username", "ignore_missing": true } }, + { "rename": { "field": "data.win.eventdata.destinationHostname", "target_field": "destination_hostname", "ignore_missing": true } }, + { "rename": { "field": "data.win.eventdata.destinationIp", "target_field": "destination_ip", "ignore_missing": true } }, + { "rename": { "field": "data.win.eventdata.destinationPort", "target_field": "destination_port", "ignore_missing": true } }, + { "rename": { "field": "data.win.eventdata.image", "target_field": "image_path", "ignore_missing": true } }, + { "rename": { "field": "data.win.eventdata.parentImage", "target_field": "parent_image_path", "ignore_missing": true } }, + { "rename": { "field": "data.win.eventdata.sourceHostname", "target_field": "source_hostname", "ignore_missing": true } }, + { "rename": { "field": "data.win.eventdata.sourceIp", "target_field": "source_ip", "ignore_missing": true } }, + { "rename": { "field": "data.win.eventdata.sourcePort", "target_field": "source_port", "ignore_missing": true } }, + { "rename": { "field": "data.win.eventdata.targetFilename", "target_field": "target_filename", "ignore_missing": true } }, + { "rename": { "field": "data.win.eventdata.user", "target_field": "username", "ignore_missing": true } }, + { "rename": { "field": "data.win.system.eventID", "target_field": "event_id", "ignore_missing": true } }, + { "rename": { "field": "predecoder.program_name", "target_field": "process", "ignore_missing": true } }, + { "rename": { "field": "wazuh-rule.level", "target_field": "alert_level", "ignore_missing": true } }, + { "rename": { "field": "wazuh-rule.description", "target_field": "description", "ignore_missing": true } }, + { "set": { "if": "ctx.alert_level == 1", "field": "classification", "value": "None" } }, + { "set": { "if": "ctx.alert_level == 2", "field": "classification", "value": "System low priority notification" } }, + { "set": { "if": "ctx.alert_level == 3", "field": "classification", "value": "Successful/authorized event" } }, + { "set": { "if": "ctx.alert_level == 4", "field": "classification", "value": "System low priority error" } }, + { "set": { "if": "ctx.alert_level == 5", "field": "classification", "value": "User generated error" } }, + { "set": { "if": "ctx.alert_level == 6", "field": "classification", "value": "Low relevance attack" } }, + { "set": { "if": "ctx.alert_level == 7", "field": "classification", "value": "\"Bad word\" matching" } }, + { "set": { "if": "ctx.alert_level == 8", "field": "classification", "value": "First time seen" } }, + { "set": { "if": "ctx.alert_level == 9", "field": "classification", "value": "Error from invalid source" } }, + { "set": { "if": "ctx.alert_level == 10", "field": "classification", "value": "Multiple user generated errors" } }, + { "set": { "if": "ctx.alert_level == 11", "field": "classification", "value": "Integrity checking warning" } }, + { "set": { "if": "ctx.alert_level == 12", "field": "classification", "value": "High importance event" } }, + { "set": { "if": "ctx.alert_level == 13", "field": "classification", "value": "Unusal error (high importance)" } }, + { "set": { "if": "ctx.alert_level == 14", "field": "classification", "value": "High importance security event" } }, + { "set": { "if": "ctx.alert_level == 15", "field": "classification", "value": "Severe attack" } }, + { "append": { "if": "ctx.alert_level != null", "field": "tags", "value": ["alert"] } }, + { "pipeline": { "name": "common" } } + ] +} diff --git a/salt/elasticsearch/files/ingest/sguild_nids b/salt/elasticsearch/files/ingest/sguild_nids new file mode 100644 index 000000000..c7bcdc418 --- /dev/null +++ b/salt/elasticsearch/files/ingest/sguild_nids @@ -0,0 +1,25 @@ +{ + "description" : "sguild_nids", + "processors" : [ + { + "dissect": { + "field": "message", + "pattern" : "%{} %{} %{} Alert Received: %{} %{priority} %{classification} %{interface} {%{alerttime}} %{} %{} {%{alert}} %{source_ip} %{destination_ip} %{protocol} %{source_port} %{destination_port} %{gid} %{sid} %{rev} ", + "on_failure": [ { "drop" : { } } ] + } + }, + { "set": { "if": "ctx.protocol == '1'", "field": "protocol", "value": "ICMP" } }, + { "set": { "if": "ctx.protocol == '6'", "field": "protocol", "value": "TCP" } }, + { "set": { "if": "ctx.protocol == '17'", "field": "protocol", "value": "UDP" } }, + { "remove": { "if": "ctx.source_ip == '{}'", "field": "source_ip" } }, + { "remove": { "if": "ctx.destination_ip == '{}'", "field": "destination_ip" } }, + { "remove": { "if": "ctx.protocol == '{}'", "field": "protocol" } }, + { "remove": { "if": "ctx.source_port == '{}'", "field": "source_port" } }, + { "remove": { "if": "ctx.destination_port == '{}'", "field": "destination_port" } }, + { "set": { "field": "type", "value": "snort" } }, + { "rename": { "field": "@timestamp", "target_field": "timestamp", "ignore_missing": true } }, + { "date": { "field": "alerttime", "target_field": "@timestamp", "formats": ["yyyy-MM-dd HH:mm:ss"], "ignore_failure": true } }, + { "remove": { "field": "alerttime", "ignore_missing": true } }, + { "pipeline": { "name": "common_nids" } } + ] +} diff --git a/salt/elasticsearch/files/ingest/snort b/salt/elasticsearch/files/ingest/snort new file mode 100644 index 000000000..b841ca917 --- /dev/null +++ b/salt/elasticsearch/files/ingest/snort @@ -0,0 +1,21 @@ +{ + "description" : "snort", + "processors" : [ + { + "dissect": { + "field": "message", + "pattern" : "[%{gid}:%{sid}:%{rev}] %{alert} [Classification: %{classification}] [Priority: %{priority}]: <%{interface}> {%{protocol}} %{source_ip_port} -> %{destination_ip_port}", + "on_failure": [ { "drop" : { } } ] + } + }, + { "split": { "field": "source_ip_port", "separator": ":", "ignore_failure": true } }, + { "split": { "field": "destination_ip_port", "separator": ":", "ignore_failure": true } }, + { "rename":{ "field": "source_ip_port.1", "target_field": "source_port", "ignore_failure": true } }, + { "rename":{ "field": "destination_ip_port.1", "target_field": "destination_port", "ignore_failure": true } }, + { "rename":{ "field": "source_ip_port.0", "target_field": "source_ip", "ignore_failure": true } }, + { "rename":{ "field": "destination_ip_port.0", "target_field": "destination_ip", "ignore_failure": true } }, + { "remove":{ "field": "source_ip_port", "ignore_failure": true } }, + { "remove":{ "field": "destination_ip_port", "ignore_failure": true } }, + { "pipeline": { "name": "common_nids" } } + ] +} diff --git a/salt/elasticsearch/files/so-elasticsearch-pipelines b/salt/elasticsearch/files/so-elasticsearch-pipelines new file mode 100755 index 000000000..c0dd44aa9 --- /dev/null +++ b/salt/elasticsearch/files/so-elasticsearch-pipelines @@ -0,0 +1,52 @@ +#!/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. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +ELASTICSEARCH_HOST=$1 +ELASTICSEARCH_PORT=9200 + +# Define a default directory to load pipelines from +ELASTICSEARCH_INGEST_PIPELINES="/opt/so/saltstack/salt/elasticsearch/files/ingest/" + +# Wait for ElasticSearch to initialize +echo -n "Waiting for ElasticSearch..." +COUNT=0 +ELASTICSEARCH_CONNECTED="no" +while [[ "$COUNT" -le 240 ]]; do + curl ${ELASTICSEARCH_AUTH} --output /dev/null --silent --head --fail http://"$ELASTICSEARCH_HOST":"$ELASTICSEARCH_PORT" + if [ $? -eq 0 ]; then + ELASTICSEARCH_CONNECTED="yes" + echo "connected!" + break + else + ((COUNT+=1)) + sleep 1 + echo -n "." + fi +done +if [ "$ELASTICSEARCH_CONNECTED" == "no" ]; then + echo + echo -e "Connection attempt timed out. Unable to connect to ElasticSearch. \nPlease try: \n -checking log(s) in /var/log/elasticsearch/\n -running 'sudo docker ps' \n -running 'sudo so-elastic-restart'" + echo +fi + +cd ${ELASTICSEARCH_INGEST_PIPELINES} + +echo "Loading pipelines..." +for i in *; do echo $i; curl ${ELASTICSEARCH_AUTH} -XPUT http://${ELASTICSEARCH_HOST}:${ELASTICSEARCH_PORT}/_ingest/pipeline/$i -H 'Content-Type: application/json' -d@$i 2>/dev/null; echo; done +echo + +cd - >/dev/null diff --git a/salt/elasticsearch/init.sls b/salt/elasticsearch/init.sls index c05cb83e4..1eb3a19e4 100644 --- a/salt/elasticsearch/init.sls +++ b/salt/elasticsearch/init.sls @@ -121,6 +121,10 @@ so-elasticsearch: - /nsm/elasticsearch:/usr/share/elasticsearch/data:rw - /opt/so/log/elasticsearch:/var/log/elasticsearch:rw +so-elasticsearch-pipelines: + cmd.run: + - name: /opt/so/saltstack/salt/elasticsearch/files/so-elasticsearch-pipelines {{ esclustername }} + # Tell the main cluster I am here #curl -XPUT http://\$ELASTICSEARCH_HOST:\$ELASTICSEARCH_PORT/_cluster/settings -H'Content-Type: application/json' -d '{"persistent": {"search": {"remote": {"$HOSTNAME": {"skip_unavailable": "true", "seeds": ["$DOCKER_INTERFACE:$REVERSE_PORT"]}}}}}' diff --git a/salt/logstash/conf/conf.enabled.txt.parser b/salt/logstash/conf/conf.enabled.txt.parser index a34b39c5f..6fbf3ba45 100644 --- a/salt/logstash/conf/conf.enabled.txt.parser +++ b/salt/logstash/conf/conf.enabled.txt.parser @@ -7,11 +7,12 @@ # /usr/share/logstash/pipeline.custom/1234_input_custom.conf ## # All of the defaults are loaded. +# Please note that Bro config is commented out because we're moving that parsing to Elasticsearch ingest. /usr/share/logstash/pipeline.dynamic/0900_input_redis.conf /usr/share/logstash/pipeline.so/1000_preprocess_log_elapsed.conf /usr/share/logstash/pipeline.so/1001_preprocess_syslogng.conf /usr/share/logstash/pipeline.so/1002_preprocess_json.conf -/usr/share/logstash/pipeline.so/1003_preprocess_bro.conf +#/usr/share/logstash/pipeline.so/1003_preprocess_bro.conf /usr/share/logstash/pipeline.so/1004_preprocess_syslog_types.conf /usr/share/logstash/pipeline.so/1026_preprocess_dhcp.conf /usr/share/logstash/pipeline.so/1029_preprocess_esxi.conf @@ -20,44 +21,44 @@ /usr/share/logstash/pipeline.so/1032_preprocess_mcafee.conf /usr/share/logstash/pipeline.so/1033_preprocess_snort.conf /usr/share/logstash/pipeline.so/1034_preprocess_syslog.conf -/usr/share/logstash/pipeline.so/1100_preprocess_bro_conn.conf -/usr/share/logstash/pipeline.so/1101_preprocess_bro_dhcp.conf -/usr/share/logstash/pipeline.so/1102_preprocess_bro_dns.conf -/usr/share/logstash/pipeline.so/1103_preprocess_bro_dpd.conf -/usr/share/logstash/pipeline.so/1104_preprocess_bro_files.conf -/usr/share/logstash/pipeline.so/1105_preprocess_bro_ftp.conf -/usr/share/logstash/pipeline.so/1106_preprocess_bro_http.conf -/usr/share/logstash/pipeline.so/1107_preprocess_bro_irc.conf -/usr/share/logstash/pipeline.so/1108_preprocess_bro_kerberos.conf -/usr/share/logstash/pipeline.so/1109_preprocess_bro_notice.conf -/usr/share/logstash/pipeline.so/1110_preprocess_bro_rdp.conf -/usr/share/logstash/pipeline.so/1111_preprocess_bro_signatures.conf -/usr/share/logstash/pipeline.so/1112_preprocess_bro_smtp.conf -/usr/share/logstash/pipeline.so/1113_preprocess_bro_snmp.conf -/usr/share/logstash/pipeline.so/1114_preprocess_bro_software.conf -/usr/share/logstash/pipeline.so/1115_preprocess_bro_ssh.conf -/usr/share/logstash/pipeline.so/1116_preprocess_bro_ssl.conf -/usr/share/logstash/pipeline.so/1117_preprocess_bro_syslog.conf -/usr/share/logstash/pipeline.so/1118_preprocess_bro_tunnel.conf -/usr/share/logstash/pipeline.so/1119_preprocess_bro_weird.conf -/usr/share/logstash/pipeline.so/1121_preprocess_bro_mysql.conf -/usr/share/logstash/pipeline.so/1122_preprocess_bro_socks.conf -/usr/share/logstash/pipeline.so/1123_preprocess_bro_x509.conf -/usr/share/logstash/pipeline.so/1124_preprocess_bro_intel.conf -/usr/share/logstash/pipeline.so/1125_preprocess_bro_modbus.conf -/usr/share/logstash/pipeline.so/1126_preprocess_bro_sip.conf -/usr/share/logstash/pipeline.so/1127_preprocess_bro_radius.conf -/usr/share/logstash/pipeline.so/1128_preprocess_bro_pe.conf -/usr/share/logstash/pipeline.so/1129_preprocess_bro_rfb.conf -/usr/share/logstash/pipeline.so/1130_preprocess_bro_dnp3.conf -/usr/share/logstash/pipeline.so/1131_preprocess_bro_smb_files.conf -/usr/share/logstash/pipeline.so/1132_preprocess_bro_smb_mapping.conf -/usr/share/logstash/pipeline.so/1133_preprocess_bro_ntlm.conf -/usr/share/logstash/pipeline.so/1134_preprocess_bro_dce_rpc.conf +#/usr/share/logstash/pipeline.so/1100_preprocess_bro_conn.conf +#/usr/share/logstash/pipeline.so/1101_preprocess_bro_dhcp.conf +#/usr/share/logstash/pipeline.so/1102_preprocess_bro_dns.conf +#/usr/share/logstash/pipeline.so/1103_preprocess_bro_dpd.conf +#/usr/share/logstash/pipeline.so/1104_preprocess_bro_files.conf +#/usr/share/logstash/pipeline.so/1105_preprocess_bro_ftp.conf +#/usr/share/logstash/pipeline.so/1106_preprocess_bro_http.conf +#/usr/share/logstash/pipeline.so/1107_preprocess_bro_irc.conf +#/usr/share/logstash/pipeline.so/1108_preprocess_bro_kerberos.conf +#/usr/share/logstash/pipeline.so/1109_preprocess_bro_notice.conf +#/usr/share/logstash/pipeline.so/1110_preprocess_bro_rdp.conf +#/usr/share/logstash/pipeline.so/1111_preprocess_bro_signatures.conf +#/usr/share/logstash/pipeline.so/1112_preprocess_bro_smtp.conf +#/usr/share/logstash/pipeline.so/1113_preprocess_bro_snmp.conf +#/usr/share/logstash/pipeline.so/1114_preprocess_bro_software.conf +#/usr/share/logstash/pipeline.so/1115_preprocess_bro_ssh.conf +#/usr/share/logstash/pipeline.so/1116_preprocess_bro_ssl.conf +#/usr/share/logstash/pipeline.so/1117_preprocess_bro_syslog.conf +#/usr/share/logstash/pipeline.so/1118_preprocess_bro_tunnel.conf +#/usr/share/logstash/pipeline.so/1119_preprocess_bro_weird.conf +#/usr/share/logstash/pipeline.so/1121_preprocess_bro_mysql.conf +#/usr/share/logstash/pipeline.so/1122_preprocess_bro_socks.conf +#/usr/share/logstash/pipeline.so/1123_preprocess_bro_x509.conf +#/usr/share/logstash/pipeline.so/1124_preprocess_bro_intel.conf +#/usr/share/logstash/pipeline.so/1125_preprocess_bro_modbus.conf +#/usr/share/logstash/pipeline.so/1126_preprocess_bro_sip.conf +#/usr/share/logstash/pipeline.so/1127_preprocess_bro_radius.conf +#/usr/share/logstash/pipeline.so/1128_preprocess_bro_pe.conf +#/usr/share/logstash/pipeline.so/1129_preprocess_bro_rfb.conf +#/usr/share/logstash/pipeline.so/1130_preprocess_bro_dnp3.conf +#/usr/share/logstash/pipeline.so/1131_preprocess_bro_smb_files.conf +#/usr/share/logstash/pipeline.so/1132_preprocess_bro_smb_mapping.conf +#/usr/share/logstash/pipeline.so/1133_preprocess_bro_ntlm.conf +#/usr/share/logstash/pipeline.so/1134_preprocess_bro_dce_rpc.conf /usr/share/logstash/pipeline.so/1998_test_data.conf /usr/share/logstash/pipeline.so/2000_network_flow.conf -/usr/share/logstash/pipeline.so/6000_bro.conf -/usr/share/logstash/pipeline.so/6001_bro_import.conf +#/usr/share/logstash/pipeline.so/6000_bro.conf +#/usr/share/logstash/pipeline.so/6001_bro_import.conf /usr/share/logstash/pipeline.so/6002_syslog.conf /usr/share/logstash/pipeline.so/6101_switch_brocade.conf /usr/share/logstash/pipeline.so/6200_firewall_fortinet.conf @@ -68,17 +69,17 @@ /usr/share/logstash/pipeline.so/6500_ossec.conf /usr/share/logstash/pipeline.so/6501_ossec_sysmon.conf /usr/share/logstash/pipeline.so/6502_ossec_autoruns.conf -/usr/share/logstash/pipeline.so/8000_postprocess_bro_cleanup.conf +#/usr/share/logstash/pipeline.so/8000_postprocess_bro_cleanup.conf /usr/share/logstash/pipeline.so/8001_postprocess_common_ip_augmentation.conf /usr/share/logstash/pipeline.so/8006_postprocess_dns.conf /usr/share/logstash/pipeline.so/8007_postprocess_dns_top1m_tagging.conf /usr/share/logstash/pipeline.so/8007_postprocess_http.conf /usr/share/logstash/pipeline.so/8008_postprocess_dns_whois_age.conf /usr/share/logstash/pipeline.so/8200_postprocess_tagging.conf -/usr/share/logstash/pipeline.so/8502_postprocess_freq_analysis_bro_dns.conf -/usr/share/logstash/pipeline.so/8503_postprocess_freq_analysis_bro_http.conf -/usr/share/logstash/pipeline.so/8504_postprocess_freq_analysis_bro_ssl.conf -/usr/share/logstash/pipeline.so/8505_postprocess_freq_analysis_bro_x509.conf +#/usr/share/logstash/pipeline.so/8502_postprocess_freq_analysis_bro_dns.conf +#/usr/share/logstash/pipeline.so/8503_postprocess_freq_analysis_bro_http.conf +#/usr/share/logstash/pipeline.so/8504_postprocess_freq_analysis_bro_ssl.conf +#/usr/share/logstash/pipeline.so/8505_postprocess_freq_analysis_bro_x509.conf /usr/share/logstash/pipeline.so/8998_postprocess_log_elapsed.conf /usr/share/logstash/pipeline.so/8999_postprocess_rename_type.conf /usr/share/logstash/pipeline.dynamic/9999_output_redis.conf diff --git a/salt/logstash/conf/conf.enabled.txt.so-eval b/salt/logstash/conf/conf.enabled.txt.so-eval index e7680b3be..d125fc829 100644 --- a/salt/logstash/conf/conf.enabled.txt.so-eval +++ b/salt/logstash/conf/conf.enabled.txt.so-eval @@ -7,6 +7,7 @@ # /usr/share/logstash/pipeline.custom/1234_input_custom.conf ## # All of the defaults are loaded. +# Please note that Bro config is commented out because we're moving that parsing to Elasticsearch ingest. #/usr/share/logstash/pipeline.so/0000_input_syslogng.conf #/usr/share/logstash/pipeline.so/0001_input_json.conf #/usr/share/logstash/pipeline.so/0002_input_windows_json.conf @@ -18,7 +19,7 @@ #/usr/share/logstash/pipeline.so/1000_preprocess_log_elapsed.conf #/usr/share/logstash/pipeline.so/1001_preprocess_syslogng.conf #/usr/share/logstash/pipeline.so/1002_preprocess_json.conf -/usr/share/logstash/pipeline.so/1003_preprocess_bro.conf +#/usr/share/logstash/pipeline.so/1003_preprocess_bro.conf #/usr/share/logstash/pipeline.so/1004_preprocess_syslog_types.conf /usr/share/logstash/pipeline.so/1026_preprocess_dhcp.conf #/usr/share/logstash/pipeline.so/1029_preprocess_esxi.conf @@ -27,44 +28,44 @@ #/usr/share/logstash/pipeline.so/1032_preprocess_mcafee.conf /usr/share/logstash/pipeline.so/1033_preprocess_snort.conf #/usr/share/logstash/pipeline.so/1034_preprocess_syslog.conf -/usr/share/logstash/pipeline.so/1100_preprocess_bro_conn.conf -/usr/share/logstash/pipeline.so/1101_preprocess_bro_dhcp.conf -/usr/share/logstash/pipeline.so/1102_preprocess_bro_dns.conf -/usr/share/logstash/pipeline.so/1103_preprocess_bro_dpd.conf -/usr/share/logstash/pipeline.so/1104_preprocess_bro_files.conf -/usr/share/logstash/pipeline.so/1105_preprocess_bro_ftp.conf -/usr/share/logstash/pipeline.so/1106_preprocess_bro_http.conf -/usr/share/logstash/pipeline.so/1107_preprocess_bro_irc.conf -/usr/share/logstash/pipeline.so/1108_preprocess_bro_kerberos.conf -/usr/share/logstash/pipeline.so/1109_preprocess_bro_notice.conf -/usr/share/logstash/pipeline.so/1110_preprocess_bro_rdp.conf -/usr/share/logstash/pipeline.so/1111_preprocess_bro_signatures.conf -/usr/share/logstash/pipeline.so/1112_preprocess_bro_smtp.conf -/usr/share/logstash/pipeline.so/1113_preprocess_bro_snmp.conf -/usr/share/logstash/pipeline.so/1114_preprocess_bro_software.conf -/usr/share/logstash/pipeline.so/1115_preprocess_bro_ssh.conf -/usr/share/logstash/pipeline.so/1116_preprocess_bro_ssl.conf -/usr/share/logstash/pipeline.so/1117_preprocess_bro_syslog.conf -/usr/share/logstash/pipeline.so/1118_preprocess_bro_tunnel.conf -/usr/share/logstash/pipeline.so/1119_preprocess_bro_weird.conf -/usr/share/logstash/pipeline.so/1121_preprocess_bro_mysql.conf -/usr/share/logstash/pipeline.so/1122_preprocess_bro_socks.conf -/usr/share/logstash/pipeline.so/1123_preprocess_bro_x509.conf -/usr/share/logstash/pipeline.so/1124_preprocess_bro_intel.conf -/usr/share/logstash/pipeline.so/1125_preprocess_bro_modbus.conf -/usr/share/logstash/pipeline.so/1126_preprocess_bro_sip.conf -/usr/share/logstash/pipeline.so/1127_preprocess_bro_radius.conf -/usr/share/logstash/pipeline.so/1128_preprocess_bro_pe.conf -/usr/share/logstash/pipeline.so/1129_preprocess_bro_rfb.conf -/usr/share/logstash/pipeline.so/1130_preprocess_bro_dnp3.conf -/usr/share/logstash/pipeline.so/1131_preprocess_bro_smb_files.conf -/usr/share/logstash/pipeline.so/1132_preprocess_bro_smb_mapping.conf -/usr/share/logstash/pipeline.so/1133_preprocess_bro_ntlm.conf -/usr/share/logstash/pipeline.so/1134_preprocess_bro_dce_rpc.conf +#/usr/share/logstash/pipeline.so/1100_preprocess_bro_conn.conf +#/usr/share/logstash/pipeline.so/1101_preprocess_bro_dhcp.conf +#/usr/share/logstash/pipeline.so/1102_preprocess_bro_dns.conf +#/usr/share/logstash/pipeline.so/1103_preprocess_bro_dpd.conf +#/usr/share/logstash/pipeline.so/1104_preprocess_bro_files.conf +#/usr/share/logstash/pipeline.so/1105_preprocess_bro_ftp.conf +#/usr/share/logstash/pipeline.so/1106_preprocess_bro_http.conf +#/usr/share/logstash/pipeline.so/1107_preprocess_bro_irc.conf +#/usr/share/logstash/pipeline.so/1108_preprocess_bro_kerberos.conf +#/usr/share/logstash/pipeline.so/1109_preprocess_bro_notice.conf +#/usr/share/logstash/pipeline.so/1110_preprocess_bro_rdp.conf +#/usr/share/logstash/pipeline.so/1111_preprocess_bro_signatures.conf +#/usr/share/logstash/pipeline.so/1112_preprocess_bro_smtp.conf +#/usr/share/logstash/pipeline.so/1113_preprocess_bro_snmp.conf +#/usr/share/logstash/pipeline.so/1114_preprocess_bro_software.conf +#/usr/share/logstash/pipeline.so/1115_preprocess_bro_ssh.conf +#/usr/share/logstash/pipeline.so/1116_preprocess_bro_ssl.conf +#/usr/share/logstash/pipeline.so/1117_preprocess_bro_syslog.conf +#/usr/share/logstash/pipeline.so/1118_preprocess_bro_tunnel.conf +#/usr/share/logstash/pipeline.so/1119_preprocess_bro_weird.conf +#/usr/share/logstash/pipeline.so/1121_preprocess_bro_mysql.conf +#/usr/share/logstash/pipeline.so/1122_preprocess_bro_socks.conf +#/usr/share/logstash/pipeline.so/1123_preprocess_bro_x509.conf +#/usr/share/logstash/pipeline.so/1124_preprocess_bro_intel.conf +#/usr/share/logstash/pipeline.so/1125_preprocess_bro_modbus.conf +#/usr/share/logstash/pipeline.so/1126_preprocess_bro_sip.conf +#/usr/share/logstash/pipeline.so/1127_preprocess_bro_radius.conf +#/usr/share/logstash/pipeline.so/1128_preprocess_bro_pe.conf +#/usr/share/logstash/pipeline.so/1129_preprocess_bro_rfb.conf +#/usr/share/logstash/pipeline.so/1130_preprocess_bro_dnp3.conf +#/usr/share/logstash/pipeline.so/1131_preprocess_bro_smb_files.conf +#/usr/share/logstash/pipeline.so/1132_preprocess_bro_smb_mapping.conf +#/usr/share/logstash/pipeline.so/1133_preprocess_bro_ntlm.conf +#/usr/share/logstash/pipeline.so/1134_preprocess_bro_dce_rpc.conf #/usr/share/logstash/pipeline.so/1998_test_data.conf #/usr/share/logstash/pipeline.so/2000_network_flow.conf -/usr/share/logstash/pipeline.so/6000_bro.conf -/usr/share/logstash/pipeline.so/6001_bro_import.conf +#/usr/share/logstash/pipeline.so/6000_bro.conf +#/usr/share/logstash/pipeline.so/6001_bro_import.conf #/usr/share/logstash/pipeline.so/6002_syslog.conf #/usr/share/logstash/pipeline.so/6101_switch_brocade.conf #/usr/share/logstash/pipeline.so/6200_firewall_fortinet.conf @@ -77,7 +78,7 @@ /usr/share/logstash/pipeline.so/6502_ossec_autoruns.conf /usr/share/logstash/pipeline.so/6600_winlogbeat_sysmon.conf /usr/share/logstash/pipeline.so/6700_winlogbeat.conf -/usr/share/logstash/pipeline.so/8000_postprocess_bro_cleanup.conf +#/usr/share/logstash/pipeline.so/8000_postprocess_bro_cleanup.conf /usr/share/logstash/pipeline.so/8001_postprocess_common_ip_augmentation.conf #/usr/share/logstash/pipeline.so/8006_postprocess_dns.conf #/usr/share/logstash/pipeline.so/8007_postprocess_dns_top1m_tagging.conf diff --git a/salt/logstash/conf/conf.enabled.txt.storage b/salt/logstash/conf/conf.enabled.txt.storage index 6d2d581db..470f19c55 100644 --- a/salt/logstash/conf/conf.enabled.txt.storage +++ b/salt/logstash/conf/conf.enabled.txt.storage @@ -7,11 +7,12 @@ # /usr/share/logstash/pipeline.custom/1234_input_custom.conf ## # All of the defaults are loaded. +# Please note that Bro config is commented out because we're moving that parsing to Elasticsearch ingest. /usr/share/logstash/pipeline.dynamic/0900_input_redis.conf /usr/share/logstash/pipeline.so/1000_preprocess_log_elapsed.conf /usr/share/logstash/pipeline.so/1001_preprocess_syslogng.conf /usr/share/logstash/pipeline.so/1002_preprocess_json.conf -/usr/share/logstash/pipeline.so/1003_preprocess_bro.conf +#/usr/share/logstash/pipeline.so/1003_preprocess_bro.conf /usr/share/logstash/pipeline.so/1004_preprocess_syslog_types.conf /usr/share/logstash/pipeline.so/1026_preprocess_dhcp.conf /usr/share/logstash/pipeline.so/1029_preprocess_esxi.conf @@ -20,44 +21,44 @@ /usr/share/logstash/pipeline.so/1032_preprocess_mcafee.conf /usr/share/logstash/pipeline.so/1033_preprocess_snort.conf /usr/share/logstash/pipeline.so/1034_preprocess_syslog.conf -/usr/share/logstash/pipeline.so/1100_preprocess_bro_conn.conf -/usr/share/logstash/pipeline.so/1101_preprocess_bro_dhcp.conf -/usr/share/logstash/pipeline.so/1102_preprocess_bro_dns.conf -/usr/share/logstash/pipeline.so/1103_preprocess_bro_dpd.conf -/usr/share/logstash/pipeline.so/1104_preprocess_bro_files.conf -/usr/share/logstash/pipeline.so/1105_preprocess_bro_ftp.conf -/usr/share/logstash/pipeline.so/1106_preprocess_bro_http.conf -/usr/share/logstash/pipeline.so/1107_preprocess_bro_irc.conf -/usr/share/logstash/pipeline.so/1108_preprocess_bro_kerberos.conf -/usr/share/logstash/pipeline.so/1109_preprocess_bro_notice.conf -/usr/share/logstash/pipeline.so/1110_preprocess_bro_rdp.conf -/usr/share/logstash/pipeline.so/1111_preprocess_bro_signatures.conf -/usr/share/logstash/pipeline.so/1112_preprocess_bro_smtp.conf -/usr/share/logstash/pipeline.so/1113_preprocess_bro_snmp.conf -/usr/share/logstash/pipeline.so/1114_preprocess_bro_software.conf -/usr/share/logstash/pipeline.so/1115_preprocess_bro_ssh.conf -/usr/share/logstash/pipeline.so/1116_preprocess_bro_ssl.conf -/usr/share/logstash/pipeline.so/1117_preprocess_bro_syslog.conf -/usr/share/logstash/pipeline.so/1118_preprocess_bro_tunnel.conf -/usr/share/logstash/pipeline.so/1119_preprocess_bro_weird.conf -/usr/share/logstash/pipeline.so/1121_preprocess_bro_mysql.conf -/usr/share/logstash/pipeline.so/1122_preprocess_bro_socks.conf -/usr/share/logstash/pipeline.so/1123_preprocess_bro_x509.conf -/usr/share/logstash/pipeline.so/1124_preprocess_bro_intel.conf -/usr/share/logstash/pipeline.so/1125_preprocess_bro_modbus.conf -/usr/share/logstash/pipeline.so/1126_preprocess_bro_sip.conf -/usr/share/logstash/pipeline.so/1127_preprocess_bro_radius.conf -/usr/share/logstash/pipeline.so/1128_preprocess_bro_pe.conf -/usr/share/logstash/pipeline.so/1129_preprocess_bro_rfb.conf -/usr/share/logstash/pipeline.so/1130_preprocess_bro_dnp3.conf -/usr/share/logstash/pipeline.so/1131_preprocess_bro_smb_files.conf -/usr/share/logstash/pipeline.so/1132_preprocess_bro_smb_mapping.conf -/usr/share/logstash/pipeline.so/1133_preprocess_bro_ntlm.conf -/usr/share/logstash/pipeline.so/1134_preprocess_bro_dce_rpc.conf +#/usr/share/logstash/pipeline.so/1100_preprocess_bro_conn.conf +#/usr/share/logstash/pipeline.so/1101_preprocess_bro_dhcp.conf +#/usr/share/logstash/pipeline.so/1102_preprocess_bro_dns.conf +#/usr/share/logstash/pipeline.so/1103_preprocess_bro_dpd.conf +#/usr/share/logstash/pipeline.so/1104_preprocess_bro_files.conf +#/usr/share/logstash/pipeline.so/1105_preprocess_bro_ftp.conf +#/usr/share/logstash/pipeline.so/1106_preprocess_bro_http.conf +#/usr/share/logstash/pipeline.so/1107_preprocess_bro_irc.conf +#/usr/share/logstash/pipeline.so/1108_preprocess_bro_kerberos.conf +#/usr/share/logstash/pipeline.so/1109_preprocess_bro_notice.conf +#/usr/share/logstash/pipeline.so/1110_preprocess_bro_rdp.conf +#/usr/share/logstash/pipeline.so/1111_preprocess_bro_signatures.conf +#/usr/share/logstash/pipeline.so/1112_preprocess_bro_smtp.conf +#/usr/share/logstash/pipeline.so/1113_preprocess_bro_snmp.conf +#/usr/share/logstash/pipeline.so/1114_preprocess_bro_software.conf +#/usr/share/logstash/pipeline.so/1115_preprocess_bro_ssh.conf +#/usr/share/logstash/pipeline.so/1116_preprocess_bro_ssl.conf +#/usr/share/logstash/pipeline.so/1117_preprocess_bro_syslog.conf +#/usr/share/logstash/pipeline.so/1118_preprocess_bro_tunnel.conf +#/usr/share/logstash/pipeline.so/1119_preprocess_bro_weird.conf +#/usr/share/logstash/pipeline.so/1121_preprocess_bro_mysql.conf +#/usr/share/logstash/pipeline.so/1122_preprocess_bro_socks.conf +#/usr/share/logstash/pipeline.so/1123_preprocess_bro_x509.conf +#/usr/share/logstash/pipeline.so/1124_preprocess_bro_intel.conf +#/usr/share/logstash/pipeline.so/1125_preprocess_bro_modbus.conf +#/usr/share/logstash/pipeline.so/1126_preprocess_bro_sip.conf +#/usr/share/logstash/pipeline.so/1127_preprocess_bro_radius.conf +#/usr/share/logstash/pipeline.so/1128_preprocess_bro_pe.conf +#/usr/share/logstash/pipeline.so/1129_preprocess_bro_rfb.conf +#/usr/share/logstash/pipeline.so/1130_preprocess_bro_dnp3.conf +#/usr/share/logstash/pipeline.so/1131_preprocess_bro_smb_files.conf +#/usr/share/logstash/pipeline.so/1132_preprocess_bro_smb_mapping.conf +#/usr/share/logstash/pipeline.so/1133_preprocess_bro_ntlm.conf +#/usr/share/logstash/pipeline.so/1134_preprocess_bro_dce_rpc.conf /usr/share/logstash/pipeline.so/1998_test_data.conf /usr/share/logstash/pipeline.so/2000_network_flow.conf -/usr/share/logstash/pipeline.so/6000_bro.conf -/usr/share/logstash/pipeline.so/6001_bro_import.conf +#/usr/share/logstash/pipeline.so/6000_bro.conf +#/usr/share/logstash/pipeline.so/6001_bro_import.conf /usr/share/logstash/pipeline.so/6002_syslog.conf /usr/share/logstash/pipeline.so/6101_switch_brocade.conf /usr/share/logstash/pipeline.so/6200_firewall_fortinet.conf @@ -70,7 +71,7 @@ /usr/share/logstash/pipeline.so/6502_ossec_autoruns.conf /usr/share/logstash/pipeline.so/6600_winlogbeat_sysmon.conf /usr/share/logstash/pipeline.so/6700_winlogbeat.conf -/usr/share/logstash/pipeline.so/8000_postprocess_bro_cleanup.conf +#/usr/share/logstash/pipeline.so/8000_postprocess_bro_cleanup.conf /usr/share/logstash/pipeline.so/8001_postprocess_common_ip_augmentation.conf #/usr/share/logstash/pipeline.so/8006_postprocess_dns.conf #/usr/share/logstash/pipeline.so/8007_postprocess_dns_top1m_tagging.conf diff --git a/salt/logstash/files/dynamic/9000_output_bro.conf b/salt/logstash/files/dynamic/9000_output_bro.conf index 54d2d20ca..553500281 100644 --- a/salt/logstash/files/dynamic/9000_output_bro.conf +++ b/salt/logstash/files/dynamic/9000_output_bro.conf @@ -20,6 +20,7 @@ output { if "bro" in [tags] and "test_data" not in [tags] and "import" not in [tags] { # stdout { codec => rubydebug } elasticsearch { + pipeline => "%{event_type}" hosts => "{{ ES }}" index => "logstash-bro-%{+YYYY.MM.dd}" template_name => "logstash" diff --git a/so-setup-network.sh b/so-setup-network.sh index 13906311d..6f1055efc 100644 --- a/so-setup-network.sh +++ b/so-setup-network.sh @@ -466,11 +466,11 @@ install_master() { ls_heapsize() { # Determine LS Heap Size - if [ $TOTAL_MEM -ge 16000 ] ; then - LS_HEAP_SIZE="4192m" + if [ $TOTAL_MEM -ge 32000 ] ; then + LS_HEAP_SIZE="1000m" else - # Set a max of 1GB heap if you have less than 16GB RAM - LS_HEAP_SIZE="2g" + # If minimal RAM, then set minimal heap + LS_HEAP_SIZE="500m" fi } @@ -1752,7 +1752,7 @@ if (whiptail_you_sure); then es_heapsize ls_heapsize NODE_ES_HEAP_SIZE="600m" - NODE_LS_HEAP_SIZE="2000m" + NODE_LS_HEAP_SIZE="500m" LSPIPELINEWORKERS=1 LSPIPELINEBATCH=125 LSINPUTTHREADS=1 From 2784542cdbd9c1d5bcd18622f7579e277e02d55b Mon Sep 17 00:00:00 2001 From: Wes Lambert Date: Mon, 23 Sep 2019 22:39:43 +0000 Subject: [PATCH 24/73] update Elastalert config --- salt/elastalert/files/modules/so/thehive.py | 130 +++++++----------- salt/elastalert/files/rules/so/nids2hive.yaml | 4 +- 2 files changed, 55 insertions(+), 79 deletions(-) diff --git a/salt/elastalert/files/modules/so/thehive.py b/salt/elastalert/files/modules/so/thehive.py index d78a8d050..42b6f9e1d 100644 --- a/salt/elastalert/files/modules/so/thehive.py +++ b/salt/elastalert/files/modules/so/thehive.py @@ -1,108 +1,84 @@ # -*- coding: utf-8 -*- from __future__ import unicode_literals 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 get_aggregation_summary_text(self, matches): - text = super(HiveAlerter, self).get_aggregation_summary_text(matches) - if text: - text = u'```\n{0}```\n'.format(text) - return text + def alert(self, matches): - 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.iteritems(): - 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.iteritems(): - if alert_config_field == 'customFields': - custom_fields = CustomFieldHelper() - for cf_key, cf_value in alert_config_value.iteritems(): - 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, basestring): - 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.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)) - alert = Alert(**alert_config) - response = api.create_alert(alert) + for match in matches: + context = {'rule': self.rule, 'match': match} - 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 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) + 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)) - 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) + 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)) def get_info(self): return { 'type': 'hivealerter', 'hive_host': self.rule.get('hive_connection', {}).get('hive_host', '') - } + } diff --git a/salt/elastalert/files/rules/so/nids2hive.yaml b/salt/elastalert/files/rules/so/nids2hive.yaml index ab0624e13..aa2287cca 100644 --- a/salt/elastalert/files/rules/so/nids2hive.yaml +++ b/salt/elastalert/files/rules/so/nids2hive.yaml @@ -23,7 +23,7 @@ filter: alert: modules.so.thehive.TheHiveAlerter hive_connection: - hive_host: {{hivehost}} + hive_host: https://{{hivehost}}/thehive/ hive_apikey: {{hivekey}} hive_proxies: @@ -31,7 +31,7 @@ hive_proxies: https: '' hive_alert_config: - title: '{rule[name]} -- {match[alert]}' + title: 'New Alert from Security Onion!' type: 'external' source: 'SecurityOnion' description: '{match[message]}' From 590827b08cef6842b3bcf9667c71c858e83803fc Mon Sep 17 00:00:00 2001 From: Mike Reeves Date: Tue, 24 Sep 2019 10:26:55 -0400 Subject: [PATCH 25/73] Suricata Module - Suricata 4.1.5 --- salt/suricata/init.sls | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/salt/suricata/init.sls b/salt/suricata/init.sls index 2739f4318..2c3b1aba8 100644 --- a/salt/suricata/init.sls +++ b/salt/suricata/init.sls @@ -72,13 +72,13 @@ suriconfigsync: so-suricataimage: cmd.run: - - name: docker pull --disable-content-trust=false soshybridhunter/so-suricata:HH1.1.0 + - name: docker pull --disable-content-trust=false soshybridhunter/so-suricata:HH1.1.1 so-suricata: docker_container.running: - require: - so-suricataimage - - image: soshybridhunter/so-suricata:HH1.1.0 + - image: soshybridhunter/so-suricata:HH1.1.1 - privileged: True - environment: - INTERFACE={{ interface }} From e080dcfe805c8c5bb86ab6e2f22999fac7b1e961 Mon Sep 17 00:00:00 2001 From: Mike Reeves Date: Tue, 24 Sep 2019 11:03:48 -0400 Subject: [PATCH 26/73] Filebeat Module - Update to 1.1.1 --- salt/filebeat/init.sls | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/salt/filebeat/init.sls b/salt/filebeat/init.sls index b7597730c..b92899ef0 100644 --- a/salt/filebeat/init.sls +++ b/salt/filebeat/init.sls @@ -58,13 +58,13 @@ filebeatconfsync: so-filebeatimage: cmd.run: - - name: docker pull --disable-content-trust=false soshybridhunter/so-filebeat:HH1.1.0 + - name: docker pull --disable-content-trust=false soshybridhunter/so-filebeat:HH1.1.1 so-filebeat: docker_container.running: - require: - so-filebeatimage - - image: soshybridhunter/so-filebeat:HH1.1.0 + - image: soshybridhunter/so-filebeat:HH1.1.1 - hostname: so-filebeat - user: root - extra_hosts: {{ MASTER }}:{{ MASTERIP }} From e6ea6b4d738647af4d9754c4a203a2af8a6962aa Mon Sep 17 00:00:00 2001 From: Mike Reeves Date: Tue, 24 Sep 2019 11:07:38 -0400 Subject: [PATCH 27/73] Wazuh Module - Fix gid error --- salt/wazuh/init.sls | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/salt/wazuh/init.sls b/salt/wazuh/init.sls index 0369fdc18..b83240dfa 100644 --- a/salt/wazuh/init.sls +++ b/salt/wazuh/init.sls @@ -5,8 +5,7 @@ ossecgroup: group.present: - name: ossec - gid: 945 - - allow_gid_change: True - + # Add ossecm user ossecm: user.present: From b1f582d218c24393d3da249d7c33c99c2c1b8baa Mon Sep 17 00:00:00 2001 From: Mike Reeves Date: Tue, 24 Sep 2019 11:22:07 -0400 Subject: [PATCH 28/73] Logstash Module - 1.1.1 --- salt/logstash/init.sls | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/salt/logstash/init.sls b/salt/logstash/init.sls index f1b41627b..589d22d1c 100644 --- a/salt/logstash/init.sls +++ b/salt/logstash/init.sls @@ -148,13 +148,13 @@ lslogdir: # Add the container so-logstashimage: cmd.run: - - name: docker pull --disable-content-trust=false soshybridhunter/so-logstash:HH1.1.0 + - name: docker pull --disable-content-trust=false soshybridhunter/so-logstash:HH1.1.1 so-logstash: docker_container.running: - require: - so-logstashimage - - image: soshybridhunter/so-logstash:HH1.1.0 + - image: soshybridhunter/so-logstash:HH1.1.1 - hostname: so-logstash - name: so-logstash - user: logstash From d65c9009816b46300c4932878e85cefc88107e70 Mon Sep 17 00:00:00 2001 From: Mike Reeves Date: Tue, 24 Sep 2019 12:32:08 -0400 Subject: [PATCH 29/73] Setup Script - New Changes for 1.1.1 --- so-setup-network.sh | 128 ++++++++++++++++++++++++++++++++++++-------- 1 file changed, 106 insertions(+), 22 deletions(-) diff --git a/so-setup-network.sh b/so-setup-network.sh index 6f1055efc..6abeb9f51 100644 --- a/so-setup-network.sh +++ b/so-setup-network.sh @@ -61,17 +61,33 @@ add_master_hostfile() { } add_socore_user_master() { - echo "Add socore on the master" >> $SETUPLOG 2>&1 + + echo "Add socore on the master" >>~/sosetup.log 2>&1 + # Add user "socore" to the master. This will be for things like accepting keys. if [ $OS == 'centos' ]; then local ADDUSER=adduser else local ADDUSER=useradd fi - # Add user "socore" to the master. This will be for things like accepting keys. groupadd --gid 939 socore $ADDUSER --uid 939 --gid 939 --home-dir /opt/so socore - # Prompt the user to set a password for the user - passwd socore + # Set the password for socore that we got during setup + echo socore:$COREPASS1 | chpasswd --crypt-method=SHA512 + +} + +#add_socore_user_master() { +# echo "Add socore on the master" >> $SETUPLOG 2>&1 +# if [ $OS == 'centos' ]; then +# local ADDUSER=adduser +# else +# local ADDUSER=useradd +# fi +# # Add user "socore" to the master. This will be for things like accepting keys. +# groupadd --gid 939 socore +# $ADDUSER --uid 939 --gid 939 --home-dir /opt/so socore +# # Prompt the user to set a password for the user +# passwd socore } @@ -168,6 +184,16 @@ checkin_at_boot() { echo "startup_states: highstate" >> /etc/salt/minion } +check_socore_pass() { + + if [ $COREPASS1 == $COREPASS2 ]; then + SCMATCH=yes + else + whiptail_passwords_dont_match + fi + +} + chown_salt_master() { echo "Chown the salt dirs on the master for socore" >> $SETUPLOG 2>&1 @@ -265,7 +291,7 @@ network_setup() { # Strip the quotes from the NIC names BONDNIC="$(echo -e "${BNIC}" | tr -d '"')" # Turn off various offloading settings for the interface - for i in rx tx sg tso ufo gso gro lro; do + for i in rx tx sg tso ufo gso gro lro; do ethtool -K $BONDNIC $i off >> $SETUPLOG 2>&1 done # Create the slave interface and assign it to the bond @@ -910,6 +936,14 @@ sensor_pillar() { } +set_hostname() { + + hostnamectl set-hostname $HOSTNAME + echo "127.0.0.1 $HOSTNAME $HOSTNAME.localdomain localhost localhost.localdomain localhost4 localhost4.localdomain" > /etc/hosts + echo "::1 localhost localhost.localdomain localhost6 localhost6.localdomain6" >> /etc/hosts + +} + set_initial_firewall_policy() { get_main_ip @@ -1090,6 +1124,27 @@ whiptail_check_exitstatus() { } +whiptail_create_socore_user() { + + whiptail --title "Security Onion Setup" --msgbox "Set a password for the socore user. This account is used \ + for adding sensors remotely." 8 78 + +} + +whiptail_create_socore_user_password1() { + + COREPASS1=$(whiptail --title "Security Onion Install" --passwordbox \ + "Enter a password for user socore" 10 60 3>&1 1>&2 2>&3) + +} + +whiptail_create_socore_user_password2() { + + COREPASS2=$(whiptail --title "Security Onion Install" --passwordbox \ + "Re-enter a password for user socore" 10 60 3>&1 1>&2 2>&3) + +} + whiptail_cur_close_days() { CURCLOSEDAYS=$(whiptail --title "Security Onion Setup" --inputbox \ @@ -1376,6 +1431,12 @@ whiptail_node_ls_input_batch_count() { } +whiptail_passwords_dont_match() { + + whiptail --title "Security Onion Setup" --msgbox "Passwords don't match. Please re-enter." 8 78 + +} + whiptail_rule_setup() { # Get pulled pork info @@ -1403,6 +1464,16 @@ whiptail_sensor_config() { } +whiptail_set_hostname() { + + HOSTNAME=$(whiptail --title "Security Onion Setup" --inputbox \ + "Enter the Hostname you would like to set." 10 60 localhost 3>&1 1>&2 2>&3) + + local exitstatus=$? + whiptail_check_exitstatus $exitstatus + +} + whiptail_setup_complete() { whiptail --title "Security Onion Setup" --msgbox "Finished installing this as an $INSTALLTYPE." 8 78 @@ -1499,6 +1570,9 @@ if (whiptail_you_sure); then # Let folks know they need their management interface already set up. whiptail_network_notice + # Set the hostname to reduce errors + whiptail_set_hostname + # Go ahead and gen the keys so we can use them for any sensor type - Disabled for now #minio_generate_keys @@ -1548,8 +1622,13 @@ if (whiptail_you_sure); then fi fi + whiptail_create_socore_user + whiptail_create_socore_user_password1 + whiptail_create_socore_user_password2 + # Last Chance to back out whiptail_make_changes + set_hostname generate_passwords auth_pillar clear_master @@ -1563,9 +1642,9 @@ if (whiptail_you_sure); then get_main_ip # Add the user so we can sit back and relax - echo "" - echo "**** Please set a password for socore. You will use this password when setting up other Nodes/Sensors" - echo "" + #echo "" + #echo "**** Please set a password for socore. You will use this password when setting up other Nodes/Sensors" + #echo "" add_socore_user_master # Install salt and dependencies @@ -1681,6 +1760,7 @@ if (whiptail_you_sure); then whiptail_basic_suri fi whiptail_make_changes + set_hostname clear_master mkdir -p /nsm get_filesystem_root @@ -1763,8 +1843,11 @@ if (whiptail_you_sure); then BROVERSION=ZEEK CURCLOSEDAYS=30 process_components + whiptail_create_socore_user + whiptail_create_socore_user_password1 + whiptail_create_socore_user_password2 whiptail_make_changes - #eval_mode_hostsfile + set_hostname generate_passwords auth_pillar clear_master @@ -1913,6 +1996,7 @@ if (whiptail_you_sure); then LSINPUTBATCHCOUNT=125 fi whiptail_make_changes + set_hostname clear_master mkdir -p /nsm get_filesystem_root @@ -1958,22 +2042,22 @@ if (whiptail_you_sure); then whiptail_setup_failed fi - set_initial_firewall_policy - saltify - docker_install - configure_minion node - set_node_type - node_pillar - copy_minion_pillar nodes - salt_checkin + #set_initial_firewall_policy + #saltify + #docker_install + #configure_minion node + #set_node_type + #node_pillar + #copy_minion_pillar nodes + #salt_checkin # Accept the Salt Key - accept_salt_key_remote + #accept_salt_key_remote # Do the big checkin but first let them know it will take a bit. - salt_checkin_message - salt_checkin - checkin_at_boot + #salt_checkin_message + #salt_checkin + #checkin_at_boot - whiptail_setup_complete + #whiptail_setup_complete fi else From eb109149694391704c3ae1b88468215f1e6624da Mon Sep 17 00:00:00 2001 From: Josh Brower Date: Tue, 24 Sep 2019 12:32:59 -0400 Subject: [PATCH 30/73] Update nids2hive.yaml --- salt/elastalert/files/rules/so/nids2hive.yaml | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/salt/elastalert/files/rules/so/nids2hive.yaml b/salt/elastalert/files/rules/so/nids2hive.yaml index aa2287cca..95f066114 100644 --- a/salt/elastalert/files/rules/so/nids2hive.yaml +++ b/salt/elastalert/files/rules/so/nids2hive.yaml @@ -6,7 +6,7 @@ # es_host: {{es}} es_port: 9200 -name: TheHive - New IDS Alert! +name: NIDS-Alert type: frequency index: "*:logstash-ids*" num_events: 1 @@ -15,10 +15,14 @@ timeframe: buffer_time: minutes: 10 allow_buffer_time_overlap: true +query_key: alert +realert: + days: 1 filter: -- term: - event_type: "ids" +- query: + query_string: + query: "event_type: ids AND NOT tags: _jsonparsefailure" alert: modules.so.thehive.TheHiveAlerter @@ -31,12 +35,12 @@ hive_proxies: https: '' hive_alert_config: - title: 'New Alert from Security Onion!' + title: '{match[alert]}' type: 'external' source: 'SecurityOnion' - description: '{match[message]}' + description: "`NIDS Dashboard:` \n\n \n\n `IPs: `{match[source_ip]}:{match[source_port]} --> {match[destination_ip]}:{match[destination_port]} \n\n `Signature:` {match[rule_signature]}" severity: 2 - tags: ['elastalert, SecurityOnion'] + tags: ['elastalert', 'SecurityOnion', 'NIDS'] tlp: 3 status: 'New' follow: True From c869a156c3167d29afc40daba361c28ffc2c3c91 Mon Sep 17 00:00:00 2001 From: Mike Reeves Date: Tue, 24 Sep 2019 12:35:32 -0400 Subject: [PATCH 31/73] Setup Script - New Changes for 1.1.1 --- so-setup-network.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/so-setup-network.sh b/so-setup-network.sh index 6abeb9f51..6949694c8 100644 --- a/so-setup-network.sh +++ b/so-setup-network.sh @@ -89,7 +89,7 @@ add_socore_user_master() { # # Prompt the user to set a password for the user # passwd socore -} +#} add_socore_user_notmaster() { echo "Add socore user on non master" >> $SETUPLOG 2>&1 From cb899943aa704e80c5c55a04d7fd4aeaf5ea5d4b Mon Sep 17 00:00:00 2001 From: doug Date: Tue, 24 Sep 2019 14:00:22 -0400 Subject: [PATCH 32/73] incoming bro_tunnel logs should go to bro_tunnels --- salt/elasticsearch/files/ingest/bro_tunnel | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 salt/elasticsearch/files/ingest/bro_tunnel diff --git a/salt/elasticsearch/files/ingest/bro_tunnel b/salt/elasticsearch/files/ingest/bro_tunnel new file mode 100644 index 000000000..21fa06deb --- /dev/null +++ b/salt/elasticsearch/files/ingest/bro_tunnel @@ -0,0 +1,7 @@ +{ + "description" : "bro_tunnel", + "processors" : [ + { "set": { "field": "event_type", "value": "bro_tunnels" } }, + { "pipeline": { "name": "bro_tunnels" } } + ] +} From 5e2cc080390561461e23553fd2589cc1e351eeca Mon Sep 17 00:00:00 2001 From: Mike Reeves Date: Tue, 24 Sep 2019 14:05:20 -0400 Subject: [PATCH 33/73] PCAP Module - Update steno image --- salt/pcap/init.sls | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/salt/pcap/init.sls b/salt/pcap/init.sls index 5a67a6ec6..ab2f6f71b 100644 --- a/salt/pcap/init.sls +++ b/salt/pcap/init.sls @@ -96,13 +96,13 @@ stenolog: so-stenoimage: cmd.run: - - name: docker pull --disable-content-trust=false soshybridhunter/so-steno:HH1.1.0 + - name: docker pull --disable-content-trust=false soshybridhunter/so-steno:HH1.1.1 so-steno: docker_container.running: - require: - so-stenoimage - - image: soshybridhunter/so-steno:HH1.1.0 + - image: soshybridhunter/so-steno:HH1.1.1 - network_mode: host - privileged: True - port_bindings: From 637eb25d23b94bfd7014e37bdd9ae9945c3628af Mon Sep 17 00:00:00 2001 From: Mike Reeves Date: Tue, 24 Sep 2019 14:07:49 -0400 Subject: [PATCH 34/73] Setup Script - More hostname stuff --- so-setup-network.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/so-setup-network.sh b/so-setup-network.sh index 6949694c8..e7748ba69 100644 --- a/so-setup-network.sh +++ b/so-setup-network.sh @@ -941,6 +941,7 @@ set_hostname() { hostnamectl set-hostname $HOSTNAME echo "127.0.0.1 $HOSTNAME $HOSTNAME.localdomain localhost localhost.localdomain localhost4 localhost4.localdomain" > /etc/hosts echo "::1 localhost localhost.localdomain localhost6 localhost6.localdomain6" >> /etc/hosts + echo "$HOSTNAME" > /etc/hostname } From 33c17ec1752b1a8da3bcca278fa7951f63838424 Mon Sep 17 00:00:00 2001 From: Mike Reeves Date: Tue, 24 Sep 2019 14:14:17 -0400 Subject: [PATCH 35/73] Setup Script - More hostname stuff --- so-setup-network.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/so-setup-network.sh b/so-setup-network.sh index e7748ba69..1414d456b 100644 --- a/so-setup-network.sh +++ b/so-setup-network.sh @@ -938,10 +938,10 @@ sensor_pillar() { set_hostname() { - hostnamectl set-hostname $HOSTNAME + hostnamectl set-hostname --static $HOSTNAME echo "127.0.0.1 $HOSTNAME $HOSTNAME.localdomain localhost localhost.localdomain localhost4 localhost4.localdomain" > /etc/hosts echo "::1 localhost localhost.localdomain localhost6 localhost6.localdomain6" >> /etc/hosts - echo "$HOSTNAME" > /etc/hostname + echo $HOSTNAME > /etc/hostname } From b0b76c18090adf618e6f7d6dbb166cc8c1b3d872 Mon Sep 17 00:00:00 2001 From: Mike Reeves Date: Tue, 24 Sep 2019 14:15:00 -0400 Subject: [PATCH 36/73] Filebeat - Roll back version --- salt/filebeat/init.sls | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/salt/filebeat/init.sls b/salt/filebeat/init.sls index b92899ef0..b7597730c 100644 --- a/salt/filebeat/init.sls +++ b/salt/filebeat/init.sls @@ -58,13 +58,13 @@ filebeatconfsync: so-filebeatimage: cmd.run: - - name: docker pull --disable-content-trust=false soshybridhunter/so-filebeat:HH1.1.1 + - name: docker pull --disable-content-trust=false soshybridhunter/so-filebeat:HH1.1.0 so-filebeat: docker_container.running: - require: - so-filebeatimage - - image: soshybridhunter/so-filebeat:HH1.1.1 + - image: soshybridhunter/so-filebeat:HH1.1.0 - hostname: so-filebeat - user: root - extra_hosts: {{ MASTER }}:{{ MASTERIP }} From 8f2e3e87ff761d3f7e2c3e7ba14cb69f629beec5 Mon Sep 17 00:00:00 2001 From: Mike Reeves Date: Tue, 24 Sep 2019 14:18:54 -0400 Subject: [PATCH 37/73] Setup Script - Actually check the passwords --- so-setup-network.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/so-setup-network.sh b/so-setup-network.sh index 1414d456b..b2f3babc2 100644 --- a/so-setup-network.sh +++ b/so-setup-network.sh @@ -1626,6 +1626,7 @@ if (whiptail_you_sure); then whiptail_create_socore_user whiptail_create_socore_user_password1 whiptail_create_socore_user_password2 + check_admin_pass # Last Chance to back out whiptail_make_changes @@ -1847,6 +1848,7 @@ if (whiptail_you_sure); then whiptail_create_socore_user whiptail_create_socore_user_password1 whiptail_create_socore_user_password2 + check_admin_pass whiptail_make_changes set_hostname generate_passwords From f92d618f823eedf927fc9bd80785152c39acd329 Mon Sep 17 00:00:00 2001 From: Mike Reeves Date: Tue, 24 Sep 2019 14:22:28 -0400 Subject: [PATCH 38/73] Setup Script - Actually check the passwords --- so-setup-network.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/so-setup-network.sh b/so-setup-network.sh index b2f3babc2..b20a6cc9d 100644 --- a/so-setup-network.sh +++ b/so-setup-network.sh @@ -1626,7 +1626,7 @@ if (whiptail_you_sure); then whiptail_create_socore_user whiptail_create_socore_user_password1 whiptail_create_socore_user_password2 - check_admin_pass + check_socore_pass # Last Chance to back out whiptail_make_changes @@ -1848,7 +1848,7 @@ if (whiptail_you_sure); then whiptail_create_socore_user whiptail_create_socore_user_password1 whiptail_create_socore_user_password2 - check_admin_pass + check_socore_pass whiptail_make_changes set_hostname generate_passwords From 5ba4c703a419dd8722e4fd4eb8c13d1faa9bf3aa Mon Sep 17 00:00:00 2001 From: Mike Reeves Date: Tue, 24 Sep 2019 14:25:03 -0400 Subject: [PATCH 39/73] Setup Script - Actually check the passwords --- so-setup-network.sh | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/so-setup-network.sh b/so-setup-network.sh index b20a6cc9d..d021434c6 100644 --- a/so-setup-network.sh +++ b/so-setup-network.sh @@ -1624,9 +1624,12 @@ if (whiptail_you_sure); then fi whiptail_create_socore_user - whiptail_create_socore_user_password1 - whiptail_create_socore_user_password2 - check_socore_pass + SCMATCH=no + while [ $SCMATCH != yes ]; do + whiptail_create_socore_user_password1 + whiptail_create_socore_user_password2 + check_socore_pass + done # Last Chance to back out whiptail_make_changes @@ -1846,9 +1849,12 @@ if (whiptail_you_sure); then CURCLOSEDAYS=30 process_components whiptail_create_socore_user - whiptail_create_socore_user_password1 - whiptail_create_socore_user_password2 - check_socore_pass + SCMATCH=no + while [ $SCMATCH != yes ]; do + whiptail_create_socore_user_password1 + whiptail_create_socore_user_password2 + check_socore_pass + done whiptail_make_changes set_hostname generate_passwords From 1fc4cca2ad2d85cc18ac3de6ca86f86fad596339 Mon Sep 17 00:00:00 2001 From: Mike Reeves Date: Tue, 24 Sep 2019 15:23:12 -0400 Subject: [PATCH 40/73] Hive Module - update version --- salt/hive/init.sls | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/salt/hive/init.sls b/salt/hive/init.sls index c72123d2a..ec5ae4a78 100644 --- a/salt/hive/init.sls +++ b/salt/hive/init.sls @@ -33,13 +33,13 @@ hiveesdata: so-thehive-esimage: cmd.run: - - name: docker pull --disable-content-trust=false soshybridhunter/so-thehive-es:HH1.1.0 + - name: docker pull --disable-content-trust=false soshybridhunter/so-thehive-es:HH1.1.1 so-thehive-es: docker_container.running: - require: - so-thehive-esimage - - image: soshybridhunter/so-thehive-es:HH1.1.0 + - image: soshybridhunter/so-thehive-es:HH1.1.1 - hostname: so-thehive-es - name: so-thehive-es - user: 939 @@ -81,13 +81,13 @@ so-thehive-es: so-thehiveimage: cmd.run: - - name: docker pull --disable-content-trust=false soshybridhunter/so-thehive:HH1.1.0 + - name: docker pull --disable-content-trust=false soshybridhunter/so-thehive:HH1.1.1 so-thehive: docker_container.running: - require: - so-thehiveimage - - image: soshybridhunter/so-thehive:HH1.1.0 + - image: soshybridhunter/so-thehive:HH1.1.1 - environment: - ELASTICSEARCH_HOST={{ MASTERIP }} - hostname: so-thehive From 497edcbe45127e82678705657564796b53e330ee Mon Sep 17 00:00:00 2001 From: Wes Lambert Date: Tue, 24 Sep 2019 19:38:06 +0000 Subject: [PATCH 41/73] update Filebeat log config --- salt/filebeat/init.sls | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/salt/filebeat/init.sls b/salt/filebeat/init.sls index b7597730c..b92899ef0 100644 --- a/salt/filebeat/init.sls +++ b/salt/filebeat/init.sls @@ -58,13 +58,13 @@ filebeatconfsync: so-filebeatimage: cmd.run: - - name: docker pull --disable-content-trust=false soshybridhunter/so-filebeat:HH1.1.0 + - name: docker pull --disable-content-trust=false soshybridhunter/so-filebeat:HH1.1.1 so-filebeat: docker_container.running: - require: - so-filebeatimage - - image: soshybridhunter/so-filebeat:HH1.1.0 + - image: soshybridhunter/so-filebeat:HH1.1.1 - hostname: so-filebeat - user: root - extra_hosts: {{ MASTER }}:{{ MASTERIP }} From 5bd77a517766407c99bd91970e083992615dab3d Mon Sep 17 00:00:00 2001 From: Wes Lambert Date: Tue, 24 Sep 2019 20:37:07 +0000 Subject: [PATCH 42/73] update log path --- salt/filebeat/etc/filebeat.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/salt/filebeat/etc/filebeat.yml b/salt/filebeat/etc/filebeat.yml index 51a751105..f0d3a8587 100644 --- a/salt/filebeat/etc/filebeat.yml +++ b/salt/filebeat/etc/filebeat.yml @@ -12,7 +12,7 @@ name: {{ HOSTNAME }} # Sets log level. The default log level is info. # Available log levels are: error, warning, info, debug -logging.level: error +logging.level: debug # Enable debug output for selected components. To enable all selectors use ["*"] # Other available selectors are "beat", "publish", "service" @@ -40,7 +40,7 @@ logging.to_files: true logging.files: # Configure the path where the logs are written. The default is the logs directory # under the home path (the binary location). - #path: /var/log/filebeat + path: /usr/share/filebeat/logs # The name of the files where the logs are written to. name: filebeat.log From bc788a3d35b23b7914c9cde32cac6f44e336c6dc Mon Sep 17 00:00:00 2001 From: Josh Brower Date: Tue, 24 Sep 2019 20:09:20 -0400 Subject: [PATCH 43/73] Playbook - initial commit --- salt/common/nginx/nginx.conf.so-eval | 25 ++++++++++ salt/firewall/init.sls | 22 +++++++++ salt/soctopus/files/SOCtopus.conf | 4 ++ .../soctopus/files/templates/generic.template | 41 ++++++++++++++++ .../soctopus/files/templates/osquery.template | 48 +++++++++++++++++++ salt/soctopus/init.sls | 16 +++++++ 6 files changed, 156 insertions(+) create mode 100644 salt/soctopus/files/templates/generic.template create mode 100644 salt/soctopus/files/templates/osquery.template diff --git a/salt/common/nginx/nginx.conf.so-eval b/salt/common/nginx/nginx.conf.so-eval index 3230e8edd..0a4b06aef 100644 --- a/salt/common/nginx/nginx.conf.so-eval +++ b/salt/common/nginx/nginx.conf.so-eval @@ -113,6 +113,31 @@ http { } + location /playbook/ { + proxy_pass http://{{ masterip }}:3200/playbook/; + 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 /navigator/ { + auth_basic "Security Onion"; + auth_basic_user_file /opt/so/conf/nginx/.htpasswd; + proxy_pass http://{{ masterip }}:4200/navigator/; + 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 /api/ { proxy_pass https://{{ masterip }}:8080/api/; proxy_read_timeout 90; diff --git a/salt/firewall/init.sls b/salt/firewall/init.sls index 7044699f0..2489b1f47 100644 --- a/salt/firewall/init.sls +++ b/salt/firewall/init.sls @@ -228,6 +228,28 @@ enable_master_osquery_8080_{{ip}}: - position: 1 - save: True +enable_master_playbook_3200_{{ip}}: + iptables.insert: + - table: filter + - chain: DOCKER-USER + - jump: ACCEPT + - proto: tcp + - source: {{ ip }} + - dport: 3200 + - position: 1 + - save: True + +enable_master_navigator_4200_{{ip}}: + iptables.insert: + - table: filter + - chain: DOCKER-USER + - jump: ACCEPT + - proto: tcp + - source: {{ ip }} + - dport: 4200 + - position: 1 + - save: True + {% endfor %} # Make it so all the minions can talk to salt and update etc. diff --git a/salt/soctopus/files/SOCtopus.conf b/salt/soctopus/files/SOCtopus.conf index 1a48ad92f..f1d311602 100644 --- a/salt/soctopus/files/SOCtopus.conf +++ b/salt/soctopus/files/SOCtopus.conf @@ -45,5 +45,9 @@ rtir_creator = root slack_url = YOURSLACKWORKSPACE slack_webhook = YOURSLACKWEBHOOK +[playbook] +playbook_url = http://{{ip}}:3200/playbook +playbook_key = a4a34538782804adfcb8dfae96262514ad70c37c + [log] logfile = /tmp/soctopus.log diff --git a/salt/soctopus/files/templates/generic.template b/salt/soctopus/files/templates/generic.template new file mode 100644 index 000000000..992db3fa9 --- /dev/null +++ b/salt/soctopus/files/templates/generic.template @@ -0,0 +1,41 @@ +{% set es = salt['pillar.get']('static:masterip', '') %} +{% set hivehost = salt['pillar.get']('static:masterip', '') %} +{% set hivekey = salt['pillar.get']('static:hivekey', '') %} +es_host: {{es}} +es_port: 9200 +name: Alert-Name +type: frequency +index: "*:logstash-*" +num_events: 1 +timeframe: + minutes: 10 +buffer_time: + minutes: 10 +allow_buffer_time_overlap: true + +filter: +- query: + query_string: + query: 'select from test' + +alert: modules.so.thehive.TheHiveAlerter + +hive_connection: + hive_host: https://{{hivehost}}/thehive/ + hive_apikey: {{hivekey}} + +hive_proxies: + http: '' + https: '' + +hive_alert_config: + title: '{rule[name]}' + type: 'external' + source: 'SecurityOnion' + description: '`Data:` {match[message]}' + severity: 2 + tags: ['elastalert', 'SecurityOnion'] + tlp: 3 + status: 'New' + follow: True + caseTemplate: '5000' diff --git a/salt/soctopus/files/templates/osquery.template b/salt/soctopus/files/templates/osquery.template new file mode 100644 index 000000000..23b3ad1af --- /dev/null +++ b/salt/soctopus/files/templates/osquery.template @@ -0,0 +1,48 @@ +{% set es = salt['pillar.get']('static:masterip', '') %} +{% set hivehost = salt['pillar.get']('static:masterip', '') %} +{% set hivekey = salt['pillar.get']('static:hivekey', '') %} +es_host: {{es}} +es_port: 9200 +name: Alert-Name +type: frequency +index: "*:logstash-*" +num_events: 1 +timeframe: + minutes: 10 +buffer_time: + minutes: 10 +allow_buffer_time_overlap: true + +filter: +- query: + query_string: + query: 'select from test' + +alert: modules.so.thehive.TheHiveAlerter + +hive_connection: + hive_host: https://{{hivehost}}/thehive/ + hive_apikey: {{hivekey}} + +hive_proxies: + http: '' + https: '' + +hive_alert_config: + title: '{rule[name]} -- {match[osquery][hostname]} -- {match[osquery][name]}' + type: 'external' + source: 'SecurityOnion' + description: '`Hostname:` __{match[osquery][hostname]}__ `Live Query:`__[Pivot Link](https://{{es}}/fleet/queries/new?host_uuids={match[osquery][LiveQuery]})__ `Pack:` __{match[osquery][name]}__ `Data:` {match[osquery][columns]}' + severity: 2 + tags: ['elastalert', 'SecurityOnion'] + tlp: 3 + status: 'New' + follow: True + caseTemplate: '5000' + +hive_observable_data_mapping: + - ip: '{match[osquery][EndpointIP1]}' + - ip: '{match[osquery][EndpointIP2]}' + - other: '{match[osquery][hostIdentifier]}' + - other: '{match[osquery][hostname]}' + - ip: '{match[osquery][columns][address]}' diff --git a/salt/soctopus/init.sls b/salt/soctopus/init.sls index 22b21eb8f..8d5d628a2 100644 --- a/salt/soctopus/init.sls +++ b/salt/soctopus/init.sls @@ -13,6 +13,21 @@ soctopussync: - group: 939 - template: jinja +playbookrulesdir: + file.directory: + - name: /opt/so/rules/elastalert/playbook + - user: 939 + - group: 939 + - makedirs: True + +playbookrulessync: + file.recurse: + - name: /opt/so/rules/elastalert/playbook + - source: salt://soctopus/files/templates + - user: 939 + - group: 939 + - template: jinja + so-soctopusimage: cmd.run: - name: docker pull --disable-content-trust=false soshybridhunter/so-soctopus:HH1.1.0 @@ -26,5 +41,6 @@ so-soctopus: - name: so-soctopus - binds: - /opt/so/conf/soctopus/SOCtopus.conf:/SOCtopus/SOCtopus.conf:ro + - /opt/so/rules/elastalert/playbook:/etc/playbook-rules:rw - port_bindings: - 0.0.0.0:7000:7000 From ee5fa8d2db2d51ca2d20a4ae4a1ff96e3ab64069 Mon Sep 17 00:00:00 2001 From: Mike Reeves Date: Wed, 25 Sep 2019 09:59:15 -0400 Subject: [PATCH 44/73] Setup Script - Remove undeeded password message --- so-setup-network.sh | 3 --- 1 file changed, 3 deletions(-) diff --git a/so-setup-network.sh b/so-setup-network.sh index d021434c6..201c78468 100644 --- a/so-setup-network.sh +++ b/so-setup-network.sh @@ -1866,9 +1866,6 @@ if (whiptail_you_sure); then get_log_size_limit get_main_ip # Add the user so we can sit back and relax - echo "" - echo "**** Please set a password for socore. You will use this password when setting up other Nodes/Sensors" - echo "" add_socore_user_master { sleep 0.5 From db7920710b98d977a7313539c223af8006892eae Mon Sep 17 00:00:00 2001 From: Mike Reeves Date: Wed, 25 Sep 2019 10:34:46 -0400 Subject: [PATCH 45/73] Hive Module - Temp remove init --- salt/hive/init.sls | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/salt/hive/init.sls b/salt/hive/init.sls index ec5ae4a78..b6272b8ed 100644 --- a/salt/hive/init.sls +++ b/salt/hive/init.sls @@ -98,8 +98,8 @@ so-thehive: - port_bindings: - 0.0.0.0:9000:9000 -hivescript: - cmd.script: - - source: salt://hive/thehive/scripts/hive_init.sh - - cwd: /opt/so - - template: jinja +#hivescript: +# cmd.script: +# - source: salt://hive/thehive/scripts/hive_init.sh +# - cwd: /opt/so +# - template: jinja From ae9624eb6498a8a13f52f2951328c86f5a1aeb67 Mon Sep 17 00:00:00 2001 From: Mike Reeves Date: Wed, 25 Sep 2019 10:35:58 -0400 Subject: [PATCH 46/73] Setup Script - Add Hive Progress --- so-setup-network.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/so-setup-network.sh b/so-setup-network.sh index 201c78468..7c2fb79fe 100644 --- a/so-setup-network.sh +++ b/so-setup-network.sh @@ -1946,6 +1946,7 @@ if (whiptail_you_sure); then salt-call state.apply schedule >> $SETUPLOG 2>&1 salt-call state.apply soctopus >> $SETUPLOG 2>&1 if [[ $THEHIVE == '1' ]]; then + echo -e "XXX\n97\nInstalling misc components... \nXXX" salt-call state.apply hive >> $SETUPLOG 2>&1 fi echo -e "XXX\n98\nSetting checkin to run on boot... \nXXX" From bb8a884cc5ced1f7129d2791252611dabd01e927 Mon Sep 17 00:00:00 2001 From: Mike Reeves Date: Wed, 25 Sep 2019 11:01:03 -0400 Subject: [PATCH 47/73] Setup Script - Fix display message for eval hive --- so-setup-network.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/so-setup-network.sh b/so-setup-network.sh index 7c2fb79fe..318d7679a 100644 --- a/so-setup-network.sh +++ b/so-setup-network.sh @@ -1946,7 +1946,7 @@ if (whiptail_you_sure); then salt-call state.apply schedule >> $SETUPLOG 2>&1 salt-call state.apply soctopus >> $SETUPLOG 2>&1 if [[ $THEHIVE == '1' ]]; then - echo -e "XXX\n97\nInstalling misc components... \nXXX" + echo -e "XXX\n97\nInstalling The Hive... \nXXX" salt-call state.apply hive >> $SETUPLOG 2>&1 fi echo -e "XXX\n98\nSetting checkin to run on boot... \nXXX" From 58073cd04fb27a7a4d478e6911cfab761d4a502d Mon Sep 17 00:00:00 2001 From: Mike Reeves Date: Wed, 25 Sep 2019 11:43:30 -0400 Subject: [PATCH 48/73] Hive Module - Fix ES --- salt/hive/thehive/etc/es/elasticsearch.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/salt/hive/thehive/etc/es/elasticsearch.yml b/salt/hive/thehive/etc/es/elasticsearch.yml index d600830b6..d00c01d5d 100644 --- a/salt/hive/thehive/etc/es/elasticsearch.yml +++ b/salt/hive/thehive/etc/es/elasticsearch.yml @@ -11,7 +11,6 @@ http.host: 0.0.0.0 http.port: 9400 transport.tcp.port: 9500 transport.host: 0.0.0.0 -script.inline: true thread_pool.index.queue_size: 100000 thread_pool.search.queue_size: 100000 thread_pool.bulk.queue_size: 100000 From 909e35ec3b6c21b3ff2fd54d90f932312706ba33 Mon Sep 17 00:00:00 2001 From: Josh Brower Date: Wed, 25 Sep 2019 13:04:53 -0400 Subject: [PATCH 49/73] Playbook and Navigator - initial salt config --- salt/common/nginx/nginx.conf.so-master | 24 +++++++++ salt/playbook/files/nav_layer_playbook.json | 33 ++++++++++++ salt/playbook/files/navigator_config.json | 59 +++++++++++++++++++++ salt/playbook/init.sls | 49 +++++++++++++++++ 4 files changed, 165 insertions(+) create mode 100644 salt/playbook/files/nav_layer_playbook.json create mode 100644 salt/playbook/files/navigator_config.json create mode 100644 salt/playbook/init.sls diff --git a/salt/common/nginx/nginx.conf.so-master b/salt/common/nginx/nginx.conf.so-master index 7999a7027..433af1228 100644 --- a/salt/common/nginx/nginx.conf.so-master +++ b/salt/common/nginx/nginx.conf.so-master @@ -113,6 +113,30 @@ http { } + location /playbook/ { + proxy_pass http://{{ masterip }}:3200/playbook/; + 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 /navigator/ { + auth_basic "Security Onion"; + auth_basic_user_file /opt/so/conf/nginx/.htpasswd; + proxy_pass http://{{ masterip }}:4200/navigator/; + 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 /api/ { proxy_pass https://{{ masterip }}:8080/api/; proxy_read_timeout 90; diff --git a/salt/playbook/files/nav_layer_playbook.json b/salt/playbook/files/nav_layer_playbook.json new file mode 100644 index 000000000..69d8aa8d3 --- /dev/null +++ b/salt/playbook/files/nav_layer_playbook.json @@ -0,0 +1,33 @@ +{ + "name": "Playbook", + "version": "2.1", + "domain": "mitre-enterprise", + "description": "Current Coverage of Playbook", + "filters": { + "stages": ["act"], + "platforms": [ + "windows", + "linux", + "mac" + ] + }, + "sorting": 0, + "viewMode": 0, + "hideDisabled": "false", + "techniques": [{ + "techniqueID": "T1003", + "color": "#5AADFF", + "comment": "", + "enabled": "true", + "metadata": [] + }], + "gradient": { + "colors": ["#ff6666", "#ffe766", "#8ec843"], + "minValue": 0, + "maxValue": 100 + }, + "metadata": [], + "showTacticRowBackground": "false", + "tacticRowBackground": "#dddddd", + "selectTechniquesAcrossTactics": "true" +} diff --git a/salt/playbook/files/navigator_config.json b/salt/playbook/files/navigator_config.json new file mode 100644 index 000000000..7e132cbf8 --- /dev/null +++ b/salt/playbook/files/navigator_config.json @@ -0,0 +1,59 @@ +{%- set ip = salt['pillar.get']('static:masterip', '') %} + +{ + "enterprise_attack_url": "https://raw.githubusercontent.com/mitre/cti/master/enterprise-attack/enterprise-attack.json", + "pre_attack_url": "https://raw.githubusercontent.com/mitre/cti/master/pre-attack/pre-attack.json", + "mobile_data_url": "https://raw.githubusercontent.com/mitre/cti/master/mobile-attack/mobile-attack.json", + "taxii_server": { + "enabled": false, + "url": "https://cti-taxii.mitre.org/", + "collections": { + "enterprise_attack": "95ecc380-afe9-11e4-9b6c-751b66dd541e", + "pre_attack": "062767bd-02d2-4b72-84ba-56caef0f8658", + "mobile_attack": "2f669986-b40b-4423-b720-4396ca6a462b" + } + }, + + "domain": "mitre-enterprise", + + "custom_context_menu_items": [ {"label": "view related plays","url": " https://{{ip}}/playbook/projects/playbook-prod/issues?utf8=%E2%9C%93&set_filter=1&sort=id%3Adesc&f%5B%5D=status_id&op%5Bstatus_id%5D=o&f%5B%5D=cf_27&op%5Bcf_27%5D=%3D&f%5B%5D=&c%5B%5D=status&c%5B%5D=cf_24&c%5B%5D=cf_25&c%5B%5D=cf_6&c%5B%5D=updated_on&group_by=&t%5B%5D=&v%5Bcf_27%5D%5B%5D=~Technique_ID~"}], + +"default_layers": { + "enabled": true, + "urls": [ + "assets/playbook.json" + ] + }, + + "comment_color": "yellow", + + "features": [ + {"name": "tabs", "enabled": true, "description": "Disable to remove the ability to open new tabs."}, + {"name": "selecting_techniques", "enabled": true, "description": "Disable to remove the ability to select techniques."}, + {"name": "header", "enabled": true, "description": "Disable to remove the header containing 'MITRE ATT&CK Navigator' and the link to the help page. The help page can still be accessed from the new tab menu."}, + {"name": "selection_controls", "enabled": true, "description": "Disable to to disable all subfeatures", "subfeatures": [ + {"name": "search", "enabled": true, "description": "Disable to remove the technique search panel from the interface."}, + {"name": "multiselect", "enabled": true, "description": "Disable to remove the multiselect panel from interface."}, + {"name": "deselect_all", "enabled": true, "description": "Disable to remove the deselect all button from the interface."} + ]}, + {"name": "layer_controls", "enabled": true, "description": "Disable to to disable all subfeatures", "subfeatures": [ + {"name": "layer_info", "enabled": true, "description": "Disable to remove the layer info (name, description and metadata) panel from the interface. Note that the layer can still be renamed in the tab."}, + {"name": "download_layer", "enabled": true, "description": "Disable to remove the button to download the layer."}, + {"name": "export_render", "enabled": true, "description": "Disable to the remove the button to render the current layer."}, + {"name": "export_excel", "enabled": true, "description": "Disable to the remove the button to export the current layer to MS Excel (.xlsx) format."}, + {"name": "filters", "enabled": true, "description": "Disable to the remove the filters panel from interface."}, + {"name": "sorting", "enabled": true, "description": "Disable to the remove the sorting button from the interface."}, + {"name": "color_setup", "enabled": true, "description": "Disable to the remove the color setup panel from interface, containing customization controls for scoring gradient and tactic row color."}, + {"name": "toggle_hide_disabled", "enabled": true, "description": "Disable to the remove the hide disabled techniques button from the interface."}, + {"name": "toggle_view_mode", "enabled": true, "description": "Disable to the remove the toggle view mode button from interface."}, + {"name": "legend", "enabled": true, "description": "Disable to the remove the legend panel from the interface."} + ]}, + {"name": "technique_controls", "enabled": true, "description": "Disable to to disable all subfeatures", "subfeatures": [ + {"name": "disable_techniques", "enabled": true, "description": "Disable to the remove the ability to disable techniques."}, + {"name": "manual_color", "enabled": true, "description": "Disable to the remove the ability to assign manual colors to techniques."}, + {"name": "scoring", "enabled": true, "description": "Disable to the remove the ability to score techniques."}, + {"name": "comments", "enabled": true, "description": "Disable to the remove the ability to add comments to techniques."}, + {"name": "clear_annotations", "enabled": true, "description": "Disable to remove the button to clear all annotations on the selected techniques."} + ]} + ] +} diff --git a/salt/playbook/init.sls b/salt/playbook/init.sls new file mode 100644 index 000000000..fbaea191d --- /dev/null +++ b/salt/playbook/init.sls @@ -0,0 +1,49 @@ +navigatordefaultlayer: + file.manage: + - name: /opt/so/conf/playbook/nav_layer_playbook.json + - source: salt://playbook/files/nav_layer_playbook.json + - user: 939 + - group: 939 + - makedirs: True + - replace: False + - template: jinja + +navigatorconfig: + file.manage: + - name: /opt/so/conf/playbook/navigator_config.json + - source: salt://playbook/files/navigator_config.json + - user: 939 + - group: 939 + - makedirs: True + - template: jinja + +so-playbookimage: + cmd.run: + - name: docker pull --disable-content-trust=false soshybridhunter/so-playbook:HH1.1.1 + +so-playbook: + docker_container.running: + - require: + - so-playbookimage + - image: soshybridhunter/so-playbook:HH1.1.1 + - hostname: playbook + - name: so-playbook + - port_bindings: + - 0.0.0.0:3200:3000 + +so-navigatorimage: + cmd.run: + - name: docker pull --disable-content-trust=false soshybridhunter/so-navigator:HH1.1.1 + +so-navigator: + docker_container.running: + - require: + - so-navigatorimage + - image: soshybridhunter/so-navigator:HH1.1.1 + - hostname: navigator + - name: so-navigator + - binds: + - /opt/so/conf/playbook/navigator_config.json:/nav-app/src/assets/config.json:ro + - /opt/so/conf/playbook/nav_layer_playbook.json:/nav-app/src/assets/playbook.json:ro + - port_bindings: + - 0.0.0.0:4200:4200 From d979be82fbf1b8b3ebfe75718bd9ba48b4f3e674 Mon Sep 17 00:00:00 2001 From: Mike Reeves Date: Wed, 25 Sep 2019 13:16:49 -0400 Subject: [PATCH 50/73] Hive Module - New Version --- salt/hive/init.sls | 11 ++- salt/hive/thehive/etc/application.conf | 96 +++++++++++++------------- 2 files changed, 52 insertions(+), 55 deletions(-) diff --git a/salt/hive/init.sls b/salt/hive/init.sls index b6272b8ed..5897f6a93 100644 --- a/salt/hive/init.sls +++ b/salt/hive/init.sls @@ -56,7 +56,6 @@ so-thehive-es: - transport.tcp.port=9500 - transport.host=0.0.0.0 - cluster.name=hive - - script.inline=true - thread_pool.index.queue_size=100000 - thread_pool.search.queue_size=100000 - thread_pool.bulk.queue_size=100000 @@ -98,8 +97,8 @@ so-thehive: - port_bindings: - 0.0.0.0:9000:9000 -#hivescript: -# cmd.script: -# - source: salt://hive/thehive/scripts/hive_init.sh -# - cwd: /opt/so -# - template: jinja +hivescript: + cmd.script: + - source: salt://hive/thehive/scripts/hive_init.sh + - cwd: /opt/so + - template: jinja diff --git a/salt/hive/thehive/etc/application.conf b/salt/hive/thehive/etc/application.conf index 1fd4b4816..e4dd1e2b2 100644 --- a/salt/hive/thehive/etc/application.conf +++ b/salt/hive/thehive/etc/application.conf @@ -5,59 +5,57 @@ # WARNING: If you deploy your application on several servers, make sure to use the same key. play.http.secret.key="letsdewdis" play.http.context=/thehive/ - +search.uri = "http://{{ MASTERIP }}:9400" # Elasticsearch search { - ## Basic configuration - # Index name. - index = the_hive - # ElasticSearch cluster name. - cluster = hive - # ElasticSearch instance address. - host = ["{{ MASTERIP }}:9500"] + # Name of the index + index = the_hive + # Name of the Elasticsearch cluster + cluster = hive + # Address of the Elasticsearch instance + host = ["{{ MASTERIP }}:9500"] + #search.uri = "http://{{ MASTERIP }}:9500" + # Scroll keepalive + keepalive = 1m + # Size of the page for scroll + pagesize = 50 + # Number of shards + nbshards = 5 + # Number of replicas + nbreplicas = 1 + # Arbitrary settings + settings { + # Maximum number of nested fields + mapping.nested_fields.limit = 100 + } - ## Advanced configuration - # Scroll keepalive. - #keepalive = 1m - # Scroll page size. - #pagesize = 50 - # Number of shards - #nbshards = 5 - # Number of replicas - #nbreplicas = 1 - # Arbitrary settings - #settings { - # # Maximum number of nested fields - # mapping.nested_fields.limit = 100 - #} + ### XPack SSL configuration + # Username for XPack authentication + #username + # Password for XPack authentication + #password + # Enable SSL to connect to ElasticSearch + ssl.enabled = false + # Path to certificate authority file + #ssl.ca + # Path to certificate file + #ssl.certificate + # Path to key file + #ssl.key - ### XPack SSL configuration - # Username for XPack authentication - #search.username = "" - # Password for XPack authentication - #search.password = "" - # Enable SSL to connect to ElasticSearch - search.ssl.enabled = false - # Path to certificate authority file - #search.ssl.ca = "" - # Path to certificate file - #search.ssl.certificate = "" - # Path to key file - #search.ssl.key = "" - - ### SearchGuard configuration - # Path to JKS file containing client certificate - #search.guard.keyStore.path = "" - # Password of the keystore - #search.guard.keyStore.password = "" - # Path to JKS file containing certificate authorities - #search.guard.trustStore.path = "" - ## Password of the truststore - #search.guard.trustStore.password = "" - # Enforce hostname verification - #search.guard.hostVerification = false - # If hostname verification is enabled specify if hostname should be resolved - #search.guard.hostVerificationResolveHostname = false + ### SearchGuard configuration + # Path to JKS file containing client certificate + #guard.keyStore.path + # Password of the keystore + #guard.keyStore.password + # Path to JKS file containing certificate authorities + #guard.trustStore.path + ## Password of the truststore + #guard.trustStore.password + # Enforce hostname verification + #guard.hostVerification + # If hostname verification is enabled specify if hostname should be resolved + #guard.hostVerificationResolveHostname } # Authentication From 57f574ff1b253287e55ada64cb20e9c28eedcb93 Mon Sep 17 00:00:00 2001 From: Doug Burks Date: Wed, 25 Sep 2019 13:47:15 -0400 Subject: [PATCH 51/73] Update so-setup-network.sh --- so-setup-network.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/so-setup-network.sh b/so-setup-network.sh index 318d7679a..c0159e71d 100644 --- a/so-setup-network.sh +++ b/so-setup-network.sh @@ -511,8 +511,8 @@ master_pillar() { echo " esheap: $ES_HEAP_SIZE" >> /opt/so/saltstack/pillar/masters/$HOSTNAME.sls echo " esclustername: {{ grains.host }}" >> /opt/so/saltstack/pillar/masters/$HOSTNAME.sls if [ $INSTALLTYPE == 'EVALMODE' ]; then - echo " freq: 1" >> /opt/so/saltstack/pillar/masters/$HOSTNAME.sls - echo " domainstats: 1" >> /opt/so/saltstack/pillar/masters/$HOSTNAME.sls + echo " freq: 0" >> /opt/so/saltstack/pillar/masters/$HOSTNAME.sls + echo " domainstats: 0" >> /opt/so/saltstack/pillar/masters/$HOSTNAME.sls echo " ls_pipeline_batch_size: 125" >> /opt/so/saltstack/pillar/masters/$HOSTNAME.sls echo " ls_input_threads: 1" >> /opt/so/saltstack/pillar/masters/$HOSTNAME.sls echo " ls_batch_count: 125" >> /opt/so/saltstack/pillar/masters/$HOSTNAME.sls From d9713cc14a6285beadcfac0aff0a2143a7e37754 Mon Sep 17 00:00:00 2001 From: Josh Brower Date: Wed, 25 Sep 2019 15:18:18 -0400 Subject: [PATCH 52/73] Playbook & SOCtopus init edits --- salt/playbook/files/nav_layer_playbook.json | 5 ----- salt/playbook/init.sls | 12 +----------- salt/soctopus/init.sls | 15 +++++++++++++-- 3 files changed, 14 insertions(+), 18 deletions(-) diff --git a/salt/playbook/files/nav_layer_playbook.json b/salt/playbook/files/nav_layer_playbook.json index 69d8aa8d3..43ed462b7 100644 --- a/salt/playbook/files/nav_layer_playbook.json +++ b/salt/playbook/files/nav_layer_playbook.json @@ -15,11 +15,6 @@ "viewMode": 0, "hideDisabled": "false", "techniques": [{ - "techniqueID": "T1003", - "color": "#5AADFF", - "comment": "", - "enabled": "true", - "metadata": [] }], "gradient": { "colors": ["#ff6666", "#ffe766", "#8ec843"], diff --git a/salt/playbook/init.sls b/salt/playbook/init.sls index fbaea191d..541d5d5e0 100644 --- a/salt/playbook/init.sls +++ b/salt/playbook/init.sls @@ -1,15 +1,5 @@ -navigatordefaultlayer: - file.manage: - - name: /opt/so/conf/playbook/nav_layer_playbook.json - - source: salt://playbook/files/nav_layer_playbook.json - - user: 939 - - group: 939 - - makedirs: True - - replace: False - - template: jinja - navigatorconfig: - file.manage: + file.managed: - name: /opt/so/conf/playbook/navigator_config.json - source: salt://playbook/files/navigator_config.json - user: 939 diff --git a/salt/soctopus/init.sls b/salt/soctopus/init.sls index 8d5d628a2..98a9a4158 100644 --- a/salt/soctopus/init.sls +++ b/salt/soctopus/init.sls @@ -28,19 +28,30 @@ playbookrulessync: - group: 939 - template: jinja +navigatordefaultlayer: + file.managed: + - name: /opt/so/conf/playbook/nav_layer_playbook.json + - source: salt://playbook/files/nav_layer_playbook.json + - user: 939 + - group: 939 + - makedirs: True + - replace: False + - template: jinja + so-soctopusimage: cmd.run: - - name: docker pull --disable-content-trust=false soshybridhunter/so-soctopus:HH1.1.0 + - name: docker pull --disable-content-trust=false soshybridhunter/so-soctopus:HH1.1.1 so-soctopus: docker_container.running: - require: - so-soctopusimage - - image: soshybridhunter/so-soctopus:HH1.1.0 + - image: soshybridhunter/so-soctopus:HH1.1.1 - hostname: soctopus - name: so-soctopus - binds: - /opt/so/conf/soctopus/SOCtopus.conf:/SOCtopus/SOCtopus.conf:ro - /opt/so/rules/elastalert/playbook:/etc/playbook-rules:rw + - /opt/so/conf/playbook/nav_layer_playbook.json:/etc/playbook/nav_layer_playbook.json:rw - port_bindings: - 0.0.0.0:7000:7000 From 063f9012d1911279902fc325d91d2ad38f3d720d Mon Sep 17 00:00:00 2001 From: Mike Reeves Date: Wed, 25 Sep 2019 16:21:02 -0400 Subject: [PATCH 53/73] PCAP Module - Fix sensoroni logging --- salt/pcap/init.sls | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/salt/pcap/init.sls b/salt/pcap/init.sls index ab2f6f71b..86408c0e3 100644 --- a/salt/pcap/init.sls +++ b/salt/pcap/init.sls @@ -116,6 +116,6 @@ so-steno: - /nsm/pcapout:/nsm/pcapout:rw - /opt/so/log/stenographer:/var/log/stenographer:rw - /opt/so/conf/steno/sensoroni.json:/opt/sensoroni/sensoroni.json:ro - - /opt/so/log/stenographer:/opt/sensoroni/log:rw + - /opt/so/log/stenographer:/opt/sensoroni/logs:rw - watch: - /opt/so/conf/steno/sensoroni.json From 1dd59e92e41fde70f82be3a509d8283d13c6d7e3 Mon Sep 17 00:00:00 2001 From: Mike Reeves Date: Wed, 25 Sep 2019 16:58:15 -0400 Subject: [PATCH 54/73] Common Module - Fix nginx for websockets --- salt/common/nginx/nginx.conf.so-eval | 6 ++++-- salt/common/nginx/nginx.conf.so-master | 2 ++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/salt/common/nginx/nginx.conf.so-eval b/salt/common/nginx/nginx.conf.so-eval index 0a4b06aef..344ca4aed 100644 --- a/salt/common/nginx/nginx.conf.so-eval +++ b/salt/common/nginx/nginx.conf.so-eval @@ -123,8 +123,8 @@ http { proxy_set_header Proxy ""; } - - + + location /navigator/ { auth_basic "Security Onion"; auth_basic_user_file /opt/so/conf/nginx/.htpasswd; @@ -198,6 +198,8 @@ http { 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"; } diff --git a/salt/common/nginx/nginx.conf.so-master b/salt/common/nginx/nginx.conf.so-master index 433af1228..dcedcafaf 100644 --- a/salt/common/nginx/nginx.conf.so-master +++ b/salt/common/nginx/nginx.conf.so-master @@ -197,6 +197,8 @@ http { 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"; } From 4352b1ebf6a9c800ae409a83b2280fd1247432ad Mon Sep 17 00:00:00 2001 From: Josh Brower Date: Thu, 26 Sep 2019 11:11:18 -0400 Subject: [PATCH 55/73] Updated Kibana NIDS SID Drilldown dashboard --- salt/elastalert/files/rules/so/nids2hive.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/salt/elastalert/files/rules/so/nids2hive.yaml b/salt/elastalert/files/rules/so/nids2hive.yaml index 95f066114..7d55b4675 100644 --- a/salt/elastalert/files/rules/so/nids2hive.yaml +++ b/salt/elastalert/files/rules/so/nids2hive.yaml @@ -38,7 +38,7 @@ hive_alert_config: title: '{match[alert]}' type: 'external' source: 'SecurityOnion' - description: "`NIDS Dashboard:` \n\n \n\n `IPs: `{match[source_ip]}:{match[source_port]} --> {match[destination_ip]}:{match[destination_port]} \n\n `Signature:` {match[rule_signature]}" + description: "`NIDS Dashboard:` \n\n \n\n `IPs: `{match[source_ip]}:{match[source_port]} --> {match[destination_ip]}:{match[destination_port]} \n\n `Signature:` {match[rule_signature]}" severity: 2 tags: ['elastalert', 'SecurityOnion', 'NIDS'] tlp: 3 From 657ddc42a85d3f804c9a467be870abfc5f374926 Mon Sep 17 00:00:00 2001 From: Mike Reeves Date: Fri, 27 Sep 2019 10:40:28 -0400 Subject: [PATCH 56/73] Playbook - Add flag for runtime --- salt/top.sls | 10 +++++++++- so-setup-network.sh | 1 + 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/salt/top.sls b/salt/top.sls index f3f8c0a73..cf5d47699 100644 --- a/salt/top.sls +++ b/salt/top.sls @@ -3,6 +3,7 @@ {%- set WAZUH = salt['pillar.get']('master:wazuh', '0') -%} {%- set GRAFANA = salt['pillar.get']('master:grafana', '0') -%} {%- set THEHIVE = salt['pillar.get']('master:thehive', '0') -%} +{%- set PLAYBOOK = salt['pillar.get']('master:playbook', '0') -%} base: 'G@role:so-sensor': - ca @@ -55,6 +56,10 @@ base: {%- if THEHIVE != 0 %} - hive {%- endif %} + {%- if PLAYBOOK != 0 %} + - playbook + {%- endif %} + 'G@role:so-master': @@ -87,7 +92,10 @@ base: {%- if THEHIVE != 0 %} - hive {%- endif %} - + {%- if PLAYBOOK != 0 %} + - playbook + {%- endif %} + # Storage node logic diff --git a/so-setup-network.sh b/so-setup-network.sh index c0159e71d..69ee7839e 100644 --- a/so-setup-network.sh +++ b/so-setup-network.sh @@ -539,6 +539,7 @@ master_pillar() { echo " osquery: $OSQUERY" >> /opt/so/saltstack/pillar/masters/$HOSTNAME.sls echo " wazuh: $WAZUH" >> /opt/so/saltstack/pillar/masters/$HOSTNAME.sls echo " thehive: $THEHIVE" >> /opt/so/saltstack/pillar/masters/$HOSTNAME.sls + echo " playbook: 0" >> /opt/so/saltstack/pillar/masters/$HOSTNAME.sls } master_static() { From a833025a736d88b0030d7b6de04da356c34bd801 Mon Sep 17 00:00:00 2001 From: Mike Reeves Date: Fri, 27 Sep 2019 10:53:50 -0400 Subject: [PATCH 57/73] Setup Script - Reboot at the end --- so-setup-network.sh | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/so-setup-network.sh b/so-setup-network.sh index 69ee7839e..3fd49d362 100644 --- a/so-setup-network.sh +++ b/so-setup-network.sh @@ -184,6 +184,23 @@ checkin_at_boot() { echo "startup_states: highstate" >> /etc/salt/minion } +check_hive_init_then_reboot() { + WAIT_STEP=0 + MAX_WAIT=100 + until [ -f /opt/so/state/thehive.txt ] ; do + WAIT_STEP=$(( ${WAIT_STEP} + 1 )) + echo "Waiting on the_hive to init...Attempt #$WAIT_STEP" + if [ ${WAIT_STEP} -gt ${MAX_WAIT} ]; then + echo "ERROR: We waited ${MAX_WAIT} seconds but the_hive is not working." + exit 5 + fi + sleep 1s; + done + docker stop so-thehive + docker rm so-thehive + shutdown -r now +} + check_socore_pass() { if [ $COREPASS1 == $COREPASS2 ]; then @@ -1478,7 +1495,7 @@ whiptail_set_hostname() { whiptail_setup_complete() { - whiptail --title "Security Onion Setup" --msgbox "Finished installing this as an $INSTALLTYPE." 8 78 + whiptail --title "Security Onion Setup" --msgbox "Finished installing this as an $INSTALLTYPE. Press Enter to reboot" 8 78 install_cleanup exit @@ -1486,7 +1503,7 @@ whiptail_setup_complete() { whiptail_setup_failed() { - whiptail --title "Security Onion Setup" --msgbox "Install had a problem. Please see $SETUPLOG for details" 8 78 + whiptail --title "Security Onion Setup" --msgbox "Install had a problem. Please see $SETUPLOG for details. Press Enter to reboot" 8 78 install_cleanup exit @@ -1736,8 +1753,10 @@ if (whiptail_you_sure); then GOODSETUP=$(tail -10 $SETUPLOG | grep Failed | awk '{ print $2}') if [[ $GOODSETUP == '0' ]]; then whiptail_setup_complete + check_hive_init_then_reboot else whiptail_setup_failed + shutdown -r now fi fi From c2109ac0372b030d7121d7432883bcb0fed7952f Mon Sep 17 00:00:00 2001 From: Mike Reeves Date: Fri, 27 Sep 2019 11:30:55 -0400 Subject: [PATCH 58/73] Setup Script - Reboot at the end v2 --- so-setup-network.sh | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/so-setup-network.sh b/so-setup-network.sh index 3fd49d362..32995de9f 100644 --- a/so-setup-network.sh +++ b/so-setup-network.sh @@ -1753,7 +1753,11 @@ if (whiptail_you_sure); then GOODSETUP=$(tail -10 $SETUPLOG | grep Failed | awk '{ print $2}') if [[ $GOODSETUP == '0' ]]; then whiptail_setup_complete - check_hive_init_then_reboot + if [[ $THEHIVE == '1' ]]; then + check_hive_init_then_reboot + else + shutdown -r now + fi else whiptail_setup_failed shutdown -r now @@ -1829,8 +1833,10 @@ if (whiptail_you_sure); then GOODSETUP=$(tail -10 $SETUPLOG | grep Failed | awk '{ print $2}') if [[ $GOODSETUP == '0' ]]; then whiptail_setup_complete + shutdown -r now else whiptail_setup_failed + shutdown -r now fi fi @@ -1979,14 +1985,26 @@ if (whiptail_you_sure); then if [ $OS == 'centos' ]; then if [[ $GOODSETUP == '1' ]]; then whiptail_setup_complete + if [[ $THEHIVE == '1' ]]; then + check_hive_init_then_reboot + else + shutdown -r now + fi else whiptail_setup_failed + shutdown -r now fi else if [[ $GOODSETUP == '0' ]]; then whiptail_setup_complete + if [[ $THEHIVE == '1' ]]; then + check_hive_init_then_reboot + else + shutdown -r now + fi else whiptail_setup_failed + shutdown -r now fi fi fi @@ -2065,8 +2083,10 @@ if (whiptail_you_sure); then GOODSETUP=$(tail -10 $SETUPLOG | grep Failed | awk '{ print $2}') if [[ $GOODSETUP == '0' ]]; then whiptail_setup_complete + shutdown -r now else whiptail_setup_failed + shutdown -r now fi #set_initial_firewall_policy From d188fd5f73e26ebe34df80797f66acb3230c193e Mon Sep 17 00:00:00 2001 From: Mike Reeves Date: Fri, 27 Sep 2019 11:59:50 -0400 Subject: [PATCH 59/73] Setup Script - Reboot at the end v3 --- so-setup-network.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/so-setup-network.sh b/so-setup-network.sh index 32995de9f..dea890d28 100644 --- a/so-setup-network.sh +++ b/so-setup-network.sh @@ -1497,7 +1497,6 @@ whiptail_setup_complete() { whiptail --title "Security Onion Setup" --msgbox "Finished installing this as an $INSTALLTYPE. Press Enter to reboot" 8 78 install_cleanup - exit } @@ -1505,7 +1504,6 @@ whiptail_setup_failed() { whiptail --title "Security Onion Setup" --msgbox "Install had a problem. Please see $SETUPLOG for details. Press Enter to reboot" 8 78 install_cleanup - exit } From 38df11826df1f6b12a56c5864bf0bd7fdadae24d Mon Sep 17 00:00:00 2001 From: Mike Reeves Date: Fri, 27 Sep 2019 12:00:17 -0400 Subject: [PATCH 60/73] Setup Script - Reboot at the end v3 --- so-setup-network.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/so-setup-network.sh b/so-setup-network.sh index dea890d28..3d4a1a1db 100644 --- a/so-setup-network.sh +++ b/so-setup-network.sh @@ -1495,14 +1495,14 @@ whiptail_set_hostname() { whiptail_setup_complete() { - whiptail --title "Security Onion Setup" --msgbox "Finished installing this as an $INSTALLTYPE. Press Enter to reboot" 8 78 + whiptail --title "Security Onion Setup" --msgbox "Finished installing this as an $INSTALLTYPE. Press Enter to reboot." 8 78 install_cleanup } whiptail_setup_failed() { - whiptail --title "Security Onion Setup" --msgbox "Install had a problem. Please see $SETUPLOG for details. Press Enter to reboot" 8 78 + whiptail --title "Security Onion Setup" --msgbox "Install had a problem. Please see $SETUPLOG for details. Press Enter to reboot." 8 78 install_cleanup } From 93c73b50ce25175e67336218ac7522796f6ae507 Mon Sep 17 00:00:00 2001 From: Josh Brower Date: Fri, 27 Sep 2019 15:21:02 -0400 Subject: [PATCH 61/73] Playbook - Move db outside of container --- salt/playbook/files/redmine.db | Bin 0 -> 1454080 bytes salt/playbook/init.sls | 19 +++++++++++++++++++ 2 files changed, 19 insertions(+) create mode 100644 salt/playbook/files/redmine.db diff --git a/salt/playbook/files/redmine.db b/salt/playbook/files/redmine.db new file mode 100644 index 0000000000000000000000000000000000000000..fdf24eae4bc011e63b0b5bcf33fb07ca0a5655e2 GIT binary patch literal 1454080 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 Date: Fri, 27 Sep 2019 16:29:32 -0400 Subject: [PATCH 62/73] Kibana - New docker HH1.1.1 --- salt/kibana/init.sls | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/salt/kibana/init.sls b/salt/kibana/init.sls index 7a403fd11..26910b5b0 100644 --- a/salt/kibana/init.sls +++ b/salt/kibana/init.sls @@ -56,14 +56,14 @@ synckibanacustom: so-kibanaimage: cmd.run: - - name: docker pull --disable-content-trust=false soshybridhunter/so-kibana:HH1.1.0 + - name: docker pull --disable-content-trust=false soshybridhunter/so-kibana:HH1.1.1 # Start the kibana docker so-kibana: docker_container.running: - require: - so-kibanaimage - - image: soshybridhunter/so-kibana:HH1.1.0 + - image: soshybridhunter/so-kibana:HH1.1.1 - hostname: kibana - user: kibana - environment: From 67509aad7c485c7f9fd5fa3bb940e4da2022ae92 Mon Sep 17 00:00:00 2001 From: Mike Reeves Date: Mon, 30 Sep 2019 06:56:17 -0400 Subject: [PATCH 63/73] Readme - Add some things I missed --- README.md | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index fbf64b35e..14891602c 100644 --- a/README.md +++ b/README.md @@ -3,18 +3,20 @@ ### Changes: - Alpha 2 is here!! Check out the [Hybrid Hunter Quick Start Guide](https://github.com/Security-Onion-Solutions/securityonion-saltstack/wiki/Hybrid-Hunter-Quick-Start-Guide). -- Suricata 4.1.5 -- Bro/Zeek 2.6.4 -- TheHive 3.4.0 (ES to 6.8.3) -- NIDS and HIDS dashboard updates +- Suricata 4.1.5. +- Bro/Zeek 2.6.4. +- TheHive 3.4.0 (ES to 6.8.3). +- Fixed Bro/Zeek packet loss calculation for Grafana. +- Updated to latest Sensoroni for websockets to enable job status updates without refreshing. +- NIDS and HIDS dashboard updates. - Playbook and ATT&CK Navigator features are now included. - Filebeat now logs to a file, instead of stdout. - Elastalert has been updated to use Python 3 and allow for use of custom alerters. - Elasticsearch Ingest is now used to consume Zeek logs and Suricata alerts (instead of the traditional Logstash pipeline). This reduces the memory footprint of Logstash dramatically! - Several changes to the setup script have been made to improve stability of the setup process: - - Setup now modifies your hosts file so that the install works better in environments without DNS - - You are now prompted for setting a password for the socore user + - Setup now modifies your hosts file so that the install works better in environments without DNS. + - You are now prompted for setting a password for the socore user. - The install now forces a reboot at the end of the install. This fixes an issue with some of the Docker containers being in the wrong state from a manual reboot. Manual reboots are fine after the initial reboot. From feabee0eafa37c39831ffa3199ec185c09108ed8 Mon Sep 17 00:00:00 2001 From: Mike Reeves Date: Mon, 30 Sep 2019 07:06:53 -0400 Subject: [PATCH 64/73] Readme - Add more detail around ES Hive --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 14891602c..f6925bee9 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ - Alpha 2 is here!! Check out the [Hybrid Hunter Quick Start Guide](https://github.com/Security-Onion-Solutions/securityonion-saltstack/wiki/Hybrid-Hunter-Quick-Start-Guide). - Suricata 4.1.5. - Bro/Zeek 2.6.4. -- TheHive 3.4.0 (ES to 6.8.3). +- TheHive 3.4.0 (Includes ES 6.8.3 for TheHive only). - Fixed Bro/Zeek packet loss calculation for Grafana. - Updated to latest Sensoroni for websockets to enable job status updates without refreshing. - NIDS and HIDS dashboard updates. From 244934b12d43cefe4c2a3fe420bd4624378d0cfa Mon Sep 17 00:00:00 2001 From: Mike Reeves Date: Mon, 30 Sep 2019 07:09:31 -0400 Subject: [PATCH 65/73] Readme - Remove prereq section --- README.md | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/README.md b/README.md index f6925bee9..768e09da7 100644 --- a/README.md +++ b/README.md @@ -47,25 +47,6 @@ Distributed: - Minimum 4 CPU cores per VM - Minimum 2 NICs for forward nodes -### Prerequisites - -If you are running CentOS 7 there are a couple of prerequisites: - -``` -sudo yum -y install git bind-utils -sudo hostnamectl set-hostname YOURHOSTNAME -sudo reboot -``` - -If you are running CentOS 7 or Ubuntu 16.04 and don't have name resolution ensure your `/etc/hosts` file looks like this: - -``` -127.0.0.1 YOURHOSTNAME YOURHOSTNAME.localdomain localhost localhost.localdomain localhost4 localhost4.localdomain4 -::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 -``` -It is imperative that YOURHOSTNAME.localdomain is included in this hosts entry for the install to complete properly. - - ### Installation Once you resolve those requirements or are using Ubuntu 16.04 do the following: From 7d62c8ece50d67acf82375e45993d852f6f7520a Mon Sep 17 00:00:00 2001 From: Mike Reeves Date: Mon, 30 Sep 2019 07:14:40 -0400 Subject: [PATCH 66/73] Readme - Add git install --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 768e09da7..2598b96f3 100644 --- a/README.md +++ b/README.md @@ -47,6 +47,12 @@ Distributed: - Minimum 4 CPU cores per VM - Minimum 2 NICs for forward nodes +### Prerequisites + +Install git if using a Centos 7 Minimal install + +```sudo yum -y install git``` + ### Installation Once you resolve those requirements or are using Ubuntu 16.04 do the following: From 5b0a02befdace13fea77237ad4603e6a7920218f Mon Sep 17 00:00:00 2001 From: Mike Reeves Date: Mon, 30 Sep 2019 07:15:32 -0400 Subject: [PATCH 67/73] Readme - Add git install --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2598b96f3..a004692fd 100644 --- a/README.md +++ b/README.md @@ -49,7 +49,7 @@ Distributed: ### Prerequisites -Install git if using a Centos 7 Minimal install +Install git if using a Centos 7 Minimal install: ```sudo yum -y install git``` From d0257243361013a94996bf1b76272f0aba5a0bb0 Mon Sep 17 00:00:00 2001 From: Doug Burks Date: Mon, 30 Sep 2019 07:17:42 -0400 Subject: [PATCH 68/73] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a004692fd..4ea1d3e04 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ ### Changes: -- Alpha 2 is here!! Check out the [Hybrid Hunter Quick Start Guide](https://github.com/Security-Onion-Solutions/securityonion-saltstack/wiki/Hybrid-Hunter-Quick-Start-Guide). +- Alpha 2 is here! - Suricata 4.1.5. - Bro/Zeek 2.6.4. - TheHive 3.4.0 (Includes ES 6.8.3 for TheHive only). From a2e07a7638fa0594450f21959d1d5bd0eb7ef658 Mon Sep 17 00:00:00 2001 From: Doug Burks Date: Mon, 30 Sep 2019 07:21:12 -0400 Subject: [PATCH 69/73] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4ea1d3e04..98413e8ea 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ - Bro/Zeek 2.6.4. - TheHive 3.4.0 (Includes ES 6.8.3 for TheHive only). - Fixed Bro/Zeek packet loss calculation for Grafana. -- Updated to latest Sensoroni for websockets to enable job status updates without refreshing. +- Updated to latest Sensoroni which includes websockets support for job status updates without having to refresh the page. - NIDS and HIDS dashboard updates. - Playbook and ATT&CK Navigator features are now included. - Filebeat now logs to a file, instead of stdout. From d10666ad976ac7e3cf19a0f0bfaf7b7db0256a8d Mon Sep 17 00:00:00 2001 From: Doug Burks Date: Mon, 30 Sep 2019 07:39:47 -0400 Subject: [PATCH 70/73] Update so-setup-network.sh --- so-setup-network.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/so-setup-network.sh b/so-setup-network.sh index 3d4a1a1db..cd043375f 100644 --- a/so-setup-network.sh +++ b/so-setup-network.sh @@ -1145,8 +1145,7 @@ whiptail_check_exitstatus() { whiptail_create_socore_user() { - whiptail --title "Security Onion Setup" --msgbox "Set a password for the socore user. This account is used \ - for adding sensors remotely." 8 78 + whiptail --title "Security Onion Setup" --msgbox "Set a password for the socore user. This account is used for adding sensors remotely." 8 78 } From 176677add41004171372fd0dffa7a99502a10dba Mon Sep 17 00:00:00 2001 From: Mike Reeves Date: Mon, 30 Sep 2019 13:57:07 -0400 Subject: [PATCH 71/73] Common Module - Upgrade core version --- salt/common/init.sls | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/salt/common/init.sls b/salt/common/init.sls index b61a0b7e9..f4a78a995 100644 --- a/salt/common/init.sls +++ b/salt/common/init.sls @@ -116,13 +116,13 @@ nginxtmp: # Start the core docker so-coreimage: cmd.run: - - name: docker pull --disable-content-trust=false soshybridhunter/so-core:HH1.1.0 + - name: docker pull --disable-content-trust=false soshybridhunter/so-core:HH1.1.1 so-core: docker_container.running: - require: - so-coreimage - - image: soshybridhunter/so-core:HH1.1.0 + - image: soshybridhunter/so-core:HH1.1.1 - hostname: so-core - user: socore - binds: From 308041fad61cb88bee8b286ccb8ca1f031a1b3b5 Mon Sep 17 00:00:00 2001 From: Josh Brower Date: Tue, 1 Oct 2019 17:59:35 -0400 Subject: [PATCH 72/73] SOCtopus - Edit osquery playbook template Fixes bug for when there is no [osquery][columns][address] field --- salt/soctopus/files/templates/osquery.template | 1 - 1 file changed, 1 deletion(-) diff --git a/salt/soctopus/files/templates/osquery.template b/salt/soctopus/files/templates/osquery.template index 23b3ad1af..1e85a3182 100644 --- a/salt/soctopus/files/templates/osquery.template +++ b/salt/soctopus/files/templates/osquery.template @@ -45,4 +45,3 @@ hive_observable_data_mapping: - ip: '{match[osquery][EndpointIP2]}' - other: '{match[osquery][hostIdentifier]}' - other: '{match[osquery][hostname]}' - - ip: '{match[osquery][columns][address]}' From 16ff276bf1629c0af1dd8b469334eaa0ed5053c4 Mon Sep 17 00:00:00 2001 From: Doug Burks Date: Thu, 3 Oct 2019 09:05:45 -0400 Subject: [PATCH 73/73] Update README.md --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 98413e8ea..a347d19ef 100644 --- a/README.md +++ b/README.md @@ -12,8 +12,7 @@ - Playbook and ATT&CK Navigator features are now included. - Filebeat now logs to a file, instead of stdout. - Elastalert has been updated to use Python 3 and allow for use of custom alerters. -- Elasticsearch Ingest is now used to consume Zeek logs and Suricata alerts (instead of the traditional Logstash pipeline). - This reduces the memory footprint of Logstash dramatically! +- Moved Bro/Zeek log parsing from Logstash to Elasticsearch Ingest for higher performance and lower memory usage! - Several changes to the setup script have been made to improve stability of the setup process: - Setup now modifies your hosts file so that the install works better in environments without DNS. - You are now prompted for setting a password for the socore user.