def write_monitor_config(self, interest=None, nosleepskip=False): config_path = format(os.getcwd()) + "\\dll\\%s.ini" % self.pid log.info("Monitor config for process %s: %s", self.pid, config_path) with open(config_path, "w", encoding="utf-8") as config: # start the logserver for this monitored process logserver_path = LOGSERVER_PREFIX + str(self.pid) if logserver_path not in LOGSERVER_POOL: LOGSERVER_POOL[logserver_path] = LogServer( self.config.ip, self.config.port, logserver_path) if "tlsdump" not in self.options: Process.process_num += 1 firstproc = Process.process_num == 1 config.write("host-ip={0}\n".format(self.config.ip)) config.write("host-port={0}\n".format(self.config.port)) config.write("pipe={0}\n".format(PIPE)) config.write("logserver={0}\n".format(logserver_path)) config.write("results={0}\n".format(PATHS["root"])) config.write("analyzer={0}\n".format(os.getcwd())) config.write("pythonpath={0}\n".format( os.path.dirname(sys.executable))) config.write( "first-process={0}\n".format("1" if firstproc else "0")) config.write("startup-time={0}\n".format(Process.startup_time)) config.write("file-of-interest={0}\n".format(interest)) config.write("shutdown-mutex={0}\n".format(SHUTDOWN_MUTEX)) config.write("terminate-event={0}{1}\n".format( TERMINATE_EVENT, self.pid)) if nosleepskip or ("force-sleepskip" not in self.options and len(interest) > 2 and interest[1] != ":" and interest[0] != "\\" and Process.process_num <= 2): config.write("force-sleepskip=0\n") if "norefer" not in self.options and "referrer" not in self.options: config.write("referrer={0}\n".format( get_referrer_url(interest))) server_options = [ "disable_cape", "dll", "dll_64", "loader", "loader_64", "route", "nohuman", "unpack", "main_task_id", "auto", ] for optname, option in self.options.items(): if optname not in server_options: config.write("{0}={1}\n".format(optname, option)) log.info("Option '%s' with value '%s' sent to monitor", optname, option)
def write_monitor_config(self, interest=None, nosleepskip=False): config_path = os.path.join(os.getcwd(), "dll", f"{self.pid}.ini") log.info("Monitor config for process %s: %s", self.pid, config_path) # start the logserver for this monitored process logserver_path = f"{LOGSERVER_PREFIX}{self.pid}" if logserver_path not in LOGSERVER_POOL: LOGSERVER_POOL[logserver_path] = LogServer(self.config.ip, self.config.port, logserver_path) if "tlsdump" not in self.options: Process.process_num += 1 firstproc = Process.process_num == 1 with open(config_path, "w", encoding="utf-8") as config: config.write(f"host-ip={self.config.ip}\n") config.write(f"host-port={self.config.port}\n") config.write(f"pipe={PIPE}\n") config.write(f"logserver={logserver_path}\n") config.write(f"results={PATHS['root']}\n") config.write(f"analyzer={os.getcwd()}\n") config.write(f"pythonpath={os.path.dirname(sys.executable)}\n") config.write(f"first-process={1 if firstproc else 0}\n") config.write(f"startup-time={Process.startup_time}\n") config.write(f"file-of-interest={interest}\n") config.write(f"shutdown-mutex={SHUTDOWN_MUTEX}\n") config.write(f"terminate-event={TERMINATE_EVENT}{self.pid}\n") if nosleepskip or ("force-sleepskip" not in self.options and len(interest) > 2 and interest[:2] != "\\:" and Process.process_num <= 2): config.write("force-sleepskip=0\n") if "norefer" not in self.options and "referrer" not in self.options: config.write(f"referrer={get_referrer_url(interest)}\n") server_options = [ "disable_cape", "dll", "dll_64", "loader", "loader_64", "route", "nohuman", "main_task_id", "auto", "pre_script_args", "pre_script_timeout", "during_script_args", ] for optname, option in self.options.items(): if optname not in server_options: config.write(f"{optname}={option}\n") log.info("Option '%s' with value '%s' sent to monitor", optname, option)
def write_monitor_config(self, interest=None, nosleepskip=False): config_path = "C:\\%s.ini" % self.pid with open(config_path, "w") as config: # start the logserver for this monitored process logserver_path = LOGSERVER_PREFIX + str(self.pid) if logserver_path not in LOGSERVER_POOL: LOGSERVER_POOL[logserver_path] = LogServer( self.config.ip, self.config.port, logserver_path) Process.process_num += 1 firstproc = Process.process_num == 1 config.write("host-ip={0}\n".format(self.config.ip)) config.write("host-port={0}\n".format(self.config.port)) config.write("pipe={0}\n".format(PIPE)) config.write("logserver={0}\n".format(logserver_path)) config.write("results={0}\n".format(PATHS["root"])) config.write("analyzer={0}\n".format(os.getcwd())) config.write( "first-process={0}\n".format("1" if firstproc else "0")) config.write("startup-time={0}\n".format(Process.startup_time)) config.write("file-of-interest={0}\n".format(interest)) config.write("shutdown-mutex={0}\n".format(SHUTDOWN_MUTEX)) config.write("terminate-event={0}{1}\n".format( TERMINATE_EVENT, self.pid)) config.write("terminate-processes={0}\n".format( "1" if self.config.terminate_processes else "0")) if nosleepskip or ("force-sleepskip" not in self.options and len(interest) > 2 and interest[1] != ':' and interest[0] != '\\' and Process.process_num <= 2): config.write("force-sleepskip=0\n") if "norefer" not in self.options and "referrer" not in self.options: config.write("referrer={0}\n".format( get_referrer_url(interest))) server_options = [ "disable_cape", "dll", "dll_64", "loader", "loader_64", "route" ] for optname, option in self.options.items(): if optname not in server_options: config.write("{0}={1}\n".format(optname, option)) log.info("Option '%s' with value '%s' sent to monitor", optname, option)
def write_monitor_config(self, interest=None, nosleepskip=False): config_path = "C:\\%s.ini" % self.pid with open(config_path, "w") as config: # start the logserver for this monitored process logserver_path = LOGSERVER_PREFIX + str(self.pid) if logserver_path not in LOGSERVER_POOL: LOGSERVER_POOL[logserver_path] = LogServer( self.config.ip, self.config.port, logserver_path) Process.process_num += 1 firstproc = Process.process_num == 1 config.write("host-ip={0}\n".format(self.config.ip)) config.write("host-port={0}\n".format(self.config.port)) config.write("pipe={0}\n".format(PIPE)) config.write("logserver={0}\n".format(logserver_path)) config.write("results={0}\n".format(PATHS["root"])) config.write("analyzer={0}\n".format(os.getcwd())) config.write( "first-process={0}\n".format("1" if firstproc else "0")) config.write("startup-time={0}\n".format(Process.startup_time)) config.write("file-of-interest={0}\n".format(interest)) config.write("shutdown-mutex={0}\n".format(SHUTDOWN_MUTEX)) config.write("terminate-event={0}{1}\n".format( TERMINATE_EVENT, self.pid)) if nosleepskip or ("force-sleepskip" not in self.options and len(interest) > 2 and interest[1] != ':' and interest[0] != '\\' and Process.process_num <= 2): config.write("force-sleepskip=0\n") if "norefer" not in self.options and "referrer" not in self.options: config.write("referrer={0}\n".format( get_referrer_url(interest))) simple_optnames = [ "force-sleepskip", "full-logs", "force-flush", "no-stealth", "buffer-max", "large-buffer-max", "referrer", "serial", "sysvol_ctimelow", "sysvol_ctimehigh", "sys32_ctimelow", "sys32_ctimehigh", "debug", "disable_hook_content", "hook-type", "base-on-api", "exclude-apis", "exclude-dlls", "dump-on-api", "bp0", "bp1", "bp2", "bp3", ] for optname in simple_optnames: if optname in self.options: config.write("{0}={1}\n".format(optname, self.options[optname])) log.info("Option '%s' with value '%s' sent to monitor", optname, self.options[optname]) if "procdump" in self.options: config.write("procdump={0}\n".format(self.options["procdump"])) if "import_reconstruction" in self.options: config.write("import_reconstruction={0}\n".format( self.options["import_reconstruction"])) if "CAPE_var1" in self.options: config.write("CAPE_var1={0}\n".format( self.options["CAPE_var1"])) if "CAPE_var2" in self.options: config.write("CAPE_var2={0}\n".format( self.options["CAPE_var2"])) if "CAPE_var3" in self.options: config.write("CAPE_var3={0}\n".format( self.options["CAPE_var3"])) if "CAPE_var4" in self.options: config.write("CAPE_var4={0}\n".format( self.options["CAPE_var4"]))
def inject(self, dll=None, interest=None, nosleepskip=False): """Cuckoo DLL injection. @param dll: Cuckoo DLL path. @param interest: path to file of interest, handed to cuckoomon config @param apc: APC use. """ if not self.pid: log.warning("No valid pid specified, injection aborted") return False thread_id = 0 if self.thread_id: thread_id = self.thread_id if not self.is_alive(): log.warning( "The process with pid %s is not alive, " "injection aborted", self.pid) return False is_64bit = self.is_64bit() if not dll: if is_64bit: dll = "cuckoomon_x64.dll" else: dll = "cuckoomon.dll" dll = randomize_dll(os.path.join("dll", dll)) if not dll or not os.path.exists(dll): log.warning( "No valid DLL specified to be injected in process " "with pid %d, injection aborted.", self.pid) return False config_path = "C:\\%s.ini" % self.pid with open(config_path, "w") as config: cfg = Config("analysis.conf") cfgoptions = cfg.get_options() # start the logserver for this monitored process self.logserver = LogServer(cfg.ip, cfg.port, self.logserver_path) firstproc = Process.first_process config.write("host-ip={0}\n".format(cfg.ip)) config.write("host-port={0}\n".format(cfg.port)) config.write("pipe={0}\n".format(PIPE)) config.write("logserver={0}\n".format(self.logserver_path)) config.write("results={0}\n".format(PATHS["root"])) config.write("analyzer={0}\n".format(os.getcwd())) config.write( "first-process={0}\n".format("1" if firstproc else "0")) config.write("startup-time={0}\n".format(Process.startup_time)) config.write("file-of-interest={0}\n".format(interest)) config.write("shutdown-mutex={0}\n".format(SHUTDOWN_MUTEX)) config.write("terminate-event={0}{1}\n".format( TERMINATE_EVENT, self.pid)) if nosleepskip: config.write("force-sleepskip=0\n") elif "force-sleepskip" in cfgoptions: config.write("force-sleepskip={0}\n".format( cfgoptions["force-sleepskip"])) if "full-logs" in cfgoptions: config.write("full-logs={0}\n".format(cfgoptions["full-logs"])) if "no-stealth" in cfgoptions: config.write("no-stealth={0}\n".format( cfgoptions["no-stealth"])) if firstproc: Process.first_process = False if thread_id or self.suspended: log.debug("Using QueueUserAPC injection.") else: log.debug("Using CreateRemoteThread injection.") bin_name = "" bit_str = "" if is_64bit: bin_name = "bin/loader_x64.exe" bit_str = "64-bit" else: bin_name = "bin/loader.exe" bit_str = "32-bit" if os.path.exists(bin_name): ret = subprocess.call( [bin_name, "inject", str(self.pid), str(thread_id), dll]) if ret != 0: if ret == 1: log.info("Injected into suspended %s process with pid %d", bit_str, self.pid) else: log.error( "Unable to inject into %s process with pid %d, error: %d", bit_str, self.pid, ret) return False else: return True else: log.error( "Please place the %s binary from cuckoomon into analyzer/windows/bin in order to analyze %s binaries.", os.path.basename(bin_name), bit_str) return False
def debug_inject(self, dll=None, interest=None, childprocess=False, nosleepskip=False): """CAPE DLL debugger injection. @param dll: CAPE DLL debugger path. @param interest: path to file of interest, handed to cuckoomon config """ global LOGSERVER_POOL if not self.pid: log.warning("No valid pid specified, injection aborted") return False thread_id = 0 if self.thread_id: thread_id = self.thread_id if not self.is_alive(): log.warning("The process with pid %s is not alive, " "injection aborted", self.pid) return False is_64bit = self.is_64bit() if not dll: log.debug("No debugger DLL has been specified for injection") if is_64bit: dll = CUCKOOMON64_NAME else: dll = CUCKOOMON32_NAME else: dll = os.path.join("dll", dll) log.info("DLL to inject is %s", dll) dll = os.path.join(os.getcwd(), dll) if not dll or not os.path.exists(dll): log.warning("No valid DLL specified to be injected in process " "with pid %d, injection aborted.", self.pid) return False config_path = "C:\\%s.ini" % self.pid with open(config_path, "w") as config: cfg = Config("analysis.conf") cfgoptions = cfg.get_options() # start the logserver for this monitored process logserver_path = LOGSERVER_PREFIX + str(self.pid) if logserver_path not in LOGSERVER_POOL: LOGSERVER_POOL[logserver_path] = LogServer(cfg.ip, cfg.port, logserver_path) Process.process_num += 1 firstproc = Process.process_num == 1 config.write("host-ip={0}\n".format(cfg.ip)) config.write("host-port={0}\n".format(cfg.port)) config.write("pipe={0}\n".format(PIPE)) config.write("logserver={0}\n".format(logserver_path)) config.write("results={0}\n".format(PATHS["root"])) config.write("analyzer={0}\n".format(os.getcwd())) config.write("first-process={0}\n".format("1" if firstproc else "0")) config.write("startup-time={0}\n".format(Process.startup_time)) config.write("file-of-interest={0}\n".format(interest)) config.write("shutdown-mutex={0}\n".format(SHUTDOWN_MUTEX)) config.write("terminate-event={0}{1}\n".format(TERMINATE_EVENT, self.pid)) if nosleepskip: config.write("force-sleepskip=0\n") elif "force-sleepskip" in cfgoptions: config.write("force-sleepskip={0}\n".format(cfgoptions["force-sleepskip"])) if "full-logs" in cfgoptions: config.write("full-logs={0}\n".format(cfgoptions["full-logs"])) if "no-stealth" in cfgoptions: config.write("no-stealth={0}\n".format(cfgoptions["no-stealth"])) if "buffer-max" in cfgoptions: config.write("buffer-max={0}\n".format(cfgoptions["buffer-max"])) if "large-buffer-max" in cfgoptions: config.write("large-buffer-max={0}\n".format(cfgoptions["large-buffer-max"])) if "serial" in cfgoptions: config.write("serial={0}\n".format(cfgoptions["serial"])) if "sysvol_ctimelow" in cfgoptions: config.write("sysvol_ctimelow={0}\n".format(cfgoptions["sysvol_ctimelow"])) if "sysvol_ctimehigh" in cfgoptions: config.write("sysvol_ctimehigh={0}\n".format(cfgoptions["sysvol_ctimehigh"])) if "sys32_ctimelow" in cfgoptions: config.write("sys32_ctimelow={0}\n".format(cfgoptions["sys32_ctimelow"])) if "sys32_ctimehigh" in cfgoptions: config.write("sys32_ctimehigh={0}\n".format(cfgoptions["sys32_ctimehigh"])) if "norefer" not in cfgoptions: config.write("referrer={0}\n".format(get_referrer_url(interest))) if firstproc: Process.first_process = False if "procmemdump" in cfgoptions: config.write("procmemdump={0}\n".format(cfgoptions["procmemdump"])) if "import_reconstruction" in cfgoptions: config.write("import_reconstruction={0}\n".format(cfgoptions["import_reconstruction"])) if "breakpoint" in cfgoptions: config.write("breakpoint={0}\n".format(cfgoptions["breakpoint"])) orig_bin_name = "" bit_str = "" if is_64bit: orig_bin_name = LOADER64_NAME bit_str = "64-bit" else: orig_bin_name = LOADER32_NAME bit_str = "32-bit" bin_name = os.path.join(os.getcwd(), orig_bin_name) if os.path.exists(bin_name) == False: log.error("Please place the %s binary from cuckoomon into analyzer/windows/bin in order to debug %s binaries.", os.path.basename(bin_name), bit_str) return False else: if childprocess == False: ret = subprocess.call([bin_name, "debug_load", str(self.pid), str(thread_id), str(self.h_process), str(self.h_thread), dll]) else: ret = subprocess.call([bin_name, "debug", str(self.pid), str(thread_id), str(self.h_process), str(self.h_thread), dll]) if ret != 0: if ret == 1: log.info("Injected debugger DLL into suspended %s process with pid %d", bit_str, self.pid) else: log.error("Unable to inject debugger DLL into %s process with pid %d, error: %d", bit_str, self.pid, ret) return False else: return True
def inject(self, dll=None, injectmode=INJECT_QUEUEUSERAPC, interest=None, nosleepskip=False): """Cuckoo DLL injection. @param dll: Cuckoo DLL path. @param interest: path to file of interest, handed to cuckoomon config @param apc: APC use. """ global LOGSERVER_POOL if not self.pid: return False thread_id = 0 if self.thread_id: thread_id = self.thread_id if not self.is_alive(): log.warning("The process with pid %s is not alive, " "injection aborted", self.pid) return False is_64bit = self.is_64bit() if not dll: log.debug("No DLL has been specified for injection") if is_64bit: dll = CUCKOOMON64_NAME else: dll = CUCKOOMON32_NAME else: dll = os.path.join("dll", dll) log.info("DLL to inject is %s", dll) dll = os.path.join(os.getcwd(), dll) if not dll or not os.path.exists(dll): log.warning("No valid DLL specified to be injected in process " "with pid %d, injection aborted.", self.pid) return False if thread_id or self.suspended: log.debug("Using QueueUserAPC injection.") else: log.debug("Using CreateRemoteThread injection.") config_path = "C:\\%s.ini" % self.pid with open(config_path, "w") as config: cfg = Config("analysis.conf") cfgoptions = cfg.get_options() # start the logserver for this monitored process logserver_path = LOGSERVER_PREFIX + str(self.pid) if logserver_path not in LOGSERVER_POOL: LOGSERVER_POOL[logserver_path] = LogServer(cfg.ip, cfg.port, logserver_path) Process.process_num += 1 firstproc = Process.process_num == 1 config.write("host-ip={0}\n".format(cfg.ip)) config.write("host-port={0}\n".format(cfg.port)) config.write("pipe={0}\n".format(PIPE)) config.write("logserver={0}\n".format(logserver_path)) config.write("results={0}\n".format(PATHS["root"])) config.write("analyzer={0}\n".format(os.getcwd())) config.write("first-process={0}\n".format("1" if firstproc else "0")) config.write("startup-time={0}\n".format(Process.startup_time)) config.write("file-of-interest={0}\n".format(interest)) config.write("shutdown-mutex={0}\n".format(SHUTDOWN_MUTEX)) config.write("terminate-event={0}{1}\n".format(TERMINATE_EVENT, self.pid)) if nosleepskip or ("force-sleepskip" not in cfgoptions and len(interest) > 2 and interest[1] != ':' and interest[0] != '\\' and Process.process_num <= 2): config.write("force-sleepskip=0\n") if "norefer" not in cfgoptions and "referrer" not in cfgoptions: config.write("referrer={0}\n".format(get_referrer_url(interest))) simple_optnames = [ "force-sleepskip", "full-logs", "force-flush", "no-stealth", "buffer-max", "large-buffer-max", "serial", "sysvol_ctimelow", "sysvol_ctimehigh", "sys32_ctimelow", "sys32_ctimehigh", "debug", "disable_hook_content", "hook-type", "exclude-apis", "exclude-dlls", "referrer", ] for optname in simple_optnames: if optname in cfgoptions: config.write("{0}={1}\n".format(optname, cfgoptions[optname])) if "procmemdump" in cfgoptions: config.write("procmemdump={0}\n".format(cfgoptions["procmemdump"])) if "import_reconstruction" in cfgoptions: config.write("import_reconstruction={0}\n".format(cfgoptions["import_reconstruction"])) if "breakpoint" in cfgoptions: config.write("breakpoint={0}\n".format(cfgoptions["breakpoint"])) orig_bin_name = "" bit_str = "" if is_64bit: orig_bin_name = LOADER64_NAME bit_str = "64-bit" else: orig_bin_name = LOADER32_NAME bit_str = "32-bit" bin_name = os.path.join(os.getcwd(), orig_bin_name) if os.path.exists(bin_name): if thread_id or self.suspended: ret = subprocess.call([bin_name, "inject", str(self.pid), str(thread_id), dll, str(INJECT_QUEUEUSERAPC)]) else: ret = subprocess.call([bin_name, "inject", str(self.pid), str(thread_id), dll, str(INJECT_CREATEREMOTETHREAD)]) if ret != 0: if ret == 1: log.info("Injected into suspended %s process with pid %d", bit_str, self.pid) else: log.error("Unable to inject into %s process with pid %d, error: %d", bit_str, self.pid, ret) return False else: return True else: log.error("Please place the %s binary from cuckoomon into analyzer/windows/bin in order to analyze %s binaries.", os.path.basename(bin_name), bit_str) return False