From ec22eb4586fb4a1508506b6050be588e7b514ee4 Mon Sep 17 00:00:00 2001 From: Logan Sampson Date: Tue, 3 Jul 2018 13:27:59 -0500 Subject: [PATCH 1/2] Fix allows symantec to run correctly. Also fixes allowing the finding of folders rather than just a single file with locate_one(). --- probe/modules/antivirus/base.py | 2 +- probe/modules/antivirus/interface.py | 1 + probe/modules/antivirus/symantec_win/symantec_win.py | 3 ++- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/probe/modules/antivirus/base.py b/probe/modules/antivirus/base.py index 12e9bb37..db92586f 100644 --- a/probe/modules/antivirus/base.py +++ b/probe/modules/antivirus/base.py @@ -236,7 +236,7 @@ def _locate(cls, pattern, paths, syspath): elif not paths: paths = [Path('/')] - return (f for path in paths for f in path.glob(pattern) if f.is_file()) + return (f for path in paths for f in path.glob(pattern) if (f.is_file()) or (f.is_file())) def identify_threat(self, filename, out): for pattern in self.scan_patterns: diff --git a/probe/modules/antivirus/interface.py b/probe/modules/antivirus/interface.py index 9d4997d8..8b30a696 100644 --- a/probe/modules/antivirus/interface.py +++ b/probe/modules/antivirus/interface.py @@ -46,6 +46,7 @@ def run(self, paths): results.database = {str(fp): self.file_metadata(fp) for fp in self.module.database} # launch an antivirus scan, automatically append scan results + fpath = str(fpath) started = timestamp(datetime.utcnow()) results.status = self.module.scan(fpath) stopped = timestamp(datetime.utcnow()) diff --git a/probe/modules/antivirus/symantec_win/symantec_win.py b/probe/modules/antivirus/symantec_win/symantec_win.py index d6a4cfd7..6d5ab99a 100644 --- a/probe/modules/antivirus/symantec_win/symantec_win.py +++ b/probe/modules/antivirus/symantec_win/symantec_win.py @@ -63,7 +63,7 @@ def get_version(self): def get_scan_path(self): """return the full path of the scan tool""" - return self.locate_one("/Symantec/*/DoScan.exe") + return self.locate_one("Symantec/*/DoScan.exe") ########################################################################## # specific scan method @@ -94,6 +94,7 @@ def check_scan_results(self, paths, results): mtime = self._log_path.stat().st_mtime delay -= 1 # look for the line corresponding to this filename + paths = str(paths) stdout = "".join( line + '\n' for line in self._log_path.read_text().splitlines() From a3afd4bb267b9d6f10c23c0f418e3ffdcc88896c Mon Sep 17 00:00:00 2001 From: Logan Sampson Date: Tue, 3 Jul 2018 13:41:42 -0500 Subject: [PATCH 2/2] ESET Windows AV module. --- probe/modules/antivirus/eset_win/__init__.py | 0 probe/modules/antivirus/eset_win/eset_win.py | 71 ++++++++++++++++++++ probe/modules/antivirus/eset_win/plugin.py | 43 ++++++++++++ 3 files changed, 114 insertions(+) create mode 100644 probe/modules/antivirus/eset_win/__init__.py create mode 100644 probe/modules/antivirus/eset_win/eset_win.py create mode 100644 probe/modules/antivirus/eset_win/plugin.py diff --git a/probe/modules/antivirus/eset_win/__init__.py b/probe/modules/antivirus/eset_win/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/probe/modules/antivirus/eset_win/eset_win.py b/probe/modules/antivirus/eset_win/eset_win.py new file mode 100644 index 00000000..49f5dc8a --- /dev/null +++ b/probe/modules/antivirus/eset_win/eset_win.py @@ -0,0 +1,71 @@ +# +# Copyright (c) 2013-2018 Quarkslab. +# This file is part of IRMA project. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License in the top-level directory +# of this distribution and at: +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# No part of the project, including this file, may be copied, +# modified, propagated, or distributed except according to the +# terms contained in the LICENSE file. + +import logging +import re + +from modules.antivirus.base import AntivirusWindows + +log = logging.getLogger(__name__) + + +class ESETWin(AntivirusWindows): + name = "ESET Anti-Virus (Windows)" + + # ================================== + # Constructor and destructor stuff + # ================================== + + def __init__(self, *args, **kwargs): + # class super class constructor + super().__init__(*args, **kwargs) + # scan tool variables + # other flag + # archivemaxrecursion=N default 10 + self.scan_args = ( + "/files", + ) + # return code + # 0 Normal nothing found + # 1 Found converning file + # 3 Suspicious files found (maybe need regex for this one and I think + # is used when heurlevel is set) + self._scan_retcodes[self.ScanResult.INFECTED] = lambda x: x in [1, 50] + self.scan_patterns = [ + re.compile('name="(?P[^\s]+)", threat="(?P.+)", action="", info=""',re.IGNORECASE) + ] + + # ========================================== + # Antivirus methods (need to be overriden) + # ========================================== + def get_version(self): + """return the version of the antivirus""" + return self._run_and_parse( + '--version', + regexp='ecls.exe\s+(?P\d+(\.\d+)+)', + group='version') + # match VDF version is for database + # matches = re.search(r'VDF Version:\s+' + # r'(?P\d+(\.\d+)+)', + # stdout, re.IGNORECASE) + # match engine version + + def get_database(self): + """return list of files in the database""" + return None + + def get_scan_path(self): + """return the full path of the scan tool""" + return self.locate_one("ESET/ESET Security/ecls.exe") diff --git a/probe/modules/antivirus/eset_win/plugin.py b/probe/modules/antivirus/eset_win/plugin.py new file mode 100644 index 00000000..0f608195 --- /dev/null +++ b/probe/modules/antivirus/eset_win/plugin.py @@ -0,0 +1,43 @@ +# +# Copyright (c) 2013-2018 Quarkslab. +# This file is part of IRMA project. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License in the top-level directory +# of this distribution and at: +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# No part of the project, including this file, may be copied, +# modified, propagated, or distributed except according to the +# terms contained in the LICENSE file. + +from .eset_win import ESETWin +from ..interface import AntivirusPluginInterface + +from irma.common.plugins import PluginMetaClass, PlatformDependency +from irma.common.base.utils import IrmaProbeType + + +class ESETWinPlugin(AntivirusPluginInterface, metaclass=PluginMetaClass): + + # ================= + # plugin metadata + # ================= + + _plugin_name_ = "ESETWin" + _plugin_display_name_ = ESETWin.name + _plugin_author_ = "clandestine" + _plugin_version_ = "0.0.1" + _plugin_category_ = IrmaProbeType.antivirus + _plugin_description_ = "Plugin for ESET AV on Windows" + _plugin_dependencies_ = [ + PlatformDependency('win32') + ] + + # ================ + # interface data + # ================ + + module_cls = ESETWin