Example #1
0
def read_disk(options):

    # Setup our log files 
    dcap_filename = options.dcap_file

    # read from the cap file in real time
    reader = CaptureReader(options.dcap_file)

    # Tailing or terminating?
    reader_iter = reader
    if options.tail_enable:
        reader_iter = reader.tail()

    # Loop over all of the dcap contents
    for (timestamp, data) in reader_iter:

        print timestamp
        if options.sensor_type == G.MACHINE_TYPES.PHYSICAL:
            sata_frame = SATAFrame(data)
            print sata_frame
        else:
            disk_sensor_pkt = [DiskSensorPacket(data)]
            print disk_sensor_pkt
def read_disk(options):

    # Setup our log files
    dcap_filename = options.dcap_file

    # read from the cap file in real time
    reader = CaptureReader(options.dcap_file)

    # Tailing or terminating?
    reader_iter = reader
    if options.tail_enable:
        reader_iter = reader.tail()

    # Loop over all of the dcap contents
    for (timestamp, data) in reader_iter:

        print timestamp
        if options.sensor_type == G.MACHINE_TYPES.PHYSICAL:
            sata_frame = SATAFrame(data)
            print sata_frame
        else:
            disk_sensor_pkt = [DiskSensorPacket(data)]
            print disk_sensor_pkt
Example #3
0
def parse_dcap(filename):

    reader = CaptureReader(filename)

    start = None
    end = None

    data_size = 0

    window_data = deque([])
    window_time = deque([])
    window_sum = 0
    max_throughput = 0
    for (ts, data) in reader:

        data_size += len(data)

        # Keep track of timestamps
        if start is None:
            start = ts
        end = ts

        window_sum += len(data)
        window_data.append(len(data))
        window_time.append(ts)

        # Only compute with a certain number of samples
        if len(window_data) >= 10000 and window_time[-1] != window_time[0]:

            throughput = window_sum / (window_time[-1] - window_time[0])

            if throughput > max_throughput:
                max_throughput = throughput

        while len(window_data) >= 1000 and window_time[-1] != window_time[0]:
            data_remove = window_data.popleft()
            window_sum -= data_remove
            window_time.popleft()

    elapsed_time = end - start

    print "Time elapsed: ", elapsed_time
    print "Bytes Read: ", data_size
    print "Avg Rate: ", (data_size / elapsed_time)
    print "Max Rate: ", max_throughput
Example #4
0
def main(options):

    if options.replay_file is not None:
        cap_reader = CaptureReader(options.replay_file)

        for (ts, data) in cap_reader:
            print "Time: ", ts, "s"
            print MemorySensorPacket(data)

        return

    if options.sensor_type == G.MACHINE_TYPES.PHYSICAL:
        client = MemorySensorPhysical(options.target,
                                      cache_timeout=0,
                                      use_threading=False)
    else:
        client = MemorySensorVirtual(options.target)

    READ_SIZE = int(options.read_size)
    start_addr = options.startaddr

    # Create our output file
    try:
        os.makedirs(os.path.dirname(options.output))
    except:
        pass

    try:
        mcap_writer = None
        if options.loop_forever == True:
            logger.debug("Creating capture file.")
            options.output += ".mcap"
            mcap_writer = CaptureWriter(options.output)
            mcap_writer.start()
        else:
            logger.debug("Creating dump file.")
            options.output += ".mfd"
            output_file = open(options.output, "w+")
    except:
        print "ERROR: Could not open output file."
        sys.exit(0)

    # Read memory
    count = 0
    start = time.time()
    sensor_packet = MemorySensorPacket()

    while True:

        try:
            # Get memory from remote system

            # Read memory
            data = client.read(start_addr, READ_SIZE)

            # Write to file?
            if not options.loop_forever:
                output_file.write(data)
            else:
                sensor_packet.address = start_addr
                sensor_packet.data = data
                sensor_packet.length = READ_SIZE
                mcap_writer.put(sensor_packet)

            # Just read once?
            if not options.loop_forever:
                break
            else:
                print "Completed read #%d" % count
                count += 1
        except:
            # Just finish up
            break
    end = time.time()

    # Do we have an mcap file to close?
    if mcap_writer is not None:
        mcap_writer.stop()
    else:
        # Close output file
        output_file.close()

    print "Memory dump (%d bytes) written to %s. Took %s seconds." % (
        len(data), options.output, end - start)
Example #5
0
    def run(self):
        """
            This function will read a raw disk capture and use a scanned disk 
            image to reconstruct the recorded SATA traffic and output the 
            semantic output.
        """

        # copy our disk image to a temporary working image
        self.working_disk_img = os.path.join(self.output_dir, "disk.img.tmp")
        print "* Creating temporary working image from disk scan. (%s)"%self.working_disk_img
        
        # Delete, copy, chmod new file
        try:
            os.unlink(self.working_disk_img)
        except:
            pass
        cmd = "cp --sparse=always %s %s" % (self.disk_img, self.working_disk_img)
        subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE).stdout.read()
        os.chmod(self.working_disk_img, 0755)

        # Set up our semantic bridge
        print "* Parsing disk image %s into our semantic engine... (This may take a while)" % self.working_disk_img
        semantic_engine = SemanticEngineDisk(self.working_disk_img)
  
        # Start processing our dcap
        print "* Processing dcap file %s..." % self.dcap_filename
        # SATA Interpreter
        sata = SATAInterpreter()  
        """
            @TODO Extract sector size from PyTSK
        """
        sata_reconstructor = SATAReconstructor(sector_size=G.SENSOR_DISK.DEFAULT_SECTOR_SIZE)
    
        # read from the cap file in real time
        reader = CaptureReader(self.dcap_filename)

        # Tailing or terminating?
        reader_iter = reader
        if self.tail_enable:
            reader_iter = reader.tail()

        # Loop over all of the dcap contents
        for (timestamp, data) in reader_iter:
            
            if self.sensor_type == G.MACHINE_TYPES.PHYSICAL:
                (header, data) = sata.extract_sata_data(data)

                # deal with SATA NCQ reordering
                disk_sensor_pkts = sata_reconstructor.process_packet(PhysicalPacket(header, data))
            else:
                disk_sensor_pkts = [DiskSensorPacket(data)]
        
            # Process all of our disk packets
            if disk_sensor_pkts:
                for dsp in disk_sensor_pkts:
                    # Skip empty packets
                    if not dsp:
                        continue
      
                    try:
                        fs_operations = semantic_engine.get_access(dsp.sector, 
                                                                   dsp.num_sectors, 
                                                                   dsp.disk_operation, 
                                                                   dsp.data)   
                        self.log_output(timestamp, fs_operations)                   
                               
                    except:
                        logging.exception("Encountered error while trying to bridge semantic gap for this disk access.")
Example #6
0
    def replay(self):
        """
        Replays the raw log of SATA frames (captured as LOPHIPackets),
        bridges the semantic gap and returns human-readable text form
        """

        # copy our disk image to a temporary working image
        self.working_disk_img = os.path.join(self.output_dir, "disk.img.tmp")
        logger.debug("* Creating temporary working image from disk scan. (%s)" % self.working_disk_img)

        # Delete, copy, chmod new file

        try:
            os.unlink(self.working_disk_img)
        except OSError:
            pass
        
        cmd = "cp --sparse=always %s %s" % (self.disk_img, self.working_disk_img)
        subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE).stdout.read()
        os.chmod(self.working_disk_img, 0755)
        
        # Set up our semantic bridge
        logger.debug("* Parsing disk image %s into our semantic engine... (This may take a while)" % self.working_disk_img)
        semantic_engine = SemanticEngineDisk(self.working_disk_img)

        # Start processing our dcap
        logger.debug("* Processing dcap file %s..." % self.dcap_url)
        # SATA Interpreter
        sata = SATAInterpreter()
        """
            @TODO Extract sector size from PyTSK
        """
        sata_reconstructor = SATAReconstructor(sector_size=G.SENSOR_DISK.DEFAULT_SECTOR_SIZE)

        # read from the cap file
        reader = CaptureReader(self.dcap_url)

        # output
        output_log = []

        # Loop over all of the dcap contents
        for (timestamp, data) in reader:

            disk_sensor_pkts = None

            if self.machine_type == G.MACHINE_TYPES.PHYSICAL:
                lophi_packet = type('AnonClass', (object,), { "sata_header": None, "sata_data": None })
                (lophi_packet.sata_header, lophi_packet.sata_data) = sata.extract_sata_data(data)

                if (lophi_packet.sata_header == None or
                    lophi_packet.sata_data == None):
                    logger.warning("Skipping abnormal physical SATA capture packet -- either sata header and/or data is None.")
                    continue

                # deal with SATA NCQ reordering
                disk_sensor_pkts = sata_reconstructor.process_packet(lophi_packet)
            else:
                # logger.debug(DiskSensorPacket(data))
                disk_sensor_pkts = [DiskSensorPacket(data)]

            # Process all of our disk packets
            if disk_sensor_pkts:
                for dsp in disk_sensor_pkts:
                    # Skip empty packets
                    if not dsp:
                        continue

                    try:
                        fs_operations = semantic_engine.get_access(dsp.sector,
                                                                   dsp.num_sectors,
                                                                   dsp.disk_operation,
                                                                   dsp.data)
                        if fs_operations == None:
                            logger.error("Got an operation to sector %s that is outside our disk." % dsp.sector)
                            continue

                        for op in fs_operations:
                            output_log.append(op)

                    except:
                        logging.exception("Encountered error while trying to bridge semantic gap for this disk access.")

        # return value
        fs_dict = {}

        # Consolidate filesystem activity into a set
        # fields should be 'sector', 'op', 'op_type', 'inode', 'filename', 'raw_data', 'semantic_data'
        # try to insert (operation, filename, inode)
        # for duplicates, use a counter
        for fs_operation in output_log:

            sector = fs_operation['sector']
            operation = fs_operation['op']
            operation_type = fs_operation['op_type']
            inode = fs_operation['inode']
            filename = fs_operation['filename']
            raw_data = fs_operation['raw_data']

            ## TODO - look at filesystem stuff for now -- more low level data later?
            # key = (sector, op, raw_data)
            key = (operation_type, filename, inode)

            if key in fs_dict:
                fs_dict[key] += 1
            else:
                fs_dict[key] = 1

        return fs_dict