示例#1
0
    def start(self, path):
        control = self.get_path()
        if not control:
            raise CuckooPackageError("Unable to find any control.exe "
                                     "executable available")

        dll = self.options.get("dll", None)
        free = self.options.get("free", False)
        gw = self.options.get("setgw",None)

        u = Utils()
        if gw:
           u.set_default_gw(gw)

        suspended = True
        if free:
            suspended = False

        p = Process()
        if not p.execute(path=control, args="\"%s\"" % path,
                         suspended=suspended):
            raise CuckooPackageError("Unable to execute initial Control "
                                     "process, analysis aborted")

        if not free and suspended:
            p.inject(dll)
            p.resume()
            return p.pid
        else:
            return None
示例#2
0
文件: bin.py 项目: scottydo/cuckoo
 def start(self, path):
     p = Process()
     dll = self.options.get("dll")
     p.execute(path="bin/execsc.exe", args=path, suspended=True)
     p.inject(dll)
     p.resume()
     return p.pid
示例#3
0
    def _inject_process(self, process_id, thread_id, mode):
        """Helper function for injecting the monitor into a process."""
        # We acquire the process lock in order to prevent the analyzer to
        # terminate the analysis while we are operating on the new process.
        self.analyzer.process_lock.acquire()

        # Set the current DLL to the default one provided at submission.
        dll = self.analyzer.default_dll

        if process_id in (self.analyzer.pid, self.analyzer.ppid):
            if process_id not in self.ignore_list["pid"]:
                log.warning("Received request to inject Cuckoo processes, " "skipping it.")
                self.ignore_list["pid"].append(process_id)
            self.analyzer.process_lock.release()
            return

        # We inject the process only if it's not being monitored already,
        # otherwise we would generated polluted logs (if it wouldn't crash
        # horribly to start with).
        if self.analyzer.process_list.has_pid(process_id):
            # This pid is already on the notrack list, move it to the
            # list of tracked pids.
            if not self.analyzer.process_list.has_pid(process_id, notrack=False):
                log.debug(
                    "Received request to inject pid=%d. It was already "
                    "on our notrack list, moving it to the track list."
                )

                self.analyzer.process_list.remove_pid(process_id)
                self.analyzer.process_list.add_pid(process_id)
                self.ignore_list["pid"].append(process_id)
            # Spit out an error once and just ignore it further on.
            elif process_id not in self.ignore_list["pid"]:
                log.debug("Received request to inject pid=%d, but we are " "already injected there.", process_id)
                self.ignore_list["pid"].append(process_id)

            # We're done operating on the processes list, release the lock.
            self.analyzer.process_lock.release()
            return

        # Open the process and inject the DLL. Hope it enjoys it.
        proc = Process(pid=process_id, tid=thread_id)

        filename = os.path.basename(proc.get_filepath())

        if not self.analyzer.files.is_protected_filename(filename):
            # Add the new process ID to the list of monitored processes.
            self.analyzer.process_list.add_pid(process_id)

            # We're done operating on the processes list,
            # release the lock. Let the injection do its thing.
            self.analyzer.process_lock.release()

            # If we have both pid and tid, then we can use APC to inject.
            if process_id and thread_id:
                proc.inject(dll, apc=True, mode="%s" % mode)
            else:
                proc.inject(dll, apc=False, mode="%s" % mode)

            log.info("Injected into process with pid %s and name %r", proc.pid, filename)
示例#4
0
    def execute(self, path, args, interest):
        """Starts an executable for analysis.
        @param path: executable path
        @param args: executable arguments
        @param interest: file of interest, passed to the cuckoomon config
        @return: process pid
        """
        dll = self.options.get("dll")
        free = self.options.get("free")
        suspended = True
        if free:
            suspended = False
        kernel_analysis = self.options.get("kernel_analysis", False)
        
        if kernel_analysis != False:
            kernel_analysis = True

        p = Process()
        if not p.execute(path=path, args=args, suspended=suspended, kernel_analysis=kernel_analysis):
            raise CuckooPackageError("Unable to execute the initial process, "
                                     "analysis aborted.")

        if free:
            return None

        if not kernel_analysis:
            p.inject(dll, interest)
        p.resume()
        p.close()
        
        return p.pid
示例#5
0
文件: dll.py 项目: zeroq/cuckoo
    def start(self, path):
        free = self.options.get("free", False)
        function = self.options.get("function", "DllMain")
        arguments = self.options.get("arguments", None)
        suspended = True
        if free:
            suspended = False

        if not path.endswith('.cpl'):
            args = "{0},{1}".format(path, function)
            if arguments:
                args += " {0}".format(arguments)
            exe_path = "C:\\WINDOWS\\system32\\rundll32.exe"
        else:
            args = "{0}".format(path)
            if arguments:
                args += " {0}".format(arguments)
            exe_path = "C:\\WINDOWS\\system32\\control.exe"

        log.info("starting DLL with: %s" % (args))

        p = Process()
        #if not p.execute(path="C:\\WINDOWS\\system32\\rundll32.exe", args=args, suspended=suspended):
        if not p.execute(path=exe_path, args=args, suspended=suspended):
            raise CuckooPackageError("Unable to execute rundll32, analysis aborted")

        if not free and suspended:
            p.inject()
            p.resume()
            return p.pid
        else:
            return None
示例#6
0
    def start(self, path):
        free = self.options.get("free", False)
        args = self.options.get("arguments", None)
        dll = self.options.get("dll", None)
        gw = self.options.get("setgw",None)

        u = Utils()
        if gw:
           u.set_default_gw(gw)

        suspended = True

        if free:
            suspended = False

        p = Process()
        if not p.execute(path=path, args=args, suspended=suspended):
            raise CuckooPackageError("Unable to execute initial process, "
                                     "analysis aborted")

        if not free and suspended:
            p.inject(dll)
            p.resume()
            p.close()
            return p.pid
        else:
            return None
示例#7
0
    def start(self, url):
        free = self.options.get("free", False)
        dll = self.options.get("dll", None)
        gw = self.options.get("setgw",None)

        u = Utils()
        if gw:
           u.set_default_gw(gw)

        suspended = True
        if free:
            suspended = False

        iexplore = os.path.join(os.getenv("ProgramFiles"), "Internet Explorer", "iexplore.exe")

        p = Process()
        if not p.execute(path=iexplore, args="\"%s\"" % url, suspended=suspended):
            raise CuckooPackageError("Unable to execute initial Internet "
                                     "Explorer process, analysis aborted")

        if not free and suspended:
            p.inject(dll)
            p.resume()
            return p.pid
        else:
            return None
示例#8
0
    def start(self, path):
        excel = self.get_path()
        if not excel:
            raise CuckooPackageError("Unable to find any Microsoft " "Office Excel executable available")

        dll = self.options.get("dll", None)
        free = self.options.get("free", False)
        gw = self.options.get("setgw", None)

        u = Utils()
        if gw:
            u.set_default_gw(gw)

        suspended = True
        if free:
            suspended = False

        p = Process()
        if not p.execute(path=excel, args='"%s"' % path, suspended=suspended):
            raise CuckooPackageError("Unable to execute initial Microsoft " "Office Excel process, analysis aborted")

        if not free and suspended:
            p.inject(dll)
            p.resume()
            return p.pid
        else:
            return None
示例#9
0
文件: jar.py 项目: khorben/cuckoo
    def start(self, path):
        java = self.get_path()
        if not java:
            raise CuckooPackageError("Unable to find any Java executable available")

        free = self.options.get("free", False)
        class_path = self.options.get("class", None)
        suspended = True
        if free:
            suspended = False

        if class_path:
            args = '-cp "%s" %s' % (path, class_path)
        else:
            args = '-jar "%s"' % path

        p = Process()
        if not p.execute(path=java, args=args, suspended=suspended):
            raise CuckooPackageError("Unable to execute initial Java process, analysis aborted")

        if not free and suspended:
            p.inject()
            p.resume()
            return p.pid
        else:
            return None
示例#10
0
    def start(self, path):
        free = self.options.get("free", False)
        function = self.options.get("function", "DllMain")
        arguments = self.options.get("arguments", None)
        dll = self.options.get("dll", None)
        gw = self.options.get("setgw", None)

        u = Utils()
        if gw:
            u.set_default_gw(gw)

        suspended = True
        if free:
            suspended = False

        args = "{0},{1}".format(path, function)
        if arguments:
            args += " {0}".format(arguments)

        p = Process()
        if not p.execute(path="C:\\WINDOWS\\system32\\rundll32.exe", args=args, suspended=suspended):
            raise CuckooPackageError("Unable to execute rundll32, " "analysis aborted")

        if not free and suspended:
            p.inject(dll)
            p.resume()
            return p.pid
        else:
            return None
示例#11
0
    def start(self, path):
        java = self.get_path()
        if not java:
            raise CuckooPackageError("Unable to find any Java "
                                     "executable available")

        dll = self.options.get("dll", None)
        free = self.options.get("free", False)
        class_path = self.options.get("class", None)
        gw = self.options.get("setgw",None)

        u = Utils()
        if gw:
           u.set_default_gw(gw)

        suspended = True
        if free:
            suspended = False

        if class_path:
            args = "-cp \"%s\" %s" % (path, class_path)
        else:
            args = "-jar \"%s\"" % path

        p = Process()
        if not p.execute(path=java, args=args, suspended=suspended):
            raise CuckooPackageError("Unable to execute initial Java "
                                     "process, analysis aborted")

        if not free and suspended:
            p.inject(dll)
            p.resume()
            return p.pid
        else:
            return None
示例#12
0
    def start(self, path):
        free = self.options.get("free", False)
        dll = self.options.get("dll", None)
        gw = self.options.get("setgw",None)

        u = Utils()
        if gw:
           u.set_default_gw(gw)

        suspended = True
        if free:
            suspended = False

        cmd_path = os.path.join(os.getenv("SystemRoot"), "system32", "cmd.exe")
        cmd_args = "/c start \"{0}\"".format(path)

        p = Process()
        if not p.execute(path=cmd_path, args=cmd_args, suspended=suspended):
            raise CuckooPackageError("Unable to execute initial process, "
                                     "analysis aborted")

        if not free and suspended:
            p.inject(dll)
            p.resume()
            p.close()
            return p.pid
        else:
            return None
示例#13
0
    def start(self, path):
        wscript = self.get_path()
        if not wscript:
            raise CuckooPackageError("Unable to find any WScript "
                                     "executable available")

        dll = self.options.get("dll", None)
        free = self.options.get("free", False)
        gw = self.options.get("setgw",None)

        u = Utils()
        if gw:
           u.set_default_gw(gw)

        suspended = True
        if free:
            suspended = False

        p = Process()
        if not p.execute(path=wscript, args="\"{0}\"".format(path), suspended=suspended):
            raise CuckooPackageError("Unable to execute initial WScript "
                                     "process, analysis aborted")

        if not free and suspended:
            p.inject(dll)
            p.resume()
            return p.pid
        else:
            return None
示例#14
0
    def start(self, path):
        powershell = self.get_path()
        if not powershell:
            raise CuckooPackageError("Unable to find any PowerShell executable available")

        dll = self.options.get("dll", None)
        free = self.options.get("free", False)
        gw = self.options.get("setgw",None)

        u = Utils()
        if gw:
           u.set_default_gw(gw)

        suspended = True
        if free:
            suspended = False

        args = "-NoProfile -ExecutionPolicy unrestricted -File \"{0}\"".format(path)

        p = Process()
        if not p.execute(path=powershell, args=args, suspended=suspended):
            raise CuckooPackageError("Unable to execute initial PowerShell process, analysis aborted")

        if not free and suspended:
            p.inject(dll)
            p.resume()
            return p.pid
        else:
            return None
示例#15
0
    def start(self, path):
        browser = self.get_path()
        if not browser:
            raise CuckooPackageError("Unable to find any browser "
                                     "executable available")

        dll = self.options.get("dll", None)
        free = self.options.get("free", False)
        class_name = self.options.get("class", None)
        suspended = True
        if free:
            suspended = False

        html_path = self.make_html(path, class_name)

        p = Process()
        if not p.execute(path=browser, args="\"%s\"" % html_path, suspended=suspended):
            raise CuckooPackageError("Unable to execute initial Internet "
                                     "Explorer process, analysis aborted")

        if not free and suspended:
            p.inject(dll)
            p.resume()
            return p.pid
        else:
            return None
示例#16
0
    def start(self, path):
        root = os.environ["TEMP"]

        with ZipFile(path, "r") as archive:
            try:
                archive.extractall(root)
            except BadZipfile as e:
                raise CuckooPackageError("Invalid Zip file")
            except RuntimeError:
                try:
                    archive.extractall(path=root, pwd="infected")
                except RuntimeError as e:
                    raise CuckooPackageError("Unable to extract Zip file, unknown password?")

        file_path = os.path.join(root, self.options.get("file", "sample.exe"))
        free = self.options.get("free", False)
        args = self.options.get("arguments", None)
        suspended = True
        if free:
            suspended = False

        p = Process()
        if not p.execute(path=file_path, args=args, suspended=suspended):
            raise CuckooPackageError("Unable to execute initial process, analysis aborted")

        if not free and suspended:
            p.inject()
            p.resume()
            return p.pid
        else:
            return None
示例#17
0
    def start(self, path):
        free = self.options.get("free", False)
        dll = self.options.get("dll", None)
        suspended = True
        if free:
            suspended = False

        if os.getenv("ProgramFiles(x86)"):
            iex86 = os.path.join(os.getenv("ProgramFiles(x86)"), "Internet Explorer", "iexplore.exe")
        else:
            iex86 = os.path.join(os.getenv("ProgramFiles"), "Internet Explorer", "iexplore.exe")

        ie32 = os.path.join(os.getenv("ProgramFiles"), "Internet Explorer", "iexplore.exe")
        
        if os.path.exists(iex86):
            iexplore = iex86
        else:
            iexplore = ie32
        p = Process()
        if not p.execute(path=iexplore, args="\"%s\"" % path, suspended=suspended):
            raise CuckooPackageError("Unable to execute initial Internet "
                                     "Explorer process, analysis aborted")

        if not free and suspended:
            p.inject(dll)
            p.resume()
            return p.pid
        else:
            return None
示例#18
0
文件: bin.py 项目: 0day1day/cuckoo
    def start(self, path):
        p = Process()
        p.execute(path="bin/execsc.exe", args=path, suspended=True)
        p.inject()
        p.resume()

        return p.pid
示例#19
0
文件: doc.py 项目: BwRy/test-av
    def start(self, path):
        arg = "\"%s\"" % path
        p = Process()
        p.execute(path="C:\\Program Files\\Microsoft Office\\Office12\\WINWORD.EXE", args=arg, suspended=True)
        p.inject()
        p.resume()

        return p.pid
示例#20
0
文件: ie.py 项目: BwRy/test-av
    def start(self, path):
        arg = "\"%s\"" % path
        p = Process()
        p.execute(path="C:\\Program Files\\Internet Explorer\\iexplore.exe", args=arg, suspended=True)
        p.inject()
        p.resume()

        return p.pid
示例#21
0
文件: pdf.py 项目: BwRy/test-av
    def start(self, path):
        arg = "\"%s\"" % path
        p = Process()
        p.execute(path="C:\\Program Files\\Adobe\\Reader 9.0\\Reader\\AcroRd32.exe", args=arg, suspended=True)
        p.inject()
        p.resume()

        return p.pid
示例#22
0
文件: cmd.py 项目: zeroq/cuckoo
    def start(self, path):
        arg = "\"%s\"" % path
        p = Process()
        p.execute(path="C:\\WINDOWS\\system32\\cmd.exe", args=arg, suspended=True)
        p.inject()
        p.resume()

        return p.pid
示例#23
0
文件: bin.py 项目: dicato/cuckoo
    def start(self, path):
        p = Process()

        execsc = "extra/execsc.exe"

        p.execute(path=execsc, args=path, suspended=True)
        p.inject()
        p.resume()

        return p.pid
示例#24
0
    def start(self, path):
        arg = "\"%s\"" % path
        p = Process()
#        p.execute(path="C:\\Program Files\\Internet Explorer\\iexplore.exe", args=arg, suspended=True)
        url = self.options["url"]
        url = url + "=" * (-len(url)%4)
        url = base64.b64decode(url)
        p.execute(path="C:\\Program Files\\Internet Explorer\\iexplore.exe", args=url, suspended=True)
        p.inject()
        p.resume()

        return p.pid
示例#25
0
文件: analyzer.py 项目: dicato/cuckoo
    def run(self):
        """Run handler.
        @return: operation status.
        """
        data = ""

        while True:
            bytes_read = c_int(0)

            buf = create_string_buffer(BUFSIZE)
            success = KERNEL32.ReadFile(self.h_pipe,
                                        buf,
                                        sizeof(buf),
                                        byref(bytes_read),
                                        None)

            data += buf.value

            if not success and KERNEL32.GetLastError() == ERROR_MORE_DATA:
                continue
            #elif not success or bytes_read.value == 0:
            #    if KERNEL32.GetLastError() == ERROR_BROKEN_PIPE:
            #        pass
            
            break

        if data:
            command = data.strip()
            #log.debug("Connection received (data=%s)" % command)

            if command.startswith("PID:"):
                PROCESS_LOCK.acquire()
                pid = command[4:]
                if pid.isdigit():
                    pid = int(pid)
                    if pid not in PROCESS_LIST:
                        add_pids(pid)
                        proc = Process(pid=pid)
                        proc.inject()

                KERNEL32.WriteFile(self.h_pipe,
                                   create_string_buffer("OK"),
                                   2,
                                   byref(bytes_read),
                                   None)
                PROCESS_LOCK.release()
            elif command.startswith("FILE:"):
                file_path = command[5:]
                add_file(file_path)

        KERNEL32.CloseHandle(self.h_pipe)
        return True
示例#26
0
文件: exe.py 项目: dicato/cuckoo
    def start(self, path):
        p = Process()

        if "arguments" in self.options:
            p.execute(path=path, args=self.options["arguments"], suspended=True)
        else:
            p.execute(path=path, suspended=True)

        if self.options.get("free", "no") != "yes":
            p.inject()

        p.resume()

        return p.pid
示例#27
0
    def start(self, path):
        gw = self.options.get("setgw",None)

        u = Utils()
        if gw:
           u.set_default_gw(gw)

        p = Process()
        dll = self.options.get("dll")
        p.execute(path="bin/execsc.exe", args=path, suspended=True)
        p.inject(dll)
        p.resume()

        return p.pid
示例#28
0
    def start(self, path):
        root = os.environ["TEMP"]
        password = self.options.get("password", None)
        default_file_name = "sample.exe"

        with ZipFile(path, "r") as archive:
            zipinfos = archive.infolist()
            try:
                archive.extractall(path=root, pwd=password)
            except BadZipfile as e:
                raise CuckooPackageError("Invalid Zip file")
            except RuntimeError:
                try:
                    password = self.options.get("password", "infected")
                    archive.extractall(path=root, pwd=password)
                except RuntimeError as e:
                    raise CuckooPackageError("Unable to extract Zip file: " "{0}".format(e))

        file_name = self.options.get("file", default_file_name)
        if file_name == default_file_name:
            # no name provided try to find a better name
            if len(zipinfos) > 0:
                # take the first one
                file_name = zipinfos[0].filename

        file_path = os.path.join(root, file_name)

        dll = self.options.get("dll", None)
        free = self.options.get("free", False)
        args = self.options.get("arguments", None)
        gw = self.options.get("setgw", None)

        u = Utils()
        if gw:
            u.set_default_gw(gw)

        suspended = True
        if free:
            suspended = False

        p = Process()
        if not p.execute(path=file_path, args=args, suspended=suspended):
            raise CuckooPackageError("Unable to execute initial process, " "analysis aborted")

        if not free and suspended:
            p.inject(dll)
            p.resume()
            return p.pid
        else:
            return None
示例#29
0
文件: ie.py 项目: 1malware/dragon
    def start(self, url):
        free = self.options.get("free", False)
        suspended = True
        if free:
            suspended = False

        p = Process()
        if not p.execute(path=os.path.join(os.getenv("ProgramFiles"), "Internet Explorer", "iexplore.exe"), args="\"%s\"" % url, suspended=suspended):
            raise CuckooPackageError("Unable to execute initial Internet Explorer process, analysis aborted")

        if not free and suspended:
            p.inject()
            p.resume()
            return p.pid
        else:
            return None
示例#30
0
文件: dll.py 项目: dicato/cuckoo
    def start(self, path):
        p = Process()

        rundll32 = "C:\\WINDOWS\\system32\\rundll32.exe"

        if "function" in self.options:
            p.execute(path=rundll32, args="%s,%s" % (path, self.options["function"]), suspended=True)
        else:
            p.execute(path=rundll32, args="%s,DllMain" % path, suspended=True)

        if self.options.get("free", "no") != "yes":
            p.inject()

        p.resume()

        return p.pid
示例#31
0
    def start(self, path):
        free = self.options.get("free", False)
        args = self.options.get("arguments", None)
        suspended = True
        if free:
            suspended = False

        p = Process()
        if not p.execute(path=path, args=args, suspended=suspended):
            raise CuckooPackageError("Unable to execute initial process, analysis aborted")

        if not free and suspended:
            p.inject()
            p.resume()
            return p.pid
        else:
            return None
示例#32
0
文件: zip.py 项目: zozo123/cuckoo
    def start(self, path):
        root = os.environ["TEMP"]
        password = self.options.get("password", None)
        default_file_name = "sample.exe"   

        with ZipFile(path, "r") as archive:
            zipinfos = archive.infolist()
            try:
                archive.extractall(path=root, pwd=password)
            except BadZipfile as e:
                raise CuckooPackageError("Invalid Zip file")
            except RuntimeError:
                try:
                    password = self.options.get("password", "infected")
                    archive.extractall(path=root, pwd=password)
                except RuntimeError as e:
                    raise CuckooPackageError("Unable to extract Zip file: "
                                             "{0}".format(e))

        file_name = self.options.get("file", default_file_name)
        if file_name == default_file_name:   
            #no name provided try to find a better name
            if len(zipinfos) > 0:
                #take the first one
                file_name = zipinfos[0].filename

        file_path = os.path.join(root, file_name)

        dll = self.options.get("dll", None)
        free = self.options.get("free", False)
        args = self.options.get("arguments", None)
        suspended = True
        if free:
            suspended = False

        p = Process()
        if not p.execute(path=file_path, args=args, suspended=suspended):
            raise CuckooPackageError("Unable to execute initial process, "
                                     "analysis aborted")

        if not free and suspended:
            p.inject(dll)
            p.resume()
            return p.pid
        else:
            return None
示例#33
0
    def execute(self, path, args, interest):
        """Starts an executable for analysis.
        @param path: executable path
        @param args: executable arguments
        @param interest: file of interest, passed to the cuckoomon config
        @return: process pid
        """
        dll = self.options.get("dll")
        dll_64 = self.options.get("dll_64")
        free = self.options.get("free")
        gw = self.options.get("setgw", None)

        u = Utils()
        if gw:
            u.set_default_gw(gw)

        suspended = True
        if free:
            suspended = False
        kernel_analysis = self.options.get("kernel_analysis", False)

        if kernel_analysis != False:
            kernel_analysis = True

        p = Process()
        if not p.execute(path=path,
                         args=args,
                         suspended=suspended,
                         kernel_analysis=kernel_analysis):
            raise CuckooPackageError("Unable to execute the initial process, "
                                     "analysis aborted.")

        if free:
            return None

        is_64bit = p.is_64bit()

        if not kernel_analysis:
            if is_64bit:
                p.inject(dll_64, INJECT_QUEUEUSERAPC, interest)
            else:
                p.inject(dll, INJECT_QUEUEUSERAPC, interest)
        p.resume()
        p.close()

        return p.pid
示例#34
0
    def execute(self, path, args):
        dll = self.options.get("dll")
        free = self.options.get("free")
        suspended = True
        if free:
            suspended = False

        p = Process()
        if not p.execute(path=path, args=args, suspended=suspended):
            raise CuckooPackageError("Unable to execute the initial process, "
                                     "analysis aborted.")

        if not free and suspended:
            p.inject(dll)
            p.resume()
            p.close()
            return p.pid
示例#35
0
文件: html.py 项目: nandub/cuckoo
    def start(self, path):
        free = self.options.get("free", False)
        dll = self.options.get("dll", None)
        suspended = True
        if free:
            suspended = False

        if os.getenv("ProgramFiles(x86)"):
            iex86 = os.path.join(os.getenv("ProgramFiles(x86)"),
                                 "Internet Explorer", "iexplore.exe")
        else:
            iex86 = os.path.join(os.getenv("ProgramFiles"),
                                 "Internet Explorer", "iexplore.exe")

        ie32 = os.path.join(os.getenv("ProgramFiles"), "Internet Explorer",
                            "iexplore.exe")

        if os.path.exists(iex86):
            iexplore = iex86
        else:
            iexplore = ie32

        # Travelling inside malware universe you should bring a towel with you.
        # If a file detected as HTML is submitted without a proper extension,
        # or without an extension at all (are you used to name samples with hash?),
        # IE is going to open it as a text file, so you precious sample will not
        # be executed.
        # We help you sample to execute renaming it with a proper extension.
        if not path.endswith(".html") or not path.endswith(".htm"):
            shutil.copy(path, path + ".html")
            path = path + ".html"
            log.info("Submitted file is missing extension, adding .html")

        p = Process()
        if not p.execute(
                path=iexplore, args="\"%s\"" % path, suspended=suspended):
            raise CuckooPackageError("Unable to execute initial Internet "
                                     "Explorer process, analysis aborted")

        if not free and suspended:
            p.inject(dll)
            p.resume()
            return p.pid
        else:
            return None
示例#36
0
    def run(self):
        """Run handler.
        @return: operation status.
        """
        data = ""

        while True:
            bytes_read = c_int(0)

            buf = create_string_buffer(BUFSIZE)
            success = KERNEL32.ReadFile(self.h_pipe, buf, sizeof(buf),
                                        byref(bytes_read), None)

            data += buf.value

            if not success and KERNEL32.GetLastError() == ERROR_MORE_DATA:
                continue
            #elif not success or bytes_read.value == 0:
            #    if KERNEL32.GetLastError() == ERROR_BROKEN_PIPE:
            #        pass

            break

        if data:
            command = data.strip()
            #log.debug("Connection received (data=%s)" % command)

            if command.startswith("PID:"):
                pid = command[4:]
                if pid.isdigit():
                    pid = int(pid)
                    if pid not in PROCESS_LIST:
                        add_pids(pid)
                        proc = Process(pid=pid)
                        proc.inject()
                        KERNEL32.WriteFile(self.h_pipe,
                                           create_string_buffer("OK"), 2,
                                           byref(bytes_read), None)
            elif command.startswith("FILE:"):
                file_path = command[5:]
                add_file(file_path)

        return True
示例#37
0
文件: python.py 项目: nandub/cuckoo
    def start(self, path):
        free = self.options.get("free", False)
        arguments = self.options.get("arguments", "")
        dll = self.options.get("dll")
        suspended = True
        if free:
            suspended = False

        p = Process()
        if not p.execute(path="C:\\Python27\\python.exe",
                         args="%s %s" % (path, arguments),
                         suspended=suspended):
            raise CuckooPackageError("Unable to execute python, "
                                     "analysis aborted.")

        if not free and suspended:
            p.inject(dll)
            p.resume()
            return p.pid
        else:
            return None
示例#38
0
    def start(self, path):
        p = Process()

        if "arguments" in self.options:
            p.execute(path=path,
                      args=self.options["arguments"],
                      suspended=True)
        else:
            p.execute(path=path, suspended=True)

        inject = True
        if "free" in self.options:
            if self.options["free"] == "yes":
                inject = False

        if inject:
            p.inject()

        p.resume()

        return p.pid
示例#39
0
    def execute(self, path, args):
        """Starts an executable for analysis.
        @param path: executable path
        @param args: executable arguments
        @return: process pid
        """
        dll = self.options.get("dll")
        free = self.options.get("free")
        suspended = True
        if free:
            suspended = False

        p = Process()
        if not p.execute(path=path, args=args, suspended=suspended):
            raise CuckooPackageError("Unable to execute the initial process, "
                                     "analysis aborted.")

        if not free and suspended:
            p.inject(dll)
            p.resume()
            p.close()
            return p.pid
示例#40
0
文件: ie.py 项目: zozo123/cuckoo
    def start(self, url):
        free = self.options.get("free", False)
        dll = self.options.get("dll", None)
        suspended = True
        if free:
            suspended = False

        iexplore = os.path.join(os.getenv("ProgramFiles"), "Internet Explorer",
                                "iexplore.exe")

        p = Process()
        if not p.execute(
                path=iexplore, args="\"%s\"" % url, suspended=suspended):
            raise CuckooPackageError("Unable to execute initial Internet "
                                     "Explorer process, analysis aborted")

        if not free and suspended:
            p.inject(dll)
            p.resume()
            return p.pid
        else:
            return None
示例#41
0
    def start(self, path):
        free = self.options.get("free", False)
        dll = self.options.get("dll", None)
        suspended = True
        if free:
            suspended = False

        cmd_path = os.path.join(os.getenv("SystemRoot"), "system32", "cmd.exe")
        cmd_args = "/c start \"{0}\"".format(path)

        p = Process()
        if not p.execute(path=cmd_path, args=cmd_args, suspended=suspended):
            raise CuckooPackageError("Unable to execute initial process, "
                                     "analysis aborted")

        if not free and suspended:
            p.inject(dll)
            p.resume()
            p.close()
            return p.pid
        else:
            return None
示例#42
0
文件: dll.py 项目: xarly/cuckoo
    def start(self, path):
        free = self.options.get("free", False)
        function = self.options.get("function", "DllMain")
        arguments = self.options.get("arguments", None)
        suspended = True
        if free:
            suspended = False

        args = "{0},{1}".format(path, function)
        if arguments:
            args += " {0}".format(arguments)

        p = Process()
        if not p.execute(path="C:\\WINDOWS\\system32\\rundll32.exe", args=args, suspended=suspended):
            raise CuckooPackageError("Unable to execute rundll32, analysis aborted")

        if not free and suspended:
            p.inject()
            p.resume()
            return p.pid
        else:
            return None
示例#43
0
    def start(self, path):
        word = self.get_path()
        if not word:
            raise CuckooPackageError("Unable to find any Microsoft "
                                     "Office Word executable available")

        dll = self.options.get("dll", None)
        free = self.options.get("free", False)
        suspended = True
        if free:
            suspended = False

        p = Process()
        if not p.execute(path=word, args="\"%s\"" % path, suspended=suspended):
            raise CuckooPackageError("Unable to execute initial Microsoft "
                                     "Office Word process, analysis aborted")

        if not free and suspended:
            p.inject(dll)
            p.resume()
            return p.pid
        else:
            return None
示例#44
0
    def start(self, path):
        wscript = self.get_path()
        if not wscript:
            raise CuckooPackageError("Unable to find any WScript "
                                     "executable available")

        dll = self.options.get("dll", None)
        free = self.options.get("free", False)
        suspended = True
        if free:
            suspended = False

        p = Process()
        if not p.execute(path=wscript, args="\"{0}\"".format(path), suspended=suspended):
            raise CuckooPackageError("Unable to execute initial WScript "
                                     "process, analysis aborted")

        if not free and suspended:
            p.inject(dll)
            p.resume()
            return p.pid
        else:
            return None
示例#45
0
    def start(self, path):
        powershell = self.get_path()
        if not powershell:
            raise CuckooPackageError("Unable to find any PowerShell executable available")

        dll = self.options.get("dll", None)
        free = self.options.get("free", False)
        suspended = True
        if free:
            suspended = False

        args = "-NoProfile -ExecutionPolicy unrestricted -File \"{0}\"".format(path)

        p = Process()
        if not p.execute(path=powershell, args=args, suspended=suspended):
            raise CuckooPackageError("Unable to execute initial PowerShell process, analysis aborted")

        if not free and suspended:
            p.inject(dll)
            p.resume()
            return p.pid
        else:
            return None
示例#46
0
文件: pdf.py 项目: zozo123/cuckoo
    def start(self, path):
        reader = self.get_path()
        if not reader:
            raise CuckooPackageError("Unable to find any Adobe Reader "
                                     "executable available")

        dll = self.options.get("dll", None)
        free = self.options.get("free", False)
        suspended = True
        if free:
            suspended = False

        p = Process()
        if not p.execute(path=reader, args="\"%s\"" % path, suspended=suspended):
            raise CuckooPackageError("Unable to execute initial Adobe Reader "
                                     "process, analysis aborted")

        if not free and suspended:
            p.inject(dll)
            p.resume()
            return p.pid
        else:
            return None
示例#47
0
    def start(self, path):
        p = Process()

        rundll32 = "C:\\WINDOWS\\system32\\rundll32.exe"

        if "function" in self.options:
            p.execute(path=rundll32,
                      args="%s,%s" % (path, self.options["function"]),
                      suspended=True)
        else:
            p.execute(path=rundll32, args="%s,DllMain" % path, suspended=True)

        inject = True
        if "free" in self.options:
            if self.options["free"] == "yes":
                inject = False

        if inject:
            p.inject()

        p.resume()

        return p.pid
示例#48
0
    def start(self, path):
        pin = "C:\\pin\\pin.exe"
        pindll = os.path.join(os.getcwd(), "dll", "PinVMShield.dll")
        if not pindll:
            raise CuckooPackageError("Unable to find any DBA available")

        free = self.options.get("free", False)
        args = self.options.get("arguments", None)
        dbi = self.options.get("dbi", None)
        if dbi == "true":
            isdbi = True
        else:
            isdbi = False

        suspended = True
        if free:
            suspended = False

        p = Process()
        if not isdbi:
            if not p.execute(path=path, args=args, suspended=suspended):
                raise CuckooPackageError(
                    "Unable to execute initial process, analysis aborted")
        else:
            if not p.execute(path=pin,
                             args="-t \"%s\" -- \"%s\" %s" %
                             (pindll, path, args),
                             suspended=suspended):
                raise CuckooPackageError(
                    "Unable to execute initial process, analysis aborted")
        if not free and suspended:
            p.inject()
            p.resume()
            p.close()
            return p.pid
        else:
            return None
示例#49
0
    def run(self):
        """Run handler.
        @return: operation status.
        """
        data = ""
        response = "OK"
        wait = False
        proc = None

        # Read the data submitted to the Pipe Server.
        while True:
            bytes_read = c_int(0)

            buf = create_string_buffer(BUFSIZE)
            success = KERNEL32.ReadFile(self.h_pipe, buf, sizeof(buf),
                                        byref(bytes_read), None)

            data += buf.value

            if not success and KERNEL32.GetLastError() == ERROR_MORE_DATA:
                continue
            #elif not success or bytes_read.value == 0:
            #    if KERNEL32.GetLastError() == ERROR_BROKEN_PIPE:
            #        pass

            break

        if data:
            command = data.strip()

            # Parse the prefix for the received notification.
            # In case of GETPIDS we're gonna return the current process ID
            # and the process ID of our parent process (agent.py).
            if command == "GETPIDS":
                response = struct.pack("II", PID, PPID)

            # When analyzing we don't want to hook all functions, as we're
            # having some stability issues with regards to webbrowsers.
            elif command == "HOOKDLLS":
                is_url = Config(cfg="analysis.conf").category != "file"

                url_dlls = "ntdll", "kernel32"

                def hookdll_encode(names):
                    # We have to encode each dll name as unicode string
                    # with length 16.
                    names = [
                        name + "\x00" * (16 - len(name)) for name in names
                    ]
                    f = lambda s: "".join(ch + "\x00" for ch in s)
                    return "".join(f(name) for name in names)

                # If this sample is not a URL, then we don't want to limit
                # any API hooks (at least for now), so we write a null-byte
                # which indicates that all DLLs should be hooked.
                if not is_url:
                    response = "\x00"
                else:
                    response = hookdll_encode(url_dlls)

            # In case of PID, the client is trying to notify the creation of
            # a new process to be injected and monitored.
            elif command.startswith("PROCESS:"):
                # We acquire the process lock in order to prevent the analyzer
                # to terminate the analysis while we are operating on the new
                # process.
                PROCESS_LOCK.acquire()

                # Set the current DLL to the default one provided
                # at submission.
                dll = DEFAULT_DLL

                # We parse the process ID.
                data = command[8:]
                process_id = thread_id = None
                if not "," in data:
                    if data.isdigit():
                        process_id = int(data)
                elif len(data.split(",")) == 2:
                    process_id, param = data.split(",")
                    thread_id = None
                    if process_id.isdigit():
                        process_id = int(process_id)
                    else:
                        process_id = None

                    if param.isdigit():
                        thread_id = int(param)
                    else:
                        # XXX: Expect a new DLL as a message parameter?
                        if isinstance(param, str):
                            dll = param

                if process_id:
                    if process_id not in (PID, PPID):
                        # We inject the process only if it's not being
                        # monitored already, otherwise we would generated
                        # polluted logs.
                        if process_id not in PROCESS_LIST:
                            # Open the process and inject the DLL.
                            # Hope it enjoys it.
                            proc = Process(pid=process_id, thread_id=thread_id)

                            filepath = proc.get_filepath()
                            filename = os.path.basename(filepath)

                            log.info("Announced process name: %s", filename)

                            if not protected_filename(filename):
                                # Add the new process ID to the list of
                                # monitored processes.
                                add_pids(process_id)

                                # If we have both pid and tid, then we can use
                                # apc to inject
                                if process_id and thread_id:
                                    proc.inject(dll, apc=True)
                                else:
                                    # we inject using CreateRemoteThread, this
                                    # needs the waiting in order to make sure
                                    # no race conditions occur
                                    proc.inject(dll)
                                    wait = True

                                log.info(
                                    "Successfully injected process with "
                                    "pid %s", proc.pid)
                    else:
                        log.warning("Received request to inject Cuckoo "
                                    "processes, skip")

                # Once we're done operating on the processes list, we release
                # the lock.
                PROCESS_LOCK.release()
            # In case of FILE_NEW, the client is trying to notify the creation
            # of a new file.
            elif command.startswith("FILE_NEW:"):
                # We extract the file path.
                file_path = command[9:].decode("utf-8")
                # We add the file to the list.
                add_file(file_path)
            # In case of FILE_DEL, the client is trying to notify an ongoing
            # deletion of an existing file, therefore we need to dump it
            # straight away.
            elif command.startswith("FILE_DEL:"):
                # Extract the file path.
                file_path = command[9:].decode("utf-8")
                # Dump the file straight away.
                del_file(file_path)
            elif command.startswith("FILE_MOVE:"):
                # syntax = FILE_MOVE:old_file_path::new_file_path
                if "::" in command[10:]:
                    old_fname, new_fname = command[10:].split("::", 1)
                    move_file(old_fname.decode("utf-8"),
                              new_fname.decode("utf-8"))

        KERNEL32.WriteFile(self.h_pipe, create_string_buffer(response),
                           len(response), byref(bytes_read), None)

        KERNEL32.CloseHandle(self.h_pipe)

        # We wait until cuckoomon reports back.
        if wait:
            proc.wait()

        if proc:
            proc.close()

        return True
示例#50
0
    def run(self):
        """Run handler.
        @return: operation status.
        """
        global MONITORED_SERVICES
        global LASTINJECT_TIME
        data = ""
        response = "OK"

        # Read the data submitted to the Pipe Server.
        while True:
            bytes_read = c_int(0)

            buf = create_string_buffer(BUFSIZE)
            success = KERNEL32.ReadFile(self.h_pipe,
                                        buf,
                                        sizeof(buf),
                                        byref(bytes_read),
                                        None)

            data += buf.value

            if not success and KERNEL32.GetLastError() == ERROR_MORE_DATA:
                continue
            # elif not success or bytes_read.value == 0:
            #    if KERNEL32.GetLastError() == ERROR_BROKEN_PIPE:
            #        pass

            break

        if data:
            command = data.strip()

            # Debug, Regular, Warning, or Critical information from CuckooMon.
            if command.startswith("DEBUG:"):
                log.debug(command[6:])
            elif command.startswith("INFO:"):
                log.info(command[5:])
            elif command.startswith("WARNING:"):
                log.warning(command[8:])
            elif command.startswith("CRITICAL:"):
                log.critical(command[9:])

            # Parse the prefix for the received notification.
            # In case of GETPIDS we're gonna return the current process ID
            # and the process ID of our parent process (agent.py).
            elif command == "GETPIDS":
                response = struct.pack("II", PID, PPID)

            # When analyzing we don't want to hook all functions, as we're
            # having some stability issues with regards to webbrowsers.
            elif command == "HOOKDLLS":
                is_url = Config(cfg="analysis.conf").category != "file"

                url_dlls = "ntdll", "kernel32"

                def hookdll_encode(names):
                    # We have to encode each dll name as unicode string
                    # with length 16.
                    names = [name + "\x00" * (16-len(name)) for name in names]
                    f = lambda s: "".join(ch + "\x00" for ch in s)
                    return "".join(f(name) for name in names)

                # If this sample is not a URL, then we don't want to limit
                # any API hooks (at least for now), so we write a null-byte
                # which indicates that all DLLs should be hooked.
                if not is_url:
                    response = "\x00"
                else:
                    response = hookdll_encode(url_dlls)

            # remove pid from process list because we received a notification
            # from kernel land
            elif command.startswith("KTERMINATE:"):
                data = command[11:]
                process_id = int(data)
                if process_id:
                    if process_id in PROCESS_LIST:
                        remove_pid(process_id) 

            # same than below but we don't want to inject any DLLs because
            # it's a kernel analysis
            elif command.startswith("KPROCESS:"):
                PROCESS_LOCK.acquire()
                data = command[9:]
                process_id = int(data)
                thread_id = None
                if process_id:
                    if process_id not in (PID, PPID):
                        if process_id not in PROCESS_LIST:
                            proc = Process(pid=process_id,thread_id=thread_id)
                            filepath = proc.get_filepath()
                            filename = os.path.basename(filepath)

                            if not protected_filename(filename):
                                add_pid(process_id)
                                log.info("Announce process name : %s", filename)
                PROCESS_LOCK.release()                
            
            elif command.startswith("KERROR:"):
                error_msg = command[7:]
                log.error("Error : %s", str(error_msg))
           
            # if a new driver has been loaded, we stop the analysis
            elif command == "KSUBVERT":
                for pid in PROCESS_LIST:
                    log.info("Process with pid %s has terminated", pid)
                    PROCESS_LIST.remove(pid)

            # Handle case of a service being started by a monitored process
            # Switch the service type to own process behind its back so we
            # can monitor the service more easily with less noise
            elif command.startswith("SERVICE:"):
                servname = command[8:]
                si = subprocess.STARTUPINFO()
                si.dwFlags = subprocess.STARTF_USESHOWWINDOW
                si.wShowWindow = subprocess.SW_HIDE
                subprocess.call("sc config " + servname + " type= own", startupinfo=si)
                log.info("Announced starting service \"%s\"", servname)

                if not MONITORED_SERVICES:
                    # Inject into services.exe so we can monitor service creation
                    # if tasklist previously failed to get the services.exe PID we'll be
                    # unable to inject
                    if SERVICES_PID:
                        servproc = Process(pid=SERVICES_PID,suspended=False)
                        filepath = servproc.get_filepath()
                        servproc.inject(dll=DEFAULT_DLL, interest=filepath, nosleepskip=True)
                        LASTINJECT_TIME = datetime.now()
                        servproc.close()
                        KERNEL32.Sleep(1000)
                        MONITORED_SERVICES = True
                    else:
                        log.error('Unable to monitor service %s' % (servname))

            # For now all we care about is bumping up our LASTINJECT_TIME to account for long delays between
            # injection and actual resume time where the DLL would have a chance to load in the new process
            # and report back to have its pid added to the list of monitored processes
            elif command.startswith("RESUME:"):
                LASTINJECT_TIME = datetime.now()

            # Handle case of malware terminating a process -- notify the target
            # ahead of time so that it can flush its log buffer
            elif command.startswith("KILL:"):
                PROCESS_LOCK.acquire()

                process_id = int(command[5:])
                if process_id not in (PID, PPID) and process_id in PROCESS_LIST:
                    # only notify processes we've hooked
                    event_name = TERMINATE_EVENT + str(process_id)
                    event_handle = KERNEL32.OpenEventA(EVENT_MODIFY_STATE, False, event_name)
                    if not event_handle:
                        log.warning("Unable to open termination event for pid %u.", process_id)
                    else:
                        # make sure process is aware of the termination
                        KERNEL32.SetEvent(event_handle)
                        KERNEL32.CloseHandle(event_handle)

                PROCESS_LOCK.release()
            # Handle notification of cuckoomon loading in a process
            elif command.startswith("LOADED:"):
                PROCESS_LOCK.acquire()
                process_id = int(command[7:])
                if process_id not in PROCESS_LIST:
                    add_pids(process_id)
                PROCESS_LOCK.release()
                log.info("Cuckoomon successfully loaded in process with pid %u.", process_id)

            # In case of PID, the client is trying to notify the creation of
            # a new process to be injected and monitored.
            elif command.startswith("PROCESS:"):
                # We acquire the process lock in order to prevent the analyzer
                # to terminate the analysis while we are operating on the new
                # process.
                PROCESS_LOCK.acquire()

                # Set the current DLL to the default one provided
                # at submission.
                dll = DEFAULT_DLL
                suspended = False
                # We parse the process ID.
                data = command[8:]
                if len(data) > 2 and data[1] == ':':
                    if data[0] == '1':
                        suspended = True
                    data = command[10:]

                process_id = thread_id = None
                if "," not in data:
                    if data.isdigit():
                        process_id = int(data)
                elif data.count(",") == 1:
                    process_id, param = data.split(",")
                    thread_id = None
                    if process_id.isdigit():
                        process_id = int(process_id)
                    else:
                        process_id = None

                    if param.isdigit():
                        thread_id = int(param)

                if process_id:
                    if process_id not in (PID, PPID):
                        # We inject the process only if it's not being
                        # monitored already, otherwise we would generate
                        # polluted logs.
                        if process_id not in PROCESS_LIST:
                            # Open the process and inject the DLL.
                            # Hope it enjoys it.
                            proc = Process(pid=process_id,
                                           thread_id=thread_id,
                                           suspended=suspended)

                            filepath = proc.get_filepath()
                            is_64bit = proc.is_64bit()
                            filename = os.path.basename(filepath)

                            log.info("Announced %s process name: %s pid: %d", "64-bit" if is_64bit else "32-bit", filename, process_id)

                            if not in_protected_path(filename):
                                res = proc.inject(dll, filepath)
                                LASTINJECT_TIME = datetime.now()
                            proc.close()
                    else:
                        log.warning("Received request to inject Cuckoo "
                                    "process with pid %d, skip", process_id)

                # Once we're done operating on the processes list, we release
                # the lock.
                PROCESS_LOCK.release()
            # In case of FILE_NEW, the client is trying to notify the creation
            # of a new file.
            elif command.startswith("FILE_NEW:"):
                # We extract the file path.
                file_path = unicode(command[9:].decode("utf-8"))
                # We add the file to the list.
                add_file(file_path)
            # In case of FILE_DEL, the client is trying to notify an ongoing
            # deletion of an existing file, therefore we need to dump it
            # straight away.
            elif command.startswith("FILE_DEL:"):
                # Extract the file path.
                file_path = unicode(command[9:].decode("utf-8"))
                # Dump the file straight away.
                del_file(file_path)
            elif command.startswith("FILE_MOVE:"):
                # Syntax = "FILE_MOVE:old_file_path::new_file_path".
                if "::" in command[10:]:
                    old_fname, new_fname = command[10:].split("::", 1)
                    move_file(unicode(old_fname.decode("utf-8")),
                              unicode(new_fname.decode("utf-8")))
            else:
                log.warning("Received unknown command from cuckoomon: %s", command)

        KERNEL32.WriteFile(self.h_pipe,
                           create_string_buffer(response),
                           len(response),
                           byref(bytes_read),
                           None)

        KERNEL32.CloseHandle(self.h_pipe)

        return True
示例#51
0
    def _inject_process(self, process_id, thread_id, mode):
        """Helper function for injecting the monitor into a process."""
        # We acquire the process lock in order to prevent the analyzer to
        # terminate the analysis while we are operating on the new process.
        self.analyzer.process_lock.acquire()

        # Set the current DLL to the default one provided at submission.
        dll = self.analyzer.default_dll

        if process_id in (self.analyzer.pid, self.analyzer.ppid):
            if process_id not in self.ignore_list["pid"]:
                log.warning("Received request to inject Cuckoo processes, "
                            "skipping it.")
                self.ignore_list["pid"].append(process_id)
            self.analyzer.process_lock.release()
            return

        # We inject the process only if it's not being monitored already,
        # otherwise we would generated polluted logs (if it wouldn't crash
        # horribly to start with).
        if self.analyzer.process_list.has_pid(process_id):
            # This pid is already on the notrack list, move it to the
            # list of tracked pids.
            if not self.analyzer.process_list.has_pid(process_id,
                                                      notrack=False):
                log.debug("Received request to inject pid=%d. It was already "
                          "on our notrack list, moving it to the track list.")

                self.analyzer.process_list.remove_pid(process_id)
                self.analyzer.process_list.add_pid(process_id)
                self.ignore_list["pid"].append(process_id)
            # Spit out an error once and just ignore it further on.
            elif process_id not in self.ignore_list["pid"]:
                log.debug(
                    "Received request to inject pid=%d, but we are "
                    "already injected there.", process_id)
                self.ignore_list["pid"].append(process_id)

            # We're done operating on the processes list, release the lock.
            self.analyzer.process_lock.release()
            return

        # Open the process and inject the DLL. Hope it enjoys it.
        proc = Process(pid=process_id, tid=thread_id)

        filename = os.path.basename(proc.get_filepath())

        if not self.analyzer.files.is_protected_filename(filename):
            # Add the new process ID to the list of monitored processes.
            self.analyzer.process_list.add_pid(process_id)

            # We're done operating on the processes list,
            # release the lock. Let the injection do its thing.
            self.analyzer.process_lock.release()

            # If we have both pid and tid, then we can use APC to inject.
            if process_id and thread_id:
                proc.inject(dll, apc=True, mode="%s" % mode)
            else:
                proc.inject(dll, apc=False, mode="%s" % mode)

            log.info("Injected into process with pid %s and name %r", proc.pid,
                     filename)
示例#52
0
    def run(self):
        """Run handler.
        @return: operation status.
        """
        global MONITORED_SERVICES
        global MONITORED_WMI
        global MONITORED_DCOM
        global MONITORED_TASKSCHED
        global MONITORED_BITS
        global LASTINJECT_TIME
        global NUM_INJECTED
        try:
            data = ""
            response = "OK"

            # Read the data submitted to the Pipe Server.
            while True:
                bytes_read = c_int(0)

                buf = create_string_buffer(BUFSIZE)
                success = KERNEL32.ReadFile(self.h_pipe,
                                            buf,
                                            sizeof(buf),
                                            byref(bytes_read),
                                            None)

                data += buf.value

                if not success and KERNEL32.GetLastError() == ERROR_MORE_DATA:
                    continue
                # elif not success or bytes_read.value == 0:
                #    if KERNEL32.GetLastError() == ERROR_BROKEN_PIPE:
                #        pass

                break

            if data:
                command = data.strip()

                # Debug, Regular, Warning, or Critical information from CuckooMon.
                if command.startswith("DEBUG:"):
                    log.debug(command[6:])
                elif command.startswith("INFO:"):
                    log.info(command[5:])
                elif command.startswith("WARNING:"):
                    log.warning(command[8:])
                elif command.startswith("CRITICAL:"):
                    log.critical(command[9:])

                # Parse the prefix for the received notification.
                # In case of GETPIDS we're gonna return the current process ID
                # and the process ID of our parent process (agent.py).
                elif command == "GETPIDS":
                    hidepids = set()
                    hidepids.update(HIDE_PIDS)
                    hidepids.update([PID, PPID])
                    response = struct.pack("%dI" % len(hidepids), *hidepids)

                # remove pid from process list because we received a notification
                # from kernel land
                elif command.startswith("KTERMINATE:"):
                    data = command[11:]
                    process_id = int(data)
                    if process_id:
                        if process_id in PROCESS_LIST:
                            remove_pid(process_id) 

                # same than below but we don't want to inject any DLLs because
                # it's a kernel analysis
                elif command.startswith("KPROCESS:"):
                    PROCESS_LOCK.acquire()
                    data = command[9:]
                    process_id = int(data)
                    thread_id = None
                    if process_id:
                        if process_id not in (PID, PPID):
                            if process_id not in PROCESS_LIST:
                                proc = Process(pid=process_id,thread_id=thread_id)
                                filepath = proc.get_filepath()
                                filename = os.path.basename(filepath)

                                if not in_protected_path(filename):
                                    add_pid(process_id)
                                    log.info("Announce process name : %s", filename)
                    PROCESS_LOCK.release()                
            
                elif command.startswith("KERROR:"):
                    error_msg = command[7:]
                    log.error("Error : %s", str(error_msg))
           
                # if a new driver has been loaded, we stop the analysis
                elif command == "KSUBVERT":
                    for pid in PROCESS_LIST:
                        log.info("Process with pid %s has terminated", pid)
                        PROCESS_LIST.remove(pid)

                elif command.startswith("INTEROP:"):
                    if not MONITORED_DCOM:
                        MONITORED_DCOM = True
                        dcom_pid = pid_from_service_name("DcomLaunch")
                        if dcom_pid:
                            servproc = Process(pid=dcom_pid,suspended=False)
                            servproc.set_critical()
                            filepath = servproc.get_filepath()
                            servproc.inject(dll=DEFAULT_DLL, interest=filepath, nosleepskip=True)
                            LASTINJECT_TIME = datetime.now()
                            servproc.close()
                            KERNEL32.Sleep(2000)

                elif command.startswith("WMI:"):
                    if not MONITORED_WMI:
                        MONITORED_WMI = True
                        si = subprocess.STARTUPINFO()
                        # STARTF_USESHOWWINDOW
                        si.dwFlags = 1
                        # SW_HIDE
                        si.wShowWindow = 0
                        log.info("Stopping WMI Service")
                        subprocess.call(['net', 'stop', 'winmgmt', '/y'], startupinfo=si)
                        log.info("Stopped WMI Service")
                        subprocess.call("sc config winmgmt type= own", startupinfo=si)

                        if not MONITORED_DCOM:
                            MONITORED_DCOM = True
                            dcom_pid = pid_from_service_name("DcomLaunch")
                            if dcom_pid:
                                servproc = Process(pid=dcom_pid,suspended=False)
                                servproc.set_critical()
                                filepath = servproc.get_filepath()
                                servproc.inject(dll=DEFAULT_DLL, interest=filepath, nosleepskip=True)
                                LASTINJECT_TIME = datetime.now()
                                servproc.close()
                                KERNEL32.Sleep(2000)

                        log.info("Starting WMI Service")
                        subprocess.call("net start winmgmt", startupinfo=si)
                        log.info("Started WMI Service")

                        wmi_pid = pid_from_service_name("winmgmt")
                        if wmi_pid:
                            servproc = Process(pid=wmi_pid,suspended=False)
                            servproc.set_critical()
                            filepath = servproc.get_filepath()
                            servproc.inject(dll=DEFAULT_DLL, interest=filepath, nosleepskip=True)
                            LASTINJECT_TIME = datetime.now()
                            servproc.close()
                            KERNEL32.Sleep(2000)

                elif command.startswith("TASKSCHED:"):
                    if not MONITORED_TASKSCHED:
                        MONITORED_TASKSCHED = True
                        si = subprocess.STARTUPINFO()
                        # STARTF_USESHOWWINDOW
                        si.dwFlags = 1
                        # SW_HIDE
                        si.wShowWindow = 0
                        log.info("Stopping Task Scheduler Service")
                        subprocess.call(['net', 'stop', 'schedule', '/y'], startupinfo=si)
                        log.info("Stopped Task Scheduler Service")
                        subprocess.call("sc config schedule type= own", startupinfo=si)

                        log.info("Starting Task Scheduler Service")
                        subprocess.call("net start schedule", startupinfo=si)
                        log.info("Started Task Scheduler Service")

                        sched_pid = pid_from_service_name("schedule")
                        if sched_pid:
                            servproc = Process(pid=sched_pid,suspended=False)
                            servproc.set_critical()
                            filepath = servproc.get_filepath()
                            servproc.inject(dll=DEFAULT_DLL, interest=filepath, nosleepskip=True)
                            LASTINJECT_TIME = datetime.now()
                            servproc.close()
                            KERNEL32.Sleep(2000)

                elif command.startswith("BITS:"):
                    if not MONITORED_BITS:
                        MONITORED_BITS = True
                        si = subprocess.STARTUPINFO()
                        # STARTF_USESHOWWINDOW
                        si.dwFlags = 1
                        # SW_HIDE
                        si.wShowWindow = 0
                        log.info("Stopping BITS Service")
                        subprocess.call(['net', 'stop', 'BITS', '/y'], startupinfo=si)
                        log.info("Stopped BITS Service")
                        subprocess.call("sc config BITS type= own", startupinfo=si)

                        if not MONITORED_DCOM:
                            MONITORED_DCOM = True
                            dcom_pid = pid_from_service_name("DcomLaunch")
                            if dcom_pid:
                                servproc = Process(pid=dcom_pid,suspended=False)
                                servproc.set_critical()
                                filepath = servproc.get_filepath()
                                servproc.inject(dll=DEFAULT_DLL, interest=filepath, nosleepskip=True)
                                LASTINJECT_TIME = datetime.now()
                                servproc.close()
                                KERNEL32.Sleep(2000)

                        log.info("Starting BITS Service")
                        subprocess.call("net start BITS", startupinfo=si)
                        log.info("Started BITS Service")

                        bits_pid = pid_from_service_name("BITS")
                        if bits_pid:
                            servproc = Process(pid=bits_pid,suspended=False)
                            servproc.set_critical()
                            filepath = servproc.get_filepath()
                            servproc.inject(dll=DEFAULT_DLL, interest=filepath, nosleepskip=True)
                            LASTINJECT_TIME = datetime.now()
                            servproc.close()
                            KERNEL32.Sleep(2000)

                # Handle case of a service being started by a monitored process
                # Switch the service type to own process behind its back so we
                # can monitor the service more easily with less noise
                elif command.startswith("SERVICE:"):
                    servname = command[8:]
                    si = subprocess.STARTUPINFO()
                    # STARTF_USESHOWWINDOW
                    si.dwFlags = 1
                    # SW_HIDE
                    si.wShowWindow = 0
                    subprocess.call("sc config " + servname + " type= own", startupinfo=si)
                    log.info("Announced starting service \"%s\"", servname)

                    if not MONITORED_SERVICES:
                        # Inject into services.exe so we can monitor service creation
                        # if tasklist previously failed to get the services.exe PID we'll be
                        # unable to inject
                        if SERVICES_PID:
                            servproc = Process(pid=SERVICES_PID,suspended=False)
                            servproc.set_critical()
                            filepath = servproc.get_filepath()
                            servproc.inject(dll=DEFAULT_DLL, interest=filepath, nosleepskip=True)
                            LASTINJECT_TIME = datetime.now()
                            servproc.close()
                            KERNEL32.Sleep(1000)
                            MONITORED_SERVICES = True
                        else:
                            log.error('Unable to monitor service %s' % (servname))

                # For now all we care about is bumping up our LASTINJECT_TIME to account for long delays between
                # injection and actual resume time where the DLL would have a chance to load in the new process
                # and report back to have its pid added to the list of monitored processes
                elif command.startswith("RESUME:"):
                    LASTINJECT_TIME = datetime.now()

                # Handle attempted shutdowns/restarts -- flush logs for all monitored processes
                # additional handling can be added later
                elif command.startswith("SHUTDOWN:"):
                    log.info("Received shutdown request")
                    PROCESS_LOCK.acquire()
                    for process_id in PROCESS_LIST:
                        event_name = TERMINATE_EVENT + str(process_id)
                        event_handle = KERNEL32.OpenEventA(EVENT_MODIFY_STATE, False, event_name)
                        if event_handle:
                            KERNEL32.SetEvent(event_handle)
                            KERNEL32.CloseHandle(event_handle)
                            if self.options.get("procmemdump"):
                                p = Process(pid=process_id)
                                p.dump_memory()
                            dump_files()
                    PROCESS_LOCK.release()
                # Handle case of malware terminating a process -- notify the target
                # ahead of time so that it can flush its log buffer
                elif command.startswith("KILL:"):
                    PROCESS_LOCK.acquire()

                    process_id = int(command[5:])
                    if process_id not in (PID, PPID) and process_id in PROCESS_LIST:
                        # only notify processes we've hooked
                        event_name = TERMINATE_EVENT + str(process_id)
                        event_handle = KERNEL32.OpenEventA(EVENT_MODIFY_STATE, False, event_name)
                        if not event_handle:
                            log.warning("Unable to open termination event for pid %u.", process_id)
                        else:
                            log.info("Notified of termination of process with pid %u.", process_id)
                            # dump the memory of exiting processes
                            if self.options.get("procmemdump"):
                                p = Process(pid=process_id)
                                p.dump_memory()
                            # make sure process is aware of the termination
                            KERNEL32.SetEvent(event_handle)
                            KERNEL32.CloseHandle(event_handle)

                    PROCESS_LOCK.release()
                # Handle notification of cuckoomon loading in a process
                elif command.startswith("LOADED:"):
                    PROCESS_LOCK.acquire()
                    process_id = int(command[7:])
                    if process_id not in PROCESS_LIST:
                        add_pids(process_id)
                    PROCESS_LOCK.release()
                    NUM_INJECTED += 1
                    log.info("Cuckoomon successfully loaded in process with pid %u.", process_id)

                # In case of PID, the client is trying to notify the creation of
                # a new process to be injected and monitored.
                elif command.startswith("PROCESS:"):
                    # We acquire the process lock in order to prevent the analyzer
                    # to terminate the analysis while we are operating on the new
                    # process.
                    PROCESS_LOCK.acquire()

                    # Set the current DLL to the default one provided
                    # at submission.
                    dll = DEFAULT_DLL
                    suspended = False
                    # We parse the process ID.
                    data = command[8:]
                    if len(data) > 2 and data[1] == ':':
                        if data[0] == '1':
                            suspended = True
                        data = command[10:]

                    process_id = thread_id = None
                    if "," not in data:
                        if data.isdigit():
                            process_id = int(data)
                    elif data.count(",") == 1:
                        process_id, param = data.split(",")
                        thread_id = None
                        if process_id.isdigit():
                            process_id = int(process_id)
                        else:
                            process_id = None

                        if param.isdigit():
                            thread_id = int(param)

                    if process_id:
                        if process_id not in (PID, PPID):
                            # We inject the process only if it's not being
                            # monitored already, otherwise we would generate
                            # polluted logs.
                            if process_id not in PROCESS_LIST:
                                # Open the process and inject the DLL.
                                # Hope it enjoys it.
                                proc = Process(pid=process_id,
                                               thread_id=thread_id,
                                               suspended=suspended)

                                filepath = proc.get_filepath()
                                # if it's a URL analysis, provide the URL to all processes as
                                # the "interest" -- this will allow cuckoomon to see in the
                                # child browser process that a URL analysis is occurring
                                if self.config.category == "file" or NUM_INJECTED > 1:
                                    interest = filepath
                                else:
                                    interest = self.config.target

                                is_64bit = proc.is_64bit()
                                filename = os.path.basename(filepath)

                                if not in_protected_path(filename) and proc.check_inject():
                                    log.info("Announced %s process name: %s pid: %d", "64-bit" if is_64bit else "32-bit", filename, process_id)
                                    proc.inject(dll, interest)
                                    LASTINJECT_TIME = datetime.now()
                                proc.close()
                        else:
                            log.warning("Received request to inject Cuckoo "
                                        "process with pid %d, skip", process_id)

                    # Once we're done operating on the processes list, we release
                    # the lock.
                    PROCESS_LOCK.release()
                # In case of FILE_NEW, the client is trying to notify the creation
                # of a new file.
                elif command.startswith("FILE_NEW:"):
                    FILES_LIST_LOCK.acquire()
                    # We extract the file path.
                    file_path = unicode(command[9:].decode("utf-8"))
                    # We add the file to the list.
                    add_file(file_path)
                    FILES_LIST_LOCK.release()
                # In case of FILE_DEL, the client is trying to notify an ongoing
                # deletion of an existing file, therefore we need to dump it
                # straight away.
                elif command.startswith("FILE_DEL:"):
                    FILES_LIST_LOCK.acquire()
                    # Extract the file path.
                    file_path = unicode(command[9:].decode("utf-8"))
                    # Dump the file straight away.
                    del_file(file_path)
                    FILES_LIST_LOCK.release()
                elif command.startswith("FILE_MOVE:"):
                    FILES_LIST_LOCK.acquire()
                    # Syntax = "FILE_MOVE:old_file_path::new_file_path".
                    if "::" in command[10:]:
                        old_fname, new_fname = command[10:].split("::", 1)
                        move_file(unicode(old_fname.decode("utf-8")),
                                  unicode(new_fname.decode("utf-8")))
                    FILES_LIST_LOCK.release()
                else:
                    log.warning("Received unknown command from cuckoomon: %s", command)

            KERNEL32.WriteFile(self.h_pipe,
                               create_string_buffer(response),
                               len(response),
                               byref(bytes_read),
                               None)

            KERNEL32.CloseHandle(self.h_pipe)

            return True
        except Exception as e:
            error_exc = traceback.format_exc()
            log.exception(error_exc)
            return True
示例#53
0
 def start(self, path):
     try:
         sc = self.get_path("sc.exe")
         servicename = self.options.get("servicename", "CAPEService")
         servicedesc = self.options.get("servicedesc", "CAPE Service")
         arguments = self.options.get("arguments")
         if "." not in os.path.basename(path):
             new_path = path + ".exe"
             os.rename(path, new_path)
             path = new_path
         binPath = '"{0}"'.format(path)
         if arguments:
             binPath += " {0}".format(arguments)
         scm_handle = ADVAPI32.OpenSCManagerA(None, None,
                                              SC_MANAGER_ALL_ACCESS)
         if scm_handle == 0:
             log.info("Failed to open SCManager")
             log.info(ctypes.FormatError())
             return
         service_handle = ADVAPI32.CreateServiceA(
             scm_handle,
             servicename,
             servicedesc,
             SERVICE_ALL_ACCESS,
             SERVICE_WIN32_OWN_PROCESS,
             SERVICE_DEMAND_START,
             SERVICE_ERROR_IGNORE,
             binPath,
             None,
             None,
             None,
             None,
             None,
         )
         if service_handle == 0:
             log.info("Failed to create service")
             log.info(ctypes.FormatError())
             return
         log.info("Created service (handle: 0x%x)", service_handle)
         servproc = Process(options=self.options,
                            config=self.config,
                            pid=self.config.services_pid,
                            suspended=False)
         filepath = servproc.get_filepath()
         is_64bit = servproc.is_64bit()
         if is_64bit:
             servproc.inject(injectmode=INJECT_QUEUEUSERAPC,
                             interest=filepath,
                             nosleepskip=True)
         else:
             servproc.inject(injectmode=INJECT_QUEUEUSERAPC,
                             interest=filepath,
                             nosleepskip=True)
         servproc.close()
         KERNEL32.Sleep(500)
         service_launched = ADVAPI32.StartServiceA(service_handle, 0, None)
         if service_launched == True:
             log.info("Successfully started service")
         else:
             log.info(ctypes.FormatError())
             log.info("Failed to start service")
         ADVAPI32.CloseServiceHandle(service_handle)
         ADVAPI32.CloseServiceHandle(scm_handle)
         return
     except Exception as e:
         log.info(sys.exc_info()[0])
         log.info(e)
         log.info(e.__dict__)
         log.info(e.__class__)
         log.exception(e)
示例#54
0
文件: analyzer.py 项目: xarly/cuckoo
    def run(self):
        """Run handler.
        @return: operation status.
        """
        data = ""
        response = "OK"
        wait = False
        proc = None

        # Read the data submitted to the Pipe Server.
        while True:
            bytes_read = c_int(0)

            buf = create_string_buffer(BUFSIZE)
            success = KERNEL32.ReadFile(self.h_pipe,
                                        buf,
                                        sizeof(buf),
                                        byref(bytes_read),
                                        None)

            data += buf.value

            if not success and KERNEL32.GetLastError() == ERROR_MORE_DATA:
                continue
            #elif not success or bytes_read.value == 0:
            #    if KERNEL32.GetLastError() == ERROR_BROKEN_PIPE:
            #        pass
            
            break

        if data:
            command = data.strip()

            # Parse the prefix for the received notification.
            # In case of GETPIDS we're gonna return the current process ID
            # and the process ID of our parent process (agent.py).
            if command == "GETPIDS":
                response = struct.pack("II", PID, PPID)
            # In case of PID, the client is trying to notify the creation of
            # a new process to be injected and monitored.
            elif command.startswith("PROCESS:"):
                # We acquire the process lock in order to prevent the analyzer
                # to terminate the analysis while we are operating on the new
                # process.
                PROCESS_LOCK.acquire()

                # We parse the process ID.
                data = command[8:]

                process_id = thread_id = None
                if not "," in data:
                    if data.isdigit():
                        process_id = int(data)
                elif len(data.split(",")) == 2:
                    process_id, thread_id = data.split(",")
                    if process_id.isdigit():
                        process_id = int(process_id)
                    else:
                        process_id = None

                    if thread_id.isdigit():
                        thread_id = int(thread_id)
                    else:
                        thread_id = None

                if process_id:
                    if process_id not in (PID, PPID):
                        # We inject the process only if it's not being monitored
                        # already, otherwise we would generated polluted logs.
                        if process_id not in PROCESS_LIST:
                            # Open the process and inject the DLL.
                            # Hope it enjoys it.
                            proc = Process(pid=process_id,
                                           thread_id=thread_id)

                            filepath = proc.get_filepath()
                            filename = os.path.basename(filepath)

                            log.info("Announced process name: %s", filename)

                            if not protected_filename(filename):
                                # Add the new process ID to the list of monitored
                                # processes.
                                add_pids(process_id)

                                # If we have both pid and tid, then we can use
                                # apc to inject
                                if process_id and thread_id:
                                    proc.inject(apc=True)
                                else:
                                    # we inject using CreateRemoteThread, this
                                    # needs the waiting in order to make sure no
                                    # race conditions occur
                                    proc.inject()
                                    wait = True

                                log.info("Successfully injected process with pid %s", proc.pid)
                    else:
                        log.warning("Received request to inject Cuckoo processes, skip")

                # Once we're done operating on the processes list, we release
                # the lock.
                PROCESS_LOCK.release()
            # In case of FILE_NEW, the client is trying to notify the creation
            # of a new file.
            elif command.startswith("FILE_NEW:"):
                # We extract the file path.
                file_path = command[9:].decode("utf-8")
                # We add the file to the list.
                add_file(file_path)
            # In case of FILE_DEL, the client is trying to notify an ongoing
            # deletion of an existing file, therefore we need to dump it
            # straight away.
            elif command.startswith("FILE_DEL:"):
                # Extract the file path.
                file_path = command[9:].decode("utf-8")
                # Dump the file straight away.
                del_file(file_path)
            elif command.startswith("FILE_MOVE:"):
                # syntax = FILE_MOVE:old_file_path::new_file_path
                if "::" in command[10:]:
                    old_fname, new_fname = command[10:].split("::", 1)
                    move_file(old_fname.decode("utf-8"),
                              new_fname.decode("utf-8"))

        KERNEL32.WriteFile(self.h_pipe,
                           create_string_buffer(response),
                           len(response),
                           byref(bytes_read),
                           None)

        KERNEL32.CloseHandle(self.h_pipe)

        # We wait until cuckoomon reports back.
        if wait:
            proc.wait()

        if proc:
            proc.close()

        return True