# Security Check script. # Email should be already set up in Tools>Email # Please put the email address to send the report to here: :local addressto "the.email.address@some.domain" # Report version 4, 12 April 2022 (and please copy your version number into the next line) :local reportVersion "4" # Please enter the name of this script from System>Scripts :local scriptName "security-check" # This script checks for the following suspicious changes # the first three might indicate the router has been recruited into a botnet # Change in the number of scripts in System>Scheduler # Change in the number of scheduled items in System>Scripts # Activation of a proxy in IP>Proxy # Critical-level log entries # If any of these has occured an email is sent along with a log extract. # It should be called, say, every 12 hours # Begun 16 September 2021, Denis de Castro, Biomedical Consulting, BMCP@pm.me # declare variables :delay 1 :local reportBody "" :local deviceName [/system identity get name] :local hwModel [/system routerboard get model] :local date [/system clock get date]; :local day [ :pick $date 4 6 ]; :local month [ :pick $date 0 3 ]; :local year [ :pick $date 7 11 ]; :local deviceTime [/system clock get time]; :local timezone [/system clock get time-zone-name];:local upTime ([/system resource get uptime]); :local runcount [/system script get [/system script find name=$scriptName] run-count]; :local sendAlert "no"; :local newScheds; :local newScripts; :local newSocks; :local newCrits; :global securityCheckCount; :global securityAlertCount; # prepare report :set $reportBody ($reportBody."Security Alert for $deviceName (a Mikrotik $hwModel)\n") :set $reportBody ($reportBody."Sent on $day $month $year at $deviceTime $timezone time\n") :set $reportBody ($reportBody."This check is carried out twelve-hourly\n\n") :set $reportBody ($reportBody."Uptime (days:hours:minutes): $upTime\n") # check for new System>Scheduler entries :global countScheduled; :if ([:len $countScheduled] = 0) do={:set $countScheduled 0} :local newCountScheduled [:len [/system scheduler find]]; :if ($newCountScheduled > $countScheduled) do={ :set sendAlert "yes"; :set $reportBody ($reportBody . "\nAttention. The number of items in System Schedules has increased since the last check.\n" ) :set $newScheds "--Item added to schedules"; } else={ :set $reportBody ($reportBody . "\nNo new scheduled items were found.\n" ) } :set $countScheduled $newCountScheduled # check for new System>Scripts entries :global countScripts; :if ([:len $countScripts] = 0) do={:set $countScripts 0} :local newcountScripts [:len [/system script find]]; :if ($newcountScripts > $countScripts) do={ :set sendAlert "yes"; :set $reportBody ($reportBody . "\nAttention. The number of items in System Scripts has increased since the last check.\n") :set $reportBody ($reportBody . "The following scripts are listed.\n") :foreach scriptId in=[/system script find] do={ :local scriptSource [/system script get $scriptId source]; :local scriptSourceLength [:len $scriptSource]; :set $scriptSourceLength [:tostr "$scriptSourceLength"]; :local scriptName [/system script get $scriptId name]; :set $reportBody ($reportBody . "'$scriptName' ($scriptSourceLength bytes)\n"); } :set $newScripts "--Item added to scripts"; } else={ :set $reportBody ($reportBody . "\nNo new scripts were found.\n" ) } :set $countScripts $newcountScripts # check for enabled SOCKS proxy at IP>Socks :local activeSocks [/ip socks get enabled] :if ($activeSocks = enabled) do={ :set sendAlert "yes"; :set $reportBody ($reportBody . "\nAttention. A SOCKS proxy is enabled.\n"); :set $newSocks "--Socks proxy active"; } else={ :set $reportBody ($reportBody . "\nNo active SOCKS proxy found.\n" ) } # check for critical-level log entries :local countcriticals [:len [/log find where topics~"critical"]] if ( $countcriticals > 0) do={ :set $newCrits "--New critical log entry"; :set sendAlert "yes" :set $reportBody ($reportBody . "\nAttention. There are critical-level log entries:\n" ) :local x :local ts :local msg foreach i in=([/log find where topics~"critical"]) do={ :set $ts [/log get $i time] :set $msg [/log get $i message] :set reportBody ($reportBody . $ts . " " . $msg . "\n" ) } } else={ :set $reportBody ($reportBody . "\nThere are no recent critical-level log entries.\n" ) } # if flag is set, send a Security Alert now :if ($sendAlert = "yes") do={ :local emailSubj ($deviceName: . "Security Alert" . $newScheds . $newScripts . $newSocks . $newCrits); /tool e-mail send subject=$emailSubj to=$addressto body=$reportBody :delay 2; :log info "***Security alert number $runcount sent$newScheds$newScripts$newSocks$newCrits***" :set securityAlertCount ($securityAlertCount + 1); } else={ :log info "***Security checked. No message sent***" } # send a Summary at intervals # when this script is run 12-hourly this will be approximately monthly :local daysToSummary (60 - $securityCheckCount); :set $reportBody ($reportBody . "\nA monthly summary will be sent in about $daysToSummary days' time.\n" ) # at month end send summary :if ($daysToSummary <= 1) do={ :local summaryBody "$deviceName a Mikrotik $hwModel performs a security check every twelve hours\n \ looking for indicators of intrusion such as new Scheduler or Scripts entries or a SOCKS proxy.\n \ $securityAlertCount Security Alerts have been sent to this address in the last month." /tool e-mail send subject="$deviceName monthly security report summary" to=$addressto body=$summaryBody; :delay 1; :set $securityAlertCount 0; :set $securityCheckCount 0; } # increment count :set securityCheckCount ($securityCheckCount + 1);