def prepare(self): """Prepare env for analysis.""" # Get SeDebugPrivilege for the Python process. It will be needed in # order to perform the injections. grant_debug_privilege() # Initialize logging. init_logging() # Parse the analysis configuration file generated by the agent. self.config = Config(cfg="analysis.conf") # Pass the configuration through to the Process class. Process.set_config(self.config) # Set virtual machine clock. set_clock(datetime.datetime.strptime( self.config.clock, "%Y%m%dT%H:%M:%S" )) # Set the default DLL to be used for this analysis. self.default_dll = self.config.options.get("dll") # If a pipe name has not set, then generate a random one. if "pipe" in self.config.options: self.config.pipe = "\\\\.\\PIPE\\%s" % self.config.options["pipe"] else: self.config.pipe = "\\\\.\\PIPE\\%s" % random_string(16, 32) # Generate a random name for the logging pipe server. self.config.logpipe = "\\\\.\\PIPE\\%s" % random_string(16, 32) # Initialize and start the Command Handler pipe server. This is going # to be used for communicating with the monitored processes. self.command_pipe = PipeServer(PipeDispatcher, self.config.pipe, message=True, dispatcher=CommandPipeHandler(self)) self.command_pipe.daemon = True self.command_pipe.start() # Initialize and start the Log Pipe Server - the log pipe server will # open up a pipe that monitored processes will use to send logs to # before they head off to the host machine. destination = self.config.ip, self.config.port self.log_pipe_server = PipeServer(PipeForwarder, self.config.logpipe, destination=destination) self.log_pipe_server.daemon = True self.log_pipe_server.start() # We update the target according to its category. If it's a file, then # we store the target path. if self.config.category == "file": self.target = os.path.join(os.environ["TEMP"] + os.sep, self.config.file_name) # If it's a URL, well.. we store the URL. else: self.target = self.config.target
def get_referrer_url(interest): """Get a Google referrer URL @return: URL to be added to the analysis config """ if "://" not in interest: return "" escapedurl = urllib.quote(interest, '') itemidx = str(random.randint(1, 30)) vedstr = "0CCEQfj" + base64.urlsafe_b64encode(random_string(random.randint(5, 8) * 3)) eistr = base64.urlsafe_b64encode(random_string(12)) usgstr = "AFQj" + base64.urlsafe_b64encode(random_string(12)) referrer = "http://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd={0}&ved={1}&url={2}&ei={3}&usg={4}".format(itemidx, vedstr, escapedurl, eistr, usgstr) return referrer
def __init__(self): Driver.__init__(self, "capcom", random_string(16)) if self.is_64bit: self.arch = self.x64() else: self.arch = self.x86() self.mem = self.allocrwx()
def randomize_dll(dll_path): """Randomize DLL name. @return: new DLL path. """ new_dll_name = random_string(6) new_dll_path = os.path.join(os.getcwd(), "dll", "{0}.dll".format(new_dll_name)) try: copy(dll_path, new_dll_path) return new_dll_path except: return dll_path
def randomize_bin(bin_path, ext): """Randomize binary name. @return: new binary path. """ new_bin_name = random_string(6) new_bin_path = os.path.join(os.getcwd(), ext, "{0}.{1}".format(new_bin_name, ext)) try: copy(bin_path, new_bin_path) return new_bin_path except: return bin_path
def start(self, path): cmd_path = self.get_path("cmd.exe") # Create random cmd.exe window title. rand_title = random_string(4, 16) # START syntax. # See: https://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/start.mspx?mfr=true # start ["title"] [/dPath] [/i] [/min] [/max] [{/separate | /shared}] # [{/low | /normal | /high | /realtime | /abovenormal | belownormal}] # [/wait] [/b] [FileName] [parameters] args = ["/c", "start", "/wait", rand_title, path] return self.execute(cmd_path, args=args)
def randomize_dylib(dylib_path): """Randomize dylib name, to prevent easy detection by malware. @return: new dylib path. """ new_dylib_name = random_string(6) # generate a random name # make a path to the random name in the current working directory new_dylib_path = os.path.join(os.getcwd(), "dylib", "{0}.dylib".format(new_dylib_name)) try: # copy the dylib file to the new path in the current working directory copy(dylib_path, new_dylib_path) return new_dylib_path except: #if this fails, just return the old path return dylib_path
def __init__(self, pid=0, h_process=0, thread_id=0, h_thread=0, suspended=False): """@param pid: PID. @param h_process: process handle. @param thread_id: thread id. @param h_thread: thread handle. """ self.pid = pid self.h_process = h_process self.thread_id = thread_id self.h_thread = h_thread self.suspended = suspended self.system_info = SYSTEM_INFO() self.logserver_path = "\\\\.\\PIPE\\" + random_string(8, 12) self.logserver = None
def start(self): dirpath = self.get_path() if not dirpath: return for idx in xrange(random.randint(5, 10)): filename = random_string(10, random.randint(10, 20)) ext = random.choice(self.extensions) filepath = os.path.join(dirpath, "%s.%s" % (filename, ext)) open(filepath, "wb").write(os.urandom(random.randint(30, 999999))) SHELL32.SHAddToRecentDocs(SHARD_PATHA, filepath) set_regkey_full( "HKEY_CURRENT_USER\\Software\\Microsoft\\Office\\12.0\\" "Word\\File MRU\\Item %d" % (idx + 1), "REG_SZ", "[F00000000][T01D1C40000000000]*%s" % filepath, )
def patch_scsi_identifiers(self): types = { "DiskPeripheral": self.HDD_IDENTIFIERS, "CdRomPeripheral": self.CDROM_IDENTIFIERS, } for row in itertools.product([0, 1, 2, 3], [0, 1, 2, 3], [0, 1, 2, 3], [0, 1, 2, 3]): type_ = query_value(HKEY_LOCAL_MACHINE, "HARDWARE\\DEVICEMAP\\Scsi\\Scsi Port %d\\Scsi Bus %d\\Target Id %d\\Logical Unit Id %d" % row, "Type") value = query_value(HKEY_LOCAL_MACHINE, "HARDWARE\\DEVICEMAP\\Scsi\\Scsi Port %d\\Scsi Bus %d\\Target Id %d\\Logical Unit Id %d" % row, "Identifier") if not type_ or not value: continue value = value.lower() if "vbox" in value or "vmware" in value or "qemu" in value or "virtual" in value: if type_ in types: new_value = random.choice(types[type_]) else: log.warning("Unknown SCSI type (%s), disguising it with a random string", type_) new_value = random_string(len(value)) set_regkey(HKEY_LOCAL_MACHINE, "HARDWARE\\DEVICEMAP\\Scsi\\Scsi Port %d\\Scsi Bus %d\\Target Id %d\\Logical Unit Id %d" % row, "Identifier", REG_SZ, new_value)
def start(self): if "USERPROFILE" not in os.environ: raise CuckooError( "Unable to populate recent files as the USERPROFILE " "environment variable is missing." ) desktop = os.path.join(os.environ["USERPROFILE"], "Desktop") for idx in xrange(random.randint(5, 10)): filename = random_string(10, random.randint(10, 20)) ext = random.choice(self.extensions) filepath = os.path.join(desktop, "%s.%s" % (filename, ext)) open(filepath, "wb").write(os.urandom(random.randint(30, 999999))) SHELL32.SHAddToRecentDocs(SHARD_PATHA, filepath) set_regkey_full( "HKEY_CURRENT_USER\\Software\\Microsoft\\Office\\12.0\\" "Word\\File MRU\\Item %d" % (idx + 1), "REG_SZ", "[F00000000][T01D1C40000000000]*%s" % filepath, )
def prepare(self): """Prepare env for analysis.""" # Get SeDebugPrivilege for the Python process. It will be needed in # order to perform the injections. grant_debug_privilege() # Initialize logging. init_logging() # Parse the analysis configuration file generated by the agent. self.config = Config(cfg="analysis.conf") # Pass the configuration through to the Process class. Process.set_config(self.config) # Set virtual machine clock. clock = datetime.strptime(self.config.clock, "%Y%m%dT%H:%M:%S") # Setting date and time. # NOTE: Windows system has only localized commands with date format # following localization settings, so these commands for english date # format cannot work in other localizations. # In addition DATE and TIME commands are blocking if an incorrect # syntax is provided, so an echo trick is used to bypass the input # request and not block analysis. os.system("echo:|date {0}".format(clock.strftime("%m-%d-%y"))) os.system("echo:|time {0}".format(clock.strftime("%H:%M:%S"))) # Set the default DLL to be used for this analysis. self.default_dll = self.config.options.get("dll") # If a pipe name has not set, then generate a random one. if "pipe" in self.config.options: self.config.pipe = "\\\\.\\PIPE\\%s" % self.config.options["pipe"] else: self.config.pipe = "\\\\.\\PIPE\\%s" % random_string(16, 32) # Generate a random name for the logging pipe server. self.config.logpipe = "\\\\.\\PIPE\\%s" % random_string(16, 32) # Initialize and start the Command Handler pipe server. This is going # to be used for communicating with the monitored processes. self.command_pipe = PipeServer(PipeDispatcher, self.config.pipe, message=True, dispatcher=CommandPipeHandler(self)) self.command_pipe.daemon = True self.command_pipe.start() # Initialize and start the Log Pipe Server - the log pipe server will # open up a pipe that monitored processes will use to send logs to # before they head off to the host machine. destination = self.config.ip, self.config.port self.log_pipe_server = PipeServer(PipeForwarder, self.config.logpipe, destination=destination) self.log_pipe_server.daemon = True self.log_pipe_server.start() # We update the target according to its category. If it's a file, then # we store the target path. if self.config.category == "file": self.target = os.path.join(os.environ["TEMP"] + os.sep, self.config.file_name) # If it's a URL, well.. we store the URL. else: self.target = self.config.target
# Copyright (C) 2010-2015 Cuckoo Foundation. # This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org # See the file 'docs/LICENSE' for copying permission. import os from lib.common.rand import random_string ROOT = os.path.join(os.getenv("SystemDrive"), "\\", random_string(6, 10)) PATHS = {"root" : ROOT, "logs" : os.path.join(ROOT, "logs"), "files" : os.path.join(ROOT, "files"), "shots" : os.path.join(ROOT, "shots"), "memory" : os.path.join(ROOT, "memory"), "drop" : os.path.join(ROOT, "drop")} PIPE = "\\\\.\\PIPE\\" + random_string(6, 10) SHUTDOWN_MUTEX = "Global\\" + random_string(6, 10) TERMINATE_EVENT = "Global\\" + random_string(6, 10) CUCKOOMON32_NAME = "dll\\" + random_string(6, 8) + ".dll" CUCKOOMON64_NAME = "dll\\" + random_string(6, 8) + ".dll" LOADER32_NAME = "bin\\" + random_string(7, 7) + ".exe" LOADER64_NAME = "bin\\" + random_string(8, 8) + ".exe"
import os from lib.common.rand import random_string ROOT = os.path.join(os.getenv("HOME"), random_string(6, 10)) PATHS = { "root": ROOT, "logs": os.path.join(ROOT, "logs"), "files": os.path.join(ROOT, "files"), "shots": os.path.join(ROOT, "shots"), "memory": os.path.join(ROOT, "memory"), "drop": os.path.join(ROOT, "drop") } PIPE = os.path.join(os.getenv("TMPDIR"), random_string(6, 10)) SHUTDOWN_MUTEX = "Global/" + random_string(6, 10)
def prepare(self): """Prepare env for analysis.""" # Get SeDebugPrivilege for the Python process. It will be needed in # order to perform the injections. grant_privilege("SeDebugPrivilege") grant_privilege("SeLoadDriverPrivilege") # Initialize logging. init_logging() # Parse the analysis configuration file generated by the agent. self.config = Config(cfg="analysis.conf") # Pass the configuration through to the Process class. Process.set_config(self.config) # Set virtual machine clock. set_clock( datetime.datetime.strptime(self.config.clock, "%Y%m%dT%H:%M:%S")) # Set the default DLL to be used for this analysis. self.default_dll = self.config.options.get("dll") # If a pipe name has not set, then generate a random one. self.config.pipe = self.get_pipe_path( self.config.options.get("pipe", random_string(16, 32))) # Generate a random name for the logging pipe server. self.config.logpipe = self.get_pipe_path(random_string(16, 32)) # Initialize and start the Command Handler pipe server. This is going # to be used for communicating with the monitored processes. self.command_pipe = PipeServer(PipeDispatcher, self.config.pipe, message=True, dispatcher=CommandPipeHandler(self)) self.command_pipe.daemon = True self.command_pipe.start() # Initialize and start the Log Pipe Server - the log pipe server will # open up a pipe that monitored processes will use to send logs to # before they head off to the host machine. destination = self.config.ip, self.config.port self.log_pipe_server = PipeServer(PipeForwarder, self.config.logpipe, destination=destination) self.log_pipe_server.daemon = True self.log_pipe_server.start() # We update the target according to its category. If it's a file, then # we store the target path. if self.config.category == "file": self.target = os.path.join(os.environ["TEMP"], self.config.file_name) elif self.config.category == "archive": zip_path = os.path.join(os.environ["TEMP"], self.config.file_name) zipfile.ZipFile(zip_path).extractall(os.environ["TEMP"]) self.target = os.path.join(os.environ["TEMP"], self.config.options["filename"]) # If it's a URL, well.. we store the URL. else: self.target = self.config.target
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
# Copyright (C) 2010-2015 Cuckoo Foundation. # This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org # See the file 'docs/LICENSE' for copying permission. import os from lib.common.rand import random_string ROOT = os.path.join(os.getenv("SystemDrive"), "\\", random_string(6, 10)) PATHS = {"root" : ROOT, "logs" : os.path.join(ROOT, "logs"), "files" : os.path.join(ROOT, "files"), "shots" : os.path.join(ROOT, "shots"), "memory" : os.path.join(ROOT, "memory"), "drop" : os.path.join(ROOT, "drop")} PIPE = "\\\\.\\PIPE\\" + random_string(6, 10) SHUTDOWN_MUTEX = "Global\\" + random_string(6, 10) TERMINATE_EVENT = "Global\\" + random_string(6, 10) CAPEMON32_NAME = "dll\\" + random_string(6, 8) + ".dll" CAPEMON64_NAME = "dll\\" + random_string(6, 8) + ".dll" LOADER32_NAME = "bin\\" + random_string(7, 7) + ".exe" LOADER64_NAME = "bin\\" + random_string(8, 8) + ".exe" LOGSERVER_PREFIX = "\\\\.\\PIPE\\" + random_string(8, 12)
# Copyright (C) 2014-2016 Cuckoo Foundation. # This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org # See the file 'docs/LICENSE' for copying permission. from __future__ import absolute_import import os import tempfile from lib.common.rand import random_string ROOT = os.path.join(tempfile.gettempdir(), random_string(6, 10)) PATHS = { "root": ROOT, "logs": os.path.join(ROOT, "logs"), "files": os.path.join(ROOT, "files"), "shots": os.path.join(ROOT, "shots"), "memory": os.path.join(ROOT, "memory"), "drop": os.path.join(ROOT, "drop"), }
# This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org # See the file 'docs/LICENSE' for copying permission. import ctypes import logging import struct from lib.common.defines import (KERNEL32, GENERIC_READ, GENERIC_WRITE, FILE_SHARE_READ, FILE_SHARE_WRITE, OPEN_EXISTING) from lib.common.rand import random_string log = logging.getLogger(__name__) # Random name for the zer0m0n driver. driver_name = random_string(16) CTL_CODE_BASE = 0x222000 class Ioctl(object): def __init__(self, pipepath): self.pipepath = pipepath def invoke(self, ctlcode, value, outlength=0x1000): device_handle = KERNEL32.CreateFileA( "\\\\.\\%s" % self.pipepath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, None, OPEN_EXISTING, 0, None) % 2**32 if device_handle == 0xffffffff:
# Copyright (C) 2010-2013 Claudio Guarnieri. # Copyright (C) 2014-2015 Cuckoo Foundation. # This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org # See the file 'docs/LICENSE' for copying permission. from lib.common.rand import random_string SHUTDOWN_MUTEX = "Global\\" + random_string(6, 10)
def set_office_mrus(self): """Adds randomized MRU's to Office software(s). Occasionally used by macros to detect sandbox environments. """ baseOfficeKeyPath = r"Software\Microsoft\Office" installedVersions = list() basePaths = [ "C:\\", "C:\\Windows\\Logs\\", "C:\\Windows\\Temp\\", "C:\\Program Files\\", ] extensions = { "Word": ["doc", "docx", "docm", "rtf"], "Excel": ["xls", "xlsx", "csv"], "PowerPoint": ["ppt", "pptx"], } try: officeKey = OpenKey(HKEY_CURRENT_USER, baseOfficeKeyPath, 0, KEY_READ) for currentKey in range(0, QueryInfoKey(officeKey)[0]): isVersion = True officeVersion = EnumKey(officeKey, currentKey) if "." in officeVersion: for intCheck in officeVersion.split("."): if not intCheck.isdigit(): isVersion = False break if isVersion: installedVersions.append(officeVersion) CloseKey(officeKey) except WindowsError: # Office isn't installed at all return for oVersion in installedVersions: for software in extensions: values = list() mruKeyPath = "" productPath = r"{0}\{1}\{2}".format(baseOfficeKeyPath, oVersion, software) try: productKey = OpenKey(HKEY_CURRENT_USER, productPath, 0, KEY_READ) CloseKey(productKey) mruKeyPath = r"{0}\File MRU".format(productPath) try: mruKey = OpenKey(HKEY_CURRENT_USER, mruKeyPath, 0, KEY_READ) except WindowsError: mruKey = CreateKeyEx(HKEY_CURRENT_USER, mruKeyPath, 0, KEY_READ) displayValue = False for mruKeyInfo in range(0, QueryInfoKey(mruKey)[1]): currentValue = EnumValue(mruKey, mruKeyInfo) if currentValue[0] == "Max Display": displayValue = True values.append(currentValue) CloseKey(mruKey) except WindowsError: # An Office version was found in the registry but the # software (Word/Excel/PowerPoint) was not installed. values = "notinstalled" if values != "notinstalled" and len(values) < 5: mruKey = OpenKey(HKEY_CURRENT_USER, mruKeyPath, 0, KEY_SET_VALUE) if not displayValue: SetValueEx(mruKey, "Max Display", 0, REG_DWORD, 25) for i in range(1, randint(10, 30)): rString = random_string(minimum=11, charset="0123456789ABCDEF") if i % 2: baseId = "T01D1C" + rString else: baseId = "T01D1D" + rString setVal = "[F00000000][{0}][O00000000]*{1}{2}.{3}".format( baseId, basePaths[randint(0, len(basePaths) - 1)], random_string( minimum=3, maximum=15, charset="abcdefghijkLMNOPQURSTUVwxyz_0369"), extensions[software][randint( 0, len(extensions[software]) - 1)]) name = "Item {0}".format(i) SetValueEx(mruKey, name, 0, REG_SZ, setVal) CloseKey(mruKey)
# Copyright (C) 2010-2014 Cuckoo Foundation. # This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org # See the file 'docs/LICENSE' for copying permission. import os from lib.common.rand import random_string ROOT = os.path.join(os.getenv("SystemDrive"), "\\", random_string(6, 10)) PATHS = { "root": ROOT, "logs": os.path.join(ROOT, "logs"), "files": os.path.join(ROOT, "files"), "shots": os.path.join(ROOT, "shots"), "memory": os.path.join(ROOT, "memory"), "drop": os.path.join(ROOT, "drop") } PIPE = "\\\\.\\PIPE\\" + random_string(6, 10)
# Copyright (C) 2010-2015 Cuckoo Foundation. # This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org # See the file 'docs/LICENSE' for copying permission. import os from lib.common.rand import random_string ROOT = os.path.join(os.getenv("SystemDrive"), "\\", random_string(6, 10)) PATHS = { "root": ROOT, "logs": os.path.join(ROOT, "logs"), "files": os.path.join(ROOT, "files"), "shots": os.path.join(ROOT, "shots"), "memory": os.path.join(ROOT, "memory"), "drop": os.path.join(ROOT, "drop") } SHUTDOWN_MUTEX = "Global\\" + random_string(6, 10)
# Copyright (C) 2010-2014 Cuckoo Foundation. # This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org # See the file 'docs/LICENSE' for copying permission. import os from lib.common.rand import random_string ROOT = os.path.join(os.getenv("SystemDrive"), "\\", random_string(6, 10)) PATHS = {"root" : ROOT, "logs" : os.path.join(ROOT, "logs"), "files" : os.path.join(ROOT, "files"), "shots" : os.path.join(ROOT, "shots"), "memory" : os.path.join(ROOT, "memory"), "drop" : os.path.join(ROOT, "drop")} PIPE = "\\\\.\\PIPE\\" + random_string(6, 10)
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 set_office_mrus(self): """Adds randomized MRU's to Office software(s). Occasionally used by macros to detect sandbox environments. """ baseOfficeKeyPath = r"Software\Microsoft\Office" installedVersions = list() basePaths = [ "C:\\", "C:\\Windows\\Logs\\", "C:\\Windows\\Temp\\", "C:\\Program Files\\", ] extensions = { "Word": ["doc", "docx", "docm", "rtf"], "Excel": ["xls", "xlsx", "csv"], "PowerPoint": ["ppt", "pptx"], } try: officeKey = OpenKey(HKEY_CURRENT_USER, baseOfficeKeyPath, 0, KEY_READ) for currentKey in xrange(0, QueryInfoKey(officeKey)[0]): isVersion = True officeVersion = EnumKey(officeKey, currentKey) if "." in officeVersion: for intCheck in officeVersion.split("."): if not intCheck.isdigit(): isVersion = False break if isVersion: installedVersions.append(officeVersion) CloseKey(officeKey) except WindowsError: # Office isn't installed at all return for oVersion in installedVersions: for software in extensions: values = list() mruKeyPath = "" productPath = r"{0}\{1}\{2}".format(baseOfficeKeyPath, oVersion, software) try: productKey = OpenKey(HKEY_CURRENT_USER, productPath, 0, KEY_READ) CloseKey(productKey) mruKeyPath = r"{0}\File MRU".format(productPath) try: mruKey = OpenKey(HKEY_CURRENT_USER, mruKeyPath, 0, KEY_READ) except WindowsError: mruKey = CreateKeyEx(HKEY_CURRENT_USER, mruKeyPath, 0, KEY_READ) displayValue = False for mruKeyInfo in xrange(0, QueryInfoKey(mruKey)[1]): currentValue = EnumValue(mruKey, mruKeyInfo) if currentValue[0] == "Max Display": displayValue = True values.append(currentValue) CloseKey(mruKey) except WindowsError: # An Office version was found in the registry but the # software (Word/Excel/PowerPoint) was not installed. values = "notinstalled" if values != "notinstalled" and len(values) < 5: mruKey = OpenKey(HKEY_CURRENT_USER, mruKeyPath, 0, KEY_SET_VALUE) if not displayValue: SetValueEx(mruKey, "Max Display", 0, REG_DWORD, 25) for i in xrange(1, randint(10, 30)): rString = random_string(minimum=11, charset="0123456789ABCDEF") if i % 2: baseId = "T01D1C" + rString else: baseId = "T01D1D" + rString setVal = "[F00000000][{0}][O00000000]*{1}{2}.{3}".format( baseId, basePaths[randint(0, len(basePaths)-1)], random_string(minimum=3, maximum=15, charset="abcdefghijkLMNOPQURSTUVwxyz_0369"), extensions[software][randint(0, len(extensions[software])-1)]) name = "Item {0}".format(i) SetValueEx(mruKey, name, 0, REG_SZ, setVal) CloseKey(mruKey)
import os from lib.common.rand import random_string ROOT = os.path.join(os.getenv("HOME"), random_string(6, 10)) PATHS = {"root" : ROOT, "logs" : os.path.join(ROOT, "logs"), "files" : os.path.join(ROOT, "files"), "shots" : os.path.join(ROOT, "shots"), "memory" : os.path.join(ROOT, "memory"), "drop" : os.path.join(ROOT, "drop")} PIPE = os.path.join(os.getenv("TMPDIR"), random_string(6, 10)) SHUTDOWN_MUTEX = "Global/" + random_string(6, 10)
# Copyright (C) 2010-2015 Cuckoo Foundation. # This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org # See the file 'docs/LICENSE' for copying permission. import os from lib.common.rand import random_string ROOT = os.path.join(os.getenv("SystemDrive"), "\\", random_string(6, 10)) PATHS = {"root" : ROOT, "logs" : os.path.join(ROOT, "logs"), "files" : os.path.join(ROOT, "files"), "shots" : os.path.join(ROOT, "shots"), "memory" : os.path.join(ROOT, "memory"), "drop" : os.path.join(ROOT, "drop")} PIPE = "\\\\.\\PIPE\\" + random_string(6, 10) SHUTDOWN_MUTEX = "Global\\" + random_string(6, 10) TERMINATE_EVENT = "Global\\" + random_string(6, 10)
# See the file 'docs/LICENSE' for copying permission. import ctypes import logging import struct from lib.common.defines import ( KERNEL32, GENERIC_READ, GENERIC_WRITE, FILE_SHARE_READ, FILE_SHARE_WRITE, OPEN_EXISTING ) from lib.common.rand import random_string log = logging.getLogger(__name__) # Random name for the zer0m0n driver. driver_name = random_string(16) CTL_CODE_BASE = 0x222000 class Ioctl(object): def __init__(self, pipepath): self.pipepath = pipepath def invoke(self, ctlcode, value, outlength=0x1000): device_handle = KERNEL32.CreateFileA( "\\\\.\\%s" % self.pipepath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, None, OPEN_EXISTING, 0, None ) % 2**32 if device_handle == 0xffffffff: # Only report an error if the error is not "name not found",
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 os.path.isfile(sys_file) or not os.path.isfile(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" f"{driver_name}.sys = 1,,\r\n" "[SourceDisksNames]\r\n" "1 = %DiskId1%,,,\r\n" "[Strings]\r\n" f'Prov = "{random_string(8)}"\r\n' f'ServiceDescription = "{random_string(12)}"\r\n' f'ServiceName = "{service_name}"\r\n' f'DriverName = "{driver_name}"\r\n' f'DiskId1 = "{service_name} Device Installation Disk"\r\n' f'DefaultInstance = "{service_name} Instance"\r\n' f'Instance1.Name = "{service_name} Instance"\r\n' 'Instance1.Altitude = "370050"\r\n' "Instance1.Flags = 0x0") new_inf = os.path.join(os.getcwd(), "dll", f"{service_name}.inf") new_sys = os.path.join(os.getcwd(), "dll", f"{driver_name}.sys") copy(sys_file, new_sys) new_exe = os.path.join(os.getcwd(), "dll", f"{exe_name}.exe") copy(exe_file, new_exe) log.info("[-] Driver name : %s", new_sys) log.info("[-] Inf name : %s", new_inf) log.info("[-] Application name : %s", new_exe) log.info("[-] Service : %s", service_name) with open(new_inf, "w") as fh: fh.write(inf_data) os_is_64bit = is_os_64bit() if os_is_64bit: wow64 = c_ulong(0) KERNEL32.Wow64DisableWow64FsRedirection(byref(wow64)) os.system( f'cmd /c "rundll32 setupapi.dll, InstallHinfSection DefaultInstall 132 {new_inf}"' ) os.system(f"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 %s.exe", exe_name) return False config_path = os.path.join(os.getenv("TEMP"), f"{self.pid}.ini") cfg = Config("analysis.conf") with open(config_path, "w") as config: config.write(f"host-ip={cfg.ip}\n") config.write(f"host-port={cfg.port}\n") config.write(f"pipe={PIPE}\n") 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 elif proc_info.sz_exeFile == "VBoxTray.exe": pid_vboxtray = proc_info.th32ProcessID log.info("VBoxTray.exe found!") flag = KERNEL32.Process32Next(snapshot, byref(proc_info)) bytes_returned = c_ulong(0) msg = f"{self.pid}_{ppid}_{os.getpid()}_{pi.dwProcessId}_{pid_vboxservice}_{pid_vboxtray}\0" KERNEL32.DeviceIoControl(hFile, IOCTL_PID, msg, len(msg), None, 0, byref(bytes_returned), None) msg = f"{os.getcwd()}\0" KERNEL32.DeviceIoControl(hFile, IOCTL_CUCKOO_PATH, msg, len(msg), None, 0, byref(bytes_returned), None) else: log.warning("Failed to access kernel driver") return True
# Copyright (C) 2010-2015 Cuckoo Foundation. # This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org # See the file 'docs/LICENSE' for copying permission. import os from lib.common.rand import random_string ROOT = os.path.join(os.getenv("SystemDrive"), "\\", random_string(6, 10)) PATHS = {"root" : ROOT, "logs" : os.path.join(ROOT, "logs"), "files" : os.path.join(ROOT, "files"), "shots" : os.path.join(ROOT, "shots"), "memory" : os.path.join(ROOT, "memory"), "drop" : os.path.join(ROOT, "drop")} SHUTDOWN_MUTEX = "Global\\" + random_string(6, 10)
# Copyright (C) 2010-2015 Cuckoo Foundation. # This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org # See the file 'docs/LICENSE' for copying permission. from __future__ import absolute_import import os from lib.common.rand import random_string ROOT = os.path.join(os.getenv("SystemDrive"), "\\", random_string(6, 10)) PATHS = { "root": ROOT, "logs": os.path.join(ROOT, "logs"), "files": os.path.join(ROOT, "files"), "shots": os.path.join(ROOT, "shots"), "memory": os.path.join(ROOT, "memory"), "drop": os.path.join(ROOT, "drop"), } PIPE = f"\\\\.\\PIPE\\{random_string(6, 10)}" SHUTDOWN_MUTEX = f"Global\\{random_string(6, 10)}" TERMINATE_EVENT = f"Global\\{random_string(6, 10)}" CAPEMON32_NAME = f"dll\\{random_string(6, 8)}.dll" CAPEMON64_NAME = f"dll\\{random_string(6, 8)}.dll" LOADER32_NAME = f"bin\\{random_string(7)}.exe" LOADER64_NAME = f"bin\\{random_string(8)}.exe" LOGSERVER_PREFIX = f"\\\\.\\PIPE\\{random_string(8, 12)}"