def driver_dump(self):
     procs = list(tasks.pslist(self.addr_space))
     mods = dict(
         (mod.DllBase.v(), mod) for mod in modules.lsmod(self.addr_space))
     for mod in mods.values():
         mod_base = mod.DllBase.v()
         mode_end = mod_base + mod.SizeOfImage
         space = tasks.find_space(self.addr_space, procs, mod_base)
         if space:
             pe_data = self.get_pe_content(space, mod_base)
             if self._config.LIST_SECTIONS:
                 yield PESection(mod.BaseDllName,
                                 self.get_pe_sections(pe_data))
             else:
                 sections = self.process_section(None, self._config.SECTION,
                                                 pe_data)
                 for sec in sections:
                     for engine in self.hash_engines:
                         yield DriverObject(sec['data'], mod_base, mode_end,
                                            mod.FullDllName, engine,
                                            sec['section'])
                         if self._config.TMP_FOLDER:
                             dump_path = os.path.join(
                                 self._config.TMP_FOLDER,
                                 'driver.{0:x}.{1}{2}.sys'.format(
                                     mod_base, mod.BaseDllName,
                                     sec['section']))
                             self.backup_file(dump_path, sec['data'])
Esempio n. 2
0
    def calculate(self):
        addr_space = utils.load_as(self._config)

        ## Get a sorted list of module addresses
        mods = dict((addr_space.address_mask(mod.DllBase), mod)
                    for mod in modules.lsmod(addr_space))
        mod_addrs = sorted(mods.keys())

        ssdts = set()

        if addr_space.profile.metadata.get('memory_model', '32bit') == '32bit':
            # Gather up all SSDTs referenced by threads
            debug.info("[x86] Gathering all referenced SSDTs from KTHREADs...")
            for proc in tasks.pslist(addr_space):
                for thread in proc.ThreadListHead.list_of_type(
                        "_ETHREAD", "ThreadListEntry"):
                    ssdt_obj = thread.Tcb.ServiceTable.dereference_as(
                        '_SERVICE_DESCRIPTOR_TABLE')
                    ssdts.add(ssdt_obj)
        else:
            debug.info(
                "[x64] Gathering all referenced SSDTs from KeAddSystemServiceTable..."
            )
            # The NT module always loads first
            ntos = list(modules.lsmod(addr_space))[0]
            func_rva = ntos.getprocaddress("KeAddSystemServiceTable")
            if func_rva == None:
                raise StopIteration("Cannot locate KeAddSystemServiceTable")
            KeAddSystemServiceTable = ntos.DllBase + func_rva
            for table_rva in find_tables(KeAddSystemServiceTable, addr_space):
                ssdt_obj = obj.Object("_SERVICE_DESCRIPTOR_TABLE",
                                      ntos.DllBase + table_rva, addr_space)
                ssdts.add(ssdt_obj)

        # Get a list of *unique* SSDT entries. Typically we see only two.
        tables = set()

        for ssdt_obj in ssdts:
            for i, desc in enumerate(ssdt_obj.Descriptors):
                # Apply some extra checks - KiServiceTable should reside in kernel memory and ServiceLimit
                # should be greater than 0 but not unbelievably high
                if not desc.is_valid(
                ) or desc.ServiceLimit <= 0 or desc.ServiceLimit >= 0xFFFF or desc.KiServiceTable <= 0x80000000:
                    break
                else:
                    tables.add(
                        (i, desc.KiServiceTable.v(), desc.ServiceLimit.v()))

        debug.info("Finding appropriate address space for tables...")
        tables_with_vm = []
        procs = list(tasks.pslist(addr_space))
        for idx, table, n in tables:
            vm = tasks.find_space(addr_space, procs, table)
            if vm:
                tables_with_vm.append((idx, table, n, vm))
            else:
                debug.debug("[SSDT not resident at 0x{0:08X}]\n".format(table))

        for idx, table, n, vm in sorted(tables_with_vm, key=itemgetter(0)):
            yield idx, table, n, vm, mods, mod_addrs
Esempio n. 3
0
 def generator(self, data):
     for addr_space, procs, mod_base, mod_name in data:
         space = tasks.find_space(addr_space, procs, mod_base)
         if space == None:
             result = "Error: Cannot acquire AS"
         else:
             dump_file = "driver.{0:x}.sys".format(mod_base)
             result = self.dump_pe(space, mod_base, dump_file)
         yield (0, [Address(mod_base), str(mod_name), str(result)])
Esempio n. 4
0
    def calculate(self):
        addr_space = utils.load_as(self._config)

        ## Get a sorted list of module addresses
        mods = dict((addr_space.address_mask(mod.DllBase), mod) for mod in modules.lsmod(addr_space))
        mod_addrs = sorted(mods.keys())

        ssdts = set()

        if addr_space.profile.metadata.get("memory_model", "32bit") == "32bit":
            # Gather up all SSDTs referenced by threads
            print "[x86] Gathering all referenced SSDTs from KTHREADs..."
            for proc in tasks.pslist(addr_space):
                for thread in proc.ThreadListHead.list_of_type("_ETHREAD", "ThreadListEntry"):
                    ssdt_obj = thread.Tcb.ServiceTable.dereference_as("_SERVICE_DESCRIPTOR_TABLE")
                    ssdts.add(ssdt_obj)
        else:
            print "[x64] Gathering all referenced SSDTs from KeAddSystemServiceTable..."
            # The NT module always loads first
            ntos = list(modules.lsmod(addr_space))[0]
            func_rva = ntos.getprocaddress("KeAddSystemServiceTable")
            if func_rva == None:
                raise StopIteration("Cannot locate KeAddSystemServiceTable")
            KeAddSystemServiceTable = ntos.DllBase + func_rva
            for table_rva in find_tables(KeAddSystemServiceTable, addr_space):
                ssdt_obj = obj.Object("_SERVICE_DESCRIPTOR_TABLE", ntos.DllBase + table_rva, addr_space)
                ssdts.add(ssdt_obj)

        # Get a list of *unique* SSDT entries. Typically we see only two.
        tables = set()

        for ssdt_obj in ssdts:
            for i, desc in enumerate(ssdt_obj.Descriptors):
                # Apply some extra checks - KiServiceTable should reside in kernel memory and ServiceLimit
                # should be greater than 0 but not unbelievably high
                if (
                    desc.is_valid()
                    and desc.ServiceLimit > 0
                    and desc.ServiceLimit < 0xFFFF
                    and desc.KiServiceTable > 0x80000000
                ):
                    tables.add((i, desc.KiServiceTable.v(), desc.ServiceLimit.v()))

        print "Finding appropriate address space for tables..."
        tables_with_vm = []
        procs = list(tasks.pslist(addr_space))
        for idx, table, n in tables:
            vm = tasks.find_space(addr_space, procs, table)
            if vm:
                tables_with_vm.append((idx, table, n, vm))
            else:
                debug.debug("[SSDT not resident at 0x{0:08X}]\n".format(table))

        for idx, table, n, vm in sorted(tables_with_vm, key=itemgetter(0)):
            yield idx, table, n, vm, mods, mod_addrs
Esempio n. 5
0
 def generator(self, data):
     for addr_space, procs, mod_base, mod_name in data:
         space = tasks.find_space(addr_space, procs, mod_base)
         if space == None:
             result = "Error: Cannot acquire AS"
         else:
             dump_file = "driver.{0:x}.sys".format(mod_base)
             result = self.dump_pe(space, mod_base, dump_file)
         yield (0, [Address(mod_base),
                       str(mod_name),
                       str(result)])
Esempio n. 6
0
    def calculate(self):
        if self._config.TAP_FILE is None or not os.path.exists(
                self._config.TAP_FILE):
            debug.error("Tap file not found")
        taplist = open(self._config.TAP_FILE, "r")

        taps = []
        for line in taplist:
            line = line.split()
            (stack, cr3) = line[:-1], line[-1]
            try:
                stack = [int(s, 16) for s in stack]
                cr3 = int(cr3, 16)
            except ValueError:
                debug.error("Tap file format invalid.")
            taps.append((stack, cr3))

        cr3s = set(t[1] for t in taps)
        cr3s.discard(0)

        # First do the userland ones
        addr_space = utils.load_as(self._config)
        procs = list(tasks.pslist(addr_space))
        # CR3 => proc mapping
        proc_map = {}
        for proc in procs:
            dtb = proc.Pcb.DirectoryTableBase.v()
            if dtb in cr3s: proc_map[dtb] = proc

        for cr3, proc in proc_map.items():
            print ">>> Working on {0}[{1}]".format(proc.ImageFileName,
                                                   proc.UniqueProcessId)

            ps_ad = proc.get_process_address_space()
            proc_taps = [t for t in taps if t[1] == cr3]
            mods = list(proc.get_load_modules())
            sorted_mods = sorted([(m.DllBase.v(), m.SizeOfImage.v(),
                                   str(m.BaseDllName)) for m in mods])

            for v in self.resolve_taps(proc_taps, sorted_mods,
                                       lambda m: ps_ad):
                yield v + (proc.ImageFileName, )

        # Now kernel mode taps
        print ">>> Working on kernel taps"
        kern_taps = [t for t in taps if t[1] == 0]
        sorted_mods = sorted([(mod.DllBase.v(), mod.SizeOfImage.v(),
                               str(mod.BaseDllName))
                              for mod in modules.lsmod(addr_space)])
        bases = [m[0] for m in sorted_mods]
        for v in self.resolve_taps(
                kern_taps, sorted_mods,
                lambda m: tasks.find_space(addr_space, procs, m)):
            yield v + ("Kernel", )
Esempio n. 7
0
 def __createModules(self):
     self.stateinfo = "Step {:<2d} / {:<2d}: Modules -- ModScan".format(
         self.__step, self.__steps)
     self.__scanned_modules = Set([
         ldr_entry.obj_offset
         for ldr_entry in modscan.ModScan(self._config).calculate()
     ])
     self.stateinfo = "Step {:<2d} / {:<2d}: Modules -- Modules calculate".format(
         self.__step, self.__steps)
     self.__loaded_modules = Set([
         module.obj_vm.vtop(module.obj_offset)
         for module in modules.Modules(self._config).calculate()
     ])
     self.__unlinked_or_hidden = self.__scanned_modules.difference(
         self.__loaded_modules)
     self.__modulesNode = Node("Modules", 0, None, self)
     self.__modulesNode.setDir()
     self.__modulesNode.__disown__()
     unknown = 0
     address_space = utils.load_as(self._config, astype='physical')
     kernel_as = utils.load_as(self._config)
     procs = list(tasks.pslist(kernel_as))
     modcount = 1
     lmodcount = len(self.__scanned_modules)
     for offset in self.__scanned_modules:
         self.stateinfo = "Step {:<2d} / {:<2d}: Modules -- creating nodes ({:>6d} / {:<6d})".format(
             self.__step, self.__steps, modcount, lmodcount)
         modcount += 1
         ldr_entry = obj.Object('_LDR_DATA_TABLE_ENTRY',
                                vm=address_space,
                                offset=offset,
                                native_vm=kernel_as)
         if not ldr_entry.BaseDllName:
             unknown += 1
             name = "Unknown" + str(unknown)
         else:
             name = str(ldr_entry.BaseDllName)
         unlinked_or_hidden = False
         if offset in self.__unlinked_or_hidden:
             unlinked_or_hidden = True
         aspace = tasks.find_space(kernel_as, procs, ldr_entry.DllBase.v())
         n = ModuleNode(name, ldr_entry, self.__modulesNode, self, aspace,
                        unlinked_or_hidden)
         n.__disown__()
     self.registerTree(self.root, self.__modulesNode)
     self.__step += 1
Esempio n. 8
0
    def render_text(self, outfd, data):
        if self._config.DUMP_DIR == None:
            debug.error("Please specify a dump directory (--dump-dir)")
        if not os.path.isdir(self._config.DUMP_DIR):
            debug.error(self._config.DUMP_DIR + " is not a directory")

        self.table_header(outfd, [("Module Base", "[addrpad]"),
                                  ("Module Name", "20"), ("Result", "")])

        for addr_space, procs, mod_base, mod_name in data:
            space = tasks.find_space(addr_space, procs, mod_base)
            if space == None:
                result = "Error: Cannot acquire AS"
            else:
                dump_file = "driver.{0:x}.sys".format(mod_base)
                result = self.dump_pe(space, mod_base, dump_file)
            self.table_row(outfd, mod_base, mod_name, result)
Esempio n. 9
0
    def render_text(self, outfd, data):
        if self._config.DUMP_DIR == None:
            debug.error("Please specify a dump directory (--dump-dir)")
        if not os.path.isdir(self._config.DUMP_DIR):
            debug.error(self._config.DUMP_DIR + " is not a directory")

        self.table_header(outfd, [("Module Base", "[addrpad]"),
                           ("Module Name", "20"),
                           ("Result", "")])

        for addr_space, procs, mod_base, mod_name in data:
            space = tasks.find_space(addr_space, procs, mod_base)
            if space == None:
                result = "Error: Cannot acquire AS"
            else:
                dump_file = "driver.{0:x}.sys".format(mod_base)
                result = self.dump_pe(space, mod_base, dump_file)
            self.table_row(outfd, mod_base, mod_name, result)
Esempio n. 10
0
    def calculate(self):

        if not has_distorm:
            debug.error("You must install distorm3")

        addr_space = utils.load_as(self._config)

        all_tasks = list(tasks.pslist(addr_space))
        all_mods = list(modules.lsmod(addr_space))

        # Operate in kernel mode if pid is not supplied
        if not self._config.PID:
            if not self._config.BASE:
                debug.error("You must specify --BASE")

            base_address = self._config.BASE
            size_to_read = self._config.SIZE

            # Get the size from the module list if its not supplied
            if not size_to_read:
                for module in all_mods:
                    if module.DllBase == base_address:
                        size_to_read = module.SizeOfImage
                        break
                # Alternately, try the size from the PE header
                if not size_to_read:
                    pefile = obj.Object("_IMAGE_DOS_HEADER",
                                        offset=base_address,
                                        vm=addr_space)
                    try:
                        nt_header = pefile.get_nt_header()
                        size_to_read = nt_header.OptionalHeader.SizeOfImage
                    except ValueError:
                        pass

                    if not size_to_read:
                        debug.error("You must specify --SIZE")

            kernel_space = tasks.find_space(addr_space, all_tasks,
                                            base_address)

            if not kernel_space:
                debug.error("Cannot read supplied address")

            data = kernel_space.zread(base_address, size_to_read)
            apis = self.enum_apis(all_mods)
            addr_space = kernel_space
        else:
            # In process mode, we find the process by PID
            task = None

            for atask in all_tasks:
                if atask.UniqueProcessId == self._config.PID:
                    task = atask
                    break

            if not task:
                debug.error("You must supply an active PID")

            task_space = task.get_process_address_space()

            if not task_space:
                debug.error("Cannot acquire process AS")

            all_mods = list(task.get_load_modules())

            # PEB is paged or no DLLs loaded
            if not all_mods:
                debug.error("Cannot load DLLs in process AS")

            # If an address is supplied with a size, try to get
            # the size from the vad node. If neither are supplied,
            # assume we should carve the main process executable.
            if self._config.BASE:
                base_address = self._config.BASE
                size_to_read = self._config.SIZE

                if not size_to_read:
                    for vad in task.VadRoot.traverse():
                        if base_address >= vad.Start and base_address <= vad.End:
                            size_to_read = vad.Length
                    if not size_to_read:
                        debug.error("You must specify --SIZE")
            else:
                # Its OK to blindly take the 0th element because the
                # executable is always the first module to load.
                base_address = all_mods[0].DllBase
                size_to_read = all_mods[0].SizeOfImage

            data = task_space.zread(base_address, size_to_read)
            apis = self.enum_apis(all_mods)
            addr_space = task_space

        # This is a dictionary of confirmed API calls.
        calls_imported = dict(
            (iat, call)
            for (_, iat,
                 call) in self.call_scan(addr_space, base_address, data)
            if call in apis)

        # Scan forward
        self._vicinity_scan(addr_space,
                            calls_imported,
                            apis,
                            base_address,
                            len(data),
                            forward=True)

        # Scan reverse
        self._vicinity_scan(addr_space,
                            calls_imported,
                            apis,
                            base_address,
                            len(data),
                            forward=False)

        for iat, call in sorted(calls_imported.items()):
            yield iat, call, apis[call][0], apis[call][1]
Esempio n. 11
0
        if "Symlink" in self._config.TYPE:
            data = filescan.SymLinkScan(self._config).calculate()
        for link in data:
            objct = link.get_object_header()
            line = "[{6}SYMLINK]{0} {1}->{2}{0} POffset: {3}/Ptr: {4}/Hnd: {5}".format(
                "" if body else "|", str(objct.NameInfo.Name or ''),
                str(link.LinkTarget or ''), link.obj_offset,
                objct.PointerCount, objct.HandleCount, self._config.MACHINE)
            yield self.getoutput(line, link.CreationTime, body=body)

        data = []
        if "TimeDateStamp" in self._config.TYPE:
            data = moddump.ModDump(self._config).calculate()
        for aspace, procs, mod_base, mod_name in data:
            mod_name = str(mod_name or '')
            space = tasks.find_space(aspace, procs, mod_base)
            if space != None:
                try:
                    pe_file = obj.Object("_IMAGE_DOS_HEADER",
                                         offset=mod_base,
                                         vm=space)
                    header = pe_file.get_nt_header()
                except ValueError, ve:
                    continue
                line = "[{3}PE HEADER (module)]{0} {1}{0} Base: {2:#010x}".format(
                    "" if body else "|", mod_name, mod_base,
                    self._config.MACHINE)
                yield self.getoutput(line,
                                     header.FileHeader.TimeDateStamp,
                                     body=body)
Esempio n. 12
0
    def calculate(self):

        addr_space = utils.load_as(self._config)

        if not has_distorm3:
            debug.error("Install distorm3 code.google.com/p/distorm/")

        if not self.is_valid_profile(addr_space.profile):
            debug.error("This command does not support the selected profile.")

        if not self._config.SKIP_PROCESS:
            for proc in self.filter_tasks(tasks.pslist(addr_space)):
                process_name = str(proc.ImageFileName).lower()

                if (self._config.QUICK
                        and process_name not in self.critical_process):
                    #debug.debug("Skipping non-critical process {0} ({1})".format(
                    #    process_name, proc.UniqueProcessId))
                    continue

                process_space = proc.get_process_address_space()
                if not process_space:
                    #debug.debug("Cannot acquire process AS for {0} ({1})".format(
                    #    process_name, proc.UniqueProcessId))
                    continue

                module_group = ModuleGroup(proc.get_load_modules())

                for dll in module_group.mods:

                    if not process_space.is_valid_address(dll.DllBase):
                        continue

                    dll_name = str(dll.BaseDllName or '').lower()

                    if (self._config.QUICK
                            and dll_name not in self.critical_dlls
                            and dll.DllBase != proc.Peb.ImageBaseAddress):
                        #debug.debug("Skipping non-critical dll {0} at {1:#x}".format(
                        #    dll_name, dll.DllBase))
                        continue

                    #debug.debug("Analyzing {0}!{1}".format(process_name, dll_name))

                    for hook in self.get_hooks(HOOK_MODE_USER, process_space,
                                               dll, module_group):
                        yield proc, dll, hook

        if not self._config.SKIP_KERNEL:
            process_list = list(tasks.pslist(addr_space))
            module_group = ModuleGroup(modules.lsmod(addr_space))

            for mod in module_group.mods:

                #module_name = str(mod.BaseDllName or '')
                #debug.debug("Analyzing {0}".format(module_name))

                kernel_space = tasks.find_space(addr_space, process_list,
                                                mod.DllBase)

                if not kernel_space:
                    #debug.debug("No kernel AS for {0} at {1:#x}".format(
                    #    module_name, mod.DllBase))
                    continue

                for hook in self.get_hooks(HOOK_MODE_KERNEL, kernel_space, mod,
                                           module_group):
                    yield None, mod, hook
Esempio n. 13
0
    def calculate(self):
        addr_space = utils.load_as(self._config)

        self._config.update('TIMELINE', -1)
        pids = {}  #dictionary of process IDs/ImageFileName
        offsets = []  #process offsets

        im = self.get_image_time(addr_space)
        event = "{0}|[END LIVE RESPONSE]\n".format(im['ImageDatetime'])
        yield event

        # Get EPROCESS
        psscan = filescan.PSScan.calculate(self)
        for eprocess in psscan:
            if eprocess.obj_offset not in offsets:
                offsets.append(eprocess.obj_offset)

            ts = eprocess.CreateTime or '-1'
            line = "{0}|{1}|{2}|{3}|{4}|{5}|0x{6:08x}||\n".format(
                eprocess.CreateTime or '-1', "[PROCESS]",
                eprocess.ImageFileName, eprocess.UniqueProcessId,
                eprocess.InheritedFromUniqueProcessId, eprocess.ExitTime or '',
                eprocess.obj_offset)
            pids[eprocess.UniqueProcessId.v()] = eprocess.ImageFileName
            yield line

        # Get Sockets and Evtlogs XP/2k3 only
        if addr_space.profile.metadata.get('major', 0) == 5:
            #socks = sockets.Sockets.calculate(self)
            socks = sockscan.SockScan.calculate(self)
            for sock in socks:
                la = "{0}:{1}".format(sock.LocalIpAddress, sock.LocalPort)
                line = "{0}|[SOCKET]|{1}|{2}|Protocol: {3} ({4})|{5:#010x}|||\n".format(
                    sock.CreateTime, sock.Pid, la, sock.Protocol,
                    protos.protos.get(sock.Protocol.v(), "-"), sock.obj_offset)
                yield line

            stuff = evtlogs.EvtLogs.calculate(self)
            for name, buf in stuff:
                lines = self.parse_evt_info(name, buf)
                for l in lines:
                    l = l.replace("\n", "")
                    t = l.split("|")
                    line = '{0} |[EVT LOG]|{1}|{2}|{3}|{4}|{5}|{6}|{7}\n'.format(
                        t[0], t[1], t[2], t[3], t[4], t[5], t[6], t[7])
                    yield line
        else:
            # Vista+
            nets = netscan.Netscan.calculate(self)
            for offset, proto, laddr, lport, raddr, rport, state, p, ctime in nets:
                conn = "{0}:{1} -> {2}:{3}".format(laddr, lport, raddr, rport)
                line = "{0}|[NETWORK CONNECTION]|{1}|{2}|{3}|{4}|{5:<#10x}||\n".format(
                    ctime, p.UniqueProcessId, conn, proto, state, offset)
                yield line

        # Get threads
        threads = modscan.ThrdScan.calculate(self)
        for thread in threads:
            try:
                image = pids[thread.Cid.UniqueProcess.v()]
            except:
                image = ""
            line = "{0}|{1}|{2}|{3}|{4}|{5}|||\n".format(
                thread.CreateTime or '-1',
                "[THREAD]",
                image,
                thread.Cid.UniqueProcess,
                thread.Cid.UniqueThread,
                thread.ExitTime or '',
            )
            yield line

        # now we get to the PE part.  All PE's are dumped in case you want to inspect them later

        # Get module offsets by scanning
        mod_offsets = []
        data = modscan.ModScan.calculate(self)
        for module in data:
            base = "{0:#010x}".format(module.DllBase)
            mod_offsets.append(base)

        # and get PE timestamps for those modules
        for base in mod_offsets:
            self._config.update('OFFSET', int(base, 16))
            data = moddump.ModDump.calculate(self)

            for addr_space, procs, mod_base, mod_name in data:
                space = tasks.find_space(addr_space, procs, mod_base)
                if space != None:
                    try:
                        header = self.get_nt_header(space, mod_base)
                    except ValueError, ve:
                        continue

                    try:
                        line = "{0}|{1}|{2}|{3}|{4:#010x}|||||\n".format(
                            self.time_stamp(header.FileHeader.TimeDateStamp)
                            or '-1', "[PE Timestamp (module)]", mod_name, "",
                            mod_base)
                    except:
                        line = "{0}|{1}|{2}|{3}|{4}|||||\n".format(
                            '-1', "[PE Timestamp (module)]", mod_name, "",
                            mod_base)
                    yield line
Esempio n. 14
0
    def calculate(self):
        addr_space = utils.load_as(self._config)

        self._config.update('TIMELINE', -1)
        pids = {}     #dictionary of process IDs/ImageFileName
        offsets = []  #process offsets
        
        im = self.get_image_time(addr_space) 
        event = "{0}|[END LIVE RESPONSE]\n".format(im['ImageDatetime'])
        yield event
                

        # Get EPROCESS 
        psscan = filescan.PSScan.calculate(self)
        for eprocess in psscan:
            if eprocess.obj_offset not in offsets:
                offsets.append(eprocess.obj_offset)

            ts = eprocess.CreateTime or '-1'
            line = "{0}|{1}|{2}|{3}|{4}|{5}|0x{6:08x}||\n".format(
                    eprocess.CreateTime or '-1', 
                    "[PROCESS]",
                    eprocess.ImageFileName,
                    eprocess.UniqueProcessId,
                    eprocess.InheritedFromUniqueProcessId,
                    eprocess.ExitTime or '',
                    eprocess.obj_offset)
            pids[eprocess.UniqueProcessId.v()] = eprocess.ImageFileName
            yield line 

        # Get Sockets and Evtlogs XP/2k3 only
        if addr_space.profile.metadata.get('major', 0) == 5:
            #socks = sockets.Sockets.calculate(self)
            socks = sockscan.SockScan.calculate(self)
            for sock in socks:
                la = "{0}:{1}".format(sock.LocalIpAddress, sock.LocalPort)
                line = "{0}|[SOCKET]|{1}|{2}|Protocol: {3} ({4})|{5:#010x}|||\n".format(
                        sock.CreateTime, 
                        sock.Pid, 
                        la,
                        sock.Protocol,
                        protos.protos.get(sock.Protocol.v(), "-"),
                        sock.obj_offset)
                yield line

            stuff = evtlogs.EvtLogs.calculate(self)
            for name, buf in stuff:
                lines = self.parse_evt_info(name, buf)
                for l in lines:
                    l = l.replace("\n","")
                    t = l.split("|")
                    line = '{0} |[EVT LOG]|{1}|{2}|{3}|{4}|{5}|{6}|{7}\n'.format(
                            t[0], t[1], t[2], t[3], t[4], t[5], t[6], t[7])
                    yield line
        else:
            # Vista+
            nets = netscan.Netscan.calculate(self)
            for offset, proto, laddr, lport, raddr, rport, state, p, ctime in nets:
                conn = "{0}:{1} -> {2}:{3}".format(laddr, lport, raddr, rport)
                line = "{0}|[NETWORK CONNECTION]|{1}|{2}|{3}|{4}|{5:<#10x}||\n".format(
                        ctime,
                        p.UniqueProcessId,
                        conn,
                        proto,
                        state,
                        offset)
                yield line

        # Get threads
        threads = modscan.ThrdScan.calculate(self)
        for thread in threads:
            try:
                image = pids[thread.Cid.UniqueProcess.v()]
            except:
                image = ""
            line = "{0}|{1}|{2}|{3}|{4}|{5}|||\n".format(
                    thread.CreateTime or '-1',
                    "[THREAD]",
                    image,
                    thread.Cid.UniqueProcess,
                    thread.Cid.UniqueThread,
                    thread.ExitTime or '',
                    )
            yield line

        # now we get to the PE part.  All PE's are dumped in case you want to inspect them later
    
        # Get module offsets by scanning
        mod_offsets = []
        data = modscan.ModScan.calculate(self)
        for module in data:
            base = "{0:#010x}".format(module.DllBase)
            mod_offsets.append(base)

        # and get PE timestamps for those modules
        for base in mod_offsets:
            self._config.update('OFFSET', int(base, 16))
            data = moddump.ModDump.calculate(self)

            for addr_space, procs, mod_base, mod_name in data:
                space = tasks.find_space(addr_space, procs, mod_base)
                if space != None:
                    try:
                        header = self.get_nt_header(space, mod_base)
                    except ValueError, ve: 
                        continue

                    try:
                        line = "{0}|{1}|{2}|{3}|{4:#010x}|||||\n".format(
                            self.time_stamp(header.FileHeader.TimeDateStamp) or '-1',
                            "[PE Timestamp (module)]",
                            mod_name,
                            "",
                            mod_base)
                    except:
                        line = "{0}|{1}|{2}|{3}|{4}|||||\n".format(
                            '-1',
                            "[PE Timestamp (module)]",
                            mod_name,
                            "",
                            mod_base)
                    yield line
Esempio n. 15
0
    def calculate(self):
        if self._config.OUTPUT == "xlsx" and not has_openpyxl:
            debug.error("You must install OpenPyxl for xlsx format:\n\thttps://bitbucket.org/ericgazoni/openpyxl/wiki/Home")
        elif self._config.OUTPUT == "xlsx" and not self._config.OUTPUT_FILE:
            debug.error("You must specify an output *.xlsx file!\n\t(Example: --output-file=OUTPUT.xlsx)")

        if (self._config.HIVE or self._config.USER) and not (self._config.REGISTRY):
            debug.error("You must use -R/--registry in conjuction with -H/--hive and/or -U/--user")

        addr_space = utils.load_as(self._config)
        version = (addr_space.profile.metadata.get('major', 0), 

                   addr_space.profile.metadata.get('minor', 0))

        pids = {}     #dictionary of process IDs/ImageFileName
        offsets = []  #process offsets
        

        im = imageinfo.ImageInfo(self._config).get_image_time(addr_space) 

        body = False
        l2tcsv = False
        plaso = False
        if self._config.OUTPUT == "body":
            body = True
    
        elif self._config.OUTPUT == "l2tcsv":
            l2tcsv = True
        elif self._config.OUTPUT == "plaso":
            plaso = True

        if l2tcsv or plaso:
            if self._config.tz:
                timezone = self._config.tz
            else:
                timezone = 'UTC'

        if l2tcsv:
            line = "date,time,timezone,MACB,source,sourcetype,type,user,host,short,desc,version,filename,inode,notes,format,extra\n"
        elif body:
            line = "0|[END LIVE RESPONSE]|0|---------------|0|0|0|{0}|{0}|{0}|{0}\n".format(im['ImageDatetime'].v())
        else:
            line = "{0}|[END LIVE RESPONSE]\n".format(im['ImageDatetime'])

        if line and not plaso:
            yield line
                

        # Get EPROCESS
        psscan = filescan.PSScan(self._config).calculate()
        for eprocess in psscan:
            if eprocess.obj_offset not in offsets:
                offsets.append(eprocess.obj_offset)

            if l2tcsv:
                unixdatetime = eprocess.CreateTime.v()
                year = (datetime.datetime.fromtimestamp(int(unixdatetime)).strftime('%m/%d/%Y'))
                time = (datetime.datetime.fromtimestamp(int(unixdatetime)).strftime('%H:%M:%S'))
                line = "{0},{1},{6},...B,MEMORY,PROCESS,Created,-,-,,Process: {2}<|>PID: {3}<|>PPID: {4}<|>POffset: 0x{5:08x},,{2},0,-,-,\n".format(
                    year,
                    time,
                    eprocess.ImageFileName,
                    eprocess.UniqueProcessId,
                    eprocess.InheritedFromUniqueProcessId,
                    eprocess.obj_offset,
                    timezone)

                unixdatetime2 = eprocess.ExitTime.v()
                year2 = (datetime.datetime.fromtimestamp(int(unixdatetime2)).strftime('%m/%d/%Y'))
                time2 = (datetime.datetime.fromtimestamp(int(unixdatetime2)).strftime('%H:%M:%S'))
                yield "{0},{1},{6},.A..,MEMORY,PROCESS,Exit,-,-,,Process:{2}<|>PID: {3}<|>PPID: {4}<|>POffset: 0x{5:08x},,{2},0,-,-,\n".format(
                    year2,
                    time2,
                    eprocess.ImageFileName,
                    eprocess.UniqueProcessId,
                    eprocess.InheritedFromUniqueProcessId,
                    eprocess.obj_offset,
                    timezone)
            elif plaso:
                unixdatetime = eprocess.CreateTime.v()
                line = vol_time.EprocessEvent(unixdatetime, eprocess, timezone)
                yield vol_time.EprocessEvent(eprocess.ExitTime.v(), eprocess, timezone, True)
            elif body:
                line = "0|[PROCESS] {2}/PID: {3}/PPID: {4}/POffset: 0x{5:08x}|0|---------------|0|0|0|{0}|{1}|{0}|{0}\n".format(
                    eprocess.CreateTime.v(),
                    eprocess.ExitTime.v(),
                    eprocess.ImageFileName,
                    eprocess.UniqueProcessId,
                    eprocess.InheritedFromUniqueProcessId,
                    eprocess.obj_offset)

            else:
                line = "{0}|{1}|{2}|{3}|{4}|{5}|0x{6:08x}||\n".format(
                    eprocess.CreateTime or '-1',
                    "[PROCESS]",
                    eprocess.ImageFileName,
                    eprocess.UniqueProcessId,
                    eprocess.InheritedFromUniqueProcessId,
                    eprocess.ExitTime or '',
                    eprocess.obj_offset)

            pids[eprocess.UniqueProcessId.v()] = eprocess.ImageFileName
            yield line

        # Get Sockets and Evtlogs XP/2k3 only
        if addr_space.profile.metadata.get('major', 0) == 5:
            socks = sockets.Sockets(self._config).calculate()
            #socks = sockscan.SockScan(self._config).calculate()   # you can use sockscan instead if you uncomment
            for sock in socks:
                la = "{0}:{1}".format(sock.LocalIpAddress, sock.LocalPort)

                if l2tcsv:
                    unixdatetime = sock.CreateTime.v()
                    year = (datetime.datetime.fromtimestamp(int(unixdatetime)).strftime('%m/%d/%Y'))
                    time = (datetime.datetime.fromtimestamp(int(unixdatetime)).strftime('%H:%M:%S'))
                    line = "{0},{1},{7},...B,MEMORY,SOCKET,Created,-,-,,PID: {2}<|>LocalIP: {3}<|>Protocol: {4}({5}),,{2},0,-,-,\n".format(
                        year,
                        time,
                        sock.Pid,
                        la,
                        sock.Protocol,
                        protos.protos.get(sock.Protocol.v(), "-"),
                        sock.obj_offset,
                        timezone)

                elif plaso:
                    unixdatetime = sock.CreateTime.v()
                    line = vol_time.SockEvent(unixdatetime, sock, protos.protos.get(sock.Protocol.v(), "-"))
                elif body:
                    line = "0|[SOCKET] PID: {1}/LocalIP: {2}/Protocol: {3}({4})/POffset: 0x{5:#010x}|0|---------------|0|0|0|{0}|{0}|{0}|{0}\n".format(
                            sock.CreateTime.v(),
                            sock.Pid,
                            la,
                            sock.Protocol,
                            protos.protos.get(sock.Protocol.v(), "-"),
                            sock.obj_offset)

                else:
                    line = "{0}|[SOCKET]|{1}|{2}|Protocol: {3} ({4})|{5:#010x}|||\n".format(
                        sock.CreateTime,
                        sock.Pid,
                        la,
                        sock.Protocol,
                        protos.protos.get(sock.Protocol.v(), "-"),
                        sock.obj_offset)
                yield line

            stuff = evtlogs.EvtLogs.calculate(self)
            for name, buf in stuff:
                for fields in self.parse_evt_info(name, buf, rawtime = True):
                    if l2tcsv:
                        unixdatetime = fields[0]
                        year = (datetime.datetime.fromtimestamp(int(unixdatetime)).strftime('%m/%d/%Y'))
                        time = (datetime.datetime.fromtimestamp(int(unixdatetime)).strftime('%H:%M:%S'))

                        line = "{0},{1},{9},...B,MEMORY,MEM-EVT LOG,Created,-,-,,{2}<|>{3}<|>{4}<|>{5}<|>{6}<|>{7}<|>{8},,-,0,-,-,\n".format(
                            year,
                            time,
                            #Need to replace , for ; so does not throw of delimitor
                            fields[1].replace(",", ";"),
                            fields[2].replace(",", ";"),
                            fields[3].replace(",", ";"),
                            fields[4].replace(",", ";"),
                            fields[5].replace(",", ";"),
                            fields[6].replace(",", ";"),
                            fields[7].replace(",", ";"),
                            timezone)
                    elif plaso:
                        unixdatetime = int(fields[0])
                        line = vol_time.EvtEvent(unixdatetime, fields)
                    elif body:
                        line = '{0} |[EVT LOG]|{1}|{2}|{3}|{4}|{5}|{6}|{7}\n'.format(
                            fields[0], fields[1], fields[2], fields[3], fields[4], fields[5], fields[6], fields[7])
                    else:
                        line = "0|[EVT LOG] {1}/{2}/{3}/{4}/{5}/{6}/{7}|0|---------------|0|0|0|{0}|{0}|{0}|{0}\n".format(
                            fields[0].v(),fields[1], fields[2], fields[3], fields[4], fields[5], fields[6], fields[7])
                    yield line
        else:
            # Vista+
            nets = netscan.Netscan(self._config).calculate()
            for net_object, proto, laddr, lport, raddr, rport, state in nets:
                conn = "{0}:{1} -> {2}:{3}".format(laddr, lport, raddr, rport)
                if l2tcsv:
                    unixdatetime = net_object.CreateTime.v()
                    year = (datetime.datetime.fromtimestamp(int(unixdatetime)).strftime('%m/%d/%Y'))
                    time = (datetime.datetime.fromtimestamp(int(unixdatetime)).strftime('%H:%M:%S'))
                    line = "{0},{1},{7},...B,MEMORY,Network Connection,Created,-,-,,{2}/{3}/{4}/{5}/{6:<#10x},,-,0,-,-,\n".format(
                        year,
                        time,
                        net_object.Owner.UniqueProcessId,
                        conn,
                        proto,
                        state,
                        net_object.obj_offset,
                        timezone)

                elif plaso:
                    unixdatetime = net_object.CreateTime.v()
                    line = vol_time.NetObjectEvent(unixdatetime, net_object, laddr, lport, raddr, rport, proto, state)

                elif body:
                    line = "0|[NETWORK CONNECTION] {1}/{2}/{3}/{4}/{5:<#10x}|0|---------------|0|0|0|{0}|{0}|{0}|{0}\n".format(
                        net_object.CreateTime.v(),
                        net_object.Owner.UniqueProcessId,
                        conn,
                        proto,
                        state,
                        net_object.obj_offset)

                else:
                    line = "{0}|[NETWORK CONNECTION]|{1}|{2}|{3}|{4}|{5:<#10x}||\n".format(
                        str(net_object.CreateTime or "-1"),
                        net_object.Owner.UniqueProcessId,
                        conn,
                        proto,
                        state,
                        net_object.obj_offset)
                yield line

        # Get threads
        threads = modscan.ThrdScan(self._config).calculate()
        for thread in threads:
            image = pids.get(thread.Cid.UniqueProcess.v(), "UNKNOWN")

            if l2tcsv:
                unixdatetime = thread.CreateTime.v()
                year = (datetime.datetime.fromtimestamp(int(unixdatetime)).strftime('%m/%d/%Y'))
                time = (datetime.datetime.fromtimestamp(int(unixdatetime)).strftime('%H:%M:%S'))

                line = "{0},{1},{5},...B,MEMORY,THREAD,Created,-,-,,File: {2}<|>PID: {3}<|>TID: {4},,-,0,-,-,\n".format(
                    year,
                    time,
                    image,
                    thread.Cid.UniqueProcess,
                    thread.Cid.UniqueThread,
                    timezone)

                unixdatetime2 = thread.ExitTime.v()
                year2 = (datetime.datetime.fromtimestamp(int(unixdatetime2)).strftime('%m/%d/%Y'))
                time2 = (datetime.datetime.fromtimestamp(int(unixdatetime2)).strftime('%H:%M:%S'))
                yield "{0},{1},{5},.A..,MEMORY,THREAD,Exit,-,-,,{2}/PID: {3}/TID: {4},,-,0,-,-,\n".format(
                    year2,
                    time2,
                    image,
                    thread.Cid.UniqueProcess,
                    thread.Cid.UniqueThread,
                    timezone)

            elif body:
                line = "0|[THREAD] {2}/PID: {3}/TID: {4}|0|---------------|0|0|0|{0}|{1}|{0}|{0}\n".format(
                    thread.CreateTime.v(),
                    thread.ExitTime.v(),
                    image,
                    thread.Cid.UniqueProcess,
                    thread.Cid.UniqueThread,
                    )
            elif plaso:
                unixdatetime = thread.CreateTime.v()
                yield vol_time.ThreadEvent(unixdatetime, image, thread)
                unixdatetime = thread.ExitTime.v()
                line = vol_time.ThreadEvent(unixdatetime, image, thread, True)

            else:
                line = "{0}|[THREAD]|{1}|{2}|{3}|{4}|||\n".format(
                    thread.CreateTime or '-1',
                    image,
                    thread.Cid.UniqueProcess,
                    thread.Cid.UniqueThread,
                    thread.ExitTime or '',
                    )
            yield line

        # now we get to the PE part.  All PE's are dumped in case you want to inspect them later
        data = moddump.ModDump(self._config).calculate()

        for addr_space, procs, mod_base, mod_name in data:
            space = tasks.find_space(addr_space, procs, mod_base)
            if space != None:
                try:
                    header = procdump.ProcExeDump(self._config).get_nt_header(space, mod_base)
                except ValueError, ve:
                    continue
                try:
                    if l2tcsv:
                        unixdatetime = header.FileHeader.TimeDateStamp.v()
                        year = (datetime.datetime.fromtimestamp(int(unixdatetime)).strftime('%m/%d/%Y'))
                        time = (datetime.datetime.fromtimestamp(int(unixdatetime)).strftime('%H:%M:%S'))
                        line = "{0},{1},{4},...B,MEMORY,MEM-PE Timestamp,Created,-,-,,File: {2}<|>Base: {3:#010x},,-,0,-,-,\n".format(
                            year,
                            time,
                            mod_name,
                            mod_base,
                            timezone)

                    elif plaso:
                        unixdatetime = header.FileHeader.TimeDateStamp.v()
                        line = vol_time.ProcExeDumpEvent(unixdatetime, mod_name, mod_base)

                    elif body:
                        line = "0|[PE Timestamp (module)] {1}/Base: {2:#010x}|0|---------------|0|0|0|{0}|{0}|{0}|{0}\n".format(
                            header.FileHeader.TimeDateStamp.v(),
                            mod_name,
                            mod_base)

                    else:
                        line = "{0}|[PE Timestamp (module)]|{1}||{2:#010x}|||||\n".format(
                            header.FileHeader.TimeDateStamp or '-1',
                            mod_name,
                            mod_base)

                except ValueError, ve:
                    if l2tcsv:
                        pass
                    elif plaso:
                        line = vol_time.ProcExeDumpEvent(0, mod_name, mod_base)

                    elif body:
                        line = "0|[PE Timestamp (module)] {0}/Base: {1:#010x}|0|---------------|0|0|0|0|0|0|0\n".format(
                            mod_name, mod_base)

                    else:
                        line = "-1|[PE Timestamp (module)]|{0}||{1}|||||\n".format(
                            mod_name,
                            mod_base)
                yield line
Esempio n. 16
0
    def calculate(self):

        if not has_distorm:
            debug.error("You must install distorm3")

        addr_space = utils.load_as(self._config)

        all_tasks = list(tasks.pslist(addr_space))
        all_mods = list(modules.lsmod(addr_space))

        # Operate in kernel mode if pid is not supplied
        if not self._config.PID:
            if not self._config.BASE:
                debug.error("You must specify --BASE")

            base_address = self._config.BASE
            size_to_read = self._config.SIZE

            # Get the size from the module list if its not supplied
            if not size_to_read:
                for module in all_mods:
                    if module.DllBase == base_address:
                        size_to_read = module.SizeOfImage
                        break
                # Alternately, try the size from the PE header 
                if not size_to_read:
                    pefile = obj.Object("_IMAGE_DOS_HEADER", 
                                        offset = base_address, 
                                        vm = addr_space)
                    try:
                        nt_header = pefile.get_nt_header()
                        size_to_read = nt_header.OptionalHeader.SizeOfImage
                    except ValueError:
                        pass

                    if not size_to_read:
                        debug.error("You must specify --SIZE")

            kernel_space = tasks.find_space(addr_space,
                                    all_tasks, base_address)

            if not kernel_space:
                debug.error("Cannot read supplied address")

            data = kernel_space.zread(base_address, size_to_read)
            apis = self.enum_apis(all_mods)
            addr_space = kernel_space
        else:
            # In process mode, we find the process by PID
            task = None

            for atask in all_tasks:
                if atask.UniqueProcessId == self._config.PID:
                    task = atask
                    break

            if not task:
                debug.error("You must supply an active PID")

            task_space = task.get_process_address_space()

            if not task_space:
                debug.error("Cannot acquire process AS")

            all_mods = list(task.get_load_modules())

            # PEB is paged or no DLLs loaded 
            if not all_mods:
                debug.error("Cannot load DLLs in process AS")

            # If an address is supplied with a size, try to get
            # the size from the vad node. If neither are supplied, 
            # assume we should carve the main process executable. 
            if self._config.BASE:
                base_address = self._config.BASE
                size_to_read = self._config.SIZE

                if not size_to_read:
                    for vad in task.VadRoot.traverse():
                        if base_address >= vad.Start and base_address <= vad.End:
                            size_to_read = vad.Length
                    if not size_to_read:
                        debug.error("You must specify --SIZE")
            else:
                # Its OK to blindly take the 0th element because the 
                # executable is always the first module to load. 
                base_address = all_mods[0].DllBase
                size_to_read = all_mods[0].SizeOfImage

            if not task_space.is_valid_address(base_address):
                debug.error("Address is not valid in process AS")

            data = task_space.zread(base_address, size_to_read)
            apis = self.enum_apis(all_mods)
            addr_space = task_space

        # This is a dictionary of confirmed API calls.
        calls_imported = dict(
                (iat, call)
                for (_, iat, call) in self.call_scan(addr_space, base_address, data)
                if call in apis
                )

        # Scan forward 
        self._vicinity_scan(addr_space,
                calls_imported, apis, base_address, len(data),
                forward = True)

        # Scan reverse 
        self._vicinity_scan(addr_space,
                calls_imported, apis, base_address, len(data),
                forward = False)

        for iat, call in sorted(calls_imported.items()):
            yield iat, call, apis[call][0], apis[call][1]
Esempio n. 17
0
            line = "[{6}SYMLINK]{0} {1}->{2}{0} POffset: {3}/Ptr: {4}/Hnd: {5}".format(
                    "" if body else "|",
                    str(objct.NameInfo.Name or ''),
                    str(link.LinkTarget or ''),
                    link.obj_offset,
                    objct.PointerCount,
                    objct.HandleCount,
                    self._config.MACHINE)
            yield self.getoutput(line, link.CreationTime, body = body)

        data = []
        if "TimeDateStamp" in self._config.TYPE:
            data = moddump.ModDump(self._config).calculate()
        for aspace, procs, mod_base, mod_name in data:
            mod_name = str(mod_name or '')
            space = tasks.find_space(aspace, procs, mod_base)
            if space != None:
                try:
                    pe_file = obj.Object("_IMAGE_DOS_HEADER", offset = mod_base, vm = space)
                    header = pe_file.get_nt_header()
                except ValueError, ve: 
                    continue
                line = "[{3}PE HEADER (module)]{0} {1}{0} Base: {2:#010x}".format(
                        "" if body else "|",
                        mod_name,
                        mod_base,
                        self._config.MACHINE)
                yield self.getoutput(line, header.FileHeader.TimeDateStamp, body = body)

        uastuff = []
        if "Userassist" in self._config.TYPE:
Esempio n. 18
0
    def calculate(self):
        if (self._config.HIVE
                or self._config.USER) and "Registry" not in self._config.TYPE:
            debug.error(
                "You must use --registry in conjuction with -H/--hive and/or -U/--user"
            )
        if self._config.TYPE != None:
            for t in self._config.TYPE.split(","):
                if t.strip() not in self.types and t.strip() != "Registry":
                    debug.error(
                        "You have entered an incorrect type: {0}".format(t))

        addr_space = utils.load_as(self._config)
        version = (
            addr_space.profile.metadata.get('major', 0),
            addr_space.profile.metadata.get('minor', 0),
        )

        pids = {}  # dictionary of process IDs/ImageFileName

        body = False
        if self._config.OUTPUT == "body":
            body = True
        if self._config.MACHINE != "":
            self._config.update("MACHINE", "{0} ".format(self._config.MACHINE))

        if "ImageDate" in self._config.TYPE:
            im = imageinfo.ImageInfo(self._config).get_image_time(addr_space)
            yield self.getoutput(
                "[{0}LIVE RESPONSE]{1} (System time){1}".format(
                    self._config.MACHINE, "" if body else "|"),
                im['ImageDatetime'],
                body=body,
            )

        if version <= (6, 1) and "IEHistory" in self._config.TYPE:
            self._config.update("LEAK", True)
            data = iehistory.IEHistory(self._config).calculate()
            for process, record in data:
                ## Extended fields are available for these records
                if record.obj_name == "_URL_RECORD":
                    line = "[{6}IEHISTORY]{0} {1}->{5}{0} PID: {2}/Cache type \"{3}\" at {4:#x}".format(
                        "" if body else "|",
                        process.ImageFileName,
                        process.UniqueProcessId,
                        record.Signature,
                        record.obj_offset,
                        record.Url,
                        self._config.MACHINE,
                    )

                    yield self.getoutput(
                        line,
                        record.LastModified,
                        end=record.LastAccessed,
                        body=body,
                    )
            self._config.remove_option("REDR")
            self._config.remove_option("LEAK")

        psx = []
        if ("Process" in self._config.Type
                or "TimeDateStamp" in self._config.Type
                or "LoadTime" in self._config.Type
                or "_CM_KEY_BODY" in self._config.Type):
            psx = psxview.PsXview(self._config).calculate()
        for offset, eprocess, ps_sources in psx:
            pids[eprocess.UniqueProcessId.v()] = eprocess.ImageFileName
            if "Process" in self._config.TYPE:
                line = "[{5}PROCESS]{0} {1}{0} PID: {2}/PPID: {3}/POffset: 0x{4:08x}".format(
                    "" if body else "|",
                    eprocess.ImageFileName,
                    eprocess.UniqueProcessId,
                    eprocess.InheritedFromUniqueProcessId,
                    offset,
                    self._config.MACHINE,
                )

                yield self.getoutput(line,
                                     eprocess.CreateTime,
                                     end=eprocess.ExitTime,
                                     body=body)

            if not hasattr(eprocess.obj_vm, "vtop"):
                eprocess = taskmods.DllList(
                    self._config).virtual_process_from_physical_offset(
                        addr_space, eprocess.obj_offset)
                if eprocess == None:
                    continue
            else:
                ps_ad = eprocess.get_process_address_space()
                if ps_ad == None:
                    continue

            if version[0] == 5 and "Process" in self._config.TYPE:
                line = "[{5}PROCESS LastTrimTime]{0} {1}{0} PID: {2}/PPID: {3}/POffset: 0x{4:08x}".format(
                    "" if body else "|",
                    eprocess.ImageFileName,
                    eprocess.UniqueProcessId,
                    eprocess.InheritedFromUniqueProcessId,
                    offset,
                    self._config.MACHINE,
                )
                yield self.getoutput(line, eprocess.Vm.LastTrimTime, body=body)

            if (eprocess.ObjectTable.HandleTableList
                    and "_CM_KEY_BODY" in self._config.TYPE):
                for handle in eprocess.ObjectTable.handles():
                    if not handle.is_valid():
                        continue

                    name = ""
                    object_type = handle.get_object_type()
                    if object_type == "Key":
                        key_obj = handle.dereference_as("_CM_KEY_BODY")
                        name = key_obj.full_key_name()
                        line = "[{6}Handle (Key)]{0} {1}{0} {2} PID: {3}/PPID: {4}/POffset: 0x{5:08x}".format(
                            "" if body else "|",
                            name,
                            eprocess.ImageFileName,
                            eprocess.UniqueProcessId,
                            eprocess.InheritedFromUniqueProcessId,
                            offset,
                            self._config.MACHINE,
                        )
                        yield self.getoutput(
                            line,
                            key_obj.KeyControlBlock.KcbLastWriteTime,
                            body=body,
                        )

            if eprocess.Peb == None or eprocess.Peb.ImageBaseAddress == None:
                continue
            # Get DLL PE timestamps for Wow64 processes (excluding 64-bit ones)
            if eprocess.IsWow64 and "TimeDateStamp" in self._config.TYPE:
                for vad, address_space in eprocess.get_vads(
                        vad_filter=eprocess._mapped_file_filter):
                    if vad.FileObject.FileName:
                        name = str(vad.FileObject.FileName).lower()
                        basename = ntpath.basename(name)
                        if not basename.endswith("dll") or basename in [
                                "wow64cpu.dll",
                                "ntdll.dll",
                                "wow64.dll",
                                "wow64win.dll",
                        ]:
                            continue
                        data = ps_ad.zread(vad.Start, vad.Length)
                        bufferas = addrspace.BufferAddressSpace(self._config,
                                                                data=data)
                        try:
                            pe_file = obj.Object("_IMAGE_DOS_HEADER",
                                                 offset=0,
                                                 vm=bufferas)
                            header = pe_file.get_nt_header()
                        except ValueError as ve:
                            continue
                        line = "[{7}PE HEADER 32-bit (dll)]{0} {4}{0} Process: {1}/PID: {2}/PPID: {3}/Process POffset: 0x{5:08x}/DLL Base: 0x{6:08x}".format(
                            "" if body else "|",
                            eprocess.ImageFileName,
                            eprocess.UniqueProcessId,
                            eprocess.InheritedFromUniqueProcessId,
                            basename,
                            offset,
                            vad.Start,
                            self._config.MACHINE,
                        )
                        yield self.getoutput(line,
                                             header.FileHeader.TimeDateStamp,
                                             body=body)

            # get DLL PE timestamps
            mods = dict()
            if ("TimeDateStamp" in self._config.TYPE
                    or "LoadTime" in self._config.TYPE):
                mods = dict((mod.DllBase.v(), mod)
                            for mod in eprocess.get_load_modules())
            for mod in list(mods.values()):
                basename = str(mod.BaseDllName or "")
                if basename == str(eprocess.ImageFileName):
                    line = "[{7}PE HEADER (exe)]{0} {4}{0} Process: {1}/PID: {2}/PPID: {3}/Process POffset: 0x{5:08x}/DLL Base: 0x{6:08x}".format(
                        "" if body else "|",
                        eprocess.ImageFileName,
                        eprocess.UniqueProcessId,
                        eprocess.InheritedFromUniqueProcessId,
                        basename,
                        offset,
                        mod.DllBase.v(),
                        self._config.MACHINE,
                    )
                else:
                    line = "[{7}PE HEADER (dll)]{0} {4}{0} Process: {1}/PID: {2}/PPID: {3}/Process POffset: 0x{5:08x}/DLL Base: 0x{6:08x}".format(
                        "" if body else "|",
                        eprocess.ImageFileName,
                        eprocess.UniqueProcessId,
                        eprocess.InheritedFromUniqueProcessId,
                        basename,
                        offset,
                        mod.DllBase.v(),
                        self._config.MACHINE,
                    )
                if "TimeDateStamp" in self._config.TYPE:
                    yield self.getoutput(line, mod.TimeDateStamp, body=body)
                    line2 = "[{7}PE DEBUG]{0} {4}{0} Process: {1}/PID: {2}/PPID: {3}/Process POffset: 0x{5:08x}/DLL Base: 0x{6:08x}".format(
                        "" if body else "|",
                        eprocess.ImageFileName,
                        eprocess.UniqueProcessId,
                        eprocess.InheritedFromUniqueProcessId,
                        basename,
                        offset,
                        mod.DllBase.v(),
                        self._config.MACHINE,
                    )
                    yield self.getoutput(
                        line2,
                        mod.get_debug_directory().TimeDateStamp,
                        body=body,
                    )
                if (hasattr(mod, "LoadTime")
                        and "LoadTime" in self._config.TYPE):
                    temp = line.replace(
                        "[{0}PE HEADER ".format(self._config.MACHINE),
                        "[{0}DLL LOADTIME ".format(self._config.MACHINE),
                    )
                    yield self.getoutput(temp, mod.LoadTime, body=body)

        # Get Sockets and Evtlogs XP/2k3 only
        if version[0] == 5:
            # socks = sockets.Sockets(self._config).calculate()
            socks = []
            if "Socket" in self._config.TYPE:
                socks = sockscan.SockScan(self._config).calculate(
                )  # you can use sockscan instead if you uncomment
            for sock in socks:
                la = "{0}:{1}".format(sock.LocalIpAddress, sock.LocalPort)
                line = "[{6}SOCKET]{0} LocalIP: {2}/Protocol: {3}({4}){0} PID: {1}/POffset: 0x{5:#010x}".format(
                    "" if body else "|",
                    sock.Pid,
                    la,
                    sock.Protocol,
                    protos.protos.get(sock.Protocol.v(), "-"),
                    sock.obj_offset,
                    self._config.MACHINE,
                )

                yield self.getoutput(line, sock.CreateTime, body=body)

            stuff = []
            if "EvtLog" in self._config.TYPE:
                evt = evtlogs.EvtLogs(self._config)
                stuff = evt.calculate()
            for name, buf in stuff:
                for fields in evt.parse_evt_info(name, buf, rawtime=True):
                    line = "[{8}EVT LOG]{0} {1}{0} {2}/{3}/{4}/{5}/{6}/{7}".format(
                        "" if body else "|",
                        fields[1],
                        fields[2],
                        fields[3],
                        fields[4],
                        fields[5],
                        fields[6],
                        fields[7],
                        self._config.MACHINE,
                    )
                    yield self.getoutput(line, fields[0], body=body)
        elif version <= (6, 1):
            # Vista+
            nets = []
            if "Socket" in self._config.TYPE:
                nets = netscan.Netscan(self._config).calculate()
            for net_object, proto, laddr, lport, raddr, rport, state in nets:

                if net_object.CreateTime.v() == 0:
                    continue

                if raddr == "*" and rport == "*":
                    conn = "{0}:{1}".format(laddr, lport)
                    socket_type = "SOCKET"
                else:
                    conn = "{0}:{1} -> {2}:{3}".format(laddr, lport, raddr,
                                                       rport)
                    socket_TYPE = "CONNECTION"

                line = (
                    "[{6}NETWORK {7}]{0} {2}{0} {1}/{3}/{4}/{5:<#10x}".format(
                        "" if body else "|",
                        net_object.Owner.UniqueProcessId,
                        conn,
                        proto,
                        state,
                        net_object.obj_offset,
                        self._config.MACHINE,
                        socket_type,
                    ))

                yield self.getoutput(line, net_object.CreateTime, body=body)

        # Get threads
        threads = []
        if "Thread" in self._config.TYPE:
            threads = modscan.ThrdScan(self._config).calculate()
        for thread in threads:
            image = pids.get(thread.Cid.UniqueProcess.v(), "UNKNOWN")
            line = "[{4}THREAD]{0} {1}{0} PID: {2}/TID: {3}".format(
                "" if body else "|",
                image,
                thread.Cid.UniqueProcess,
                thread.Cid.UniqueThread,
                self._config.MACHINE,
            )
            yield self.getoutput(line,
                                 thread.CreateTime,
                                 end=thread.ExitTime,
                                 body=body)

        data = []
        if "Symlink" in self._config.TYPE:
            data = filescan.SymLinkScan(self._config).calculate()
        for link in data:
            objct = link.get_object_header()
            line = "[{6}SYMLINK]{0} {1}->{2}{0} POffset: {3}/Ptr: {4}/Hnd: {5}".format(
                "" if body else "|",
                str(objct.NameInfo.Name or ''),
                str(link.LinkTarget or ''),
                link.obj_offset,
                objct.PointerCount,
                objct.HandleCount,
                self._config.MACHINE,
            )
            yield self.getoutput(line, link.CreationTime, body=body)

        data = []
        if "TimeDateStamp" in self._config.TYPE:
            data = moddump.ModDump(self._config).calculate()
        for aspace, procs, mod_base, mod_name in data:
            mod_name = str(mod_name or '')
            space = tasks.find_space(aspace, procs, mod_base)
            if space != None:
                try:
                    pe_file = obj.Object("_IMAGE_DOS_HEADER",
                                         offset=mod_base,
                                         vm=space)
                    header = pe_file.get_nt_header()
                except ValueError as ve:
                    continue
                line = (
                    "[{3}PE HEADER (module)]{0} {1}{0} Base: {2:#010x}".format(
                        "" if body else "|",
                        mod_name,
                        mod_base,
                        self._config.MACHINE,
                    ))
                yield self.getoutput(line,
                                     header.FileHeader.TimeDateStamp,
                                     body=body)

        uastuff = []
        if "Userassist" in self._config.TYPE:
            uastuff = userassist.UserAssist(self._config).calculate()
        for win7, reg, key in uastuff:
            ts = "{0}".format(key.LastWriteTime)
            for v in rawreg.values(key):
                tp, dat = rawreg.value_data(v)
                subname = v.Name
                if tp == 'REG_BINARY':
                    dat_raw = dat
                    try:
                        subname = codecs.encode(subname, 'rot_13')
                    except UnicodeDecodeError:
                        pass
                    if win7:
                        guid = subname.split("\\")[0]
                        if guid in userassist.folder_guids:
                            subname = subname.replace(
                                guid, userassist.folder_guids[guid])
                    bufferas = addrspace.BufferAddressSpace(self._config,
                                                            data=dat_raw)
                    uadata = obj.Object("_VOLUSER_ASSIST_TYPES",
                                        offset=0,
                                        vm=bufferas)
                    ID = "N/A"
                    count = "N/A"
                    fc = "N/A"
                    tf = "N/A"
                    lw = "N/A"
                    if (len(dat_raw) < bufferas.profile.get_obj_size(
                            '_VOLUSER_ASSIST_TYPES') or uadata == None):
                        continue
                    else:
                        if hasattr(uadata, "ID"):
                            ID = "{0}".format(uadata.ID)
                        if hasattr(uadata, "Count"):
                            count = "{0}".format(uadata.Count)
                        else:
                            count = "{0}".format(
                                uadata.CountStartingAtFive
                                if uadata.CountStartingAtFive < 5 else
                                uadata.CountStartingAtFive - 5)
                        if hasattr(uadata, "FocusCount"):
                            seconds = (uadata.FocusTime + 500) / 1000.0
                            time = (datetime.timedelta(seconds=seconds)
                                    if seconds > 0 else uadata.FocusTime)
                            fc = "{0}".format(uadata.FocusCount)
                            tf = "{0}".format(time)
                        lw = "{0}".format(uadata.LastUpdated)

                subname = subname.replace("|", "%7c")
                line = "[{7}USER ASSIST]{0} {2}{0} Registry: {1}/ID: {3}/Count: {4}/FocusCount: {5}/TimeFocused: {6}".format(
                    "" if body else "|",
                    reg,
                    subname,
                    ID,
                    count,
                    fc,
                    tf,
                    self._config.MACHINE,
                )
                yield self.getoutput(line, uadata.LastUpdated, body=body)

        shimdata = []
        if "Shimcache" in self._config.TYPE:
            shimdata = shimcache.ShimCache(self._config).calculate()
        for path, lm, lu in shimdata:
            line = "[{2}SHIMCACHE]{0} {1}{0} ".format("" if body else "|",
                                                      path,
                                                      self._config.MACHINE)
            if lu:
                yield self.getoutput(line, lm, end=lu, body=body)
            else:
                yield self.getoutput(line, lm, body=body)

        if ("_HBASE_BLOCK" in self._config.TYPE
                or "_CMHIVE" in self._config.TYPE
                or "Registry" in self._config.TYPE):
            regapi = registryapi.RegistryApi(self._config)
            for o in regapi.all_offsets:
                if "_HBASE_BLOCK" in self._config.TYPE:
                    line = "[{2}_HBASE_BLOCK TimeStamp]{0} {1}{0} ".format(
                        "" if body else "|",
                        regapi.all_offsets[o],
                        self._config.MACHINE,
                    )
                    h = obj.Object("_HHIVE", o, addr_space)
                    yield self.getoutput(line,
                                         h.BaseBlock.TimeStamp,
                                         body=body)

                if ("_CMHIVE" in self._config.TYPE and version[0] == 6 and
                        addr_space.profile.metadata.get('build', 0) >= 7601):
                    line = (
                        line) = "[{2}_CMHIVE LastWriteTime]{0} {1}{0} ".format(
                            "" if body else "|",
                            regapi.all_offsets[o],
                            self._config.MACHINE,
                        )
                    cmhive = obj.Object("_CMHIVE", o, addr_space)
                    yield self.getoutput(line, cmhive.LastWriteTime, body=body)

        if "Registry" in self._config.TYPE:
            regapi.reset_current()
            regdata = regapi.reg_get_all_keys(self._config.HIVE,
                                              self._config.USER,
                                              reg=True,
                                              rawtime=True)

            for lwtime, reg, item in regdata:
                item = item.replace("|", "%7c")
                line = "[{3}REGISTRY]{0} {2}{0} Registry: {1}".format(
                    "" if body else "|", reg, item, self._config.MACHINE)

                yield self.getoutput(line, lwtime, body=body)

        if "Timer" in self._config.TYPE:
            volmagic = obj.VolMagic(addr_space)
            KUSER_SHARED_DATA = obj.Object(
                "_KUSER_SHARED_DATA",
                offset=volmagic.KUSER_SHARED_DATA.v(),
                vm=addr_space,
            )
            interrupt = (KUSER_SHARED_DATA.InterruptTime.High1Time <<
                         32) | KUSER_SHARED_DATA.InterruptTime.LowPart
            now = KUSER_SHARED_DATA.SystemTime.as_windows_timestamp()
            data = timers.Timers(self._config).calculate()
            for timer, module in data:
                signaled = "-"
                if timer.Header.SignalState.v():
                    signaled = "Yes"

                module_name = "UNKNOWN"
                if module:
                    module_name = str(module.BaseDllName or '')

                try:
                    # human readable time taken from http://computer.forensikblog.de/en/2011/10/timers-and-times.html
                    bufferas = addrspace.BufferAddressSpace(
                        self._config,
                        data=struct.pack(
                            '<Q', timer.DueTime.QuadPart - interrupt + now),
                    )
                    due_time = obj.Object("WinTimeStamp",
                                          is_utc=True,
                                          offset=0,
                                          vm=bufferas)
                except TypeError:
                    due_time = 0

                line = "[{6}TIMER]{0} {1}{0} Signaled: {2}/Routine: 0x{3:x}/Period(ms): {4}/Offset: 0x{5:x}".format(
                    "" if body else "|",
                    module_name,
                    signaled,
                    timer.Dpc.DeferredRoutine,
                    timer.Period,
                    timer.obj_offset,
                    self._config.MACHINE,
                )

                yield self.getoutput(line, due_time, body=body)
Esempio n. 19
0
    def calculate(self):

        addr_space = utils.load_as(self._config)

        if not has_distorm3:
            debug.error("Install distorm3 code.google.com/p/distorm/")

        if not self._config.SKIP_PROCESS:
            for proc in self.filter_tasks(tasks.pslist(addr_space)):
                process_name = str(proc.ImageFileName).lower()

                if (self._config.QUICK and
                        process_name not in self.critical_process):
                    #debug.debug("Skipping non-critical process {0} ({1})".format(
                    #    process_name, proc.UniqueProcessId))
                    continue

                process_space = proc.get_process_address_space()
                if not process_space:
                    #debug.debug("Cannot acquire process AS for {0} ({1})".format(
                    #    process_name, proc.UniqueProcessId))
                    continue

                module_group = ModuleGroup(proc.get_load_modules())

                for dll in module_group.mods:

                    if not process_space.is_valid_address(dll.DllBase):
                        continue

                    dll_name = str(dll.BaseDllName or '').lower()

                    if (self._config.QUICK and
                            dll_name not in self.critical_dlls and
                            dll.DllBase != proc.Peb.ImageBaseAddress):
                        #debug.debug("Skipping non-critical dll {0} at {1:#x}".format(
                        #    dll_name, dll.DllBase))
                        continue

                    #debug.debug("Analyzing {0}!{1}".format(process_name, dll_name))

                    for hook in self.get_hooks(HOOK_MODE_USER, process_space, dll, module_group):
                        if not self._config.NO_WHITELIST:
                            if self.whitelist(hook.hook_mode | hook.hook_type, str(proc.ImageFileName), hook.VictimModule, hook.HookModule, hook.Function):
                                continue
                        yield proc, dll, hook

        if not self._config.SKIP_KERNEL:
            process_list = list(tasks.pslist(addr_space))
            module_group = ModuleGroup(modules.lsmod(addr_space))

            for mod in module_group.mods:

                #module_name = str(mod.BaseDllName or '')
                #debug.debug("Analyzing {0}".format(module_name))

                kernel_space = tasks.find_space(addr_space,
                    process_list, mod.DllBase)

                if not kernel_space:
                    #debug.debug("No kernel AS for {0} at {1:#x}".format(
                    #    module_name, mod.DllBase))
                    continue

                for hook in self.get_hooks(HOOK_MODE_KERNEL, kernel_space, mod, module_group):
                    if not self._config.NO_WHITELIST:
                        if self.whitelist(hook.hook_mode | hook.hook_type, "", hook.VictimModule, hook.HookModule, hook.Function):
                            continue
                    yield None, mod, hook
Esempio n. 20
0
    def calculate(self):
        if self._config.OUTPUT == "xlsx" and not has_openpyxl:
            debug.error("You must install OpenPyxl for xlsx format:\n\thttps://bitbucket.org/ericgazoni/openpyxl/wiki/Home")
        elif self._config.OUTPUT == "xlsx" and not self._config.OUTPUT_FILE:
            debug.error("You must specify an output *.xlsx file!\n\t(Example: --output-file=OUTPUT.xlsx)")

        if (self._config.HIVE or self._config.USER) and not (self._config.REGISTRY):
            debug.error("You must use -R/--registry in conjuction with -H/--hive and/or -U/--user")

        addr_space = utils.load_as(self._config)
        version = (addr_space.profile.metadata.get('major', 0), 
                   addr_space.profile.metadata.get('minor', 0))

        pids = {}     #dictionary of process IDs/ImageFileName
        offsets = []  #process offsets
        
        im = imageinfo.ImageInfo(self._config).get_image_time(addr_space) 
        body = False
        if self._config.OUTPUT == "body":
            body = True
    
        if not body:
            event = "{0}|[END LIVE RESPONSE]\n".format(im['ImageDatetime'])
        else:
            event = "0|[END LIVE RESPONSE]|0|---------------|0|0|0|{0}|{0}|{0}|{0}\n".format(im['ImageDatetime'].v())
        yield event
                
        # Get EPROCESS 
        psscan = filescan.PSScan(self._config).calculate()
        for eprocess in psscan:
            if eprocess.obj_offset not in offsets:
                offsets.append(eprocess.obj_offset)

            if not body:
                line = "{0}|{1}|{2}|{3}|{4}|{5}|0x{6:08x}||\n".format(
                    eprocess.CreateTime or '-1', 
                    "[PROCESS]",
                    eprocess.ImageFileName,
                    eprocess.UniqueProcessId,
                    eprocess.InheritedFromUniqueProcessId,
                    eprocess.ExitTime or '',
                    eprocess.obj_offset)
            else:
                line = "0|[PROCESS] {2}/PID: {3}/PPID: {4}/POffset: 0x{5:08x}|0|---------------|0|0|0|{0}|{1}|{0}|{0}\n".format(
                        eprocess.CreateTime.v(), 
                        eprocess.ExitTime.v(),
                        eprocess.ImageFileName,
                        eprocess.UniqueProcessId,
                        eprocess.InheritedFromUniqueProcessId,
                        eprocess.obj_offset)
            pids[eprocess.UniqueProcessId.v()] = eprocess.ImageFileName
            yield line 

        # Get Sockets and Evtlogs XP/2k3 only
        if addr_space.profile.metadata.get('major', 0) == 5:
            socks = sockets.Sockets(self._config).calculate()
            #socks = sockscan.SockScan(self._config).calculate()   # you can use sockscan instead if you uncomment
            for sock in socks:
                la = "{0}:{1}".format(sock.LocalIpAddress, sock.LocalPort)
                if not body:
                    line = "{0}|[SOCKET]|{1}|{2}|Protocol: {3} ({4})|{5:#010x}|||\n".format(
                        sock.CreateTime, 
                        sock.Pid, 
                        la,
                        sock.Protocol,
                        protos.protos.get(sock.Protocol.v(), "-"),
                        sock.obj_offset)
                else:
                    line = "0|[SOCKET] PID: {1}/LocalIP: {2}/Protocol: {3}({4})/POffset: 0x{5:#010x}|0|---------------|0|0|0|{0}|{0}|{0}|{0}\n".format(
                            sock.CreateTime.v(), 
                            sock.Pid,
                            la,
                            sock.Protocol,
                            protos.protos.get(sock.Protocol.v(), "-"),
                            sock.obj_offset)
                yield line

            stuff = evtlogs.EvtLogs.calculate(self)
            for name, buf in stuff:
                for fields in self.parse_evt_info(name, buf, rawtime = True):
                    if not body:
                        line = '{0} |[EVT LOG]|{1}|{2}|{3}|{4}|{5}|{6}|{7}\n'.format(
                            fields[0], fields[1], fields[2], fields[3], fields[4], fields[5], fields[6], fields[7])
                    else:
                        line = "0|[EVT LOG] {1}/{2}/{3}/{4}/{5}/{6}/{7}|0|---------------|0|0|0|{0}|{0}|{0}|{0}\n".format(
                            fields[0].v(),fields[1], fields[2], fields[3], fields[4], fields[5], fields[6], fields[7])
                    yield line
        else:
            # Vista+
            nets = netscan.Netscan(self._config).calculate()
            for net_object, proto, laddr, lport, raddr, rport, state in nets:
                conn = "{0}:{1} -> {2}:{3}".format(laddr, lport, raddr, rport)
                if not body:
                    line = "{0}|[NETWORK CONNECTION]|{1}|{2}|{3}|{4}|{5:<#10x}||\n".format(
                        str(net_object.CreateTime or "-1"),
                        net_object.Owner.UniqueProcessId,
                        conn,
                        proto,
                        state,
                        net_object.obj_offset)
                else:
                    line = "0|[NETWORK CONNECTION] {1}/{2}/{3}/{4}/{5:<#10x}|0|---------------|0|0|0|{0}|{0}|{0}|{0}\n".format(
                        net_object.CreateTime.v(),
                        net_object.Owner.UniqueProcessId,
                        conn,
                        proto,
                        state,
                        net_object.obj_offset)
                yield line

        # Get threads
        threads = modscan.ThrdScan(self._config).calculate()
        for thread in threads:
            image = pids.get(thread.Cid.UniqueProcess.v(), "UNKNOWN")
            if not body:
                line = "{0}|[THREAD]|{1}|{2}|{3}|{4}|||\n".format(
                    thread.CreateTime or '-1',
                    image,
                    thread.Cid.UniqueProcess,
                    thread.Cid.UniqueThread,
                    thread.ExitTime or '',
                    )
            else:
                line = "0|[THREAD] {2}/PID: {3}/TID: {4}|0|---------------|0|0|0|{0}|{1}|{0}|{0}\n".format(
                    thread.CreateTime.v(),
                    thread.ExitTime.v(),
                    image,
                    thread.Cid.UniqueProcess,
                    thread.Cid.UniqueThread,
                    )
            yield line

        # now we get to the PE part.  All PE's are dumped in case you want to inspect them later
    
        data = moddump.ModDump(self._config).calculate()

        for addr_space, procs, mod_base, mod_name in data:
            space = tasks.find_space(addr_space, procs, mod_base)
            if space != None:
                try:
                    header = procdump.ProcExeDump(self._config).get_nt_header(space, mod_base)
                except ValueError, ve: 
                    continue
                try:
                    if not body:
                        line = "{0}|[PE Timestamp (module)]|{1}||{2:#010x}|||||\n".format(
                            header.FileHeader.TimeDateStamp or '-1',
                            mod_name,
                            mod_base)
                    else:
                        line = "0|[PE Timestamp (module)] {1}/Base: {2:#010x}|0|---------------|0|0|0|{0}|{0}|{0}|{0}\n".format(
                            header.FileHeader.TimeDateStamp.v(),
                            mod_name, mod_base)
                except ValueError, ve:
                    if not body:
                        line = "-1|[PE Timestamp (module)]|{0}||{1}|||||\n".format(
                            mod_name,
                            mod_base)
                    else:
                        line = "0|[PE Timestamp (module)] {0}/Base: {1:#010x}|0|---------------|0|0|0|0|0|0|0\n".format(
                            mod_name, mod_base)

                yield line
Esempio n. 21
0
    def calculate(self):
        if self._config.OUTPUT == "xlsx" and not has_openpyxl:
            debug.error(
                "You must install OpenPyxl for xlsx format:\n\thttps://bitbucket.org/ericgazoni/openpyxl/wiki/Home"
            )
        elif self._config.OUTPUT == "xlsx" and not self._config.OUTPUT_FILE:
            debug.error(
                "You must specify an output *.xlsx file!\n\t(Example: --output-file=OUTPUT.xlsx)"
            )

        if (self._config.HIVE
                or self._config.USER) and not (self._config.REGISTRY):
            debug.error(
                "You must use -R/--registry in conjuction with -H/--hive and/or -U/--user"
            )

        addr_space = utils.load_as(self._config)
        version = (addr_space.profile.metadata.get('major', 0),
                   addr_space.profile.metadata.get('minor', 0))

        pids = {}  #dictionary of process IDs/ImageFileName
        offsets = []  #process offsets

        im = imageinfo.ImageInfo(self._config).get_image_time(addr_space)
        body = False
        if self._config.OUTPUT == "body":
            body = True

        if not body:
            event = "{0}|[END LIVE RESPONSE]\n".format(im['ImageDatetime'])
        else:
            event = "0|[END LIVE RESPONSE]|0|---------------|0|0|0|{0}|{0}|{0}|{0}\n".format(
                im['ImageDatetime'].v())
        yield event

        # Get EPROCESS
        psscan = filescan.PSScan(self._config).calculate()
        for eprocess in psscan:
            if eprocess.obj_offset not in offsets:
                offsets.append(eprocess.obj_offset)

            if not body:
                line = "{0}|{1}|{2}|{3}|{4}|{5}|0x{6:08x}||\n".format(
                    eprocess.CreateTime or '-1', "[PROCESS]",
                    eprocess.ImageFileName, eprocess.UniqueProcessId,
                    eprocess.InheritedFromUniqueProcessId, eprocess.ExitTime
                    or '', eprocess.obj_offset)
            else:
                line = "0|[PROCESS] {2}/PID: {3}/PPID: {4}/POffset: 0x{5:08x}|0|---------------|0|0|0|{0}|{1}|{0}|{0}\n".format(
                    eprocess.CreateTime.v(), eprocess.ExitTime.v(),
                    eprocess.ImageFileName, eprocess.UniqueProcessId,
                    eprocess.InheritedFromUniqueProcessId, eprocess.obj_offset)
            pids[eprocess.UniqueProcessId.v()] = eprocess.ImageFileName
            yield line

        # Get Sockets and Evtlogs XP/2k3 only
        if addr_space.profile.metadata.get('major', 0) == 5:
            socks = sockets.Sockets(self._config).calculate()
            #socks = sockscan.SockScan(self._config).calculate()   # you can use sockscan instead if you uncomment
            for sock in socks:
                la = "{0}:{1}".format(sock.LocalIpAddress, sock.LocalPort)
                if not body:
                    line = "{0}|[SOCKET]|{1}|{2}|Protocol: {3} ({4})|{5:#010x}|||\n".format(
                        sock.CreateTime, sock.Pid, la, sock.Protocol,
                        protos.protos.get(sock.Protocol.v(), "-"),
                        sock.obj_offset)
                else:
                    line = "0|[SOCKET] PID: {1}/LocalIP: {2}/Protocol: {3}({4})/POffset: 0x{5:#010x}|0|---------------|0|0|0|{0}|{0}|{0}|{0}\n".format(
                        sock.CreateTime.v(), sock.Pid, la, sock.Protocol,
                        protos.protos.get(sock.Protocol.v(), "-"),
                        sock.obj_offset)
                yield line

            evt = evtlogs.EvtLogs(self._config)
            stuff = evt.calculate()
            for name, buf in stuff:
                for fields in evt.parse_evt_info(name, buf, rawtime=True):
                    if not body:
                        line = '{0} |[EVT LOG]|{1}|{2}|{3}|{4}|{5}|{6}|{7}\n'.format(
                            fields[0], fields[1], fields[2], fields[3],
                            fields[4], fields[5], fields[6], fields[7])
                    else:
                        line = "0|[EVT LOG] {1}/{2}/{3}/{4}/{5}/{6}/{7}|0|---------------|0|0|0|{0}|{0}|{0}|{0}\n".format(
                            fields[0].v(), fields[1], fields[2], fields[3],
                            fields[4], fields[5], fields[6], fields[7])
                    yield line
        else:
            # Vista+
            nets = netscan.Netscan(self._config).calculate()
            for net_object, proto, laddr, lport, raddr, rport, state in nets:
                conn = "{0}:{1} -> {2}:{3}".format(laddr, lport, raddr, rport)
                if not body:
                    line = "{0}|[NETWORK CONNECTION]|{1}|{2}|{3}|{4}|{5:<#10x}||\n".format(
                        str(net_object.CreateTime
                            or "-1"), net_object.Owner.UniqueProcessId, conn,
                        proto, state, net_object.obj_offset)
                else:
                    line = "0|[NETWORK CONNECTION] {1}/{2}/{3}/{4}/{5:<#10x}|0|---------------|0|0|0|{0}|{0}|{0}|{0}\n".format(
                        net_object.CreateTime.v(),
                        net_object.Owner.UniqueProcessId, conn, proto, state,
                        net_object.obj_offset)
                yield line

        # Get threads
        threads = modscan.ThrdScan(self._config).calculate()
        for thread in threads:
            image = pids.get(thread.Cid.UniqueProcess.v(), "UNKNOWN")
            if not body:
                line = "{0}|[THREAD]|{1}|{2}|{3}|{4}|||\n".format(
                    thread.CreateTime or '-1',
                    image,
                    thread.Cid.UniqueProcess,
                    thread.Cid.UniqueThread,
                    thread.ExitTime or '',
                )
            else:
                line = "0|[THREAD] {2}/PID: {3}/TID: {4}|0|---------------|0|0|0|{0}|{1}|{0}|{0}\n".format(
                    thread.CreateTime.v(),
                    thread.ExitTime.v(),
                    image,
                    thread.Cid.UniqueProcess,
                    thread.Cid.UniqueThread,
                )
            yield line

        # now we get to the PE part.  All PE's are dumped in case you want to inspect them later

        data = moddump.ModDump(self._config).calculate()

        for addr_space, procs, mod_base, mod_name in data:
            mod_name = str(mod_name or '')
            space = tasks.find_space(addr_space, procs, mod_base)
            if space != None:
                try:
                    header = procdump.ProcExeDump(self._config).get_nt_header(
                        space, mod_base)
                except ValueError, ve:
                    continue
                try:
                    if not body:
                        line = "{0}|[PE Timestamp (module)]|{1}||{2:#010x}|||||\n".format(
                            header.FileHeader.TimeDateStamp or '-1', mod_name,
                            mod_base)
                    else:
                        line = "0|[PE Timestamp (module)] {1}/Base: {2:#010x}|0|---------------|0|0|0|{0}|{0}|{0}|{0}\n".format(
                            header.FileHeader.TimeDateStamp.v(), mod_name,
                            mod_base)
                except ValueError, ve:
                    if not body:
                        line = "-1|[PE Timestamp (module)]|{0}||{1}|||||\n".format(
                            mod_name, mod_base)
                    else:
                        line = "0|[PE Timestamp (module)] {0}/Base: {1:#010x}|0|---------------|0|0|0|0|0|0|0\n".format(
                            mod_name, mod_base)

                yield line
Esempio n. 22
0
    def calculate(self):
        """ TODO """

        self.addr_space = utils.load_as(self._config)
        if self._config.PID:
            pids = self._config.PID.split(',')

        log_file = None
        if self._config.LOGFILE:
            log_file = open(self._config.LOGFILE, "w+")

        # Modules on user space
        for task in tasks.pslist(self.addr_space):
            if (not self._config.PID) or (str(task.UniqueProcessId) in pids):
                task_space = task.get_process_address_space()
                for mod in task.get_load_modules():
                    count_valid_pages = 0
                    _list = []
                    for i in range(0, mod.SizeOfImage, PAGE_SIZE):
                        if task_space.is_valid_address(mod.DllBase + i):
                            count_valid_pages += 1
                            _list.append([
                                mod.DllBase + i,
                                task_space.vtop(mod.DllBase + i)
                            ])

                    dump_file = None
                    if self._config.DUMP_DIR:
                        if not os.path.exists(self._config.DUMP_DIR):
                            os.makedirs(self._config.DUMP_DIR)
                        # Create dump_file
                        dump_file = os.path.join(
                            self._config.DUMP_DIR,
                            '{0}-{1}-{2}.csv'.format(task.ImageFileName,
                                                     task.UniqueProcessId,
                                                     mod.BaseDllName.v()))
                        self.write_to_file(dump_file, _list)

                    total_pages = mod.SizeOfImage / PAGE_SIZE
                    if log_file:
                        baseDllName = (mod.BaseDllName.v())
                        if type(baseDllName) == obj.NoneObject:
                            baseDllName = '-----'
                        fullDllName = mod.FullDllName.v()
                        if type(fullDllName) == obj.NoneObject:
                            fullDllName = '-----'
                        log_file.write('\t'.join(
                            (str(task.UniqueProcessId),
                             str(task.ImageFileName), baseDllName,
                             str(mod.DllBase.v()), str(count_valid_pages),
                             str(total_pages), fullDllName)) + '\n')
                    version = obj.Object("_IMAGE_DOS_HEADER", mod.DllBase,
                                         task_space).get_version_info()
                    yield (task.UniqueProcessId, task.ImageFileName,
                           mod.BaseDllName.v(),
                           mod.DllBase.v(), count_valid_pages, total_pages,
                           mod.FullDllName.v(), dump_file,
                           version.FileInfo.file_version() if version else '')

        # Drivers -- part of this code is inspired in moddump plugin
        mods = dict(
            (mod.DllBase.v(), mod) for mod in modules.lsmod(self.addr_space))
        procs = list(tasks.pslist(self.addr_space))

        for mod in mods.values():
            mod_base = mod.DllBase.v()
            space = tasks.find_space(self.addr_space, procs, mod_base)
            count_valid_pages = 0
            _list = []
            if space != None:  # check if we have retrieved the correct AS
                # when no retrieved, paged memory pages will be equal to the total pages
                for i in range(0, mod.SizeOfImage, PAGE_SIZE):
                    if space.is_valid_address(mod.DllBase + i):
                        count_valid_pages += 1
                        _list.append(
                            [mod.DllBase + i,
                             space.vtop(mod.DllBase + i)])

            dump_file = None
            if self._config.DUMP_DIR:
                if not os.path.exists(self._config.DUMP_DIR):
                    os.makedirs(self._config.DUMP_DIR)
                # Create dump_file
                dump_file = os.path.join(
                    self._config.DUMP_DIR,
                    'drv_{}.csv'.format(mod.BaseDllName.v()))
                self.write_to_file(dump_file, _list)

            total_pages = mod.SizeOfImage / PAGE_SIZE
            if log_file:
                log_file.write('\t'.join(
                    ('--', '--', str(mod.BaseDllName.v()),
                     str(mod.DllBase.v()), str(count_valid_pages),
                     str(total_pages), str(mod.FullDllName.v()))) + '\n')
            version = obj.Object("_IMAGE_DOS_HEADER", mod.DllBase,
                                 task_space).get_version_info()
            yield ('--', '--', mod.BaseDllName.v(),
                   mod.DllBase.v(), count_valid_pages, total_pages,
                   mod.FullDllName.v(), dump_file,
                   version.FileInfo.file_version() if version else '')

        if self._config.LOGFILE:
            log_file.close()