Ejemplo n.º 1
0
    def negotiate_protocol(self):
        # read until newline
        buf = self.read_newline()

        if "NETLOG" in buf:
            self.protocol = NetlogParser(self)
        elif "FILE" in buf:
            self.protocol = FileUpload(self)
        elif "LOG" in buf:
            self.protocol = LogHandler(self)
        else:
            raise CuckooOperationalError(
                "Netlog failure, unknown protocol requested.")
Ejemplo n.º 2
0
 def parse_first_and_reset(self):
     self.fd = open(self._log_path, "rb")
     self.parser = NetlogParser(self)
     self.parser.read_next_message()
     self.fd.seek(0)
Ejemplo n.º 3
0
class ParseProcessLog(list):
    """Parses process log file."""
    
    def __init__(self, log_path):
        """@param log_path: log file path."""
        self._log_path = log_path
        self.fd = None
        self.parser = None

        self.process_id = None
        self.process_name = None
        self.parent_id = None
        self.first_seen = None
        self.calls = self
        self.lastcall = None

        if os.path.exists(log_path) and os.stat(log_path).st_size > 0:
            self.parse_first_and_reset()

    def parse_first_and_reset(self):
        self.fd = open(self._log_path, "rb")
        self.parser = NetlogParser(self)
        self.parser.read_next_message()
        self.fd.seek(0)

    def read(self, length):
        if length == 0: return b''
        buf = self.fd.read(length)
        if not buf or len(buf) != length: raise EOFError()
        return buf

    def __iter__(self):
        #log.debug('iter called by this guy: {0}'.format(inspect.stack()[1]))
        return self

    def __getitem__(self, key):
        return getattr(self, key)

    def __repr__(self):
        return 'ParseProcessLog {0}'.format(self._log_path)

    def __nonzero__(self):
        return True

    def compare_calls(self, a, b):
        """Compare two calls for equality. Same implementation as before netlog.
        @param a: call a
        @param b: call b
        @return: True if a == b else False
        """
        if a["api"] == b["api"] and \
           a["status"] == b["status"] and \
           a["arguments"] == b["arguments"] and \
           a["return"] == b["return"]:
            return True
        return False

    def wait_for_lastcall(self):
        while not self.lastcall:
            r = None
            try: r = self.parser.read_next_message()
            except EOFError:
                return False

            if not r: return False
        return True

    def next(self):
        x = self.wait_for_lastcall()
        if not x:
            self.fd.seek(0)
            raise StopIteration()

        nextcall, self.lastcall = self.lastcall, None

        x = self.wait_for_lastcall()
        while self.lastcall and self.compare_calls(nextcall, self.lastcall):
            nextcall['repeated'] += 1
            self.lastcall = None
            x = self.wait_for_lastcall()

        return nextcall

    def log_process(self, context, timestring, pid, ppid, modulepath, procname):
        self.process_id, self.parent_id, self.process_name = pid, ppid, procname
        self.first_seen = timestring

    def log_thread(self, context, pid):
        pass

    def log_call(self, context, apiname, modulename, arguments):
        apiindex, status, returnval, tid, timediff = context

        current_time = self.first_seen + datetime.timedelta(0,0, timediff*1000)
        timestring = logtime(current_time)

        self.lastcall = self._parse([timestring,
                                     tid,
                                     modulename,
                                     apiname, 
                                     status,
                                     returnval] + arguments)

    def _parse(self, row):
        """Parse log row.
        @param row: row data.
        @return: parsed information dict.
        """
        call = {}
        arguments = []

        try:
            timestamp = row[0]    # Timestamp of current API call invocation.
            thread_id = row[1]    # Thread ID.
            category = row[2]     # Win32 function category.
            api_name = row[3]     # Name of the Windows API.
            status_value = row[4] # Success or Failure?
            return_value = row[5] # Value returned by the function.
        except IndexError as e:
            log.debug("Unable to parse process log row: %s", e)
            return None

        # Now walk through the remaining columns, which will contain API
        # arguments.
        for index in range(6, len(row)):
            argument = {}

            # Split the argument name with its value based on the separator.
            try:                
                (arg_name, arg_value) = row[index]
            except ValueError as e:
                log.debug("Unable to parse analysis row argument (row=%s): %s", row[index], e)
                continue

            argument["name"] = arg_name
            argument["value"] = convert_to_printable(str(arg_value)).lstrip("\\??\\")
            arguments.append(argument)

        call["timestamp"] = timestamp
        call["thread_id"] = str(thread_id)
        call["category"] = category
        call["api"] = api_name
        call["status"] = bool(int(status_value))

        if isinstance(return_value, int):
            call["return"] = "0x%.08x" % return_value
        else:
            call["return"] = convert_to_printable(str(return_value))

        call["arguments"] = arguments
        call["repeated"] = 0

        return call
Ejemplo n.º 4
0
 def parse_first_and_reset(self):
     self.fd = open(self._log_path, "rb")
     self.parser = NetlogParser(self)
     self.parser.read_next_message()
     self.fd.seek(0)
Ejemplo n.º 5
0
class ParseProcessLog(list):
    """Parses process log file."""
    def __init__(self, log_path):
        """@param log_path: log file path."""
        self._log_path = log_path
        self.fd = None
        self.parser = None

        self.process_id = None
        self.process_name = None
        self.parent_id = None
        self.first_seen = None
        self.calls = self
        self.lastcall = None

        if os.path.exists(log_path) and os.stat(log_path).st_size > 0:
            self.parse_first_and_reset()

    def parse_first_and_reset(self):
        self.fd = open(self._log_path, "rb")
        self.parser = NetlogParser(self)
        self.parser.read_next_message()
        self.fd.seek(0)

    def read(self, length):
        if length == 0: return b''
        buf = self.fd.read(length)
        if not buf or len(buf) != length: raise EOFError()
        return buf

    def __iter__(self):
        #log.debug('iter called by this guy: {0}'.format(inspect.stack()[1]))
        return self

    def __getitem__(self, key):
        return getattr(self, key)

    def __repr__(self):
        return 'ParseProcessLog {0}'.format(self._log_path)

    def __nonzero__(self):
        return True

    def compare_calls(self, a, b):
        """Compare two calls for equality. Same implementation as before netlog.
        @param a: call a
        @param b: call b
        @return: True if a == b else False
        """
        if a["api"] == b["api"] and \
           a["status"] == b["status"] and \
           a["arguments"] == b["arguments"] and \
           a["return"] == b["return"]:
            return True
        return False

    def wait_for_lastcall(self):
        while not self.lastcall:
            r = None
            try:
                r = self.parser.read_next_message()
            except EOFError:
                return False

            if not r: return False
        return True

    def next(self):
        x = self.wait_for_lastcall()
        if not x:
            self.fd.seek(0)
            raise StopIteration()

        nextcall, self.lastcall = self.lastcall, None

        x = self.wait_for_lastcall()
        while self.lastcall and self.compare_calls(nextcall, self.lastcall):
            nextcall['repeated'] += 1
            self.lastcall = None
            x = self.wait_for_lastcall()

        return nextcall

    def log_process(self, context, timestring, pid, ppid, modulepath,
                    procname):
        self.process_id, self.parent_id, self.process_name = pid, ppid, procname
        self.first_seen = timestring

    def log_thread(self, context, pid):
        pass

    def log_call(self, context, apiname, modulename, arguments):
        apiindex, status, returnval, tid, timediff = context

        current_time = self.first_seen + datetime.timedelta(
            0, 0, timediff * 1000)
        timestring = logtime(current_time)

        self.lastcall = self._parse(
            [timestring, tid, modulename, apiname, status, returnval] +
            arguments)

    def _parse(self, row):
        """Parse log row.
        @param row: row data.
        @return: parsed information dict.
        """
        call = {}
        arguments = []

        try:
            timestamp = row[0]  # Timestamp of current API call invocation.
            thread_id = row[1]  # Thread ID.
            category = row[2]  # Win32 function category.
            api_name = row[3]  # Name of the Windows API.
            status_value = row[4]  # Success or Failure?
            return_value = row[5]  # Value returned by the function.
        except IndexError as e:
            log.debug("Unable to parse process log row: %s", e)
            return None

        # Now walk through the remaining columns, which will contain API
        # arguments.
        for index in range(6, len(row)):
            argument = {}

            # Split the argument name with its value based on the separator.
            try:
                (arg_name, arg_value) = row[index]
            except ValueError as e:
                log.debug("Unable to parse analysis row argument (row=%s): %s",
                          row[index], e)
                continue

            argument["name"] = arg_name
            argument["value"] = convert_to_printable(
                str(arg_value)).lstrip("\\??\\")
            arguments.append(argument)

        call["timestamp"] = timestamp
        call["thread_id"] = str(thread_id)
        call["category"] = category
        call["api"] = api_name
        call["status"] = bool(int(status_value))

        if isinstance(return_value, int):
            call["return"] = "0x%.08x" % return_value
        else:
            call["return"] = convert_to_printable(str(return_value))

        call["arguments"] = arguments
        call["repeated"] = 0

        return call