Пример #1
0
    def __init__(self,
                 debug=False,
                 config_path=None,
                 file_list=None,
                 vt_api_key=None):

        # Initialize parent class
        super().__init__(debug, config_path, file_list, vt_api_key)

        if self.os_name:
            try:
                # Load threads
                self._WORKERS = self.config_dict[
                    self.os_name]["scanner"]["clamav"]["threads"]
            except KeyError:
                self.logger.log("Could not load configuration for: {}".format(
                    self.os_name),
                                logtype="error")
                sys.exit(0)
        else:
            self.logger.log("Could not determine the OS", logtype="error")
            sys.exit(0)

        # Setup Clam AV object
        self.clamd_client = clamd.ClamdUnixSocket()
def status():
    try:
        clamd.ClamdUnixSocket().ping()
    except Exception:
        return '', 500

    return 'ok', 200
def scan():
    if 'document' not in request.files:
        abort(
            400,
            'The file for scanning should be uploaded under the name `document`.'
        )

    file = request.files['document']

    try:
        client = clamd.ClamdUnixSocket()

        with logged_duration_for_external_request(
                service='ClamAV', description='instream scan via unix socket'):
            scan_result = client.instream(BytesIO(
                file.stream.read()))['stream']

    except clamd.ClamdError as e:
        current_app.logger.error(f'Unable to scan file: {str(e)}')
        return abort(500)

    response_json = {
        'infectionFound': False if scan_result[0] == 'OK' else True,
        'details': scan_result[1:]
    }

    return jsonify(response_json), 200
Пример #4
0
def scan():
    sys.stderr.write("scan()")
    start = time.time()

    if not request.json:
        jsonify({'status': 'failed'}), 401

    file = request.json["file"]

    if not file:
        jsonify({'status': 'failed'}), 401

    file_data = base64.b64decode(file)

    cd = clamd.ClamdUnixSocket()

    last_result = cd.instream(BytesIO(file_data))

    scan = {
        'status': last_result
    }

    elapsed_time = time.time() - start
    sys.stderr.write(str(elapsed_time))

    return jsonify(scan)
Пример #5
0
 def _get_connection(self):
     """
     :return: A different connection for each time you call the method.
              Thought about having a connection pool, but it doesn't make
              much sense; plus it adds complexity due to the threads.
     """
     return clamd.ClamdUnixSocket(path=self._clamd_socket)
def get_clamAV_results(file_object):
    # Connects to UNIX socket on /var/run/clamav/clamd.ctl
    clam_daemon = clamd.ClamdUnixSocket()

    clamd_res = clam_daemon.instream(BytesIO(file_object.content))

    return clamd_res["stream"][0]
Пример #7
0
def connect_to_clamav(connection_string: str) -> clamd.ClamdNetworkSocket:
    if connection_string.startswith("unix://"):
        return clamd.ClamdUnixSocket(connection_string.replace("unix://", ""))
    elif ":" in connection_string:
        host, port = connection_string.split(":")
        return clamd.ClamdNetworkSocket(host, int(port))
    else:
        raise Exception("ClamAV connection string is invalid. It must be unix socket path with 'unix://' prefix or IP:PORT.")
Пример #8
0
def clamd_client():
    init_daemon()

    client = clamd.ClamdUnixSocket(_clamd_sock)
    # smoke-test
    client.ping()

    return client
Пример #9
0
def test(socket='/var/run/clamav/clamd.ctl'):
    try:
        client = clamd.ClamdUnixSocket(socket)
        client.ping()
        show_ok('ClamavDeamon')
    except clamd.ConnectionError, e:
        show_ko('ClamavDeamon',
                'Try: systemctl restart clamav-daemon.socket',
                e)
    def virusScan(self, files_to_scan):
        files_results = []
        cd = clamd.ClamdUnixSocket()
        for file_to_scan in files_to_scan:
            scan_result = cd.scan(file_to_scan)
            if scan_result[file_to_scan][0] == "FOUND":
                files_results.append({
                    'name': file_to_scan,
                    'result': "INFECTED"
                })
            else:
                hasher = hashlib.md5()
                with open(file_to_scan, 'rb') as afile:
                    buf = afile.read()
                    hasher.update(buf)
                    params = {
                        'apikey': VT_API_KEY,
                        'resource': hasher.hexdigest()
                    }
                    url = requests.get(
                        'https://www.virustotal.com/vtapi/v2/file/report',
                        params=params)
                    if url.status_code == 200:
                        json_response = url.json()
                        response = int(json_response.get('response_code'))
                        if response == 0:
                            files_results.append({
                                'name': file_to_scan,
                                'result': "NOT INFECTED"
                            })
                        elif response == 1:
                            positives = int(json_response.get('positives'))
                            if positives == 0:
                                files_results.append({
                                    'name': file_to_scan,
                                    'result': "NOT INFECTED"
                                })
                            else:
                                files_results.append({
                                    'name': file_to_scan,
                                    'result': "INFECTED"
                                })
                        else:
                            files_results.append({
                                'name':
                                file_to_scan,
                                'result':
                                " MAY BE NOT INFECTED"
                            })
                    else:
                        files_results.append({
                            'name': file_to_scan,
                            'result': "MAY BE NOT INFECTED"
                        })

        return files_results
Пример #11
0
def clamav_scan(stream):

    cd = clamd.ClamdUnixSocket()
    result = cd.instream(stream)

    if result['stream'][0] == 'FOUND':
        current_app.logger.error('VIRUS FOUND {}'.format(result['stream'][1]))
        return False
    else:
        return True
Пример #12
0
def get_scanner():
    """Lazy get scanner configured scanner when needed"""
    import clamd
    from . import conf

    if conf.CLAMAV_USE_TCP:
        return clamd.ClamdNetworkSocket(conf.CLAMAV_TCP_ADDR,
                                        conf.CLAMAV_TCP_PORT)

    return clamd.ClamdUnixSocket(conf.CLAMAV_UNIX_SOCKET)
Пример #13
0
def _make_clamd(type, **kwargs):
    timeout = kwargs.get('timeout', 10.0)
    if type == 'socket':
        socketpath = kwargs.get('socketpath', '/var/run/clamd')
        return clamd.ClamdUnixSocket(path=socketpath, timeout=timeout)
    elif type == 'net':
        host = kwargs.get('host', 'localhost')
        port = kwargs.get('port', 3310)
        return clamd.ClamdNetworkSocket(host=host, port=port, timeout=timeout)
    else:
        raise ScanError('Invalid call')
Пример #14
0
 def __init__(self, handler, config):
     self.handler = handler
     self.config = config
     clamd_debug = config.get('pyramid_clamav.debug', 'False')
     if clamd_debug.lower().strip() in ('false', '0', 'no'):
         clamd_debug = False
     if sys.platform == 'darwin':
         self.clamd = clamd.ClamdUnixSocket('/tmp/clamd.socket')
     else:
         self.clamd = clamd.ClamdUnixSocket()
     if clamd_debug:
         try:
             self.clamd.ping()
         except clamd.ConnectionError:
             self.scanning = False
     if not self.scanning:
         clamlog.warn('Virus scanning deactivated. (pyramid_clamav.debug '
                      'is true and clamav not properly configured!')
     else:
         clamlog.info('Found clamd and its responding. Virus scanning '
                      'activated.')
Пример #15
0
def get_scanner(socket, timeout=None):
    if socket.startswith('unix://'):
        return clamd.ClamdUnixSocket(socket[7:], timeout)
    elif socket.startswith('tcp://'):
        uri = urlparse(socket)

        return clamd.ClamdNetworkSocket(uri.hostname, uri.port or 3310,
                                        timeout)
    else:
        raise NotImplementedError(
            'Missed or unsupported ClamAV connection string schema. '
            'Only tcp:// or unix:// is allowed.')
Пример #16
0
  def submit(self, fileName=None, block=False, timeout=CLAM_SUBMIT_TIMEOUT_SEC):
    clamavResult = AnalyzerResult()
    allowed = False
    connected = False

    # timeout only applies if block=True
    timeoutTime = int(time.time()) + timeout

    # while limit only repeats if block=True
    while (not allowed) and (not clamavResult.finished):

      if not connected:
        if self.verboseDebug: eprint(f"{get_ident()}: ClamAV attempting connection")
        clamAv = clamd.ClamdUnixSocket(path=self.socketFileName) if self.socketFileName is not None else clamd.ClamdUnixSocket()
      try:
        clamAv.ping()
        connected = True
        if self.verboseDebug: eprint(f"{get_ident()}: ClamAV connected!")
      except Exception as e:
        connected = False
        if self.debug: eprint(f"{get_ident()}: ClamAV connection failed: {str(e)}")

      if connected:
        # first make sure we haven't exceeded rate limits
        if (self.scanningFilesCount.increment() <= CLAM_MAX_REQS):
          # we've got fewer than the allowed requests open, so we're good to go!
          allowed = True
        else:
          self.scanningFilesCount.decrement()

      if connected and allowed:
        try:
          if self.verboseDebug: eprint(f'{get_ident()} ClamAV scanning: {fileName}')
          clamavResult.result = clamAv.scan(fileName)
          if self.verboseDebug: eprint(f'{get_ident()} ClamAV scan result: {clamavResult.result}')
          clamavResult.success = (clamavResult.result is not None)
          clamavResult.finished = True
        except Exception as e:
          if clamavResult.result is None:
            clamavResult.result = str(e)
          if self.debug: eprint(f'{get_ident()} ClamAV scan error: {clamavResult.result}')
        finally:
          self.scanningFilesCount.decrement()

      elif block and (nowTime < timeoutTime):
        # rate limited, wait for a bit and come around and try again
        time.sleep(1)

      else:
        break

    return clamavResult
Пример #17
0
def clamscan_file(file):
    """
    Uses ClamAV to scan given file.
    :param file: file to be scanned
    :return:
    """
    cd = clamd.ClamdUnixSocket()
    open('/tmp/EICAR', 'wb').write(clamd.EICAR)
    scan_result = cd.scan(file).__str__()
    if 'FOUND' in scan_result:
        print('ClamAV has detected an infected file!')
        print(f'ClamAV\'s output: {scan_result}')
    else:
        print('ClamAV has not detected malicious code.')
Пример #18
0
def check_clamav(document_id):
    document = Document.objects.get(pk=document_id)
    clam = clamd.ClamdUnixSocket(settings.CLAMAV_SOCKET)
    status, sig = clam.scan(document.pdf.path)[document.pdf.path]
    if status == 'OK':
        document.isClean = True
    elif status == 'FOUND':
        document.isClean = False
        print("Signature found", sig)
    else:
        # unknown state
        document.isClean = False
        print("Unknown return of clamav", status, sig)

    document.save()
Пример #19
0
def clamd_scan(url):
    try:
        clamd_socket = clamd.ClamdUnixSocket()
        body = fetch(url)[0]
        result = clamd_socket.scan_stream(body)
        if result:
            if "FOUND" in str(result):
                print result, url
                return 1
        return 0
    except RequestException:
        pass
    except Exception as e:
        print e.message
    return 0.5
Пример #20
0
def virus_scanner_init():
    try:
        import clamd

        cd = clamd.ClamdUnixSocket()

        def clamd_scan(fpath):
            r = cd.scan(fpath)
            found, msg = r.values()[0]
            return (found == 'FOUND', msg)

        return clamd_scan

    except ImportError as e:
        return lambda fpath: (False, None)
    def virus_scan_device(self, mountpoint_path):
        """
        Scans a device for viruses

        :param mountpoint_path: The path to the mountpoint directory of the connected device
        """
        
        clam_daemon = clamd.ClamdUnixSocket()
        clam_daemon.reload()

        Logger().log('> Initiating virus scan.')

        scan_result = clam_daemon.scan(mountpoint_path)
        Logger().log('> {}'.format(scan_result), silent=True)
        
        return 'OK' in str(scan_result)
Пример #22
0
def get_clamd_status():
    client = clamd.ClamdUnixSocket()

    try:
        if client.ping() == 'PONG':
            return {
                'clamd': {
                    'status': 'OK',
                    'stats': client.stats()
                },
            }

    except clamd.ClamdError as e:
        raise StatusError(str(e))

    raise StatusError('Unknown error')
Пример #23
0
 def is_safe(self, content=None):
     if content:
         cd = clamd.ClamdUnixSocket()
         if cd.ping() == 'PONG':
             cd.reload()
             file_buffer = BytesIO()
             file_buffer.write(content)
             file_buffer.seek(0)
             result = cd.instream(file_buffer)
             if result['stream'] == ('OK', None):
                 return [True, "File is very safe."]
             else:
                 return [False, "The file looks malicious."]
         else:
             return [False, "Clamd Cannot be reached."]
     else:
         return [True, "No content. So it is very safe."]
Пример #24
0
 def __init__(self, handler, config):
     self.handler = handler
     clamd_debug = config.get('pyramid_clamav.debug', 'False')
     if clamd_debug.lower().strip() in ('false', '0', 'no'):
         clamd_debug = False
     clamd_socket_location = config.get('pyramid_clamav.socket',
                                        CLAMD_DEFAULT)
     if not os.path.exists(clamd_socket_location) and clamd_debug:
         self.scanning = False
     self.clamd = clamd.ClamdUnixSocket(clamd_socket_location)
     if clamd_debug:
         try:
             self.clamd.ping()
         except clamd.ConnectionError:
             self.scanning = False
     if not self.scanning:
         clamlog.warn('Virus scanning deactivated. (pyramid_clamav.debug '
                      'is true and clamav not properly configured!')
Пример #25
0
 def malwareScanClick(self):
     cd = clamd.ClamdUnixSocket()
     try:
         cd.ping()
         Dialog = QtWidgets.QDialog()
         ui = Ui_MalwareScanWindow()
         ui.setupUi(Dialog)
         Dialog.show()
         Dialog.exec_()
     except ConnectionError as e:
         msgBox = QtWidgets.QMessageBox()
         msgBox.setIcon(QtWidgets.QMessageBox.Critical)
         msgBox.setText("Error")
         msgBox.setInformativeText(
             'Sorry the antivirus daemon is still in initilization mode, retry in few minutes please.'
         )
         msgBox.setWindowTitle("Antivirus initialization")
         msgBox.exec_()
Пример #26
0
def main():
    options, args = opt_args()
    if not (len(options.users) or options.all):
        print('Run `zarafa-scan-attachments.py --help` for parameters')
        return

    clam = clamd.ClamdUnixSocket()

    if not clam.ping():
        print('No ClamAV Daemon connection')
    else:
        conn = kopano.Server(options=options)
        for user in conn.users():
            print('Scanning user: [%s]' % user.name)
            for folder in user.store.folders():
                print('\tScanning folder: [%s]' % folder.name)
                for item in folder.items():
                    scanmail(clam, item, options.autoremove)
def scanall(mntns, namespace, podname, container, scancache):
    '''Scan all processes in a given mount namespace'''
    clam = clamd.ClamdUnixSocket(path='/var/run/clamd.scan/clamd.sock')
    # iterated over all running processes
    for pid in [pid for pid in os.listdir('/proc') if pid.isdigit()]:
        try:
            # get the process's mount namespace
            this_mntns = os.stat('/proc/{pid}/ns/mnt'.format(pid=pid)).st_ino
        except OSError:
            # no worries if we tried to open it and failed. The process has probably gone away
            pass
        # ignore processes that don't have the requested mount namespace
        if this_mntns == mntns:
            # scan the process and iterate over the results.
            for fname, found in scanpid(pid, scancache, clam).iteritems():
                print "Found in {ns}/{pod}/{container}:{file}: {result}".format(
                    ns=namespace,
                    pod=podname,
                    container=container,
                    file=fname,
                    result=found)
Пример #28
0
    def get_clamav(self):
        """Get Yara signatures matches.
        @return: matched Yara signatures.
        """
        matches = None

        if HAVE_CLAMAV:
            if os.path.getsize(self.file_path) > 0:
                try:
                    cd = clamd.ClamdUnixSocket()
                except:
                    log.warning("failed to connect to clamd socket")
                    return matches
                try:
                    r = cd.scan(self.file_path)
                except Exception as e:
                    log.warning("failed to scan file with clamav %s", e)
                    return matches
                for key in r:
                    if r[key][0] == "FOUND":
                        matches = r[key][1]
        return matches
Пример #29
0
    def __init__(self,
                 debug=False,
                 config_path=None,
                 file_list=None,
                 vt_api_key=None):
        """
        Initialize ClamAVScanner.

        Args:
            debug (bool): Log on terminal or not
            config_path (str): Configuration JSON file path
            file_list (list): List of files to scan
            vt_api_key (str): Virus Total API Key

        Raises:
            None

        Returns:
            None
        """
        # Initialize parent class
        super().__init__(debug, config_path, file_list, vt_api_key)

        if self.os_name:
            try:
                # Load threads
                self._WORKERS = self.config_dict[
                    self.os_name]["scanner"]["clamav"]["threads"]
            except KeyError:
                self.logger.log("Could not load configuration for: {}".format(
                    self.os_name),
                                logtype="error")
                sys.exit(0)
        else:
            self.logger.log("Could not determine the OS", logtype="error")
            sys.exit(0)

        # Setup Clam AV object
        self.clamd_client = clamd.ClamdUnixSocket()
Пример #30
0
    def run_scan(cls, path=None):

        if path is None:
            path = cls.CONFIG.get('DEFAULT_SCAN_PATH')

        if not path.startswith(cls.CONFIG.get('DEFAULT_SCAN_PATH')):
            flash("Due to security reasons, the path must start with {}".format(cls.CONFIG.get('DEFAULT_SCAN_PATH')), "error")
            return []

        events = []
        try:
            clam = clamd.ClamdUnixSocket()
            files = clam.multiscan(path)
            for file in files:
                result = files[file][0]
                msg = files[file][1]

                if result == 'FOUND':
                    event = HostEvent(cls.__name__)
                    event.file = file
                    event.signature = msg
                    events.append(event)
                    flash("Found {} in file {}!".format(msg, file), "warning")

                elif result == 'ERROR':
                    flash("Error in file {}: {}".format(file, msg), "error")

                elif result == 'OK':
                    flash("Nothing found in path/file: {}".format(file), "success")

                else:
                    print("ClamAV: unhandled result in file {}: {}, Msg: {}".format(file, result, msg))

        except Exception:
            flash(traceback.format_exc(0), "error")

        return events