예제 #1
0
    def __init__(self, base, config, layered=False, **kwargs):
        addrspace.BaseAddressSpace.__init__(self, base, config, **kwargs)
        self.as_assert(base == None or layered, 'Must be first address space')

        if config.LOPHI_CACHE:
            logger.info("LO-PHI Cache ENABLED.")
            cache_timeout = 1
        else:
            cache_timeout = 0

        if config.LOCATION.startswith("lophi://"):
            location = config.LOCATION[8:]
            self.client = MemorySensorPhysical(location,
                                               cache_timeout=cache_timeout)
        elif config.LOCATION.startswith("vmi://"):
            location = config.LOCATION[6:]
            self.client = MemorySensorVirtual(location,
                                              cache_timeout=cache_timeout)
            self.dtb = self.get_cr3()
        else:
            raise (
                "Not a valid LO-PHI URN. (lophi:// for physical and vmi:// for virtual)"
            )

        self.fname = location
        self.name = location
        self.cache = False
        self.cache_data = {}
        self.address = 0

        if config.RAM_SIZE is None:
            print "ERROR/LO-PHI: No RAM size defined. (e.g. --ram_size=12GB)"
            sys.exit(0)

        self.size = self.parse_byte_amount(config.RAM_SIZE)

        self.config = config

        self._exclusions = sorted(
            [])  # no info about the HW, nothing to exclude
예제 #2
0
    def __init__(self, base, config, layered=False, **kwargs):
        addrspace.BaseAddressSpace.__init__(self, base, config, **kwargs)
        self.as_assert(base == None or layered, 'Must be first address space')
        
        if config.LOPHI_CACHE:
            logger.info("LO-PHI Cache ENABLED.")
            cache_timeout = 1
        else:
            cache_timeout = 0
        
        if config.LOCATION.startswith("lophi://"):
            location = config.LOCATION[8:]
            self.client = MemorySensorPhysical(location,
                                               cache_timeout=cache_timeout)
        elif config.LOCATION.startswith("vmi://"):
            location = config.LOCATION[6:]
            self.client = MemorySensorVirtual(location,
                                              cache_timeout=cache_timeout)
            self.dtb = self.get_cr3()
        else:
            raise("Not a valid LO-PHI URN. (lophi:// for physical and vmi:// for virtual)")
            
        self.fname = location
        self.name = location
        self.cache = False
        self.cache_data = {}
        self.address = 0
        
        
        if config.RAM_SIZE is None:
            print "ERROR/LO-PHI: No RAM size defined. (e.g. --ram_size=12GB)"
            sys.exit(0)

        self.size  = self.parse_byte_amount(config.RAM_SIZE)
        
        self.config = config
        
        self._exclusions = sorted([]) # no info about the HW, nothing to exclude
예제 #3
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)
예제 #4
0
class LoPhiAddressSpace(addrspace.BaseAddressSpace):
    """Address space for using LO-PHI memory sensor.
     Mediates requests for the contents of a physical address and length
     through the network to a LO-PHI memory device.
     This is selected for locations of type 'lophi://hostname-or-IPv4'"""

    order = 98

    def __init__(self, base, config, layered=False, **kwargs):
        addrspace.BaseAddressSpace.__init__(self, base, config, **kwargs)
        self.as_assert(base == None or layered, 'Must be first address space')

        if config.LOPHI_CACHE:
            logger.info("LO-PHI Cache ENABLED.")
            cache_timeout = 1
        else:
            cache_timeout = 0

        if config.LOCATION.startswith("lophi://"):
            location = config.LOCATION[8:]
            self.client = MemorySensorPhysical(location,
                                               cache_timeout=cache_timeout)
        elif config.LOCATION.startswith("vmi://"):
            location = config.LOCATION[6:]
            self.client = MemorySensorVirtual(location,
                                              cache_timeout=cache_timeout)
            self.dtb = self.get_cr3()
        else:
            raise (
                "Not a valid LO-PHI URN. (lophi:// for physical and vmi:// for virtual)"
            )

        self.fname = location
        self.name = location
        self.cache = False
        self.cache_data = {}
        self.address = 0

        if config.RAM_SIZE is None:
            print "ERROR/LO-PHI: No RAM size defined. (e.g. --ram_size=12GB)"
            sys.exit(0)

        self.size = self.parse_byte_amount(config.RAM_SIZE)

        self.config = config

        self._exclusions = sorted(
            [])  # no info about the HW, nothing to exclude

    def set_cache(self, status):
        """
            Enable/Disable caching
            
        """
        self.cache = status

        if status == False:
            self.cache_data = {}

    def read(self, addr, length):
        """
            Read data from memory
            
            @param addr: Address to read from
            @param lengt: Length of data to read
        """
        return self.client.read(addr, length)

    def write(self, addr, data):
        """
            Write data to memory
            
            @param addr: Address to write to
            @param data: Data to write to memory 
        """
        nbytes = self.vmi.write_pa(addr, data)
        if nbytes != len(data):
            return False
        return True

    def get_cr3(self):
        """
            Return cr3 value with virtual sensor only
        """
        if isinstance(self.client, MemorySensorVirtual):
            return self.client.get_vcpureg("cr3", 0)
        else:
            return None

    """
        Unsure what all of these do, but Josh implement them.
        Leaving them to investigate later.
        
    """

    @staticmethod
    def register_options(config):
        config.add_option(
            "RETRIES",
            type='int',
            default=5,
            help="Maximum attempts to retry a timed-out LO-PHI request")

        config.add_option("TIMEOUT",
                          type='float',
                          default=0.5,
                          help="Timeout period for LO-PHI read operations")

        config.add_option(
            "RAM_SIZE",
            type='string',
            help=
            "Amount of RAM in the target device. This is used to bound scans."
            " Units can be bytes, or KB with 'K' or 'KB' suffix, MB with 'M' or 'MB' "
            "suffix, or GB with 'G' or 'GB' suffix.")
        config.add_option("LOPHI_CACHE",
                          type='int',
                          default=False,
                          help="Enable caching for LO-PHI.")
        # There are no kibibytes, mebibytes, or gibibytes in this program.

    @staticmethod
    def parse_byte_amount(spec_string):

        if spec_string is None: return None

        spec_string = str(spec_string)

        normalized = spec_string.lower().strip()
        multiplier = 1
        if normalized.endswith('kb') or normalized.endswith('k'):
            multiplier = 1024
        elif normalized.endswith('mb') or normalized.endswith('m'):
            multiplier = 1024 * 1024
        elif normalized.endswith('gb') or normalized.endswith('g'):
            multiplier = 1024 * 1024 * 1024
        if normalized[-1] == 'b':
            normalized = normalized[:-2]
        elif not normalized[-1].isdigit():
            #while not normalized[-1].isdigit():
            normalized = normalized[:-1]

        return int(normalized) * multiplier

    def intervals(self, start, end):
        return [(start, end)]

    def fread(self, len):
        data = self.read(self.address, len)
        self.address += len
        return data

    def zread(self, addr, len):
        return self.read(addr, len)

    def read_long(self, addr):
        string = self.read(addr, 4)
        (longval, ) = struct.unpack('=L', string)
        return longval

    def get_available_addresses(self):
        yield (0, self.size - 1)

    def is_valid_address(self, addr):
        if addr == None:
            return False
        return self.size is None or addr < self.size

    def close(self):
        #self.fhandle.close()
        pass

    def subscribe(self, startaddr, endaddr, data, threadclass):
        return self.client.subscribe_api(startaddr, endaddr, data, threadclass)
예제 #5
0
class LoPhiAddressSpace(addrspace.BaseAddressSpace):
    """Address space for using LO-PHI memory sensor.
     Mediates requests for the contents of a physical address and length
     through the network to a LO-PHI memory device.
     This is selected for locations of type 'lophi://hostname-or-IPv4'"""

    order = 98
    def __init__(self, base, config, layered=False, **kwargs):
        addrspace.BaseAddressSpace.__init__(self, base, config, **kwargs)
        self.as_assert(base == None or layered, 'Must be first address space')
        
        if config.LOPHI_CACHE:
            logger.info("LO-PHI Cache ENABLED.")
            cache_timeout = 1
        else:
            cache_timeout = 0
        
        if config.LOCATION.startswith("lophi://"):
            location = config.LOCATION[8:]
            self.client = MemorySensorPhysical(location,
                                               cache_timeout=cache_timeout)
        elif config.LOCATION.startswith("vmi://"):
            location = config.LOCATION[6:]
            self.client = MemorySensorVirtual(location,
                                              cache_timeout=cache_timeout)
            self.dtb = self.get_cr3()
        else:
            raise("Not a valid LO-PHI URN. (lophi:// for physical and vmi:// for virtual)")
            
        self.fname = location
        self.name = location
        self.cache = False
        self.cache_data = {}
        self.address = 0
        
        
        if config.RAM_SIZE is None:
            print "ERROR/LO-PHI: No RAM size defined. (e.g. --ram_size=12GB)"
            sys.exit(0)

        self.size  = self.parse_byte_amount(config.RAM_SIZE)
        
        self.config = config
        
        self._exclusions = sorted([]) # no info about the HW, nothing to exclude

    def set_cache(self,status):
        """
            Enable/Disable caching
            
        """
        self.cache = status
        
        if status == False:
            self.cache_data = {}

    def read(self, addr, length):
        """
            Read data from memory
            
            @param addr: Address to read from
            @param lengt: Length of data to read
        """
        return self.client.read(addr,length)

    def write(self, addr, data):
        """
            Write data to memory
            
            @param addr: Address to write to
            @param data: Data to write to memory 
        """
        nbytes = self.vmi.write_pa(addr, data)
        if nbytes != len(data):
            return False
        return True


    def get_cr3(self):
        """
            Return cr3 value with virtual sensor only
        """
        if isinstance(self.client,MemorySensorVirtual):
            return self.client.get_vcpureg("cr3", 0);
        else:
            return None


    """
        Unsure what all of these do, but Josh implement them.
        Leaving them to investigate later.
        
    """
    @staticmethod
    def register_options(config):
        config.add_option("RETRIES", type = 'int', default = 5,
              help = "Maximum attempts to retry a timed-out LO-PHI request")

        config.add_option("TIMEOUT", type = 'float', default = 0.5,
              help = "Timeout period for LO-PHI read operations")

        config.add_option("RAM_SIZE", type = 'string',
              help = "Amount of RAM in the target device. This is used to bound scans."
              " Units can be bytes, or KB with 'K' or 'KB' suffix, MB with 'M' or 'MB' "
              "suffix, or GB with 'G' or 'GB' suffix.")
        config.add_option("LOPHI_CACHE", type = 'int', default = False,
                          help="Enable caching for LO-PHI.")
            # There are no kibibytes, mebibytes, or gibibytes in this program.

    @staticmethod
    def parse_byte_amount(spec_string):
        
        if spec_string is None: return None
        
        spec_string = str(spec_string)
        
        normalized = spec_string.lower().strip()
        multiplier = 1
        if normalized.endswith ('kb') or normalized.endswith('k'):
            multiplier = 1024
        elif normalized.endswith('mb') or normalized.endswith('m'):
            multiplier = 1024*1024
        elif normalized.endswith('gb') or normalized.endswith('g'):
            multiplier = 1024*1024*1024
        if normalized[-1] == 'b':
            normalized = normalized[:-2]
        elif not normalized[-1].isdigit():
        #while not normalized[-1].isdigit():
            normalized = normalized[:-1]
        
        return int(normalized) * multiplier

    def intervals(self, start, end):
        return [(start,end)]

    def fread(self,len):
        data = self.read(self.address,len)
        self.address += len
        return data

    
    def zread(self, addr, len):
        return self.read(addr, len)

    def read_long(self, addr):
        string = self.read(addr, 4)
        (longval, ) =  struct.unpack('=L', string)
        return longval

    def get_available_addresses(self):
        yield (0,self.size -1)

    def is_valid_address(self, addr):
        if addr == None:
            return False
        return self.size is None or addr < self.size

    def close(self):
        #self.fhandle.close()
        pass

    def subscribe(self, startaddr, endaddr, data, threadclass):
        return self.client.subscribe_api(startaddr, endaddr, data, threadclass)
예제 #6
0
    def __init__(self, vm_name, 
                 vm_type=G.MACHINE_TYPES.KVM, 
                 static_mac=None,
                 memory_size=1073741824,
                 cpu_count=1, 
                 force_new=False,
                 volatility_profile=None,
                 **kargs):
        """
            Initialize 
            
            @param config: Machine configuration object
            @param init_sensors: Initialize all sensors by default
        """
        # Initialize our state variables
        self.type = vm_type
        self.MACHINE_TYPE = vm_type
        
        class MachineConfig():
            # Name
            name = vm_name
            # DISK
            disk = os.path.join(G.DIR_ROOT,G.DIR_VM_OUTPUT,vm_name+".qcow2")
            disk_base = None
            # Config
            vm_config = os.path.join(G.DIR_ROOT,G.DIR_VM_OUTPUT,vm_name+".xml")
            
        config = MachineConfig()
        # MAC
        if static_mac is None:
            config.__dict__['mac_addr'] = self.__get_new_mac()
        else:
            config.__dict__['mac_addr'] = static_mac
        config.__dict__['vm_name'] = vm_name
        config.__dict__['memory_size'] = memory_size
        config.__dict__['cpu_count'] = cpu_count
        config.__dict__['volatility_profile'] = volatility_profile
        

        Machine.__init__(self, config)
        
        # Add all of our sensors
        
        # Control sensor must be added first to interact with libvirt
        self.add_sensor(ControlSensorVirtual(vm_name,vm_type))
        
        # What state are we in?
        state = self.control.get_state()
        
        # UKNOWN is does not exist
        if force_new and state is None:
            self.lophi_init()
        elif state != G.SENSOR_CONTROL.POWER_STATUS.UNKNOWN:
            logger.debug("VM (%s) already exists."%self.config.name)
        
        # Add all of our sensors to this VM
        vm_disk = self.disk_get_filename()
        if vm_disk is not None:
            self.add_sensor(DiskSensorVirtual(vm_disk))
        else:
            self.add_sensor(DiskSensorVirtual(self.config.disk))
        self.add_sensor(CPUSensorVirtual(config.vm_name))
        self.add_sensor(MemorySensorVirtual(config.vm_name))
        
        net_iface = self.network_get_interface()
        if net_iface is not None:
            self.add_sensor(NetworkSensorVirtual(net_iface))
        else:
            logger.warn("No network intface exists for %s"%self.config.vm_name)
            
            
        # Do we need to mutex these accesses?
        self.REQUIRE_MUTEX = False
        if "require_mutex" in kargs and kargs['require_mutex']:
            self.REQUIRE_MUTEX = True

        # Force a completely fresh instance?
        if "force_new" in kargs and kargs['force_new']:
            # Poweroff existing machine
            self.control.power_off()