''' Command realscanners for sagator, version 0.5 (c) 2003-2018 Jan ONDREJ (SAL) 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 2 of the License, or (at your option) any later version. ''' from avlib import * import re __all__=['cmd','cmd_clamav','cmd_kavscanner','cmd_drweb','cmd_fprot', 'cmd_trendmicro','cmd_bdc','cmd_uvscan','cmd_vbuster', 'cmd_mks'] ##################################################################### ### exec_any class class cmd(ascanner): ''' A realscanner used to scan over command line programs. Usage: cmd(['command','arg1',...],StatusCLEAN,StatusINFECTED,RE) Where: 'command' is a string, which command to run 'argX' are command line arguments, as last argument the filename is added StatusCLEAN may be: an array of integers, which defines "clean" exit codes an regexp, indication no virus found StatusINFECTED may be: an array of integers, which defines "virus found" exit codes RE is an regular expression string, which can extract virus names from scanner output. ''' name='cmd()' DIR=('DIR') FILES=('FILES') def __init__(self,cmd_args,clean_status=[0],infected_status=[1],vreg=None): self.cmd_args=cmd_args if type(clean_status)==type(b''): self.clean_status=re.compile(clean_status, re.M) else: self.clean_status=clean_status if type(infected_status)==type(b''): self.infected_status=re.compile(infected_status, re.M) else: self.infected_status=infected_status if type(vreg)==type(b''): self.vreg=re.compile(vreg, re.M) else: self.vreg=vreg def check_vname(self,ret): reg1=self.vreg.search(b''.join(ret)) if reg1: return reg1.group(1) else: return "UnknownVirus" def scanfile(self,files,dir='',args={}): cmd_args=[] for arg in self.cmd_args: if arg==self.DIR: cmd_args.append(safe.fn(dir)) elif arg==self.FILES: for f in files: cmd_args.append(safe.fn(f)) else: cmd_args.append(arg) pf=popen(cmd_args) pf.tocmd.close() ret=pf.readlines() debug.echo(6,ret) pf.wait() pf.fromcmd.close() if type(self.infected_status)==type([]): if pf.exitstatus in self.infected_status: return 1.0, self.check_vname(ret), ret else: regi=self.infected_status.search(b''.join(ret)) if regi: return 1.0, self.check_vname(ret), ret if type(self.clean_status)==type([]): if pf.exitstatus in self.clean_status: return 0.0, b'', [] else: regc=self.clean_status.search(''.join(ret)) if regc: return 0.0, b'', [] debug.echo(1,self.name+': command: ',' '.join(cmd_args), ' ExitStatus: ',str(pf.exitstatus),ret) raise ScannerError(self.name+' error') class cmd_clamav(cmd): ''' This scanner uses clamscan command from clamav project. See http://www.clamav.net/ for more info. Usage: cmd_clamav(command='clamscan') Example: s2f(cmd_clamav('clamscan')) ''' name='cmd_clamav()' def __init__(self,command='clamscan'): cmd.__init__(self, [command,'--stdout','--disable-summary','-r',cmd.DIR], [0],[1], '^.*?: (?!Infected Archive)(.*) FOUND$' ) class cmd_kavscanner(cmd): ''' This scanner uses kavscanner command from KasperskyLab kavscanner. See http://www.kaspersky.com/ for more info. Usage: cmd_kavscanner(command='/opt/kav/bin/kavscanner') Example: s2f(cmd_kavscanner('/opt/kav/bin/kavscanner') ''' name='cmd_kavscanner()' def __init__(self,command='/opt/kav/bin/kavscanner'): cmd.__init__(self, [command,'-i1','-xp',cmd.DIR], [0,10,15], [5,20,21,25], '(?:CURED|INFECTED|CUREFAILED|WARNING|SUSPICION) (.*)' ) class cmd_drweb(cmd): ''' This scanner uses drweb command from DRWEB antivirus. See http://www.sald.com/, http://drweb.imshop.de/ for more info. Usage: cmd_drweb(command='/usr/local/drweb/drweb') Example: s2f(cmd_drweb('/usr/local/drweb/drweb')) ''' name='cmd_drweb()' def __init__(self,command='/usr/local/drweb/drweb'): cmd.__init__(self, [command,'-path',cmd.DIR,'-al','-go','-ot','-cn','-upn','-ok-'], [0,32], [1,9,33], ' infected (?:with|by)(?: virus)? (.*)$' ) class cmd_fprot(cmd): ''' This scanner uses f-prot command from FRISK F-Prot antivirus. See http://www.f-prot.com/ for more info. Usage: cmd_fprot(command='f-prot', params=[]) Example: s2f(cmd_fprot('f-prot')) ''' name='cmd_fprot()' def __init__(self,command='f-prot',params=[]): cmd.__init__(self, [command]+params+['-dumb','-archive','-packed']+[cmd.DIR], [0,8], [3,6], 'Infection: (.+)' ) class cmd_trendmicro(cmd): ''' This scanner uses trendmicro command from Trend Micro FileScanner. See http://www.trendmicro.com/ for more info. Usage: cmd_trendmicro(command='/etc/iscan/vscan') Example: s2f(cmd_trendmicro('/etc/iscan/vscan')) ''' name='cmd_trendmicro()' def __init__(self,command='/etc/iscan/vscan'): cmd.__init__(self, [command,'-za','-a',cmd.DIR], [0], 'Found virus', 'Found virus (.+) in' ) class cmd_bdc(cmd): ''' This scanner uses bdc command from BitDefender antivirus. See http://www.bitdefender.com/ for more info. Usage: cmd_bdc(command='/opt/bdc/bdc') Example: s2f(cmd_bdc('/opt/bdc/bdc')) ''' name='cmd_bdc()' def __init__(self,command='/opt/bdc/bdc'): cmd.__init__(self, [command,'--arc','--mail','--all',cmd.DIR], '^Infected files *:0+(?!\d)', '^(?:Infected files|Identified viruses|Suspect files) *:0*[1-9]', '(?:suspected|infected): (.*)(?:\033|$)' ) class cmd_uvscan(cmd): ''' This scanner uses uvscan command from McAfee AntiVirus. See http://www.mcafee.com/ for more info. Usage: cmd_uvscan(command='uvscan') Example: s2f(cmd_uvscan('uvscan')) ''' name='cmd_uvscan()' def __init__(self,command='uvscan'): cmd.__init__(self, [command,'--secure','-rv','--mime','--summary','--noboot','-',cmd.DIR], [0], [13], ' the (.+) (?:virus|trojan)' ) class cmd_vbuster(cmd): ''' This scanner uses vbuster command from VirusBuster. See http://www.virusbuster.hu/en/ for more info. Usage: cmd_vbuster(command='vbscan') Example: s2f(cmd_vbuster('vbscan')) ''' name='cmd_vbuster()' def __init__(self,command='vbscan'): cmd.__init__(self, [command,'--action=skip',cmd.DIR], [0,1,2,3,4,5], '(?:virus|iworm) found: ', "(?:virus|iworm) found: (.+) \\.\\.\\. " ) class cmd_mks(cmd): ''' This scanner uses mks antivirus. See http://linux.mks.com.pl/ for more info. Usage: cmd_mks(command='mks32',extra_params_array=[]) Example: s2f(cmd_mks('mks32')) ''' name='cmd_mks()' def __init__(self,command='mks32',params=[]): cmd.__init__(self, [command]+params+['--',cmd.FILES], [0], [1,2,4], "^mks_vir: \t--(?:|destroyed by |scanstring of )virus (.+)" )