Example #1
0
    def _QueryHash(self, digest):
        """Queries the Viper Server for a specfic hash.

    Args:
      digest (str): hash to look up.

    Returns:
      dict[str, object]: JSON response or None on error.
    """
        if not self._url:
            self._url = '{0:s}://{1:s}:{2:d}/file/find'.format(
                self._protocol, self._host, self._port)

        request_data = {self.lookup_hash: digest}

        try:
            json_response = self.MakeRequestAndDecodeJSON(self._url,
                                                          'POST',
                                                          data=request_data)

        except errors.ConnectionError as exception:
            json_response = None
            logger.error(
                'Unable to query Viper with error: {0!s}.'.format(exception))

        return json_response
Example #2
0
    def _QueryHash(self, nsrl_socket, digest):
        """Queries nsrlsvr for a specific hash.

    Args:
      nsrl_socket (socket._socketobject): socket of connection to nsrlsvr.
      digest (str): hash to look up.

    Returns:
      bool: True if the hash was found, False if not or None on error.
    """
        try:
            query = 'QUERY {0:s}\n'.format(digest).encode('ascii')
        except UnicodeDecodeError:
            logger.error(
                'Unable to encode digest: {0!s} to ASCII.'.format(digest))
            return False

        response = None

        try:
            nsrl_socket.sendall(query)
            response = nsrl_socket.recv(self._RECEIVE_BUFFER_SIZE)

        except socket.error as exception:
            logger.error(
                'Unable to query nsrlsvr with error: {0!s}.'.format(exception))

        if not response:
            return False

        # Strip end-of-line characters since they can differ per platform on which
        # nsrlsvr is running.
        response = response.strip()
        # nsrlsvr returns "OK 1" if the has was found or "OK 0" if not.
        return response == b'OK 1'
Example #3
0
  def _QueryHash(self, nsrl_socket, digest):
    """Queries nsrlsvr for a specific hash.

    Args:
      nsrl_socket (socket._socketobject): socket of connection to nsrlsvr.
      digest (str): hash to look up.

    Returns:
      bool: True if the hash was found, False if not or None on error.
    """
    try:
      query = 'QUERY {0:s}\n'.format(digest).encode('ascii')
    except UnicodeDecodeError:
      logger.error('Unable to encode digest: {0!s} to ASCII.'.format(digest))
      return False

    response = None

    try:
      nsrl_socket.sendall(query)
      response = nsrl_socket.recv(self._RECEIVE_BUFFER_SIZE)

    except socket.error as exception:
      logger.error('Unable to query nsrlsvr with error: {0!s}.'.format(
          exception))

    if not response:
      return False

    # Strip end-of-line characters since they can differ per platform on which
    # nsrlsvr is running.
    response = response.strip()
    # nsrlsvr returns "OK 1" if the has was found or "OK 0" if not.
    return response == b'OK 1'
Example #4
0
    def _GenerateLabels(self, hash_information):
        """Generates a list of strings that will be used in the event tag.

    Args:
      hash_information (dict[str, object]): the JSON decoded contents of the
          result of a VirusTotal lookup, as produced by the VirusTotalAnalyzer.

    Returns:
      list[str]: strings describing the results from VirusTotal.
    """
        response_code = hash_information['response_code']
        if response_code == self._VIRUSTOTAL_NOT_PRESENT_RESPONSE_CODE:
            return ['virustotal_not_present']

        if response_code == self._VIRUSTOTAL_PRESENT_RESPONSE_CODE:
            positives = hash_information['positives']
            if positives > 0:
                return ['virustotal_detections_{0:d}'.format(positives)]

            return ['virsutotal_no_detections']

        if response_code == self._VIRUSTOTAL_ANALYSIS_PENDING_RESPONSE_CODE:
            return ['virustotal_analysis_pending']

        logger.error('VirusTotal returned unknown response code {0!s}'.format(
            response_code))
        return ['virustotal_unknown_response_code_{0:d}'.format(response_code)]
Example #5
0
  def GenerateLabels(self, hash_information):
    """Generates a list of strings that will be used in the event tag.

    Args:
      hash_information (dict[str, object]): the JSON decoded contents of the
          result of a VirusTotal lookup, as produced by the VirusTotalAnalyzer.

    Returns:
      list[str]: strings describing the results from VirusTotal.
    """
    response_code = hash_information['response_code']
    if response_code == self._VIRUSTOTAL_NOT_PRESENT_RESPONSE_CODE:
      return ['virustotal_not_present']

    if response_code == self._VIRUSTOTAL_PRESENT_RESPONSE_CODE:
      positives = hash_information['positives']
      if positives > 0:
        return ['virustotal_detections_{0:d}'.format(positives)]

      return ['virsutotal_no_detections']

    if response_code == self._VIRUSTOTAL_ANALYSIS_PENDING_RESPONSE_CODE:
      return ['virustotal_analysis_pending']

    logger.error(
        'VirusTotal returned unknown response code {0!s}'.format(
            response_code))
    return ['virustotal_unknown_response_code_{0:d}'.format(response_code)]
Example #6
0
  def _QueryHash(self, digest):
    """Queries the Viper Server for a specfic hash.

    Args:
      digest (str): hash to look up.

    Returns:
      dict[str, object]: JSON response or None on error.
    """
    if not self._url:
      self._url = '{0:s}://{1:s}:{2:d}/file/find'.format(
          self._protocol, self._host, self._port)

    request_data = {self.lookup_hash: digest}

    try:
      json_response = self.MakeRequestAndDecodeJSON(
          self._url, 'POST', data=request_data)

    except errors.ConnectionError as exception:
      json_response = None
      logger.error('Unable to query Viper with error: {0!s}.'.format(
          exception))

    return json_response
Example #7
0
    def _HandleHashAnalysis(self, mediator, hash_analysis):
        """Deals with the results of the analysis of a hash.

    This method ensures that labels are generated for the hash,
    then tags all events derived from files with that hash.

    Args:
      mediator (AnalysisMediator): mediates interactions between
          analysis plugins and other components, such as storage and dfVFS.
      hash_analysis (HashAnalysis): hash analysis plugin's results for a given
          hash.

    Returns:
      collections.Counter: number of events per label.
    """
        events_per_labels_counter = collections.Counter()
        labels = self.GenerateLabels(hash_analysis.hash_information)

        try:
            data_stream_identifiers = self._data_streams_by_hash.pop(
                hash_analysis.subject_hash)
        except KeyError:
            data_stream_identifiers = []
            logger.error(
                ('unable to retrieve data streams for digest hash: {0:s}'
                 ).format(hash_analysis.subject_hash))

        for data_stream_identifier in data_stream_identifiers:
            event_identifiers = self._event_identifiers_by_data_stream.pop(
                data_stream_identifier)

            # Do no bail out earlier to maintain the state of
            # self._data_streams_by_hash and self._event_identifiers_by_data_stream.
            if not labels:
                continue

            for event_identifier in event_identifiers:
                event_tag = events.EventTag()
                event_tag.SetEventIdentifier(event_identifier)

                try:
                    event_tag.AddLabels(labels)
                except (TypeError, ValueError):
                    error_label = 'error_{0:s}'.format(self.NAME)
                    logger.error((
                        'unable to add labels: {0!s} for digest hash: {1:s} defaulting '
                        'to: {2:s}').format(labels, hash_analysis.subject_hash,
                                            error_label))
                    labels = [error_label]
                    event_tag.AddLabels(labels)

                mediator.ProduceEventTag(event_tag)

                for label in labels:
                    events_per_labels_counter[label] += 1

        return events_per_labels_counter
Example #8
0
  def _GetSocket(self):
    """Establishes a connection to an nsrlsvr instance.

    Returns:
      socket._socketobject: socket connected to an nsrlsvr instance or None if
          a connection cannot be established.
    """
    try:
      return socket.create_connection(
          (self._host, self._port), self._SOCKET_TIMEOUT)

    except socket.error as exception:
      logger.error(
          'Unable to connect to nsrlsvr with error: {0!s}.'.format(exception))
Example #9
0
    def _GetSocket(self):
        """Establishes a connection to an nsrlsvr instance.

    Returns:
      socket._socketobject: socket connected to an nsrlsvr instance or None if
          a connection cannot be established.
    """
        try:
            return socket.create_connection((self._host, self._port),
                                            self._SOCKET_TIMEOUT)

        except socket.error as exception:
            logger.error(
                'Unable to connect to nsrlsvr with error: {0!s}.'.format(
                    exception))
Example #10
0
    def _HandleHashAnalysis(self, hash_analysis):
        """Deals with the results of the analysis of a hash.

    This method ensures that labels are generated for the hash,
    then tags all events derived from files with that hash.

    Args:
      hash_analysis (HashAnalysis): hash analysis plugin's results for a given
          hash.

    Returns:
      tuple: containing:

        list[dfvfs.PathSpec]: path specifications that had the hash value
            looked up.
        list[str]: labels that corresponds to the hash value that was looked up.
        list[EventTag]: event tags for all events that were extracted from the
            path specifications.
    """
        tags = []
        labels = self.GenerateLabels(hash_analysis.hash_information)
        path_specifications = self._hash_path_specs.pop(
            hash_analysis.subject_hash)
        for path_specification in path_specifications:
            event_identifiers = self._event_identifiers_by_path_spec.pop(
                path_specification, [])

            if not labels:
                continue

            for event_identifier in event_identifiers:
                try:
                    event_tag = events.EventTag()
                    event_tag.SetEventIdentifier(event_identifier)
                    event_tag.AddLabels(labels)
                    tags.append(event_tag)
                except (TypeError, ValueError) as exception:
                    logger.error(
                        'unable to add labels to event with error: {0!s}'.
                        format(exception))

        return path_specifications, labels, tags
Example #11
0
  def _QueryHashes(self, digests):
    """Queries VirusTotal for a specfic hashes.

    Args:
      digests (list[str]): hashes to look up.

    Returns:
      dict[str, object]: JSON response or None on error.
    """
    url_parameters = {'apikey': self._api_key, 'resource': ', '.join(digests)}

    try:
      json_response = self.MakeRequestAndDecodeJSON(
          self._VIRUSTOTAL_API_REPORT_URL, 'GET', params=url_parameters)
    except errors.ConnectionError as exception:
      json_response = None
      logger.error('Unable to query VirusTotal with error: {0!s}.'.format(
          exception))

    return json_response
Example #12
0
    def _QueryHashes(self, digests):
        """Queries VirusTotal for a specific hashes.

    Args:
      digests (list[str]): hashes to look up.

    Returns:
      dict[str, object]: JSON response or None on error.
    """
        url_parameters = {
            'apikey': self._api_key,
            'resource': ', '.join(digests)
        }

        try:
            json_response = self.MakeRequestAndDecodeJSON(
                self._VIRUSTOTAL_API_REPORT_URL, 'GET', params=url_parameters)
        except errors.ConnectionError as exception:
            json_response = None
            logger.error(
                'Unable to query VirusTotal with error: {0!s}.'.format(
                    exception))

        return json_response