예제 #1
0
def main():
    with open(sys.argv[1], 'r') as f:
        with contextlib.closing(
                mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ)) as buf:
            fh = FileHeader(buf, 0x0)
            for chunk in fh.chunks():
                for record in chunk.records():
                    try:
                        evtx_record_xml_view(record).encode("utf-8")
                    except Exception as e:
                        print str(e)
                        print repr(e)
                        print evtx_record_xml_view(record).encode("utf-8")
                        return
예제 #2
0
def main():
    with open(sys.argv[1], 'r') as f:
        with contextlib.closing(mmap.mmap(f.fileno(), 0,
                                          access=mmap.ACCESS_READ)) as buf:
            fh = FileHeader(buf, 0x0)
            for chunk in fh.chunks():
                for record in chunk.records():
                    try:
                        evtx_record_xml_view(record).encode("utf-8")
                    except Exception as e:
                        print str(e)
                        print repr(e)
                        print evtx_record_xml_view(record).encode("utf-8")
                        return
예제 #3
0
def main():
    import argparse

    parser = argparse.ArgumentParser(
        description="Extract a single EVTX record and pretty print it.")
    parser.add_argument("evtx", type=str, help="Path to the Windows EVTX file")
    parser.add_argument("record",
                        type=int,
                        help="The record number of the record to extract")
    args = parser.parse_args()

    with Evtx(args.evtx) as evtx:
        record = evtx.get_record(args.record)
        if record is None:
            raise RuntimeError("Cannot find the record specified.")

        try:
            print prettify_xml(
                "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\" ?>\n%s"
                % evtx_record_xml_view(record))
        except ExpatError as e:
            print "Exception: "
            print repr(e)
            print ""
            print ""
            print "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\" ?>\n%s" % evtx_record_xml_view(
                record)
예제 #4
0
def main():
    import argparse

    parser = argparse.ArgumentParser(description="Pretty print the binary structure of an EVTX record.")
    parser.add_argument("evtx", type=str, help="Path to the Windows EVTX file")
    parser.add_argument("record", type=int, help="Record number")
    parser.add_argument("--suppress_values", action="store_true", help="Do not print the values of substitutions.")
    args = parser.parse_args()

    with Evtx(args.evtx) as evtx:
        print hex_dump(evtx.get_record(args.record).data())

        print ("record(absolute_offset=%s)" % (evtx.get_record(args.record).offset()))
        print describe_root(
            evtx.get_record(args.record), evtx.get_record(args.record).root(), suppress_values=args.suppress_values
        )
        print evtx_record_xml_view(evtx.get_record(args.record))
예제 #5
0
def main():
    import argparse

    parser = argparse.ArgumentParser(
        description="Pretty print the binary structure of an EVTX record.")
    parser.add_argument("evtx", type=str, help="Path to the Windows EVTX file")
    parser.add_argument("record", type=int, help="Record number")
    parser.add_argument("--suppress_values",
                        action="store_true",
                        help="Do not print the values of substitutions.")
    args = parser.parse_args()

    with Evtx(args.evtx) as evtx:
        print hex_dump(evtx.get_record(args.record).data())

        print("record(absolute_offset=%s)" % \
                  (evtx.get_record(args.record).offset()))
        print describe_root(evtx.get_record(args.record),
                            evtx.get_record(args.record).root(),
                            suppress_values=args.suppress_values)
        print evtx_record_xml_view(evtx.get_record(args.record))
def extract_chunk(buf, offset, state, templates):
    """
    Parse an EVTX chunk
      updating the State with new valid records, and
      extracting the templates into a TemplateDatabase.

    @sideeffect: parameter `templates`
    @sideeffect: parameter `state`

    @type buf: bytestring
    @type offset: int
    @type state: State
    @type templates: TemplateDatabase
    """
    logger.debug("Considering chunk at offset %d", offset)

    chunk = ChunkHeader(buf, offset)

    xml = []
    cache = {}
    for record in chunk.records():
        try:
            offset = record.offset()
            logger.debug("Considering record at offset %d",  offset)
            record_xml = evtx_record_xml_view(record, cache=cache)
            eid = get_eid(record_xml)

            state.add_valid_record(offset, eid, record_xml)

            template = get_template(record, record_xml)
            templates.add_template(template)
        except UnicodeEncodeError:
            logger.info("Unicode encoding issue processing record at %s" % \
                        hex(record.offset()))
            continue
        except UnicodeDecodeError:
            logger.info("Unicode decoding issue processing record at %s" % \
                        hex(record.offset()))
            continue
        except InvalidRecordException:
            logger.info("EVTX parsing issue processing record at %s" % \
                        hex(record.offset()))
            continue
        except Exception as e:
            logger.info("Unknown exception processing record at %s: %s" % \
                        (hex(record.offset()), str(e)))
            continue
예제 #7
0
def extract_chunk(buf, offset, state, templates):
    """
    Parse an EVTX chunk
      updating the State with new valid records, and
      extracting the templates into a TemplateDatabase.

    @sideeffect: parameter `templates`
    @sideeffect: parameter `state`

    @type buf: bytestring
    @type offset: int
    @type state: State
    @type templates: TemplateDatabase
    """
    logger.debug("Considering chunk at offset %d", offset)

    chunk = ChunkHeader(buf, offset)

    xml = []
    cache = {}
    for record in chunk.records():
        try:
            offset = record.offset()
            logger.debug("Considering record at offset %d", offset)
            record_xml = evtx_record_xml_view(record, cache=cache)
            eid = get_eid(record_xml)

            state.add_valid_record(offset, eid, record_xml)

            template = get_template(record, record_xml)
            templates.add_template(template)
        except UnicodeEncodeError:
            logger.info("Unicode encoding issue processing record at %s" % \
                        hex(record.offset()))
            continue
        except UnicodeDecodeError:
            logger.info("Unicode decoding issue processing record at %s" % \
                        hex(record.offset()))
            continue
        except InvalidRecordException:
            logger.info("EVTX parsing issue processing record at %s" % \
                        hex(record.offset()))
            continue
        except Exception as e:
            logger.info("Unknown exception processing record at %s: %s" % \
                        (hex(record.offset()), str(e)))
            continue
예제 #8
0
    def getRecord(self, filename, record_number):
        #         parser = argparse.ArgumentParser(
        #             description="Write the raw data for a EVTX record to STDOUT")
        #         parser.add_argument("evtx", type=str,
        #                             help="Path to the Windows EVTX file")
        #         parser.add_argument("record", type=int,
        #                             help="The record number of the record to extract")
        #         args = parser.parse_args()
        if(os.name == 'posix'):
            log_dir = log_dir_linux
        else:
            log_dir = log_dir_windows
        with Evtx(os.path.join(log_dir, filename)) as evtx:
            record = evtx.get_record(record_number)

            if record is None:
                raise RuntimeError("Cannot find the record specified.")
#             sys.stdout.write(record.data())
            record_str = evtx_record_xml_view(record)
#             print record_str
            return record_str
예제 #9
0
def main():
    import argparse

    parser = argparse.ArgumentParser(
        description="Extract a single EVTX record and pretty print it.")
    parser.add_argument("evtx", type=str,
                        help="Path to the Windows EVTX file")
    parser.add_argument("record", type=int,
                        help="The record number of the record to extract")
    args = parser.parse_args()

    with Evtx(args.evtx) as evtx:
        record = evtx.get_record(args.record)
        if record is None:
            raise RuntimeError("Cannot find the record specified.")

        try:
            print prettify_xml("<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\" ?>\n%s" % evtx_record_xml_view(record))
        except ExpatError as e:
            print "Exception: "
            print repr(e)
            print ""
            print ""
            print "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\" ?>\n%s" % evtx_record_xml_view(record)
예제 #10
0
def main():
  args = parse_cli_arguments()

  print
  print("Reading records from {}...".format(args.input_path.name))

  # try to create a temporary copy of the evtx file
  corrected_file = temp_evtx_copy(args.input_path)

  if not corrected_file:
    print("Could not create temporary file!")
    exit(1)
  else:
    offsets_restored_records = []

    # Loop through corrected file until no changes are needed anymore
    file_ready = False
    while not file_ready:
      # No changes made (since last loop)
      corrected = False

      # loop over the records inside the evtx file
      for record in read_evtx_records(corrected_file):
        # Retrieve the complete contents of this record.
        record_data = record.data()

        # Deleted records are not actually deleted, but are still
        # present within the content of the preceeding record.
        # This is easily spotted by checking for the magic value
        # of a record within the record data.

        # We start searching at the end of the header
        start_pos = 24
        while not corrected:
          magic_pos = record_data.find('\x2a\x2a\x00\x00', start_pos,
                                       record.size() - 28)
          if magic_pos == -1:
            # No magic found
            break
          else:
            # Magic found; this could be a record.
            # If this is in fact a deleted record, a copy the
            # record size of the preceeding record is present
            # just before the magic of the deleted record. We would
            # find the size of the deleted record just after
            # the magic. The position where we found the magic is
            # also the old size of the record.
            cur_size = record.size()
            (old_size,) = unpack('I', record_data[(magic_pos - 4)
                          :magic_pos])
            (del_size,) = unpack('I', record_data[(magic_pos + 4)
                          :(magic_pos + 8)])

            if magic_pos == old_size and \
                            (del_size + old_size) == record.size():
              print(
                'Found a deleted record within record number {}'
                ' at offset 0x{:04X}').format(
                record.record_num(),
                magic_pos)

              # Flag
              corrected = True
              # Restore original size
              corrected_file.seek(record.offset() + 4)
              corrected_file.write(pack('I', old_size))
              # Restore deleted size
              corrected_file.seek(record.offset() + cur_size - 4)
              corrected_file.write(pack('I', del_size))
              # Remember that we restored a record on this offset
              offsets_restored_records.append(
                old_size + record.offset())

            # Find next
            start_pos = magic_pos + 1

      if not corrected:
        file_ready = True
      # Else: if a correction was made, we need to
      # go back and start over,
      # as more records may have been deleted.

    # Dump corrected record
    if args.output_path:
      corrected_file.seek(0)
      with closing(mmap(corrected_file.fileno(), 0, \
                        access=ACCESS_READ)) as buf:
        args.output_path.write(buf)

    # Print all records for which we found a deleted record
    if offsets_restored_records:
      corrected_file.seek(0)
      with closing(mmap(corrected_file.fileno(), 0, \
                        access=ACCESS_READ)) as buf:

        # We simply open the corrected file and enumerate the records
        #  until we found a record which starts on the offset that we
        #  have remembered.
        fh = FileHeader(buf, 0x0)
        for chunk in fh.chunks():
          for record in chunk.records():

            if record.offset() in offsets_restored_records:
              xml = evtx_record_xml_view(record)

              # Export record in XML
              if args.export_path:
                args.export_path.write(xml)

    print