def __init__(self, machine, plugins, command_queue=None, output_queue=None, poll_interval=1, debug_vol=False): """ Given a config object, will initialize the SUA thread """ # Init our multiprocess multiprocessing.Process.__init__(self) self.machine = machine self.plugins = plugins self.poll_interval = poll_interval # seconds if self.machine.type == G.MACHINE_TYPES.PHYSICAL: HOST = "lophi://" + self.machine.memory.sensor_ip else: HOST = "vmi://" + self.machine.config.vm_name self.vol = VolatilityWrapper(HOST, self.machine.config.volatility_profile, self.machine.memory_get_size()) self.RUNNING = False self.PAUSED = False self.command_queue = command_queue self.output_queue = output_queue
def analyze_sample(self, url, profile, output_queue, memory_size=1073741824): """ Analyzes a single memory image sample Puts output in output queue """ worker_id = multiprocessing.current_process().name logger.info(worker_id + " Running memory analysis for profile %s" % profile) t0 = time.time() vol_wrapper = VolatilityWrapper(url, profile, memory_size=memory_size) # return structure ret = {} for plugin_name in PLUGINS_TO_USE: try: logger.info("Running plugin: %s" % plugin_name) t1 = time.time() output = vol_wrapper.execute_plugin(plugin_name) t2 = time.time() # add to return structure ret[plugin_name] = output logger.info(worker_id + " ran plugin %s -- %d s." % (plugin_name, t2 - t1)) except Exception as e: logger.error( worker_id + " Error running plugin %s for memory image %s: %s" % (plugin_name, url, str(e))) logger.info(worker_id + " Putting result in output queue") output_queue.put(ret) tf = time.time() logger.info(worker_id + " Memory analysis completed in %d seconds" % (tf - t0))
def main(options, positionals): # Initialize volatility vol = VolatilityWrapper(options.target_uri, options.profile, '2147483648') # 2GB print "* Getting screenshot from memory..." # get our screenshots screenshots = vol.execute_plugin("screenshot") # Dump these to files idx = 0 for session in screenshots['HEADER']: filename = session + ".png" screenshots['DATA'][idx].save(filename, "PNG") print "* Saved %s" % filename idx += 1
def analyze_sample(self, url, profile, output_queue, memory_size=1073741824): """ Analyzes a single memory image sample Puts output in output queue """ worker_id = multiprocessing.current_process().name logger.info(worker_id + " Running memory analysis for profile %s" % profile) t0 = time.time() vol_wrapper = VolatilityWrapper(url, profile, memory_size=memory_size) # return structure ret = {} for plugin_name in PLUGINS_TO_USE: try: logger.info("Running plugin: %s" % plugin_name) t1 = time.time() output = vol_wrapper.execute_plugin(plugin_name) t2 = time.time() # add to return structure ret[plugin_name] = output logger.info(worker_id + " ran plugin %s -- %d s." % (plugin_name, t2 - t1)) except Exception as e: logger.error( worker_id + " Error running plugin %s for memory image %s: %s" % (plugin_name, url, str(e)) ) logger.info(worker_id + " Putting result in output queue") output_queue.put(ret) tf = time.time() logger.info(worker_id + " Memory analysis completed in %d seconds" % (tf - t0))
def screenshot(self,filename,vol_uri=None): """ Screenshot the display of the machine and save it to a file. @param filename: Filename to save screenshot data to. """ save_name = filename+".png" from lophi_semanticgap.memory.volatility_extensions import VolatilityWrapper if vol_uri is None: vol_uri = "lophi://"+self.memory.sensor_ip vol_profile = self.config.volatility_profile vol = VolatilityWrapper(vol_uri, vol_profile, self.memory_get_size()) screenshots = vol.execute_plugin("screenshot") # Loop over the returned sessions and only save the Default one. idx = 0 for session in screenshots['HEADER']: if "Win7" in self.config.volatility_profile: if session == "session_1.WinSta0.Default": screenshots['DATA'][idx].save(save_name,"PNG") logger.debug("Saved Volatility screenshot to %s."%filename) break elif session == "session_0.WinSta0.Default": screenshots['DATA'][idx].save(save_name,"PNG") logger.debug("Saved Volatility screenshot to %s."%filename) break idx += 1 return save_name
def screenshot(self, filename, vol_uri=None): """ Screenshot the display of the machine and save it to a file. @param filename: Filename to save screenshot data to. """ save_name = filename + ".png" from lophi_semanticgap.memory.volatility_extensions import VolatilityWrapper if vol_uri is None: vol_uri = "lophi://" + self.memory.sensor_ip vol_profile = self.config.volatility_profile vol = VolatilityWrapper(vol_uri, vol_profile, self.memory_get_size()) screenshots = vol.execute_plugin("screenshot") # Loop over the returned sessions and only save the Default one. idx = 0 for session in screenshots['HEADER']: if "Win7" in self.config.volatility_profile: if session == "session_1.WinSta0.Default": screenshots['DATA'][idx].save(save_name, "PNG") logger.debug("Saved Volatility screenshot to %s." % filename) break elif session == "session_0.WinSta0.Default": screenshots['DATA'][idx].save(save_name, "PNG") logger.debug("Saved Volatility screenshot to %s." % filename) break idx += 1 return save_name
class VolatilityEngine(multiprocessing.Process): """ This class handles bridging the semantic gap using Volatility. Because of how Volailtity is constructed this will ultimately initalize a new sensor but will use the information from the currently assigned sensor. """ lophi_config = None volatility_config = None init_ok = True def __init__(self, machine, plugins, command_queue=None, output_queue=None, poll_interval=1, debug_vol=False): """ Given a config object, will initialize the SUA thread """ # Init our multiprocess multiprocessing.Process.__init__(self) self.machine = machine self.plugins = plugins self.poll_interval = poll_interval # seconds if self.machine.type == G.MACHINE_TYPES.PHYSICAL: HOST = "lophi://" + self.machine.memory.sensor_ip else: HOST = "vmi://" + self.machine.config.vm_name self.vol = VolatilityWrapper(HOST, self.machine.config.volatility_profile, self.machine.memory_get_size()) self.RUNNING = False self.PAUSED = False self.command_queue = command_queue self.output_queue = output_queue def report_output(self, output): """ This is an abstract function to report output back out control thread. It also handles logging for this particular SUA """ if self.output_queue is not None: self.output_queue.put(output, False) def run(self): """ This thread will initialize every module, and then run them forever at a fixed interval """ # Make sure that modules were selected if len(self.plugins) == 0: print "No modules were selected." return self.RUNNING = True # Loop forever while self.RUNNING: START = time() # Get the command from our controller try : cmd = self.command_queue.get(False).split(" ") logger.debug("Got cmd: %s" % cmd) if cmd[0] == "addmodule": logger.debug("Adding module %s" % cmd[1]) self.plugins.append(cmd[1]) if cmd[0] == "delmodule": logger.debug("Removing module %s" % cmd[1]) self.plugins.remove(cmd[1]) if cmd[0] == G.CTRL_CMD_PAUSE: logger.debug("Pausing analysis") self.PAUSED = True if cmd[0] == G.CTRL_CMD_UNPAUSE: logger.deubg("Resumming Analysis") self.PAUSED = False if cmd[0] == G.CTRL_CMD_KILL or cmd[0] == G.CTRL_CMD_STOP: logger.debug("Got kill command") self.RUNNING = False break except: # Do nothing pass if self.PAUSED: sleep(self.poll_interval) continue try: for plugin_name in self.plugins: # Render out output into the format we want output = self.vol.execute_plugin(plugin_name) # logger.debug("Output: %s"%output) # Report the output back to the control process if output is not None: # We have to append our output specific info for processing output['MODULE'] = plugin_name output['SENSOR'] = self.machine.memory.name output['PROFILE'] = self.machine.config.volatility_profile output['MACHINE'] = self.machine.config.name self.report_output(output) else: logger.error("No data processer exists for %s."%plugin_name) except: logger.error("There was a problem executing modules. Trying to reload address space... (Is the VM Running?)") raise # Wait for X seconds until we poll again elapsed_time = time() - START if elapsed_time < self.poll_interval: sleep(self.poll_interval - elapsed_time) logger.debug("Stopping memory analysis") # Kill process sys.exit(0)