diff --git a/agents/custom/linux_all_spring4shell/lib/bin/README b/agents/custom/linux_all_spring4shell/lib/bin/README new file mode 100755 index 0000000000000000000000000000000000000000..d8f8091a0420d1cf6ea4b678afdda61a7810ad15 --- /dev/null +++ b/agents/custom/linux_all_spring4shell/lib/bin/README @@ -0,0 +1,3 @@ +https://github.com/hillu/local-spring-vuln-scanner + + diff --git a/agents/custom/linux_all_spring4shell/lib/local/86400/local_spring-vuln-scanner.sh b/agents/custom/linux_all_spring4shell/lib/local/86400/local_spring-vuln-scanner.sh new file mode 100755 index 0000000000000000000000000000000000000000..7f46fce9b094af8186e4b0b9736a1222b73a84f6 --- /dev/null +++ b/agents/custom/linux_all_spring4shell/lib/local/86400/local_spring-vuln-scanner.sh @@ -0,0 +1,120 @@ +#!/bin/bash + +# Check local-spring-vuln-scanner +# checkmk Local Check +# Christian Wirtz, 2022-04 <doc@snowheaven.de> +# +# https://github.com/hillu/local-spring-vuln-scanner + +START_DATE=$(date +%s) + +DEST="/" # scan under this path +WAITTIME="10800" # max scan runtime (default: 3h = 10800sec) + +EXCLUDE_PATHS="--exclude /mnt" +LOGFILE="/tmp/local-spring-vuln-scanner" +ARGS="--quiet --log $LOGFILE $EXCLUDE_PATHS" +SERVICENAME="CVE-Spring4Shell" +PWD="/usr/lib/check_mk_agent" + +# search pattern +PATTERN_VULNERABLE="^indicator for vulnerable component found in " +PATTERN_DENY=": permission denied$" +PATTERN_CVES="^Checking for vulnerabilities: " +PATTERN_REPLACE="indicator for vulnerable component found in " + +WAITMAX=$(which waitmax) + +COMMAND="$WAITMAX $WAITTIME $PWD/bin/local-spring-vuln-scanner $ARGS $DEST" + +MSG="Scanned path: $DEST" + +# Check if a scan is already running +PROCESSES=$(pgrep -lfc local-spring-vuln-scanner) + +# Output if another scan is running +if [[ $PROCESSES -gt 1 ]] +then + PROCESSES=$(($PROCESSES - 1)) + echo "3 $SERVICENAME processes=$PROCESSES; Another scan is already running, number of processes: $PROCESSES" + exit 3 +fi + +eval "$COMMAND" +EXITCODE=$? + +CVES=$(grep -E "$PATTERN_CVES" $LOGFILE) +# cut "Checking for vulnerabilities: " from "Checking for vulnerabilities: CVE-2022-22965" +CVES=$(echo "$CVES" | awk -F':' '{print $2}') +# trim spaces at the beginning of string +CVES=${CVES##*( )} + +MSG="Checked for: $CVES, $MSG" + +DENIED=$(grep -c "$PATTERN_DENY" $LOGFILE) +VULNERABLE=$(grep -cE "$PATTERN_VULNERABLE" $LOGFILE) + +END_DATE=$(date +%s) +RUN_TIME=$(("$END_DATE" - "$START_DATE")) + +# Perfdata +PERFDATA="files_vulnerable=$VULNERABLE;1;1|files_not_permitted=$DENIED;1|run_time=$RUN_TIME;" + +# Output if errors while scanning +if [[ $EXITCODE -gt 0 ]] +then + echo "2 $SERVICENAME - Error on scanner run: $EXITCODE" + exit 2 +fi + +# Output if suspicious files found +if [[ $VULNERABLE -eq 0 ]] +then + MSG="$MSG, No vulnerabilities found" +else + # get files with indicator + FILES_VULNERABLE=$(sed -n -e "/$PATTERN_VULNERABLE/p" $LOGFILE | sed "s/$PATTERN_REPLACE//g" | sed ':a;N;$!ba;s/\n/\\n/g') + FILES_VULNERABLE="\nIndicator for vulnerable component found in:\n$FILES_VULNERABLE" + MSG="$MSG, Found indicators for vulnerable components" +fi + +if [[ DENIED -gt 0 ]] +then + # get denied files + FILES_DENIED=$(sed -n -e "/$PATTERN_DENY/p" $LOGFILE | sed ':a;N;$!ba;s/\n/\\n/g') + FILES_DENIED="\Unscanned files:\n$FILES_DENIED" +fi + +LONGOUTPUT="$FILES_VULNERABLE\n$FILES_DENIED" + +# Default output +echo "P $SERVICENAME $PERFDATA $MSG $LONGOUTPUT" + +# cleanup +unset ARGS +unset COMMAND +unset CVES +unset DENIED +unset DEST +unset END_DATE +unset EXITCODE +unset FILES_DENIED +unset FILES_VULNERABLE +unset LOGFILE +unset LONGOUTPUT +unset MSG +unset PATTERN_CVES +unset PATTERN_DENY +unset PATTERN_REPLACE +unset PATTERN_VULNERABLE +unset PERFDATA +unset PROCESSES +unset PWD +unset RUN_TIME +unset SERVICENAME +unset START_DATE +unset VULNERABLE +unset WAITMAX +unset WAITTIME + +exit 0 diff --git a/agents/custom/win_spring4shell/lib/local/local_spring-vuln-scanner.ps1 b/agents/custom/win_spring4shell/lib/local/local_spring-vuln-scanner.ps1 new file mode 100755 index 0000000000000000000000000000000000000000..07957b542f7d230aa5292a94d45e3e04c53f3668 --- /dev/null +++ b/agents/custom/win_spring4shell/lib/local/local_spring-vuln-scanner.ps1 @@ -0,0 +1,92 @@ +<# +.Synopsis + Checks for CVE-2022-22965 wrapper for checkmk for a scan tool to check all drives and parse the output +.DESCRIPTION + Author: Christopher Stegmann + Date: 2022-04 +#> + +$START_TIME = Get-Date + +$ErrorActionPreference = "SilentlyContinue" +$SVC_NAME = "CVE-Spring4Shell" + +# pattern to search in output +$PATTERN_VULNERABLE="^indicator for vulnerable component found in " +$PATTERN_DENY=": Access is denied\.$" +$PATTERN_CVES="^Checking for vulnerabilities: " +$PATTERN_REPLACE="indicator for vulnerable component found in " + +# get list of drives to check without empty drives (like CDROM), returns i.e. "C:\ D:\" +$DRIVES_TO_CHECK = (Get-PSDrive -PSProvider "FileSystem" | Where-Object used -gt 0 | Select -ExpandProperty root) -join " " + +$MSG = "Scanned drive(s): $($DRIVES_TO_CHECK)" + +$EXECUTABLE = "c:\ProgramData\checkmk\agent\bin\local-spring-vuln-scanner.exe" +$EXCLUDE_PATHS = "" +$LOGFILE = "$env:TEMP\spring4shell.log" +$ARGS = "--quiet --log $($LOGFILE) $($EXCLUDE_PATHS)" + +$RUN = "$EXECUTABLE $ARGS $DRIVES_TO_CHECK" + +if (Test-Path -Path $LOGFILE -PathType Leaf) { + Remove-Item -Path $LOGFILE +} + +if ( -not (Test-Path -Path $EXECUTABLE -PathType Leaf)) { + # warn scanner not found + Write-Output "1 $($SVC_NAME) - Error: $($EXECUTABLE) not found" + return +} + +# run the scanner tool +try{ + & cmd /c $RUN +} +catch { + $ERRORINFO = $_ + # warn error on scanning + Write-output "1 $($SVC_NAME) - Error on scanner run: $($ERRORINFO)" + return +} + + if (Test-Path -Path "$LOGFILE" -PathType Leaf) { + # search for vulnerabilites and remove log file name from output: + $FILES_VULNERABLE = Select-String -Path $LOGFILE -CaseSensitive -Pattern $PATTERN_VULNERABLE | Select -ExpandProperty Line + $VULNERABLE = $FILES_VULNERABLE.Length + if ( $VULNERABLE -gt 0 ) { + $FILES_VULNERABLE=($FILES_VULNERABLE -join "\n") -replace $PATTERN_REPLACE, "" + $FILES_VULNERABLE = "\nIndicator for vulnerable component found in:\n$FILES_VULNERABLE" + $MSG = "$MSG, Found indicators for vulnerable components" + } else { + $MSG = "$MSG, No vulnerabilities found" + } + + # get number/list of denied files + $FILES_DENIED= (Select-String -Path $LOGFILE -CaseSensitive -Pattern $PATTERN_DENY) + $DENIED = $FILES_DENIED.Length + if ( $DENIED -gt 0 ) { + $FILES_DENIED=($FILES_DENIED -join "\n") + $FILES_DENIED = "\nUnscanned files:\n$FILES_DENIED" + } + + # search for CVEs checked for: + $CVES = (Select-String -Path $LOGFILE -CaseSensitive -Pattern $PATTERN_CVES | Select -ExpandProperty Line).split(":")[1].trim() + } else { + Write-output "1 $($SVC_NAME) Logfile $($LOGFILE) not found" + return + } + +if (Test-Path -Path $LOGFILE -PathType Leaf) { + Remove-Item -Path $LOGFILE +} + +$MSG = "Checked for: $CVES, $MSG" +$LONGOUTPUT="$FILES_VULNERABLE\n$FILES_DENIED" + +$END_TIME = Get-Date +$RUN_TIME = (New-TimeSpan -Start $START_TIME -End $END_TIME).TotalSeconds +$PERFDATA="files_vulnerable=$VULNERABLE;1;1|files_not_permitted=$DENIED;1|run_time=$RUN_TIME;" +write-output "P $($SVC_NAME) $PERFDATA $MSG\n$LONGOUTPUT\n" + +exit 0 diff --git a/packages/spring4shell b/packages/spring4shell new file mode 100644 index 0000000000000000000000000000000000000000..545c15cf1a8da0d06cdd1cdac73df642a7eb599a --- /dev/null +++ b/packages/spring4shell @@ -0,0 +1,39 @@ +{'author': 'Christian Wirtz, doc[at]snowheaven[dot]de & Christopher Stegmann & ' + 'thl-cmk[at]outlook[dot]com', + 'description': 'Wrapper around spring-vuln-scanner\n' + 'from Hilko Bengen <bengen@hilluzination.de>\n' + '\n' + 'https://github.com/hillu/local-spring-vuln-scanner\n' + '\n' + 'Scan interval:\n' + 'Linux:daily (86400sec)\n' + 'Windows; Rule needed: Set cache age for plugins and local ' + 'checks: 86400\n' + '\n' + 'ToDo\n' + '- nicer output requested ' + '(https://github.com/hillu/local-spring-vuln-scanner/issues/2)\n' + '- async config not so nice\n' + '\n' + 'Changelog\n' + '2022-04-06 Wrt same perfdata-labels for Linux and Windows\n' + '2022-04-06 Wrt,thl-cmk nicer code from thl-cmk; some things ' + 'from Christian\n' + '2022-04-05 Wrt,thl-cmk Windows, added Run-time perfdata\n' + '2022-04-05 Wrt Windows ok, with the help of thl-cmk\n' + '2022-04-05 Wrt Linux check finalized\n' + '2022-04-05 Wrt running Windows baseversion together with ' + 'Christopher\n' + '2022-04-05 Wrt running Linux baseversion\n', + 'download_url': '', + 'files': {'agents': ['custom/linux_all_spring4shell/lib/bin/README', + 'custom/linux_all_spring4shell/lib/local/86400/local_spring-vuln-scanner.sh', + 'custom/win_spring4shell/lib/local/local_spring-vuln-scanner.ps1'], + 'web': ['plugins/metrics/spring4shell.py']}, + 'name': 'spring4shell', + 'num_files': 4, + 'title': 'Spring4Shell check plugin', + 'version': '0.95', + 'version.min_required': '2.0.0', + 'version.packaged': '2021.09.20', + 'version.usable_until': None} \ No newline at end of file diff --git a/spring4shell.mkp b/spring4shell.mkp new file mode 100644 index 0000000000000000000000000000000000000000..3f002ac6ed74a8d2151978bfff7d13243f98a6c9 Binary files /dev/null and b/spring4shell.mkp differ diff --git a/web/plugins/metrics/spring4shell.py b/web/plugins/metrics/spring4shell.py new file mode 100644 index 0000000000000000000000000000000000000000..fb8fd6e793f61ae50dc976e3cf9cf3be9ea6613a --- /dev/null +++ b/web/plugins/metrics/spring4shell.py @@ -0,0 +1,53 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# +# License: GNU General Public License v2 +# +# Author: thl-cmk[at]outlook[dot]com +# URL : https://thl-cmk.hopto.org +# Date : 2022-04-08 +# +# Metrics file for the spring4shell plugin +# +from cmk.gui.i18n import _ + +from cmk.gui.plugins.metrics import ( + metric_info, + graph_info, + perfometer_info, + check_metrics, +) + +metric_info['files_vulnerable'] = { + 'title': _('Vulnerable'), + 'unit': 'count', + 'color': '11/a', +} +metric_info['files_not_permitted'] = { + 'title': _('Files denied'), + 'unit': 'count', + 'color': '21/a', +} +metric_info['run_time'] = { + 'title': _('Run time'), + 'unit': 's', + 'color': '33/b', +} + +perfometer_info.append(('stacked', [ + { + 'type': 'linear', + 'segments': [ + 'files_vulnerable', + 'files_not_permitted', + ], + 'total': 100, + }, + { + 'type': 'linear', + 'segments': [ + 'run_time', + ], + 'total': 7200, + }, +]))