Providers/Modules/Plugins/Antimalware/plugin/collectsophosinfo.rb (239 lines of code) (raw):

require "rexml/document" require "cgi" require 'digest' require 'json' require 'date' require 'time' require 'logger' require_relative 'antimalwarecommon' class Sophos def self.detect() begin sophosPath = "/opt/sophos-av/bin/savdstatus" if !File.file?('/opt/sophos-av/bin/savdstatus') findSophosCmd = `readlink $(which savscan)`.lines.map(&:chomp) if !$?.success? || findSophosCmd.nil? || findSophosCmd.empty? return false else savscanPath = findSophosCmd[0].strip sophosPathArray = savscanPath.split("/") sophosPathArray[sophosPathArray.length-1] = "savdstatus" sophosPath = sophosPathArray.join('/') if !File.file?(sophosPath) return false end end end detectioncmd = `#{sophosPath} --version 2>&1`.lines.map(&:chomp) if !$?.success? || detectioncmd.nil? || detectioncmd.empty? return false else sophosInfo = detectioncmd[1].split(" = ") sophosName = sophosInfo[0].strip sophosVersion = sophosInfo[1].strip if sophosName != "Sophos Anti-Virus" #puts "Sophos Name is not Sophos Anti-Virus" return false elsif sophosVersion.split(".")[0].to_i < 9 #puts "Sophos version is less than 9, please install latest Sophos" return false end end #puts "Sophos is detected on the machine at path " + sophosPath return true rescue => e #puts "Getting exception when checking sophos is installed or not: " + e.message return false end end def self.getprotectionstatus() ret = {} sophosName = "Sophos Anti-Virus" sophosVersion = "NA" lastUpdate = "NA" lastUpdateTime = "NA" buildRevision = "NA" threatDetectionEngine = "NA" threatData = "NA" threatCount = "NA" threatDataRelease = "NA" ondemandscan = "NA" scheduledscan = "NA" rmsstatus = "NA" onaccessscan = "NA" liveprotection = "NA" scanDate = "" protectionStatusDetails = "" protectionStatusAlertArray = [] protectionStatusDetailsArray = [] error = "" ($ProtectionStatusRank, $ProtectionStatus) = AntimalwareCommon::UnknownProtectionCode ($ThreatStatusRank, $ThreatStatus) = AntimalwareCommon::UnknownThreatCode begin sophosPath = "/opt/sophos-av/bin/savdstatus" #if !File.file?('/opt/sophos-av/bin/savdstatus') #findSophosCmd = `find / -iname savdstatus | grep /bin/savdstatus 2>&1`.lines.map(&:chomp) #if !$?.success? || findSophosCmd.nil? || findSophosCmd.empty? #error += "Getting issue when trying to find custmized sophos path, Sophos not detected; " #else #sophosPath = findSophosCmd[0] #end #end if !File.file?('/opt/sophos-av/bin/savdstatus') findSophosCmd = `readlink $(which savscan)`.lines.map(&:chomp) if !$?.success? || findSophosCmd.nil? || findSophosCmd.empty? error += "Getting issue when trying to find custmized sophos path, Sophos not detected; " else savscanPath = findSophosCmd[0].strip sophosPathArray = savscanPath.split("/") sophosPathArray[sophosPathArray.length-1] = "savdstatus" sophosPath = sophosPathArray.join('/') end end detectioncmd = `LANG=en_US.UTF-8 #{sophosPath} --version 2>&1`.lines.map(&:chomp) if !$?.success? || detectioncmd.nil? || detectioncmd.empty? error += "Getting issue when running sophos version cmd; " else sophosInfo = detectioncmd[1].split(" = ") sophosVersion = sophosInfo[1].strip buildRevision = detectioncmd[2].split(" = ")[1].strip threatDetectionEngine = detectioncmd[3].split(" = ")[1].strip threatData = detectioncmd[4].split(" = ")[1].strip threatCount = detectioncmd[5].split(" = ")[1].strip threatDataRelease = detectioncmd[6].split(" = ")[1].split("UTC")[0].strip lastUpdate = detectioncmd[7].split(" = ")[1].split("UTC")[0].strip #250 #signature date #threat release date lastUpdate = Time.strptime(lastUpdate, '%a %d %b %Y %I:%M:%S %p') threatDataRelease = Time.strptime(threatDataRelease, '%a %d %b %Y %I:%M:%S %p') protectionStatusDetailsArray.push("buildRevision: " + buildRevision) protectionStatusDetailsArray.push("threatData: " + threatData) protectionStatusDetailsArray.push("threatCount: " + threatCount) #puts "threatDataRelease " + threatDataRelease.to_s if (!threatDataRelease.nil? && threatDataRelease != "NA") #if (threatDataRelease < (Time.now - 30*24*3600).utc) #($ProtectionStatusRank, $ProtectionStatus) = AntimalwareCommon::SignaturesOutOfDateProtectionCode #protectionStatusAlertArray.push("Threat Data Release Update out of 30 days: " + threatDataRelease.to_s) #else protectionStatusDetailsArray.push("Threat Data Release Update: " + threatDataRelease.to_s) #end else error += "threat Data Release not found; " ($ProtectionStatusRank, $ProtectionStatus) = AntimalwareCommon::SignaturesOutOfDateProtectionCode protectionStatusAlertArray.push("Threat Data Release not found: " + threatDataRelease) end #puts "lastUpdate " + lastUpdate.to_s if (!lastUpdate.nil? && lastUpdate != "NA") if (lastUpdate < (Time.now - 7*24*3600).utc) ($ProtectionStatusRank, $ProtectionStatus) = AntimalwareCommon::SignaturesOutOfDateProtectionCode protectionStatusAlertArray.push("Last Update out of 7 days: " + lastUpdate.to_s) else protectionStatusDetailsArray.push("Last Update within 7 days: " + lastUpdate.to_s) end else error += "Last Update not found, running lastupdate cmd; " lutcmd = `LANG=en_US.UTF-8 #{sophosPath} --lastupdate 2>&1`.lines.map(&:chomp) if !$?.success? || lutcmd.nil? || lutcmd.empty? error += "Fail to run last update time cmd; " ($ProtectionStatusRank, $ProtectionStatus) = AntimalwareCommon::SignaturesOutOfDateProtectionCode protectionStatusAlertArray.push("Last Update not when running last update cmd: " + lastUpdateTime) else lastUpdateTime = lutcmd[0].split("UTC")[0].strip if(lastUpdateTime == "NA") or (lastUpdateTime.include? "Never updated") ($ProtectionStatusRank, $ProtectionStatus) = AntimalwareCommon::SignaturesOutOfDateProtectionCode protectionStatusAlertArray.push("Last Update not found: " + lastUpdateTime) else lastUpdateTime = Time.strptime(lastUpdateTime, '%a %d %b %Y %I:%M:%S %p') if (lastUpdateTime < (Time.now - 7*24*3600).utc) ($ProtectionStatusRank, $ProtectionStatus) = AntimalwareCommon::SignaturesOutOfDateProtectionCode protectionStatusAlertArray.push("Last Update out of 7 days: " + lastUpdateTime.to_s) else protectionStatusDetailsArray.push("Last Update within 7 days: " + lastUpdateTime.to_s) end end end end end ############################# #270 #on access scan #live protection ################################################# oascmd = `#{sophosPath} -v 2>&1`.lines.map(&:chomp) if !$?.success? || oascmd.nil? || oascmd.empty? error += "Fail to run On Access Scan cmd; " else onaccessscan = oascmd[0].strip + "; " + oascmd[1].strip if(onaccessscan == "NA") or (onaccessscan.include? "On-access scanning is not running") ($ProtectionStatusRank, $ProtectionStatus) = AntimalwareCommon::NoRealTimeProtectionProtectionCode protectionStatusAlertArray.push("On Access Scan is not running: " + onaccessscan) else protectionStatusDetailsArray.push(onaccessscan) end end ########################### sophosconfigpathArray = sophosPath.split("/") sophosconfigpathArray[sophosconfigpathArray.length-1] = "savconfig" sophosconfigpath = sophosconfigpathArray.join('/') lpcmd = `#{sophosconfigpath} get LiveProtection 2>&1`.lines.map(&:chomp) if !$?.success? || lpcmd.nil? || lpcmd.empty? error += "live protection cmd failed; " else liveProtection = lpcmd[0].strip if(liveProtection == "NA") or (liveProtection != "enabled") ($ProtectionStatusRank, $ProtectionStatus) = AntimalwareCommon::NoRealTimeProtectionProtectionCode protectionStatusAlertArray.push("liveProtection is not enabled: " + liveProtection) else protectionStatusDetailsArray.push("Live Protection is enabled") end end #350 #find scan date #rms not connected ############################# rmscmd = `#{sophosPath} --rms 2>&1`.lines.map(&:chomp) status = $? if rmscmd.nil? || rmscmd.empty? error += "Fail to run Remote Management status cmd; " else rmsstatus = rmscmd[0].strip if(rmsstatus == "NA") or (rmsstatus.include? "inactive") #($ProtectionStatusRank, $ProtectionStatus) = AntimalwareCommon::ActionRequiredProtectionCode protectionStatusDetailsArray.push("Remote Management status is not active: " + rmsstatus) else protectionStatusDetailsArray.push(rmsstatus) end end ############################# sophoslogArray = sophosPath.split("/") sophoslogArray[sophoslogArray.length-1] = "savlog" sophoslogpath = sophoslogArray.join('/') scancmd = `LANG=en_US.UTF-8 #{sophoslogpath} --maxage=7 | grep "scan finished" | tail -1 2>&1`.lines.map(&:chomp) if !$?.success? || scancmd.nil? || scancmd.empty? error += "On demand scan cmd failed; " else ondemandscan = scancmd[0].split("UTC: savscan.log")[0].strip if(ondemandscan == "NA" || ondemandscan.nil? || ondemandscan.empty? ) #puts "On demand scanDate within 7 days not found" else ondemandscan = Time.strptime(ondemandscan, '%a %d %b %Y %I:%M:%S %p') end end #puts ondemandscan.to_s ######################################### scheduleScancmd = `LANG=en_US.UTF-8 #{sophoslogpath} --maxage=7 | grep -i "Scheduled scan .* completed" | tail -1`.lines.map(&:chomp) if !$?.success? || scheduleScancmd.nil? || scheduleScancmd.empty? error += "Scheduled scan cmd failed; " else scheduledscan = scheduleScancmd[0].split("UTC: scheduled.scan.log")[0].strip if(scheduledscan == "NA" || scheduledscan.nil? || scheduledscan.empty? ) #puts "scheduled scanDate within 7 days not found" else scheduledscan = Time.strptime(scheduledscan, '%a %d %b %Y %I:%M:%S %p ') end end #puts scheduledscan.to_s ############################# if (scheduledscan == "NA" && ondemandscan == "NA") ($ProtectionStatusRank, $ProtectionStatus) = AntimalwareCommon::ActionRequiredProtectionCode protectionStatusAlertArray.push("No On demand Scan or scheduled Scan found in past 7 days, please run an active scan") else if(ondemandscan != "NA") scanDate = ondemandscan protectionStatusDetailsArray.push("On Demand Scan Date: " + ondemandscan.to_s) end if(scheduledscan != "NA") scanDate = scheduledscan protectionStatusDetailsArray.push("Scheduled Scan Date: " + scheduledscan.to_s) end end if protectionStatusAlertArray.length == 0 ($ProtectionStatusRank, $ProtectionStatus) = AntimalwareCommon::RealTimeProtectionCode protectionStatusDetails += "Sophos is running healthy. " protectionStatusDetails += protectionStatusDetailsArray.join('; ') else protectionStatusDetails += protectionStatusDetailsArray.join('; ') protectionStatusDetails += "; " protectionStatusDetails += protectionStatusAlertArray.join('; ') end rescue => e error += "Getting exception when trying to find Sophos health info: " + e.message + " " + e.backtrace.inspect ret["Error"] = error end ret["ProtectionStatusRank"] = $ProtectionStatusRank ret["ProtectionStatus"] = $ProtectionStatus ret["ProtectionStatusDetails"] = protectionStatusDetails ret["DetectionId"] = SecureRandom.uuid ret["Threat"] = "" ret["ThreatStatusRank"] = $ThreatStatusRank ret["ThreatStatus"] = $ThreatStatus ret["ThreatStatusDetails"] = "Threat Status is currently not supported in Linux Sophos" ret["Signature"] = (threatDetectionEngine.nil? || threatDetectionEngine.empty? || threatDetectionEngine == "NA")? "Signature version not found" : threatDetectionEngine ret["ScanDate"] = scanDate ret["DateCollected"] = DateTime.now.strftime("%m/%d/%Y %H:%M") ret["Tool"] = sophosName ret["AMProductVersion"] = (sophosVersion.nil? || sophosVersion.empty? || sophosVersion == "NA")? "Sophos version not found" : sophosVersion return ret end end