예제 #1
0
    def old_inject(self, dll, apc):
        arg = KERNEL32.VirtualAllocEx(self.h_process,
                                      None,
                                      len(dll) + 1,
                                      MEM_RESERVE | MEM_COMMIT,
                                      PAGE_READWRITE)

        if not arg:
            log.error("VirtualAllocEx failed when injecting process with "
                      "pid %d, injection aborted (Error: %s)",
                      self.pid, get_error_string(KERNEL32.GetLastError()))
            return False

        bytes_written = c_int(0)
        if not KERNEL32.WriteProcessMemory(self.h_process,
                                           arg,
                                           dll + "\x00",
                                           len(dll) + 1,
                                           byref(bytes_written)):
            log.error("WriteProcessMemory failed when injecting process with "
                      "pid %d, injection aborted (Error: %s)",
                      self.pid, get_error_string(KERNEL32.GetLastError()))
            return False

        kernel32_handle = KERNEL32.GetModuleHandleA("kernel32.dll")
        load_library = KERNEL32.GetProcAddress(kernel32_handle, "LoadLibraryA")

        if apc or self.suspended:
            if not self.h_thread:
                log.info("No valid thread handle specified for injecting "
                         "process with pid %d, injection aborted.", self.pid)
                return False

            if not KERNEL32.QueueUserAPC(load_library, self.h_thread, arg):
                log.error("QueueUserAPC failed when injecting process with "
                          "pid %d (Error: %s)",
                          self.pid, get_error_string(KERNEL32.GetLastError()))
                return False
        else:
            new_thread_id = c_ulong(0)
            thread_handle = KERNEL32.CreateRemoteThread(self.h_process,
                                                        None,
                                                        0,
                                                        load_library,
                                                        arg,
                                                        0,
                                                        byref(new_thread_id))
            if not thread_handle:
                log.error("CreateRemoteThread failed when injecting process "
                          "with pid %d (Error: %s)",
                          self.pid, get_error_string(KERNEL32.GetLastError()))
                return False
            else:
                KERNEL32.CloseHandle(thread_handle)

        return True
예제 #2
0
    def old_inject(self, dll, apc):
        arg = KERNEL32.VirtualAllocEx(self.h_process,
                                      None,
                                      len(dll) + 1,
                                      MEM_RESERVE | MEM_COMMIT,
                                      PAGE_READWRITE)

        if not arg:
            log.error("VirtualAllocEx failed when injecting process with "
                      "pid %d, injection aborted (Error: %s)",
                      self.pid, get_error_string(KERNEL32.GetLastError()))
            return False

        bytes_written = c_int(0)
        if not KERNEL32.WriteProcessMemory(self.h_process,
                                           arg,
                                           dll + "\x00",
                                           len(dll) + 1,
                                           byref(bytes_written)):
            log.error("WriteProcessMemory failed when injecting process with "
                      "pid %d, injection aborted (Error: %s)",
                      self.pid, get_error_string(KERNEL32.GetLastError()))
            return False

        kernel32_handle = KERNEL32.GetModuleHandleA("kernel32.dll")
        load_library = KERNEL32.GetProcAddress(kernel32_handle, "LoadLibraryA")

        if apc or self.suspended:
            if not self.h_thread:
                log.info("No valid thread handle specified for injecting "
                         "process with pid %d, injection aborted.", self.pid)
                return False

            if not KERNEL32.QueueUserAPC(load_library, self.h_thread, arg):
                log.error("QueueUserAPC failed when injecting process with "
                          "pid %d (Error: %s)",
                          self.pid, get_error_string(KERNEL32.GetLastError()))
                return False
        else:
            new_thread_id = c_ulong(0)
            thread_handle = KERNEL32.CreateRemoteThread(self.h_process,
                                                        None,
                                                        0,
                                                        load_library,
                                                        arg,
                                                        0,
                                                        byref(new_thread_id))
            if not thread_handle:
                log.error("CreateRemoteThread failed when injecting process "
                          "with pid %d (Error: %s)",
                          self.pid, get_error_string(KERNEL32.GetLastError()))
                return False
            else:
                KERNEL32.CloseHandle(thread_handle)

        return True
예제 #3
0
    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
예제 #4
0
    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
예제 #5
0
    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
예제 #6
0
    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,
                                          None,
                                          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
예제 #7
0
    def execute(self,
                path,
                args=None,
                dll=None,
                free=False,
                curdir=None,
                source=None,
                mode=None,
                maximize=False,
                env=None,
                trigger=None):
        """Execute sample process.
        @param path: sample path.
        @param args: process args.
        @param dll: dll path.
        @param free: do not inject our monitor.
        @param curdir: current working directory.
        @param source: process identifier or process name which will
                       become the parent process for the new process.
        @param mode: monitor mode - which functions to instrument.
        @param maximize: whether the GUI should be maximized.
        @param env: environment variables.
        @param trigger: trigger to indicate analysis start
        @return: operation status.
        """
        if not os.access(path, os.X_OK):
            log.error("Unable to access file at path %r, execution aborted!",
                      path)
            return False

        is32bit = self.is32bit(path=path)

        if not dll:
            if is32bit:
                dll = "monitor-x86.dll"
            else:
                dll = "monitor-x64.dll"

        dllpath = os.path.abspath(os.path.join("bin", dll))

        if not os.path.exists(dllpath):
            log.warning("No valid DLL specified to be injected, "
                        "injection aborted.")
            return False

        if source:
            if isinstance(source, (int, long)) or source.isdigit():
                inject_is32bit = self.is32bit(pid=int(source))
            else:
                inject_is32bit = self.is32bit(process_name=source)
        else:
            inject_is32bit = is32bit

        if inject_is32bit:
            inject_exe = os.path.join("bin", "inject-x86.exe")
        else:
            inject_exe = os.path.join("bin", "inject-x64.exe")

        argv = [
            inject_exe,
            "--app",
            self.shortpath(path),
            "--only-start",
        ]

        if args:
            argv += ["--args", self._encode_args(args)]

        if curdir:
            argv += ["--curdir", self.shortpath(curdir)]

        if source:
            if isinstance(source, (int, long)) or source.isdigit():
                argv += ["--from", "%s" % source]
            else:
                argv += ["--from-process", source]

        if maximize:
            argv += ["--maximize"]

        try:
            output = subprocess_checkoutput(argv, env)
            self.pid, self.tid = map(int, output.split())
        except Exception:
            log.error(
                "Failed to execute process from path %r with "
                "arguments %r (Error: %s)", path, argv,
                get_error_string(KERNEL32.GetLastError()))
            return False

        # Report this PID to the kernel driver (if present).
        zer0m0n.addpid(self.pid)

        if is32bit:
            inject_exe = os.path.join("bin", "inject-x86.exe")
        else:
            inject_exe = os.path.join("bin", "inject-x64.exe")

        argv = [
            inject_exe,
            "--resume-thread",
            "--pid",
            "%s" % self.pid,
            "--tid",
            "%s" % self.tid,
        ]

        if free:
            argv.append("--free")
        else:
            argv += [
                "--apc",
                "--dll",
                dllpath,
                "--config",
                self.drop_config(mode=mode, trigger=trigger),
            ]

        try:
            subprocess_checkoutput(argv, env)
        except Exception:
            log.error(
                "Failed to execute process from path %r with "
                "arguments %r (Error: %s)", path, argv,
                get_error_string(KERNEL32.GetLastError()))
            return False

        log.info(
            "Successfully executed process from path %r with "
            "arguments %r and pid %d", path, args or "", self.pid)
        return True
예제 #8
0
파일: process.py 프로젝트: scottydo/cuckoo
    def inject(self, dll=None, apc=False):
        """Cuckoo DLL injection.
        @param dll: Cuckoo DLL path.
        @param apc: APC use.
        """
        if not self.pid:
            log.warning("No valid pid specified, injection aborted")
            return False

        if not self.is_alive():
            log.warning("The process with pid %s is not alive, " "injection aborted", self.pid)
            return False

        if not dll:
            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

        arg = KERNEL32.VirtualAllocEx(self.h_process, None, len(dll) + 1, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE)

        if not arg:
            log.error(
                "VirtualAllocEx failed when injecting process with " "pid %d, injection aborted (Error: %s)",
                self.pid,
                get_error_string(KERNEL32.GetLastError()),
            )
            return False

        bytes_written = c_int(0)
        if not KERNEL32.WriteProcessMemory(self.h_process, arg, dll + "\x00", len(dll) + 1, byref(bytes_written)):
            log.error(
                "WriteProcessMemory failed when injecting process with " "pid %d, injection aborted (Error: %s)",
                self.pid,
                get_error_string(KERNEL32.GetLastError()),
            )
            return False

        kernel32_handle = KERNEL32.GetModuleHandleA("kernel32.dll")
        load_library = KERNEL32.GetProcAddress(kernel32_handle, "LoadLibraryA")

        config_path = os.path.join(os.getenv("TEMP"), "%s.ini" % self.pid)
        with open(config_path, "w") as config:
            cfg = Config("analysis.conf")
            cfgoptions = cfg.get_options()

            # The first time we come up with a random startup-time.
            if Process.first_process:
                # This adds 1 up to 30 times of 20 minutes to the startup
                # time of the process, therefore bypassing anti-vm checks
                # which check whether the VM has only been up for <10 minutes.
                Process.startup_time = random.randint(1, 30) * 20 * 60 * 1000

            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("results={0}\n".format(PATHS["root"]))
            config.write("analyzer={0}\n".format(os.getcwd()))
            config.write("first-process={0}\n".format("1" if Process.first_process else "0"))
            config.write("startup-time={0}\n".format(Process.startup_time))
            config.write("shutdown-mutex={0}\n".format(SHUTDOWN_MUTEX))
            config.write("force-sleepskip={0}\n".format(cfgoptions.get("force-sleepskip", "0")))

            Process.first_process = False

        if apc or self.suspended:
            log.debug("Using QueueUserAPC injection.")
            if not self.h_thread:
                log.info(
                    "No valid thread handle specified for injecting " "process with pid %d, injection aborted.",
                    self.pid,
                )
                return False

            if not KERNEL32.QueueUserAPC(load_library, self.h_thread, arg):
                log.error(
                    "QueueUserAPC failed when injecting process with " "pid %d (Error: %s)",
                    self.pid,
                    get_error_string(KERNEL32.GetLastError()),
                )
                return False
        else:
            event_name = "CuckooEvent%d" % self.pid
            self.event_handle = KERNEL32.CreateEventA(None, False, False, event_name)
            if not self.event_handle:
                log.warning("Unable to create notify event..")
                return False

            log.debug("Using CreateRemoteThread injection.")
            new_thread_id = c_ulong(0)
            thread_handle = KERNEL32.CreateRemoteThread(
                self.h_process, None, 0, load_library, arg, 0, byref(new_thread_id)
            )
            if not thread_handle:
                log.error(
                    "CreateRemoteThread failed when injecting process " "with pid %d (Error: %s)",
                    self.pid,
                    get_error_string(KERNEL32.GetLastError()),
                )
                KERNEL32.CloseHandle(self.event_handle)
                self.event_handle = None
                return False
            else:
                KERNEL32.CloseHandle(thread_handle)

        log.info("Successfully injected process with pid %d." % self.pid)

        return True
예제 #9
0
    def inject(self, dll=None, apc=False):
        """Cuckoo DLL injection.
        @param dll: Cuckoo DLL path.
        @param apc: APC use.
        """
        if not self.pid:
            log.warning("No valid pid specified, injection aborted")
            return False

        if not self.is_alive():
            log.warning(
                "The process with pid %s is not alive, "
                "injection aborted", self.pid)
            return False

        if not dll:
            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

        arg = KERNEL32.VirtualAllocEx(self.h_process, None,
                                      len(dll) + 1, MEM_RESERVE | MEM_COMMIT,
                                      PAGE_READWRITE)

        if not arg:
            log.error(
                "VirtualAllocEx failed when injecting process with "
                "pid %d, injection aborted (Error: %s)", self.pid,
                get_error_string(KERNEL32.GetLastError()))
            return False

        bytes_written = c_int(0)
        if not KERNEL32.WriteProcessMemory(self.h_process, arg, dll + "\x00",
                                           len(dll) + 1, byref(bytes_written)):
            log.error(
                "WriteProcessMemory failed when injecting process with "
                "pid %d, injection aborted (Error: %s)", self.pid,
                get_error_string(KERNEL32.GetLastError()))
            return False

        kernel32_handle = KERNEL32.GetModuleHandleA("kernel32.dll")
        load_library = KERNEL32.GetProcAddress(kernel32_handle, "LoadLibraryA")

        config_path = os.path.join(os.getenv("TEMP"), "%s.ini" % self.pid)
        with open(config_path, "w") as config:
            cfg = Config("analysis.conf")
            cfgoptions = cfg.get_options()

            # The first time we come up with a random startup-time.
            if Process.first_process:
                # This adds 1 up to 30 times of 20 minutes to the startup
                # time of the process, therefore bypassing anti-vm checks
                # which check whether the VM has only been up for <10 minutes.
                Process.startup_time = random.randint(1, 30) * 20 * 60 * 1000

            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("results={0}\n".format(PATHS["root"]))
            config.write("analyzer={0}\n".format(os.getcwd()))
            config.write("first-process={0}\n".format(
                "1" if Process.first_process else "0"))
            config.write("startup-time={0}\n".format(Process.startup_time))
            config.write("shutdown-mutex={0}\n".format(SHUTDOWN_MUTEX))
            config.write("force-sleepskip={0}\n".format(
                cfgoptions.get("force-sleepskip", "0")))

            Process.first_process = False

        if apc or self.suspended:
            log.info("Using QueueUserAPC injection.")
            if not self.h_thread:
                log.info(
                    "No valid thread handle specified for injecting "
                    "process with pid %d, injection aborted.", self.pid)
                return False

            if not KERNEL32.QueueUserAPC(load_library, self.h_thread, arg):
                log.error(
                    "QueueUserAPC failed when injecting process with "
                    "pid %d (Error: %s)", self.pid,
                    get_error_string(KERNEL32.GetLastError()))
                return False
            log.info("Successfully injected process with pid %d." % self.pid)
        else:
            event_name = "CuckooEvent%d" % self.pid
            self.event_handle = KERNEL32.CreateEventA(None, False, False,
                                                      event_name)
            if not self.event_handle:
                log.warning("Unable to create notify event..")
                return False

            log.info("Using CreateRemoteThread injection.")
            new_thread_id = c_ulong(0)
            thread_handle = KERNEL32.CreateRemoteThread(
                self.h_process, None, 0, load_library, arg, 0,
                byref(new_thread_id))
            if not thread_handle:
                log.error(
                    "CreateRemoteThread failed when injecting process "
                    "with pid %d (Error: %s)", self.pid,
                    get_error_string(KERNEL32.GetLastError()))
                KERNEL32.CloseHandle(self.event_handle)
                self.event_handle = None
                return False
            else:
                KERNEL32.CloseHandle(thread_handle)

        return True
예제 #10
0
    def execute(self,
                path,
                args=None,
                dll=None,
                free=False,
                curdir=None,
                source=None,
                mode=None,
                maximize=False):
        """Execute sample process.
        @param path: sample path.
        @param args: process args.
        @param dll: dll path.
        @param free: do not inject our monitor.
        @param curdir: current working directory.
        @param source: process identifier or process name which will
                       become the parent process for the new process.
        @param mode: monitor mode - which functions to instrument.
        @param maximize: whether the GUI should be maximized.
        @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

        is32bit = self.is32bit(path=path)

        if not dll:
            if is32bit:
                dll = "monitor-x86.dll"
            else:
                dll = "monitor-x64.dll"

        dllpath = os.path.abspath(os.path.join("bin", dll))

        if not os.path.exists(dllpath):
            log.warning("No valid DLL specified to be injected, "
                        "injection aborted.")
            return False

        if is32bit:
            inject_exe = os.path.join("bin", "inject-x86.exe")
        else:
            inject_exe = os.path.join("bin", "inject-x64.exe")

        argv = [inject_exe, "--app", self.shortpath(path)]

        if args:
            argv += ["--args", self._encode_args(args)]

        if free:
            argv += ["--free"]
        else:
            argv += [
                "--apc", "--dll", dllpath, "--config",
                self.drop_config(mode=mode)
            ]

        if curdir:
            argv += ["--curdir", self.shortpath(curdir)]

        if source:
            if isinstance(source, (int, long)) or source.isdigit():
                argv += ["--from", "%s" % source]
            else:
                argv += ["--from-process", source]

        if maximize:
            argv += ["--maximize"]

        try:
            self.pid = int(subprocess.check_output(argv))
        except Exception:
            log.error(
                "Failed to execute process from path %r with "
                "arguments %r (Error: %s)", path, argv,
                get_error_string(KERNEL32.GetLastError()))
            return False

        log.info(
            "Successfully executed process from path %r with "
            "arguments %r and pid %d", path, args or "", self.pid)
        return True
예제 #11
0
파일: process.py 프로젝트: psrok1/cuckoo
    def execute(self, path, args=None, dll=None, free=False, curdir=None,
                source=None, mode=None, maximize=False, env=None,
                trigger=None):
        """Execute sample process.
        @param path: sample path.
        @param args: process args.
        @param dll: dll path.
        @param free: do not inject our monitor.
        @param curdir: current working directory.
        @param source: process identifier or process name which will
                       become the parent process for the new process.
        @param mode: monitor mode - which functions to instrument.
        @param maximize: whether the GUI should be maximized.
        @param env: environment variables.
        @param trigger: trigger to indicate analysis start
        @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

        is32bit = self.is32bit(path=path)

        if not dll:
            if is32bit:
                dll = "monitor-x86.dll"
            else:
                dll = "monitor-x64.dll"

        dllpath = os.path.abspath(os.path.join("bin", dll))

        if not os.path.exists(dllpath):
            log.warning("No valid DLL specified to be injected, "
                        "injection aborted.")
            return False

        if source:
            if isinstance(source, (int, long)) or source.isdigit():
                inject_is32bit = self.is32bit(pid=int(source))
            else:
                inject_is32bit = self.is32bit(process_name=source)
        else:
            inject_is32bit = is32bit

        if inject_is32bit:
            inject_exe = os.path.join("bin", "inject-x86.exe")
        else:
            inject_exe = os.path.join("bin", "inject-x64.exe")

        argv = [
            inject_exe,
            "--app", self.shortpath(path),
            "--only-start",
        ]

        if args:
            argv += ["--args", self._encode_args(args)]

        if curdir:
            argv += ["--curdir", self.shortpath(curdir)]

        if source:
            if isinstance(source, (int, long)) or source.isdigit():
                argv += ["--from", "%s" % source]
            else:
                argv += ["--from-process", source]

        if maximize:
            argv += ["--maximize"]

        try:
            output = subprocess_checkoutput(argv, env)
            self.pid, self.tid = map(int, output.split())
        except Exception:
            log.error("Failed to execute process from path %r with "
                      "arguments %r (Error: %s)", path, argv,
                      get_error_string(KERNEL32.GetLastError()))
            return False

        if is32bit:
            inject_exe = os.path.join("bin", "inject-x86.exe")
        else:
            inject_exe = os.path.join("bin", "inject-x64.exe")

        argv = [
            inject_exe,
            "--resume-thread",
            "--pid", "%s" % self.pid,
            "--tid", "%s" % self.tid,
        ]

        if free:
            argv.append("--free")
        else:
            argv += [
                "--apc",
                "--dll", dllpath,
                "--config", self.drop_config(mode=mode, trigger=trigger),
            ]

        try:
            subprocess_checkoutput(argv, env)
        except Exception:
            log.error("Failed to execute process from path %r with "
                      "arguments %r (Error: %s)", path, argv,
                      get_error_string(KERNEL32.GetLastError()))
            return False

        log.info("Successfully executed process from path %r with "
                 "arguments %r and pid %d", path, args or "", self.pid)
        return True
예제 #12
0
파일: process.py 프로젝트: 1malware/dragon
    def inject(self, dll=os.path.join("dll", "cuckoomon.dll"), apc=False):
        """Cuckoo DLL injection.
        @param dll: Cuckoo DLL path.
        @param apc: APC use.
        """
        if self.pid == 0:
            log.warning("No valid pid specified, injection aborted")
            return False

        if not self.is_alive():
            log.warning("The process with pid %d is not alive, injection "
                        "aborted" % self.pid)
            return False

        dll = randomize_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

        arg = KERNEL32.VirtualAllocEx(self.h_process,
                                      None,
                                      len(dll) + 1,
                                      MEM_RESERVE | MEM_COMMIT,
                                      PAGE_READWRITE)

        if not arg:
            log.error("VirtualAllocEx failed when injecting process with "
                      "pid %d, injection aborted (Error: %s)"
                      % (self.pid, get_error_string(KERNEL32.GetLastError())))
            return False

        bytes_written = c_int(0)
        if not KERNEL32.WriteProcessMemory(self.h_process,
                                           arg,
                                           dll + '\x00',
                                           len(dll) + 1,
                                           byref(bytes_written)):
            log.error("WriteProcessMemory failed when injecting process "
                      "with pid %d, injection aborted (Error: %s)"
                      % (self.pid, get_error_string(KERNEL32.GetLastError())))
            return False

        kernel32_handle = KERNEL32.GetModuleHandleA("kernel32.dll")
        load_library = KERNEL32.GetProcAddress(kernel32_handle,
                                               "LoadLibraryA")

        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))
            config.write("results={0}\n".format(PATHS["root"]))
            config.write("analyzer={0}\n".format(os.getcwd()))
            config.write("first-process={0}\n".format(Process.first_process))

            Process.first_process = False

        if apc or self.suspended:
            log.info("Using QueueUserAPC injection")
            if not self.h_thread:
                log.info("No valid thread handle specified for injecting "
                         "process with pid %d, injection aborted" % self.pid)
                return False

            if not KERNEL32.QueueUserAPC(load_library, self.h_thread, arg):
                log.error("QueueUserAPC failed when injecting process "
                          "with pid %d (Error: %s)"
                          % (self.pid,
                             get_error_string(KERNEL32.GetLastError())))
                return False
            log.info("Successfully injected process with pid %d" % self.pid)
        else:
            event_name = 'CuckooEvent%d' % self.pid
            self.event_handle = KERNEL32.CreateEventA(None,
                                                      False,
                                                      False,
                                                      event_name)
            if not self.event_handle:
                log.warning('Unable to create notify event..')
                return False

            log.info("Using CreateRemoteThread injection")
            new_thread_id = c_ulong(0)
            thread_handle = KERNEL32.CreateRemoteThread(self.h_process,
                                                        None,
                                                        0,
                                                        load_library,
                                                        arg,
                                                        0,
                                                        byref(new_thread_id))
            if not thread_handle:
                log.error("CreateRemoteThread failed when injecting " +
                    "process with pid %d (Error: %s)" % (self.pid,
                    get_error_string(KERNEL32.GetLastError())))
                KERNEL32.CloseHandle(self.event_handle)
                self.event_handle = None
                return False
            else:
                KERNEL32.CloseHandle(thread_handle)

        return True
예제 #13
0
    def execute(self, path, args=None, dll=None, free=False, curdir=None,
                source=None):
        """Execute sample process.
        @param path: sample path.
        @param args: process args.
        @param dll: dll path.
        @param free: do not inject our monitor.
        @param curdir: current working directory.
        @param source: process identifier or process name which will
                       become the parent process for the new process.
        @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

        is32bit = self.is32bit(path=path)

        if not dll:
            if is32bit:
                dll = "monitor-x86.dll"
            else:
                dll = "monitor-x64.dll"

        dllpath = os.path.abspath(os.path.join("bin", dll))

        if not os.path.exists(dllpath):
            log.warning("No valid DLL specified to be injected, "
                        "injection aborted.")
            return False

        if is32bit:
            inject_exe = os.path.join("bin", "inject-x86.exe")
        else:
            inject_exe = os.path.join("bin", "inject-x64.exe")

        argv = [inject_exe, "--app", self.shortpath(path)]

        if args:
            argv += ["--args", self._encode_args(args)]

        if free:
            argv += ["--free"]
        else:
            argv += ["--apc", "--dll", dllpath,
                     "--config", self.drop_config()]

        if curdir:
            argv += ["--curdir", self.shortpath(curdir)]

        if source:
            if isinstance(source, (int, long)) or source.isdigit():
                argv += ["--from", "%s" % source]
            else:
                argv += ["--from-process", source]

        try:
            self.pid = int(subprocess.check_output(argv))
        except Exception:
            log.error("Failed to execute process from path %r with "
                      "arguments %r (Error: %s)", path, argv,
                      get_error_string(KERNEL32.GetLastError()))
            return False

        log.info("Successfully executed process from path %r with "
                 "arguments %r with pid %d", path, args or "", self.pid)
        return True
예제 #14
0
    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
예제 #15
0
    def inject(self, dll=os.path.join("dll", "cuckoomon.dll"), apc=False):
        """Cuckoo DLL injection.
        @param dll: Cuckoo DLL path.
        @param apc: APC use.
        """
        if self.pid == 0:
            log.warning("No valid pid specified, injection aborted")
            return False

        if not self.is_alive():
            log.warning("The process with pid %d is not alive, injection "
                        "aborted" % self.pid)
            return False

        dll = randomize_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

        arg = KERNEL32.VirtualAllocEx(self.h_process, None,
                                      len(dll) + 1, MEM_RESERVE | MEM_COMMIT,
                                      PAGE_READWRITE)

        if not arg:
            log.error("VirtualAllocEx failed when injecting process with "
                      "pid %d, injection aborted (Error: %s)" %
                      (self.pid, get_error_string(KERNEL32.GetLastError())))
            return False

        bytes_written = c_int(0)
        if not KERNEL32.WriteProcessMemory(self.h_process, arg, dll + '\x00',
                                           len(dll) + 1, byref(bytes_written)):
            log.error("WriteProcessMemory failed when injecting process "
                      "with pid %d, injection aborted (Error: %s)" %
                      (self.pid, get_error_string(KERNEL32.GetLastError())))
            return False

        kernel32_handle = KERNEL32.GetModuleHandleA("kernel32.dll")
        load_library = KERNEL32.GetProcAddress(kernel32_handle, "LoadLibraryA")

        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))
            config.write("results={0}\n".format(PATHS["root"]))
            config.write("analyzer={0}\n".format(os.getcwd()))
            config.write("first-process={0}\n".format(Process.first_process))

            Process.first_process = False

        if apc or self.suspended:
            log.info("Using QueueUserAPC injection")
            if not self.h_thread:
                log.info("No valid thread handle specified for injecting "
                         "process with pid %d, injection aborted" % self.pid)
                return False

            if not KERNEL32.QueueUserAPC(load_library, self.h_thread, arg):
                log.error(
                    "QueueUserAPC failed when injecting process "
                    "with pid %d (Error: %s)" %
                    (self.pid, get_error_string(KERNEL32.GetLastError())))
                return False
            log.info("Successfully injected process with pid %d" % self.pid)
        else:
            event_name = 'CuckooEvent%d' % self.pid
            self.event_handle = KERNEL32.CreateEventA(None, False, False,
                                                      event_name)
            if not self.event_handle:
                log.warning('Unable to create notify event..')
                return False

            log.info("Using CreateRemoteThread injection")
            new_thread_id = c_ulong(0)
            thread_handle = KERNEL32.CreateRemoteThread(
                self.h_process, None, 0, load_library, arg, 0,
                byref(new_thread_id))
            if not thread_handle:
                log.error(
                    "CreateRemoteThread failed when injecting " +
                    "process with pid %d (Error: %s)" %
                    (self.pid, get_error_string(KERNEL32.GetLastError())))
                KERNEL32.CloseHandle(self.event_handle)
                self.event_handle = None
                return False
            else:
                KERNEL32.CloseHandle(thread_handle)

        return True
예제 #16
0
파일: process.py 프로젝트: by700git/cuckoo
    def execute(self, path, args=None, dll=None, free=False, curdir=None,
                source=None, mode=None, maximize=False):
        """Execute sample process.
        @param path: sample path.
        @param args: process args.
        @param dll: dll path.
        @param free: do not inject our monitor.
        @param curdir: current working directory.
        @param source: process identifier or process name which will
                       become the parent process for the new process.
        @param mode: monitor mode - which functions to instrument.
        @param maximize: whether the GUI should be maximized.
        @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

        if source:
            source_is32bit = self.is32bit(process_name=source)
        else:
            source_is32bit = self.is32bit(pid=os.getpid())

        sample_is32bit = self.is32bit(path=path)

        if not dll:
            if sample_is32bit:
                dll = "monitor-x86.dll"
            else:
                dll = "monitor-x64.dll"

        dllpath = os.path.abspath(os.path.join("bin", dll))
        if not os.path.exists(dllpath):
            log.warning("No valid DLL specified to be injected, "
                        "injection aborted.")
            return False

        if source_is32bit:
            inject_exe = os.path.join("bin", "inject-x86.exe")
        else:
            inject_exe = os.path.join("bin", "inject-x64.exe")

        # The --free is required because otherwise we have to provide a DLL
        # to inject even though we won't be injecting anything at this point.
        argv = [
            inject_exe, "--app", self.shortpath(path),
            "--only-start", "--free",
        ]

        if args:
            argv += ["--args", self._encode_args(args)]

        if curdir:
            argv += ["--curdir", self.shortpath(curdir)]

        if maximize:
            argv += ["--maximize"]

        if source:
            argv += ["--from-process", source]
        else:
            argv += ["--from", "%s" % os.getpid()]

        try:
            pid, tid = subprocess.check_output(argv).strip().split()
        except Exception:
            log.error("Failed to execute process from path %r with "
                      "arguments %r (Error: %s)", path, argv,
                      get_error_string(KERNEL32.GetLastError()))
            return False

        if free:
            return True

        if sample_is32bit:
            inject_exe = os.path.join("bin", "inject-x86.exe")
        else:
            inject_exe = os.path.join("bin", "inject-x64.exe")

        argv = [
            inject_exe, "--apc", "--dll", dllpath,
            "--pid", pid, "--tid", tid, "--resume-thread",
            "--config", self.drop_config(mode=mode),
        ]

        try:
            self.pid = int(subprocess.check_output(argv))
        except Exception:
            log.error("Failed to execute process from path %r with "
                      "arguments %r (Error: %s)", path, argv,
                      get_error_string(KERNEL32.GetLastError()))
            return False

        log.info("Successfully executed process from path %r with "
                 "arguments %r and pid %d", path, args or "", self.pid)
        return True