def execute(self, path, args=None, suspended=False, kernel_analysis=False): """Execute sample process. @param path: sample path. @param args: process args. @param suspended: is suspended. @return: operation status. """ if not os.access(path, os.X_OK): log.error( 'Unable to access file at path "%s", ' "execution aborted", path) return False startup_info = STARTUPINFO() startup_info.cb = sizeof(startup_info) # STARTF_USESHOWWINDOW startup_info.dwFlags = 1 # SW_SHOWNORMAL startup_info.wShowWindow = 1 process_info = PROCESS_INFORMATION() arguments = '"' + path + '" ' if args: arguments += args creation_flags = CREATE_NEW_CONSOLE if suspended: self.suspended = True creation_flags += CREATE_SUSPENDED created = KERNEL32.CreateProcessW(path, arguments, None, None, None, creation_flags, None, os.getenv("TEMP"), byref(startup_info), byref(process_info)) if created: self.pid = process_info.dwProcessId self.h_process = process_info.hProcess self.thread_id = process_info.dwThreadId self.h_thread = process_info.hThread log.info( 'Successfully executed process from path "%s" with ' 'arguments "%s" with pid %d', path, args or "", self.pid) if kernel_analysis: return self.kernel_analyze() return True else: log.error( 'Failed to execute process from path "%s" with ' 'arguments "%s" (Error: %s)', path, args, get_error_string(KERNEL32.GetLastError()), ) return False
def execute(self, path, args=None, suspended=False, kernel_analysis=False): """Execute sample process. @param path: sample path. @param args: process args. @param suspended: is suspended. @return: operation status. """ if not os.access(path, os.X_OK): log.error("Unable to access file at path \"%s\", " "execution aborted", path) return False startup_info = STARTUPINFO() startup_info.cb = sizeof(startup_info) # STARTF_USESHOWWINDOW startup_info.dwFlags = 1 # SW_SHOWNORMAL startup_info.wShowWindow = 1 process_info = PROCESS_INFORMATION() arguments = "\"" + path + "\" " if args: arguments += args creation_flags = CREATE_NEW_CONSOLE if suspended: self.suspended = True creation_flags += CREATE_SUSPENDED created = KERNEL32.CreateProcessA(path, arguments, None, None, None, creation_flags, None, os.getenv("TEMP"), byref(startup_info), byref(process_info)) if created: self.pid = process_info.dwProcessId self.h_process = process_info.hProcess self.thread_id = process_info.dwThreadId self.h_thread = process_info.hThread log.info("Successfully executed process from path \"%s\" with " "arguments \"%s\" with pid %d", path, args or "", self.pid) if kernel_analysis: return self.kernel_analyze() return True else: log.error("Failed to execute process from path \"%s\" with " "arguments \"%s\" (Error: %s)", path, args, get_error_string(KERNEL32.GetLastError())) return False
def create_monitored_process(self, process_path, args=""): """ Creating a new process to monitor by the driver. The process will be created in suspended mode, then after the PID will be sent to the driver for further monitoring. When the driver is done initializing, the process can be resumed. Parameters: process_path (string), the path of the process to create, unicode string. args (unicode), additional arguments to provide to the process Return value: list of process parameters: (h_process, h_thread, pid, tid) """ # Initializations startup_info = STARTUPINFO() startup_info.cb = sizeof(startup_info) startup_info.dwFlags = win32process.STARTF_USESHOWWINDOW startup_info.wShowWindow = win32con.SW_NORMAL KERNEL32.CreateProcessW.errcheck = self.errcheck # assign a callable process_info = PROCESS_INFORMATION() creation_flags = CREATE_NEW_CONSOLE | CREATE_SUSPENDED # Create new process (UNICODE) success = KERNEL32.CreateProcessW(None, "%s %s" % (process_path, args), None, None, None, creation_flags, None, None, # Starting path? ctypes.byref(startup_info), ctypes.byref(process_info)) # Data h_process, h_thread, pid, tid = process_info.hProcess, process_info.hThread, process_info.dwProcessId, process_info.dwThreadId, pid = self._check_preloaded_pid(pid) # Hack to monitor first pid - this process try: self._send_ioctl(self._driver_communication_device, self._ioctl_monitor, str(pid)) pass except Exception, e: error_code = KERNEL32.GetLastError() log.error("Failed monitoring, GLE: [%d]-[%s]", error_code, get_error_string(error_code)) log.error(str(e)) return (False, h_process, h_thread, pid, tid)
def execute(self, path, args=None, suspended=False): """Execute sample process. @param path: sample path. @param args: process args. @param suspended: is suspended. @return: operation status. """ if not os.access(path, os.X_OK): log.error("Unable to access file at path \"%s\", " "execution aborted", path) return False startup_info = STARTUPINFO() startup_info.cb = sizeof(startup_info) process_info = PROCESS_INFORMATION() if args: arguments = "\"" + path + "\" " + args else: arguments = None creation_flags = CREATE_NEW_CONSOLE if suspended: self.suspended = True creation_flags += CREATE_SUSPENDED created = KERNEL32.CreateProcessA(path, arguments, None, None, None, creation_flags, None, os.getenv("TEMP"), byref(startup_info), byref(process_info)) if created: self.pid = process_info.dwProcessId self.h_process = process_info.hProcess self.thread_id = process_info.dwThreadId self.h_thread = process_info.hThread log.info("Successfully executed process from path \"%s\" with " "arguments \"%s\" with pid %d", path, args, self.pid) return True else: log.error("Failed to execute process from path \"%s\" with " "arguments \"%s\" (Error: %s)", path, args, get_error_string(KERNEL32.GetLastError())) return False
def kernel_analyze(self): """zer0m0n kernel analysis """ log.info("Starting kernel analysis") log.info("Installing driver") if is_os_64bit(): sys_file = os.path.join(os.getcwd(), "dll", "zer0m0n_x64.sys") else: sys_file = os.path.join(os.getcwd(), "dll", "zer0m0n.sys") exe_file = os.path.join(os.getcwd(), "dll", "logs_dispatcher.exe") if not sys_file or not exe_file or not os.path.exists(sys_file) or not os.path.exists(exe_file): log.warning("No valid zer0m0n files to be used for process with pid %d, injection aborted", self.pid) return False exe_name = random_string(6) service_name = random_string(6) driver_name = random_string(6) inf_data = '[Version]\r\nSignature = "$Windows NT$"\r\nClass = "ActivityMonitor"\r\nClassGuid = {b86dff51-a31e-4bac-b3cf-e8cfe75c9fc2}\r\nProvider= %Prov%\r\nDriverVer = 22/01/2014,1.0.0.0\r\nCatalogFile = %DriverName%.cat\r\n[DestinationDirs]\r\nDefaultDestDir = 12\r\nMiniFilter.DriverFiles = 12\r\n[DefaultInstall]\r\nOptionDesc = %ServiceDescription%\r\nCopyFiles = MiniFilter.DriverFiles\r\n[DefaultInstall.Services]\r\nAddService = %ServiceName%,,MiniFilter.Service\r\n[DefaultUninstall]\r\nDelFiles = MiniFilter.DriverFiles\r\n[DefaultUninstall.Services]\r\nDelService = %ServiceName%,0x200\r\n[MiniFilter.Service]\r\nDisplayName= %ServiceName%\r\nDescription= %ServiceDescription%\r\nServiceBinary= %12%\\%DriverName%.sys\r\nDependencies = "FltMgr"\r\nServiceType = 2\r\nStartType = 3\r\nErrorControl = 1\r\nLoadOrderGroup = "FSFilter Activity Monitor"\r\nAddReg = MiniFilter.AddRegistry\r\n[MiniFilter.AddRegistry]\r\nHKR,,"DebugFlags",0x00010001 ,0x0\r\nHKR,"Instances","DefaultInstance",0x00000000,%DefaultInstance%\r\nHKR,"Instances\\"%Instance1.Name%,"Altitude",0x00000000,%Instance1.Altitude%\r\nHKR,"Instances\\"%Instance1.Name%,"Flags",0x00010001,%Instance1.Flags%\r\n[MiniFilter.DriverFiles]\r\n%DriverName%.sys\r\n[SourceDisksFiles]\r\n'+driver_name+'.sys = 1,,\r\n[SourceDisksNames]\r\n1 = %DiskId1%,,,\r\n[Strings]\r\n'+'Prov = "'+random_string(8)+'"\r\nServiceDescription = "'+random_string(12)+'"\r\nServiceName = "'+service_name+'"\r\nDriverName = "'+driver_name+'"\r\nDiskId1 = "'+service_name+' Device Installation Disk"\r\nDefaultInstance = "'+service_name+' Instance"\r\nInstance1.Name = "'+service_name+' Instance"\r\nInstance1.Altitude = "370050"\r\nInstance1.Flags = 0x0' new_inf = os.path.join(os.getcwd(), "dll", "{0}.inf".format(service_name)) new_sys = os.path.join(os.getcwd(), "dll", "{0}.sys".format(driver_name)) copy(sys_file, new_sys) new_exe = os.path.join(os.getcwd(), "dll", "{0}.exe".format(exe_name)) copy(exe_file, new_exe) log.info("[-] Driver name : "+new_sys) log.info("[-] Inf name : "+new_inf) log.info("[-] Application name : "+new_exe) log.info("[-] Service : "+service_name) fh = open(new_inf,"w") fh.write(inf_data) fh.close() os_is_64bit = is_os_64bit() if os_is_64bit: wow64 = c_ulong(0) KERNEL32.Wow64DisableWow64FsRedirection(byref(wow64)) os.system('cmd /c "rundll32 setupapi.dll, InstallHinfSection DefaultInstall 132 '+new_inf+'"') os.system("net start "+service_name) si = STARTUPINFO() si.cb = sizeof(si) pi = PROCESS_INFORMATION() cr = CREATE_NEW_CONSOLE ldp = KERNEL32.CreateProcessA(new_exe, None, None, None, None, cr, None, os.getenv("TEMP"), byref(si), byref(pi)) if not ldp: if os_is_64bit: KERNEL32.Wow64RevertWow64FsRedirection(wow64) log.error("Failed starting "+exe_name+".exe.") return False config_path = os.path.join(os.getenv("TEMP"), "%s.ini" % self.pid) with open(config_path, "w") as config: cfg = Config("analysis.conf") 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)) log.info("Sending startup information") hFile = KERNEL32.CreateFileA(PATH_KERNEL_DRIVER, GENERIC_READ|GENERIC_WRITE, 0, None, OPEN_EXISTING, 0, None) if os_is_64bit: KERNEL32.Wow64RevertWow64FsRedirection(wow64) if hFile: p = Process(pid=os.getpid()) ppid = p.get_parent_pid() pid_vboxservice = 0 pid_vboxtray = 0 # get pid of VBoxService.exe and VBoxTray.exe proc_info = PROCESSENTRY32() proc_info.dwSize = sizeof(PROCESSENTRY32) snapshot = KERNEL32.CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0) flag = KERNEL32.Process32First(snapshot, byref(proc_info)) while flag: if proc_info.sz_exeFile == "VBoxService.exe": log.info("VBoxService.exe found !") pid_vboxservice = proc_info.th32ProcessID flag = 0 elif proc_info.sz_exeFile == "VBoxTray.exe": pid_vboxtray = proc_info.th32ProcessID log.info("VBoxTray.exe found !") flag = 0 flag = KERNEL32.Process32Next(snapshot, byref(proc_info)) bytes_returned = c_ulong(0) msg = str(self.pid)+"_"+str(ppid)+"_"+str(os.getpid())+"_"+str(pi.dwProcessId)+"_"+str(pid_vboxservice)+"_"+str(pid_vboxtray)+'\0' KERNEL32.DeviceIoControl(hFile, IOCTL_PID, msg, len(msg), None, 0, byref(bytes_returned), None) msg = os.getcwd()+'\0' KERNEL32.DeviceIoControl(hFile, IOCTL_CUCKOO_PATH, unicode(msg), len(unicode(msg)), None, 0, byref(bytes_returned), None) else: log.warning("Failed to access kernel driver") return True
def kernel_analyze(self): """zer0m0n kernel analysis """ log.info("Starting kernel analysis") log.info("Installing driver") if is_os_64bit(): sys_file = os.path.join(os.getcwd(), "dll", "zer0m0n_x64.sys") else: sys_file = os.path.join(os.getcwd(), "dll", "zer0m0n.sys") exe_file = os.path.join(os.getcwd(), "dll", "logs_dispatcher.exe") if not sys_file or not exe_file or not os.path.exists( sys_file) or not os.path.exists(exe_file): log.warning( "No valid zer0m0n files to be used for process with pid %d, injection aborted", self.pid) return False exe_name = service_name = driver_name = random_string(6) inf_data = ('[Version]\r\n' 'Signature = "$Windows NT$"\r\n' 'Class = "ActivityMonitor"\r\n' 'ClassGuid = {{b86dff51-a31e-4bac-b3cf-e8cfe75c9fc2}}\r\n' 'Provider = %Prov%\r\n' 'DriverVer = 22/01/2014,1.0.0.0\r\n' 'CatalogFile = %DriverName%.cat\r\n' '[DestinationDirs]\r\n' 'DefaultDestDir = 12\r\n' 'MiniFilter.DriverFiles = 12\r\n' '[DefaultInstall]\r\n' 'OptionDesc = %ServiceDescription%\r\n' 'CopyFiles = MiniFilter.DriverFiles\r\n' '[DefaultInstall.Services]\r\n' \ 'AddService = %ServiceName%,,MiniFilter.Service\r\n' '[DefaultUninstall]\r\n' 'DelFiles = MiniFilter.DriverFiles\r\n' '[DefaultUninstall.Services]\r\n' 'DelService = %ServiceName%,0x200\r\n' '[MiniFilter.Service]\r\n' 'DisplayName = %ServiceName%\r\n' 'Description = %ServiceDescription%\r\n' 'ServiceBinary = %12%\\%DriverName%.sys\r\n' 'Dependencies = "FltMgr"\r\n' 'ServiceType = 2\r\n' 'StartType = 3\r\n' 'ErrorControl = 1\r\n' 'LoadOrderGroup = "FSFilter Activity Monitor"\r\n' 'AddReg = MiniFilter.AddRegistry\r\n' '[MiniFilter.AddRegistry]\r\n' 'HKR,,"DebugFlags",0x00010001 ,0x0\r\n' 'HKR,"Instances","DefaultInstance",0x00000000,%DefaultInstance%\r\n' 'HKR,"Instances\\"%Instance1.Name%,"Altitude",0x00000000,%Instance1.Altitude%\r\n' 'HKR,"Instances\\"%Instance1.Name%,"Flags",0x00010001,%Instance1.Flags%\r\n' '[MiniFilter.DriverFiles]\r\n' '%DriverName%.sys\r\n' '[SourceDisksFiles]\r\n' '{driver_name}.sys = 1,,\r\n' '[SourceDisksNames]\r\n' '1 = %DiskId1%,,,\r\n' '[Strings]\r\n' 'Prov = "{random_string8}"\r\n' 'ServiceDescription = "{random_string12}"\r\n' 'ServiceName = "{service_name}"\r\n' 'DriverName = "{driver_name}"\r\n' 'DiskId1 = "{service_name} Device Installation Disk"\r\n' 'DefaultInstance = "{service_name} Instance"\r\n' 'Instance1.Name = "{service_name} Instance"\r\n' 'Instance1.Altitude = "370050"\r\n' 'Instance1.Flags = 0x0' ).format( service_name=service_name, driver_name=driver_name, random_string8=random_string(8), random_string12=random_string(12) ) new_inf = os.path.join(os.getcwd(), "dll", "{0}.inf".format(service_name)) new_sys = os.path.join(os.getcwd(), "dll", "{0}.sys".format(driver_name)) copy(sys_file, new_sys) new_exe = os.path.join(os.getcwd(), "dll", "{0}.exe".format(exe_name)) copy(exe_file, new_exe) log.info("[-] Driver name : " + new_sys) log.info("[-] Inf name : " + new_inf) log.info("[-] Application name : " + new_exe) log.info("[-] Service : " + service_name) fh = open(new_inf, "w") fh.write(inf_data) fh.close() os_is_64bit = is_os_64bit() if os_is_64bit: wow64 = c_ulong(0) KERNEL32.Wow64DisableWow64FsRedirection(byref(wow64)) os.system( 'cmd /c "rundll32 setupapi.dll, InstallHinfSection DefaultInstall 132 ' + new_inf + '"') os.system("net start " + service_name) si = STARTUPINFO() si.cb = sizeof(si) pi = PROCESS_INFORMATION() cr = CREATE_NEW_CONSOLE ldp = KERNEL32.CreateProcessW(new_exe, None, None, None, None, cr, None, os.getenv("TEMP"), byref(si), byref(pi)) if not ldp: if os_is_64bit: KERNEL32.Wow64RevertWow64FsRedirection(wow64) log.error("Failed starting " + exe_name + ".exe.") return False config_path = os.path.join(os.getenv("TEMP"), "%s.ini" % self.pid) with open(config_path, "w") as config: cfg = Config("analysis.conf") 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)) log.info("Sending startup information") hFile = KERNEL32.CreateFileW(PATH_KERNEL_DRIVER, GENERIC_READ | GENERIC_WRITE, 0, None, OPEN_EXISTING, 0, None) if os_is_64bit: KERNEL32.Wow64RevertWow64FsRedirection(wow64) if hFile: p = Process(pid=os.getpid()) ppid = p.get_parent_pid() pid_vboxservice = 0 pid_vboxtray = 0 # get pid of VBoxService.exe and VBoxTray.exe proc_info = PROCESSENTRY32() proc_info.dwSize = sizeof(PROCESSENTRY32) snapshot = KERNEL32.CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0) flag = KERNEL32.Process32First(snapshot, byref(proc_info)) while flag: if proc_info.sz_exeFile == "VBoxService.exe": log.info("VBoxService.exe found !") pid_vboxservice = proc_info.th32ProcessID flag = 0 elif proc_info.sz_exeFile == "VBoxTray.exe": pid_vboxtray = proc_info.th32ProcessID log.info("VBoxTray.exe found !") flag = 0 flag = KERNEL32.Process32Next(snapshot, byref(proc_info)) bytes_returned = c_ulong(0) msg = str(self.pid) + "_" + str(ppid) + "_" + str( os.getpid()) + "_" + str(pi.dwProcessId) + "_" + str( pid_vboxservice) + "_" + str(pid_vboxtray) + '\0' KERNEL32.DeviceIoControl(hFile, IOCTL_PID, msg, len(msg), None, 0, byref(bytes_returned), None) msg = os.getcwd() + '\0' KERNEL32.DeviceIoControl(hFile, IOCTL_CUCKOO_PATH, str(msg, 'utf-8'), len(str(msg, 'utf-8')), None, 0, byref(bytes_returned), None) else: log.warning("Failed to access kernel driver") return True
def execute(self, path, args=None, suspended=False, kernel_analysis=False): """Execute sample process. @param path: sample path. @param args: process args. @param suspended: is suspended. @return: operation status. """ if not os.access(path, os.X_OK): log.error('Unable to access file at path "%s", execution aborted', path) return False startup_info = STARTUPINFO() startup_info.cb = sizeof(startup_info) # STARTF_USESHOWWINDOW startup_info.dwFlags = 1 # SW_SHOWNORMAL startup_info.wShowWindow = 1 process_info = PROCESS_INFORMATION() arguments = f'"{path}" ' if args: arguments += args creation_flags = CREATE_NEW_CONSOLE if suspended: self.suspended = True creation_flags += CREATE_SUSPENDED # Use the custom execution directory if provided, otherwise launch in the same location # where the sample resides (default %TEMP%) if "executiondir" in self.options.keys(): execution_directory = self.options["executiondir"] elif "curdir" in self.options.keys(): execution_directory = self.options["curdir"] else: execution_directory = os.getenv("TEMP") # Try to create the custom directories so that the execution path is deemed valid create_custom_folders(execution_directory) created = KERNEL32.CreateProcessW(path, arguments, None, None, None, creation_flags, None, execution_directory, byref(startup_info), byref(process_info)) if created: self.pid = process_info.dwProcessId self.h_process = process_info.hProcess self.thread_id = process_info.dwThreadId self.h_thread = process_info.hThread log.info( 'Successfully executed process from path "%s" with arguments "%s" with pid %d', path, args or "", self.pid) if kernel_analysis: return self.kernel_analyze() return True else: log.error( 'Failed to execute process from path "%s" with arguments "%s" (Error: %s)', path, args, get_error_string(KERNEL32.GetLastError()), ) return False