Exemple #1
0
    def calculate(self):
        ## Just grab the AS and scan it using our scanner
        address_space = utils.load_as(self._config, astype = 'physical')

        ## Will need the kernel AS for later:
        kernel_as = utils.load_as(self._config)

        for offset in PoolScanSymlink().scan(address_space):
            pool_obj = obj.Object("_POOL_HEADER", vm = address_space,
                                 offset = offset)

            ## We work out the object from the end of the
            ## allocation (bottom up).
            pool_alignment = obj.VolMagic(address_space).PoolAlignment.v()

            link_obj = obj.Object("_OBJECT_SYMBOLIC_LINK", vm = address_space,
                     offset = (offset + pool_obj.BlockSize * pool_alignment -
                               common.pool_align(kernel_as, "_OBJECT_SYMBOLIC_LINK", pool_alignment)),
                     native_vm = kernel_as)

            ## The _OBJECT_HEADER is immediately below the _OBJECT_SYMBOLIC_LINK
            object_obj = obj.Object(
                "_OBJECT_HEADER", vm = address_space,
                offset = link_obj.obj_offset -
                address_space.profile.get_obj_offset('_OBJECT_HEADER', 'Body'),
                native_vm = kernel_as
                )

            if object_obj.get_object_type() != "SymbolicLink":
                continue

            yield object_obj, link_obj
    def calculate(self):
        flat_space = utils.load_as(self._config, astype = 'physical')
        kernel_space = utils.load_as(self._config)

        # Scan for window station objects 
        for offset in PoolScanWind().scan(flat_space):

            window_station = obj.Object("tagWINDOWSTATION",
                offset = offset, vm = flat_space)

            # Basic sanity checks are included here 
            if not window_station.is_valid():
                continue

            # Find an address space for this window station's session  
            session = self.find_session_space(
                kernel_space, window_station.dwSessionId)

            if not session:
                continue

            # Reset the object's native VM so pointers are
            # dereferenced in session space 
            window_station.set_native_vm(session.obj_vm)

            for winsta in window_station.traverse():
                if winsta.is_valid():
                    yield winsta
Exemple #3
0
    def calculate(self):

        # Virtual kernel space for dereferencing pointers
        kernel_space = utils.load_as(self._config)
        # Physical space for scanning 
        flat_space = utils.load_as(self._config, astype = 'physical')

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

        # Scan for TCP listeners also known as sockets
        for offset in PoolScanTcpListener().scan(flat_space):

            tcpentry = obj.Object('_TCP_LISTENER', offset = offset,
                                  vm = flat_space, native_vm = kernel_space)

            # Only accept IPv4 or IPv6
            if tcpentry.AddressFamily not in (AF_INET, AF_INET6):
                continue

            # For TcpL, the state is always listening and the remote port is zero
            for ver, laddr, raddr in tcpentry.dual_stack_sockets():
                yield tcpentry, "TCP" + ver, laddr, tcpentry.Port, raddr, 0, "LISTENING"

        # Scan for TCP endpoints also known as connections 
        for offset in PoolScanTcpEndpoint().scan(flat_space):

            tcpentry = obj.Object('_TCP_ENDPOINT', offset = offset,
                                  vm = flat_space, native_vm = kernel_space)

            if tcpentry.AddressFamily == AF_INET:
                proto = "TCPv4"
            elif tcpentry.AddressFamily == AF_INET6:
                proto = "TCPv6"
            else:
                continue

            # These are our sanity checks 
            if (tcpentry.State.v() not in tcpip_vtypes.TCP_STATE_ENUM or
                    (not tcpentry.LocalAddress and (not tcpentry.Owner or
                    tcpentry.Owner.UniqueProcessId == 0 or
                    tcpentry.Owner.UniqueProcessId > 65535))):
                continue

            yield tcpentry, proto, tcpentry.LocalAddress, tcpentry.LocalPort, \
                    tcpentry.RemoteAddress, tcpentry.RemotePort, tcpentry.State

        # Scan for UDP endpoints 
        for offset in PoolScanUdpEndpoint().scan(flat_space):

            udpentry = obj.Object('_UDP_ENDPOINT', offset = offset,
                                  vm = flat_space, native_vm = kernel_space)

            # Only accept IPv4 or IPv6
            if udpentry.AddressFamily not in (AF_INET, AF_INET6):
                continue

            # For UdpA, the state is always blank and the remote end is asterisks
            for ver, laddr, _ in udpentry.dual_stack_sockets():
                yield udpentry, "UDP" + ver, laddr, udpentry.Port, "*", "*", ""
Exemple #4
0
	def calculate(self):
		self.kernel_address_space = utils.load_as(self._config)
		self.flat_address_space = utils.load_as(self._config, astype = 'physical')
		if not(bool(self._config.DIR)):
			debug.error("--dir needs to be present")
		if not(bool(self._config.pid) ^ bool(self._config.eproc) ^ bool(self._config.fobj) ^ bool(self._config.pool)):
			if not(bool(self._config.pid) or bool(self._config.eproc) or bool(self._config.fobj) or bool(self._config.pool)):
				debug.error("exactly *ONE* of the options --pid, --eproc, --fobj or --pool must be specified (you have not specified _any_ of these options)")
			else:
				debug.error("exactly *ONE* of the options --pid, --eproc, --fobj or --pool must be specified (you have used _multiple_ such options)")
		if bool(self._config.pid):
			# --pid
			eproc_matches = [ eproc for eproc in tasks.pslist(self.kernel_address_space) if eproc.UniqueProcessId == self._config.pid ]
			if len(eproc_matches) != 1:
				debug.error("--pid needs to take a *VALID* PID argument (could not find PID {0} in the process listing for this memory image)".format(self._config.pid))
			return self.dump_from_eproc(eproc_matches[0])
		elif bool(self._config.eproc):
			# --eproc
			return self.dump_from_eproc(obj.Object("_EPROCESS", offset = self._config.eproc, vm = self.kernel_address_space))
		elif bool(self._config.fobj):
			# --fobj
			try:
				file_object = obj.Object("_FILE_OBJECT", offset = self._config.fobj, vm = self.flat_address_space)
				if bool(self._config.reconstruct):
					# --reconstruct
					return [ (file_object, self.parse_string(file_object.FileName)) ]
				else:
					return filter(None, [ self.dump_file_object(file_object) ])
			except ExportException as exn:
				debug.error(exn)
		else:
			# --pool
			return self.dump_from_pool()
Exemple #5
0
    def calculate(self):
        eproc = {}
        found = {}
        cmdline = {}
        pathname = {}
              
        # Brute force search for eproc blocks in pool memory
        address_space = utils.load_as(self._config)
        for eprocess in filescan.PSScan(self._config).calculate():
            eproc[eprocess.obj_offset] = eprocess
            found[eprocess.obj_offset] = 1
        
        # Walking the active process list.
        # Remove any tasks we find here from the brute force search if the --short option is set.
        # Anything left is something which was hidden/terminated/of interest.
        address_space = utils.load_as(self._config)
        for task in tasks.pslist(address_space):
            phys = address_space.vtop(task.obj_offset)
            if phys in eproc:
                if self._config.SHORT :
                    del eproc[phys]
                    del found[phys] 
                else:
                    found[phys] = 0                
                    
        # Grab command line and parameters            
            peb = task.Peb
            if peb:
                cmdline[phys] = peb.ProcessParameters.CommandLine
                pathname[phys] = peb.ProcessParameters.ImagePathName
                    
        ret = [eproc, found, cmdline, pathname]

        return ret
Exemple #6
0
    def calculate(self):
        vspace = utils.load_as(self._config)
        pspace = utils.load_as(self._config, astype = 'physical')

        for offset in PoolScanTcpListener().scan(pspace):
            tcpentry = obj.Object('_TCP_LISTENER', offset, pspace)

            lport = socket.ntohs(tcpentry.Port)

            # For TcpL, the state is always listening and the remote port is zero
            state = "LISTENING"
            rport = 0

            for ver, laddr, raddr, owner in self.enumerate_listeners(tcpentry, vspace):
                yield tcpentry.obj_offset, "TCP" + ver, laddr, lport, \
                    raddr, rport, state, owner, tcpentry.CreateTime

        for offset in PoolScanTcpEndpoint().scan(pspace):
            tcpentry = obj.Object('_TCP_ENDPOINT', offset, pspace)
            AddrInfo = obj.Object('_ADDRINFO', tcpentry.AddrInfo, vspace)
            InetAF = obj.Object('_INETAF', tcpentry.InetAF, vspace)
            Owner = obj.Object('_EPROCESS', tcpentry.Owner, vspace)

            lport = socket.ntohs(tcpentry.LocalPort)
            rport = socket.ntohs(tcpentry.RemotePort)

            try:
                state = tcp_states[tcpentry.State + 1]
            except IndexError:
                state = hex(tcpentry.State)

            l_inaddr = AddrInfo.Local.pData.dereference().dereference().v()
            r_inaddr = AddrInfo.Remote.dereference().v()

            if InetAF.AddressFamily == AF_INET:
                proto = "TCPv4"
                laddr = inet_ntop(socket.AF_INET, vspace.zread(l_inaddr, 4))
                raddr = inet_ntop(socket.AF_INET, vspace.zread(r_inaddr, 4))
            elif InetAF.AddressFamily == AF_INET6:
                proto = "TCPv6"
                laddr = inet_ntop(socket.AF_INET6, vspace.zread(l_inaddr, 16))
                raddr = inet_ntop(socket.AF_INET6, vspace.zread(r_inaddr, 16))
            else:
                continue

            yield tcpentry.obj_offset, proto, laddr, lport, raddr, \
                rport, state, Owner, tcpentry.CreateTime

        for offset in PoolScanUdpEndpoint().scan(pspace):
            udpentry = obj.Object('_UDP_ENDPOINT', offset, pspace)

            lport = socket.ntohs(udpentry.Port)

            # For UdpA, the state is always blank and the remote end is asterisks
            state = ""
            raddr = rport = "*"

            for ver, laddr, _, owner in self.enumerate_listeners(udpentry, vspace):
                yield udpentry.obj_offset, "UDP" + ver, laddr, lport, \
                    raddr, rport, state, owner, udpentry.CreateTime
Exemple #7
0
    def calculate(self):
        """Determines the address space"""
        profilelist = [ p.__name__ for p in registry.get_plugin_classes(obj.Profile).values() ]

        encrypted_kdbg_profiles = []
        proflens = {}
        maxlen = 0
        origprofile = self._config.PROFILE
        for p in profilelist:
            self._config.update('PROFILE', p)
            buf = addrspace.BufferAddressSpace(self._config)
            if buf.profile.metadata.get('os', 'unknown') == 'windows':
                proflens[p] = str(obj.VolMagic(buf).KDBGHeader)
                maxlen = max(maxlen, len(proflens[p]))
                if (buf.profile.metadata.get('memory_model', '64bit') == '64bit' and 
                            (buf.profile.metadata.get('major', 0), 
                            buf.profile.metadata.get('minor', 0)) >= (6, 2)):
                    encrypted_kdbg_profiles.append(p)
                    
        self._config.update('PROFILE', origprofile)
        # keep track of the number of potential KDBGs we find
        count = 0

        if origprofile not in encrypted_kdbg_profiles:
            scanner = KDBGScanner(needles = proflens.values())

            aspace = utils.load_as(self._config, astype = 'any')

            suspects = []
            for offset in scanner.scan(aspace):
                val = aspace.read(offset, maxlen + 0x10)
                for l in proflens:
                    if val.find(proflens[l]) >= 0:
                        kdbg = obj.Object("_KDDEBUGGER_DATA64", offset = offset, vm = aspace)
                        suspects.append((l, kdbg))
                        count += 1
            for p, k in suspects:
                if not self._config.FORCE:
                    yield p, k
                    continue
                self._config.update("PROFILE", p)
                nspace = utils.load_as(self._config, astype = "any")
                for offset in scanner.scan(nspace):
                    val = nspace.read(offset, maxlen + 0x10)
                    if val.find(proflens[p]) >= 0:
                        kdbg = obj.Object("_KDDEBUGGER_DATA64", offset = offset, vm = nspace)
                        yield p, kdbg
            self._config.update('PROFILE', origprofile)

        # only perform the special win8/2012 scan if we didn't find 
        # any others and if a virtual x64 address space is available 
        if count == 0:
            if origprofile in encrypted_kdbg_profiles:
                encrypted_kdbg_profiles = [origprofile]
            for profile in encrypted_kdbg_profiles:
                self._config.update('PROFILE', profile)
                aspace = utils.load_as(self._config, astype = 'any')
                if hasattr(aspace, 'vtop'):
                    for kdbg in obj.VolMagic(aspace).KDBG.generate_suggestions():
                        yield profile, kdbg 
Exemple #8
0
    def calculate(self):
        ## Just grab the AS and scan it using our scanner
        address_space = utils.load_as(self._config, astype="physical")
        kernel_as = utils.load_as(self._config)

        for offset in PoolScanProcess().scan(address_space):
            eprocess = obj.Object("_EPROCESS", vm=address_space, native_vm=kernel_as, offset=offset)
            yield eprocess
Exemple #9
0
    def calculate(self):
        ## Here we scan the physical address space
        address_space = utils.load_as(self._config, astype = 'physical')
        kernel_as = utils.load_as(self._config)

        scanner = PoolScanThreadFast()
        for found in scanner.scan(address_space):
            thread = obj.Object('_ETHREAD', vm = address_space,
                               native_vm = kernel_as, offset = found)

            yield thread
Exemple #10
0
 def virtual_process_from_physical_offset(self, offset):
     pspace = utils.load_as(self._config, astype = 'physical')
     vspace = utils.load_as(self._config)
     task = obj.Object("task_struct", vm = pspace, offset = offset)
     parent = obj.Object("task_struct", vm = vspace, offset = task.parent)
     
     for child in parent.children.list_of_type("task_struct", "sibling"):
         if child.obj_vm.vtop(child.obj_offset) == task.obj_offset:
             return child
     
     return obj.NoneObject("Unable to bounce back from task_struct->parent->task_struct")
Exemple #11
0
    def calculate(self):
        ## Here we scan the physical address space
        address_space = utils.load_as(self._config, astype = 'physical')

        ## We need the kernel_address_space later
        kernel_as = utils.load_as(self._config)

        scanner = PoolScanModuleFast()
        for offset in scanner.scan(address_space):
            ldr_entry = obj.Object('_LDR_DATA_TABLE_ENTRY', vm = address_space,
                                  offset = offset, native_vm = kernel_as)
            yield ldr_entry
Exemple #12
0
    def calculate(self):
        # start with a physical space so we can find processes without a DTB 
        addr_space = utils.load_as(self._config, astype = 'physical')
        meta = addr_space.profile.metadata
        win10 = (meta.get("major"), meta.get("minor")) == (6, 4)

        # if the user selected virtual space or if we're on win10, switch 
        # to a virtual kernel space 
        if self._config.VIRTUAL or win10:
            addr_space = utils.load_as(self._config) 

        return self.scan_results(addr_space)
Exemple #13
0
    def __config(self):
        """Creates a volatility configuration."""
        if self.config != None and self.addr_space != None:
            return self.config

        self.config = conf.ConfObject()
        self.config.optparser.set_conflict_handler("resolve")
        registry.register_global_options(self.config, commands.Command)
        base_conf = {
            "profile": "WinXPSP2x86",
            "use_old_as": None,
            "kdbg": None,
            "help": False,
            "kpcr": None,
            "tz": None,
            "pid": None,
            "output_file": None,
            "physical_offset": None,
            "conf_file": None,
            "dtb": None,
            "output": None,
            "info": None,
            "location": "file://" + self.memdump,
            "plugins": None,
            "debug": None,
            "cache_dtb": True,
            "filename": None,
            "cache_directory": None,
            "verbose": None,
            "write": False
        }

        if self.osprofile:
            base_conf["profile"] = self.osprofile

        for key, value in base_conf.items():
            self.config.update(key, value)

        # Deal with Volatility support for KVM/qemu memory dump.
        # See: #464.
        try:
          self.addr_space = utils.load_as(self.config)
        except exc.AddrSpaceError as e:
          if self._get_dtb():
              self.addr_space = utils.load_as(self.config)
          else:
              raise

        self.plugins = registry.get_plugin_classes(commands.Command,
                                                   lower=True)

        return self.config
Exemple #14
0
    def calculate(self):
        # All scanners will share a kernel and physical space 
        self.kern_space = utils.load_as(self._config)
        self.phys_space = utils.load_as(self._config, astype = 'physical')

        # We currently dont support x64
        if not self.is_valid_profile(self.kern_space.profile):
            debug.error("This command does not support the selected profile.")

        # Get the OS version we're analyzing
        version = (self.kern_space.profile.metadata.get('major', 0),
                   self.kern_space.profile.metadata.get('minor', 0))

        modlist = list(modules.lsmod(self.kern_space))
        mods = dict((self.kern_space.address_mask(mod.DllBase), mod) for mod in modlist)
        mod_addrs = sorted(mods.keys())

        # First few routines are valid on all OS versions 
        for info in self.get_fs_callbacks():
            yield info, mods, mod_addrs

        for info in self.get_bugcheck_callbacks():
            yield info, mods, mod_addrs

        for info in self.get_shutdown_callbacks():
            yield info, mods, mod_addrs

        for info in self.get_generic_callbacks():
            yield info, mods, mod_addrs

        for info in self.get_bugcheck_reason_callbacks(modlist[0]):
            yield info, mods, mod_addrs

        for info in self.get_kernel_callbacks(modlist[0]):
            yield info, mods, mod_addrs

        # Valid for Vista and later
        if version >= (6, 0):
            for info in self.get_dbgprint_callbacks():
                yield info, mods, mod_addrs

            for info in self.get_registry_callbacks():
                yield info, mods, mod_addrs

            for info in self.get_pnp_callbacks():
                yield info, mods, mod_addrs

        # Valid for XP 
        if version == (5, 1):
            for info in self.get_registry_callbacks_legacy(modlist[0]):
                yield info, mods, mod_addrs
Exemple #15
0
def doProcessors(config):
    ''' Retrieve IDT data. '''

    physical_address_space = utils.load_as(config)
    kernel_address_space = utils.load_as(config,astype='kernel')
    processors_obj = datastruct.rootType()
    proc_num = 0
    for kpcr in FindKPCR(physical_address_space):
        processor_obj = processors_obj.Processor.add()
        processor_obj.ID = proc_num
        proc_num += 1
        IdtBase = kpcr.IdtBase
        IDTs = obj.Array(None,physical_address_space.address_mask(IdtBase.v()),physical_address_space,count=256,target=IdtBase.target)
        for idt in IDTs:
            entry_obj = processor_obj.InterruptDescriptorTable.IDTEntry.add()
            iswin32 = not idt.m('OffsetMiddle')
            if iswin32:
                idttype = idt.Access & 0x1f
                if idt.Access >= 256 or (idt.Access & 0x80) != 0x80:
                    entry_obj.InvalidGate = ''
                elif idttype==0x5:
                    entry_obj.TaskGate = ''
                elif idttype==0x6 or idttype==0xe:
                    entry_obj.InterruptGate = ''
                elif idttype==0x7 or idttype==0xf:
                    entry_obj.TrapGate = ''
                else:
                    entry_obj.InvalidGate = ''
                entry_obj.Address = (idt.ExtendedOffset << 16) | idt.Offset
                entry_obj.Attributes = idt.Access
            else:
                idttype = idt.Type
                if idt.Reserved0!=0 or idt.Reserved1!=0 or idt.Present==0:
                    entry_obj.InvalidGate = ''
                elif idttype==0x5:
                    entry_obj.TaskGate = ''
                elif idttype==0xe:
                    entry_obj.InterruptGate = ''
                elif idttype==0xf:
                    entry_obj.TrapGate = ''
                else:
                    entry_obj.InvalidGate = ''
                entry_obj.Address = ((idt.OffsetHigh & 0xffffffff) << 32) | ((idt.OffsetMiddle & 0xffff) << 16) | (idt.OffsetLow & 0xffff)
                entry_obj.Attributes = (idt.IstIndex << 13) | (idt.Type << 3) | (idt.Dpl<<1) | idt.Present

            entry_obj.Selector = idt.Selector.v()
            module = find_module(config,entry_obj.Address)
            if module:
                entry_obj.Module = module.FullDllName.v()

    return processors_obj
Exemple #16
0
    def calculate(self):
        ## Just grab the AS and scan it using our scanner
        address_space = utils.load_as(self._config, astype="physical")

        ## Will need the kernel AS for later:
        kernel_as = utils.load_as(self._config)

        for offset in PoolScanDriver().scan(address_space):
            pool_obj = obj.Object("_POOL_HEADER", vm=address_space, offset=offset)

            ## We work out the _DRIVER_OBJECT from the end of the
            ## allocation (bottom up).
            pool_alignment = obj.VolMagic(address_space).PoolAlignment.v()

            extension_obj = obj.Object(
                "_DRIVER_EXTENSION",
                vm=address_space,
                offset=(
                    offset
                    + pool_obj.BlockSize * pool_alignment
                    - common.pool_align(kernel_as, "_DRIVER_EXTENSION", pool_alignment)
                ),
                native_vm=kernel_as,
            )

            ## The _DRIVER_OBJECT is immediately below the _DRIVER_EXTENSION
            driver_obj = obj.Object(
                "_DRIVER_OBJECT",
                vm=address_space,
                offset=extension_obj.obj_offset - common.pool_align(kernel_as, "_DRIVER_OBJECT", pool_alignment),
                native_vm=kernel_as,
            )

            ## The _OBJECT_HEADER is immediately below the _DRIVER_OBJECT
            object_obj = obj.Object(
                "_OBJECT_HEADER",
                vm=address_space,
                offset=driver_obj.obj_offset - address_space.profile.get_obj_offset("_OBJECT_HEADER", "Body"),
                native_vm=kernel_as,
            )

            ## Skip unallocated objects
            # if object_obj.Type == 0xbad0b0b0:
            #    continue

            if object_obj.get_object_type() != "Driver":
                continue

            yield (object_obj, driver_obj, extension_obj)
Exemple #17
0
    def calculate(self):
        flat_space = utils.load_as(self._config, astype = 'physical')
        kernel_space = utils.load_as(self._config)

        # Scan for atom tables
        for offset in PoolScanAtom().scan(flat_space):

            # There's no way to tell which session or window station 
            # owns an atom table by *just* looking at the atom table, 
            # so we have to instantiate it from the default kernel AS. 
            atom_table = obj.Object('_RTL_ATOM_TABLE', offset = offset,
                    vm = flat_space, native_vm = kernel_space)

            if atom_table.is_valid():
                yield atom_table
Exemple #18
0
    def calculate(self):
        addr_space = utils.load_as(self._config)

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

        for objct in self.scan_results(addr_space):

            if isinstance(objct, _UDP_ENDPOINT):
                # For UdpA, the state is always blank and the remote end is asterisks
                for ver, laddr, _ in objct.dual_stack_sockets():
                    yield objct, "UDP" + ver, laddr, objct.Port, "*", "*", ""
            elif isinstance(objct, _TCP_ENDPOINT):

                if objct.AddressFamily == AF_INET:
                    proto = "TCPv4"
                elif objct.AddressFamily == AF_INET6:
                    proto = "TCPv6"

                yield objct, proto, objct.LocalAddress, objct.LocalPort, \
                    objct.RemoteAddress, objct.RemotePort, objct.State
            elif isinstance(objct, _TCP_LISTENER):
                # For TcpL, the state is always listening and the remote port is zero
                for ver, laddr, raddr in objct.dual_stack_sockets():
                    yield objct, "TCP" + ver, laddr, objct.Port, raddr, 0, "LISTENING"
Exemple #19
0
    def calculate(self):
        addr_space = utils.load_as(self._config)
        win7 = addr_space.profile.metadata.get('major', 0) == 6 and addr_space.profile.metadata.get('minor', 0) == 1

        if not self._config.HIVE_OFFSET:
            hive_offsets = [(self.hive_name(h), h.obj_offset) for h in hivelist.HiveList.calculate(self)]
        else:
            hive_offsets = [("User Specified", self._config.HIVE_OFFSET)]

        for name, hoff in set(hive_offsets):
            h = hivemod.HiveAddressSpace(addr_space, self._config, hoff)
            root = rawreg.get_root(h)
            if not root:
                if self._config.HIVE_OFFSET:
                    debug.error("Unable to find root key. Is the hive offset correct?")
            else:
                skey = "software\\microsoft\\windows\\currentversion\\explorer\\userassist\\"
                if win7:
                    uakey = skey + "{CEBFF5CD-ACE2-4F4F-9178-9926F41749EA}\\Count"
                    yield win7, name, rawreg.open_key(root, uakey.split('\\'))
                    uakey = skey + "{F4E57C4B-2036-45F0-A9AB-443BCFE33D9F}\\Count"
                    yield win7, name, rawreg.open_key(root, uakey.split('\\'))
                else:
                    uakey = skey + "{75048700-EF1F-11D0-9888-006097DEACF9}\\Count"
                    yield win7, name, rawreg.open_key(root, uakey.split('\\'))
                    uakey = skey + "{5E6AB780-7743-11CF-A12B-00AA004AE837}\\Count"
                    yield win7, name, rawreg.open_key(root, uakey.split('\\'))
Exemple #20
0
    def calculate(self):
        addr_space = utils.load_as(self._config)
        
        if not self.is_valid_profile(addr_space.profile):
            debug.error("This plugin only works on XP and 2003")

        ## When verbose is specified, we recalculate the list of SIDs for
        ## services in the registry. Otherwise, we take the list from the 
        ## pre-populated dictionary in getservicesids.py
        if self._config.VERBOSE:
            ssids = getservicesids.GetServiceSids(self._config).calculate()
            for sid, service in ssids:
                self.extrasids[sid] = " (Service: " + service + ")" 
        else:
            for sid, service in getservicesids.servicesids.items():
                self.extrasids[sid] = " (Service: " + service + ")"

        ## Get the user's SIDs from the registry
        self.load_user_sids()

        for proc in tasks.pslist(addr_space):
            if str(proc.ImageFileName).lower() == "services.exe":
                for vad, process_space in proc.get_vads(vad_filter = proc._mapped_file_filter):
                    if vad.FileObject.FileName:
                        name = str(vad.FileObject.FileName).lower()
                        if name.endswith(".evt"):
                            ## Maybe check the length is reasonable, though probably there won't 
                            ## ever be event logs that are multiple GB or TB in size.
                            data = process_space.zread(vad.Start, vad.Length)
                            yield name, data
Exemple #21
0
    def calculate(self):
        """Calculate and carry out any processing that may take time upon the image"""
        # Load the address space
        addr_space = utils.load_as(self._config)

        # Call a subfunction so that it can be used by other plugins
        return self.get_image_time(addr_space)
Exemple #22
0
    def virtual_process_from_physical_offset(addr_space, offset):
        """ Returns a virtual process from a physical offset in memory """
        # Since this is a physical offset, we find the process
        flat_addr_space = utils.load_as(addr_space.get_config(), astype = 'physical')
        flateproc = obj.Object("_EPROCESS", offset, flat_addr_space)
        # then use the virtual address of its first thread to get into virtual land
        # (Note: the addr_space and flat_addr_space use the same config, so should have the same profile)
        tleoffset = addr_space.profile.get_obj_offset("_ETHREAD", "ThreadListEntry")

        # start out with the member offset given to us from the profile 
        offsets = [tleoffset]

        # if (and only if) we're dealing with 64-bit Windows 7 SP1 
        # then add the other commonly seen member offset to the list 
        meta = addr_space.profile.metadata
        major = meta.get("major", 0)
        minor = meta.get("minor", 0)
        build = meta.get("build", 0)
        version = (major, minor, build)

        if meta.get("memory_model") == "64bit" and version == (6, 1, 7601):
            offsets.append(tleoffset + 8)

        ## use the member offset from the profile 
        for ofs in offsets:
            ethread = obj.Object("_ETHREAD", offset = flateproc.ThreadListHead.Flink.v() - ofs, vm = addr_space)
            # and ask for the thread's process to get an _EPROCESS with a virtual address space
            virtual_process = ethread.owning_process()
            # Sanity check the bounce. See Issue 154.
            if virtual_process and offset == addr_space.vtop(virtual_process.obj_offset):
                return virtual_process

        return obj.NoneObject("Unable to bounce back from virtual _ETHREAD to virtual _EPROCESS")
Exemple #23
0
    def calculate(self):
        addr_space = utils.load_as(self._config)

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

        return win32.network.determine_sockets(addr_space)
    def render_text(self, outfd, data):

        profile = utils.load_as(self._config).profile

        # Get the OS version being analyzed 
        version = (profile.metadata.get('major', 0),
                   profile.metadata.get('minor', 0))

        # Choose which USER handle enum to use 
        if version >= (6, 1):
            handle_types = consts.HANDLE_TYPE_ENUM_SEVEN
        else:
            handle_types = consts.HANDLE_TYPE_ENUM

        self.table_header(outfd,
                         [("Session", "8"),
                          ("Type", "20"),
                          ("Tag", "8"),
                          ("fnDestroy", "[addrpad]"),
                          ("Flags", ""),
                         ])

        for session in data:
            gahti = session.find_gahti()
            if gahti:
                for i, h in list(handle_types.items()):
                    self.table_row(outfd,
                                    session.SessionId,
                                    h,
                                    gahti.types[i].dwAllocTag,
                                    gahti.types[i].fnDestroy,
                                    gahti.types[i].bObjectCreateFlags)
Exemple #25
0
    def calculate(self):
        """Calculates the physical to virtual address mapping"""
        if self._config.STRING_FILE is None or not os.path.exists(self._config.STRING_FILE):
            debug.error("Strings file not found")

        addr_space = utils.load_as(self._config)

        if self._config.OFFSET != None:
            tasks = [self.virtual_process_from_physical_offset(addr_space, self._config.OFFSET)]
        elif self._config.SCAN:
            procs = list(filescan.PSScan(self._config).calculate())
            tasks = []
            for task in procs:
                tasks.append(self.virtual_process_from_physical_offset(addr_space, task.obj_offset))
        else:
            tasks = win32.tasks.pslist(addr_space)

        try:
            if self._config.PIDS is not None:
                pidlist = [int(p) for p in self._config.PIDS.split(',')]
                tasks = [t for t in tasks if int(t.UniqueProcessId) in pidlist]
        except (ValueError, TypeError):
            # TODO: We should probably print a non-fatal warning here
            pass

        return addr_space, tasks
Exemple #26
0
    def calculate(self):
        addr_space = utils.load_as(self._config)

        tag = self._config.TAG

        if tag == None:
            debug.error("You must enter a --tag to find")

        minsize = self._config.MIN_SIZE
        maxsize = self._config.MAX_SIZE 
        poolsize = lambda x : x >= minsize and x <= maxsize 

        if self._config.PAGED:
            paged = True
            non_paged = False
        else:
            paged = False
            non_paged = True

        scanner = GenericPoolScan()
        scanner.checks = [ 
                ('PoolTagCheck', dict(tag = tag)),
                ('CheckPoolSize', dict(condition = poolsize)),
                ('CheckPoolType', dict(paged = paged, non_paged = non_paged)),
                ]

        for offset in scanner.scan(addr_space):
            pool = obj.Object("_POOL_HEADER", offset = offset, vm = addr_space) 
            buf = addr_space.zread(offset, minsize)
            yield pool, buf
Exemple #27
0
    def calculate(self):
        kernel_space = utils.load_as(self._config)
        
        ## Select the tags to scan for. Always find visited URLs,
        ## but make freed and redirected records optional. 
        tags = ["URL "]
        if self._config.LEAK:
            tags.append("LEAK")
        if self._config.REDR:
            tags.append("REDR")
            
        ## Define the record type based on the tag
        tag_records = {
            "URL " : "_URL_RECORD", 
            "LEAK" : "_URL_RECORD", 
            "REDR" : "_REDR_RECORD"}
 
        ## Enumerate processes based on the --pid and --offset 
        for proc in self.filter_tasks(tasks.pslist(kernel_space)):
        
            ## Acquire a process specific AS
            ps_as = proc.get_process_address_space()
            
            for hit in proc.search_process_memory(tags):
                ## Get a preview of the data to see what tag was detected 
                tag = ps_as.read(hit, 4)
                
                ## Create the appropriate object type based on the tag 
                record = obj.Object(tag_records[tag], offset = hit, vm = ps_as)
                if record.is_valid():
                    yield proc, record
Exemple #28
0
    def calculate(self):
        addr_space = utils.load_as(self._config)

        seen = []

        for wind in self.scan_results(addr_space):
            
            # Find an address space for this window station's session  
            session = self.find_session_space(
                addr_space, wind.dwSessionId)

            if not session:
                continue

            # Reset the object's native VM so pointers are
            # dereferenced in session space 
            wind.set_native_vm(session.obj_vm)

            for winsta in wind.traverse():
                if winsta.is_valid():

                    offset = winsta.PhysicalAddress
                    if offset in seen:
                        continue
                    seen.append(offset)

                    yield winsta
    def calculate(self):
        addr_space = utils.load_as(self._config)

        if self._config.REGEX:
            try:
                if self._config.IGNORE_CASE:
                    mod_re = re.compile(self._config.REGEX, re.I)
                else:
                    mod_re = re.compile(self._config.REGEX)
            except re.error as e:
                debug.error('Error parsing regular expression: %s' % e)

        mods = dict((mod.DllBase.v(), mod) for mod in modules.lsmod(addr_space))
        # We need the process list to find spaces for some drivers. Enumerate them here
        # instead of inside the find_space function, so we only have to do it once. 
        procs = list(tasks.pslist(addr_space))

        if self._config.BASE:
            if self._config.BASE in mods:
                mod_name = mods[self._config.BASE].BaseDllName
            else:
                mod_name = "UNKNOWN"
            yield addr_space, procs, int(self._config.BASE), mod_name
        else:
            for mod in list(mods.values()):
                if self._config.REGEX:
                    if not mod_re.search(str(mod.FullDllName or '')) and not mod_re.search(str(mod.BaseDllName or '')):
                        continue
                yield addr_space, procs, mod.DllBase.v(), mod.BaseDllName
    def calculate(self):
        """Begin carving and analysing"""

        #Check output dir is provided
        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")

        
        #Carve packets from all mempages
        self.addr_space = utils.load_as(self._config)
        for mempage in self.addr_space.get_available_addresses():
            self.carve_packets(self.addr_space.zread(mempage[0], mempage[1]))

        
        #Analyze the carved/parsed packets
        packet_stats = self.analyze_packets(self.parsed_packets)
        
        #Dump files to dump-dir
        self.dump_packets_to_pcap(self.hex_packets, os.path.abspath(os.path.join(self._config.DUMP_DIR, 'packets.pcap')))
        with open(os.path.abspath(os.path.join(self._config.DUMP_DIR, 'ips.txt')), 'w') as fd:
            for ip_to_check in packet_stats['unique_public_ips']:
                fd.write(ip_to_check + '\n')
        
        
        return packet_stats
Exemple #31
0
 def calculate(self):
     
     regapi = registryapi.RegistryApi(self._config)    
     addr_space = utils.load_as(self._config)
     
     tasks = win32.tasks.pslist(addr_space)
     
     registerKeys = open('/Users/Lunde/volatility_plugins/registerRunKeys.txt').read().splitlines()
     for locations in registerKeys:
         base =locations.split('\\')[0]
         search_location = locations.split('\\',2)[2]
         if base == 'HKLM':
             hive = 'software' 
         if base == 'HKCU':
             hive = 'NTUSER.DAT'
         
         #regapi.set_current(hive_name= "software", user = "******")
         regapi.set_current(hive_name= hive)
         key_ = search_location
     
         for value, data in regapi.reg_yield_values(hive_name = str(hive), key = str(key_)):
             yield value, data, locations
Exemple #32
0
    def calculate(self):

        if not has_yara:
            debug.error("Yara must be installed for this plugin")

        addr_space = utils.load_as(self._config)

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

        rules = yara.compile(sources=cobaltstrike_sig)

        for task in self.filter_tasks(tasks.pslist(addr_space)):
            scanner = malfind.VadYaraScanner(task=task, rules=rules)

            for hit, address in scanner.scan():

                vad_base_addr, end = self.get_vad_base(task, address)
                proc_addr_space = task.get_process_address_space()
                data = proc_addr_space.zread(vad_base_addr,
                                             end - vad_base_addr)

                config_data = []

                for nw in CONF_PATTERNS:
                    cfg_addr = data.find(nw['pattern'])
                    if cfg_addr != -1:
                        break
                    else:
                        continue

                cfg_blob = data[cfg_addr:cfg_addr + nw['cfg_size']]
                config_data.append(
                    self.parse_config(self.decode_config(cfg_blob), nw))

                yield task, vad_base_addr, end, hit, memory_model, config_data
                break
    def calculate(self):
        if self._config.MACHINE != "":
            self._config.update("MACHINE", "{0} ".format(self._config.MACHINE))
        offsets = []
        address_space = utils.load_as(self._config, astype = 'physical')
        if self._config.OFFSET != None:
            items = [int(o, 16) for o in self._config.OFFSET.split(',')]
            for offset in items:
                mft_buff = address_space.read(offset, self._config.ENTRYSIZE)
                bufferas = addrspace.BufferAddressSpace(self._config, data = mft_buff)
                mft_entry = obj.Object('MFT_FILE_RECORD', vm = bufferas, offset = 0)
                offsets.append((offset, mft_entry))
        else:
            scanner = poolscan.MultiPoolScanner(needles = ['FILE', 'BAAD'])
            print "Scanning for MFT entries and building directory, this can take a while"
            seen = []
            for _, offset in scanner.scan(address_space):
                mft_buff = address_space.read(offset, self._config.ENTRYSIZE)
                bufferas = addrspace.BufferAddressSpace(self._config, data = mft_buff)
                mft_entry = obj.Object('MFT_FILE_RECORD', vm = bufferas,
                               offset = 0)
                temp = mft_entry.advance_one(mft_entry.ResidentAttributes.STDInfo.obj_offset + mft_entry.ResidentAttributes.ContentSize, mft_buff, self._config.ENTRYSIZE)
                name = ""
                if temp != None:
                    mft_entry.add_path(temp.FileName)
                    name = temp.FileName.get_name()
                if (int(mft_entry.RecordNumber), name) in seen:
                    continue
                else:
                    seen.append((int(mft_entry.RecordNumber), name))
                offsets.append((offset, mft_entry))

        for offset, mft_entry in offsets:
            mft_buff = address_space.read(offset, self._config.ENTRYSIZE)
            if self._config.DEBUGOUT:
                print "Processing MFT Entry at offset:", hex(offset)
            attributes = mft_entry.parse_attributes(mft_buff, not self._config.NOCHECK, self._config.ENTRYSIZE)
            yield offset, mft_entry, attributes
Exemple #34
0
    def calculate(self):
        addr_space = utils.load_as(self._config)

        modlist = list(modules.lsmod(addr_space))
        mods = dict((addr_space.address_mask(mod.DllBase), mod) for mod in modlist)
        mod_addrs = sorted(mods.keys())
            
        drivers = dtree.DriverIrp(self._config).calculate()    
        found_driver = "UNKNOWN"

        if self._config.ADDR:
            find_address = self._config.ADDR
            
            found_module = tasks.find_module(mods, mod_addrs, mods.values()[0].obj_vm.address_mask(find_address))
            if found_module:
                found_module = found_module.BaseDllName or found_module.FullDllName
            else:
                found_module = "UNKNOWN"

            for driver in drivers:
                if driver.DriverStart <= find_address < driver.DriverStart + driver.DriverSize:
                    header = driver.get_object_header()
                    found_driver = header.NameInfo.Name
                    break
            
            yield (found_module, found_driver)

        else:                
            for driver in drivers:
                driver_name = driver.get_object_header().NameInfo.Name
                owning_module = tasks.find_module(mods, mod_addrs, mods.values()[0].obj_vm.address_mask(driver.DriverStart))

                if owning_module:
                    module_name = owning_module.BaseDllName or owning_module.FullDllName
                else:
                    module_name = "UNKNOWN"

                yield (module_name, driver_name)
Exemple #35
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)"
            )

        addr_space = utils.load_as(self._config)

        all_tasks = list(tasks.pslist(addr_space))

        ps_sources = {}
        # The keys are names of process sources. The values
        # are dictionaries whose keys are physical process
        # offsets and the values are _EPROCESS objects.
        ps_sources['pslist'] = self.check_pslist(all_tasks)
        ps_sources['psscan'] = self.check_psscan()
        ps_sources['thrdproc'] = self.check_thrdproc(addr_space)
        ps_sources['csrss'] = self.check_csrss_handles(all_tasks)
        ps_sources['pspcid'] = self.check_pspcid(addr_space)
        ps_sources['session'] = self.check_sessions(addr_space)
        if addr_space.profile.metadata.get(
                'major',
                0) == 6 and addr_space.profile.metadata.get('minor', 0) >= 2:
            ps_sources['deskthrd'] = {}
        else:
            ps_sources['deskthrd'] = self.check_desktop_thread(addr_space)

        # Build a list of offsets from all sources
        seen_offsets = []
        for source in ps_sources.values():
            for offset in source.keys():
                if offset not in seen_offsets:
                    seen_offsets.append(offset)
                    yield offset, source[offset], ps_sources
Exemple #36
0
    def calculate(self):
        addr_space = utils.load_as(self._config)
        self.regapi = registryapi.RegistryApi(self._config)
        result = {}

        if not self._config.HIVE_OFFSET:
            self.regapi.set_current("SYSTEM")
        else:
            name = obj.Object("_CMHIVE",
                              vm=addr_space,
                              offset=self._config.HIVE_OFFSET).get_name()
            self.regapi.all_offsets[self._config.HIVE_OFFSET] = name
            self.regapi.current_offsets[self._config.HIVE_OFFSET] = name

        self.regapi.reset_current()
        currentcs = self.regapi.reg_get_currentcontrolset()
        if currentcs == None:
            currentcs = "ControlSet001"

        shutdownkey = currentcs + "\\Control\\Windows"
        key = self.regapi.reg_get_key("system", shutdownkey)
        value = self.regapi.reg_get_value("system",
                                          shutdownkey,
                                          "ShutdownTime",
                                          given_root=key)
        result["key"] = key
        result["hive"] = "SYSTEM"
        result["valuename"] = "ShutdownTime"
        result["value"] = value
        try:
            bufferas = addrspace.BufferAddressSpace(self._config, data=value)
            result["timestamp"] = obj.Object("WinTimeStamp",
                                             vm=bufferas,
                                             offset=0,
                                             is_utc=True)
        except struct.error:
            result["timestamp"] = ""
        yield result
Exemple #37
0
    def calculate(self):

        if not has_yara:
            debug.error("Yara must be installed for this plugin")

        addr_space = utils.load_as(self._config)

        osversion, memory_model = self.is_valid_profile(addr_space.profile)
        if not osversion:
            debug.error("This command does not support the selected profile.")
        base = os.path.dirname(os.path.abspath(__file__))
        rules = yara.compile(base + "/yara/rule.yara")

        for task in self.filter_tasks(tasks.pslist(addr_space)):
            scanner = malfind.VadYaraScanner(task=task, rules=rules)

            for hit, address in scanner.scan():

                vad_base_addr, end = self.get_vad_base(task, address)

                malname = str(hit).lower()
                if str(hit) in ["Himawari", "Lavender", "Armadill", "zark20rk"]:
                    malname = "redleaves"
                if str(hit) in "TSC_Loader":
                    malname = "tscookie"
                if "Agenttesla" in str(hit):
                    malname = "agenttesla"

                try:
                    module = import_module("volatility.plugins.malware.utils.{name}scan".format(name=malname))
                    module_cls = getattr(module, malname + "Config")
                    instance = module_cls(self._config)
                except:
                    debug.error("Can't loading module volatility.plugins.malware.utils.{name}scan".format(name=malname))

                for task, vad_base_addr, end, hit, memory_model, config_data in instance.calculate():
                    yield task, vad_base_addr, end, hit, memory_model, config_data
                break
Exemple #38
0
    def calculate(self):
        addr_space = utils.load_as(self._config)

        # Currently we only support x86. The x64 does still have a IDT 
        # but hooking is prohibited and results in bugcheck. 
        if not self.is_valid_profile(addr_space.profile):
            debug.error("This command does not support the selected profile.")

        mods = dict((mod.DllBase, mod) for mod in modules.lsmod(addr_space))
        mod_addrs = sorted(mods.keys())

        for kpcr in tasks.get_kdbg(addr_space).kpcrs():
            # Get the GDT for access to selector bases
            gdt = dict((i * 8, sd.Base) for i, sd in kpcr.gdt_entries())
            for i, entry in kpcr.idt_entries():
                # Where the IDT entry points. Per MITRE, add the GDT selector 
                # base if available. This allows us to detect sneaky attempts 
                # to hook IDT entries by changing the entry's GDT selector. 
                addr = entry.Address + gdt.get(entry.Selector.v(), 0)
                # Lookup the function's owner 
                module = tasks.find_module(mods, mod_addrs, addr)

                yield i, entry, addr, module
Exemple #39
0
    def get_registry_keys(self):

        addr_space = utils.load_as(self._config)

        hl = hivelist.HiveList(self._config)

        if not self._config.HIVE_OFFSET:
            hive_offsets = [h.obj_offset for h in hl.calculate()]
        else:
            hive_offsets = [self._config.HIVE_OFFSET]

        for hoff in set(hive_offsets):
            h = hivemod.HiveAddressSpace(addr_space, self._config, hoff)
            name = obj.Object("_CMHIVE", vm = addr_space, offset = hoff).get_name()
            root = rawreg.get_root(h)
            if not root:
                if self._config.HIVE_OFFSET:
                    self.console_print("Unable to find root key. Is the hive offset correct?")
            else:
                if self._config.KEY:
                    yield name, rawreg.open_key(root, self._config.KEY.split('\\'))
                else:
                    yield name, root
Exemple #40
0
 def __init__(self, config, *args, **kwargs):
     common.AbstractWindowsCommand.__init__(self, config, *args, **kwargs)
     # Plugin parameters
     self._config.add_option('DUMP-DIR', short_option='D', default=None,
                             help='Directory to which to dump found text',
                             action='store', type='str')
     self._config.add_option('NULLS', short_option='n', default=False,
                             help='keep nulls when outputting to stdout', action='store_true')
     self._config.add_option('PID', short_option='p', default=None,
                             help='This Process ID', action='store', type='int')
     self._config.add_option('MINIMAL', short_option='m', default=None,
                             help='Process name and text only',
                             action='store_true')
     self._config.add_option('EXPERIMENTAL', short_option='e', default=None,
                             help='Enable experimental options',
                             action='store_true')
     self._config.add_option('EXPERIMENTAL-ONLY', short_option='E', default=None,
                             help='Only do experimental options',
                             action='store_true')
     # Object variables
     self._addr_space = utils.load_as(self._config)
     self._profile_is_32bit = (self._addr_space.profile.metadata['memory_model'] == '32bit')
     self._tagWND_size = self._addr_space.profile.get_obj_size('tagWND')
    def calculate(self):
        #The returned data will be passed as data to render_text
        if not has_re:
            debug.error("Please install re ")

        addr_space = utils.load_as(self._config)  ###????
        # maybe I should add kernel space ?????????
        if not self.is_valid_profile(addr_space.profile):
            debug.error("This command does not support the selected profile.")
        #check_addr_space(addr_space)
        base = getBaseAddress(addr_space)

        if not self.is_valid_profile(addr_space.profile):
            debug.error("This command does not support the selected profile.")
        # get a list of all all processes runing from the memory dump
        tasks = self.generateProcesses(addr_space)
        pids = self.filter_tasks(tasks)  # HOW TO USE IT ???
        if self._config.PID is not None:
            return pids, addr_space
        print "type tasks" + str(type(tasks))
        # create a new generator : and add only the new elements

        return tasks, addr_space
Exemple #42
0
    def calculate(self):
        if not self.is_nasm():
            debug.error("Please install nasm")

        if not self._config.IJSON:
            debug.error("Please provide the input JSON trace")
       
        self._addrspace = utils.load_as(self._config)

        self.md = self.init_capstone()
        self.md.detail = True

        print "[+] From gadget: %s" % self._config.SGADGET
        print "[+] To gadget: %s" % self._config.GLIMIT

        self.get_json_trace()
        self.follow_trace()

        if self._config.DEBUG:
            self.get_trace_asm()
          
        if self._config.DB or self._config.IDB:
            self.serialize_opcodes()
Exemple #43
0
    def calculate(self):
        addr_space = utils.load_as(self._config)

        if not has_yara:
            debug.error("You must install yara to use this plugin")

        if not self._config.DUMP_DIR:
            debug.error("You must supply a --dump-dir parameter")

        if self._config.PHYSICAL:
            # Find the FileAddressSpace
            while addr_space.__class__.__name__ != "FileAddressSpace":
                addr_space = addr_space.base
            scanner = malfind.DiscontigYaraScanner(
                address_space=addr_space, rules=DumpCerts.rules
            )
            for hit, address in scanner.scan():
                cert = obj.Object(
                    DumpCerts.type_map.get(hit.rule),
                    vm=scanner.address_space,
                    offset=address,
                )
                if cert.is_valid():
                    yield None, cert
        else:
            for process in self.filter_tasks(tasks.pslist(addr_space)):
                scanner = malfind.VadYaraScanner(
                    task=process, rules=DumpCerts.rules
                )
                for hit, address in scanner.scan():
                    cert = obj.Object(
                        DumpCerts.type_map.get(hit.rule),
                        vm=scanner.address_space,
                        offset=address,
                    )
                    if cert.is_valid():
                        yield process, cert
Exemple #44
0
    def render_text(self, outfd, data):

        addr_space = utils.load_as(self._config)
        syscalls = addr_space.profile.syscalls
        bits32 = addr_space.profile.metadata.get('memory_model',
                                                 '32bit') == '32bit'

        # Print out the entries for each table
        for idx, table, n, vm, mods, mod_addrs in data:
            outfd.write("SSDT[{0}] at {1:x} with {2} entries\n".format(
                idx, table, n))
            for i in range(n):
                if bits32:
                    # These are absolute function addresses in kernel memory.
                    syscall_addr = obj.Object('address', table + (i * 4),
                                              vm).v()
                else:
                    # These must be signed long for x64 because they are RVAs relative
                    # to the base of the table and can be negative.
                    offset = obj.Object('long', table + (i * 4), vm).v()
                    # The offset is the top 20 bits of the 32 bit number.
                    syscall_addr = table + (offset >> 4)
                try:
                    syscall_name = syscalls[idx][i]
                except IndexError:
                    syscall_name = "UNKNOWN"

                syscall_mod = tasks.find_module(mods, mod_addrs, syscall_addr)
                if syscall_mod:
                    syscall_modname = syscall_mod.BaseDllName
                else:
                    syscall_modname = "UNKNOWN"

                outfd.write(
                    "  Entry {0:#06x}: {1:#x} ({2}) owned by {3}\n".format(
                        idx * 0x1000 + i, syscall_addr, syscall_name,
                        syscall_modname))
Exemple #45
0
    def calculate(self, use_heuristics=False):
        address_space = utils.load_as(self._config, astype="physical")

        # Special needle: the first field, "type", is always equal to "table"
        # for the entries we're looking for.
        #
        # You might think a better needle is looking for "CREATE TABLE" in the
        # "sql" field, but we can't count backwards over other text fields to
        # get to the beginning of the record.
        needle = sqlitetools.Needle(
            yara.compile(
                source='rule r1 { strings: $a = "table" condition: $a }'),
            size=5,
            varint_offset=-8,
            byte_offset=0,
        )
        schema = sqlitetools.TableSchema.from_str(
            PREDEFINED_TABLES["sqlite_master"])
        searcher = sqlitetools.RowSearch(schema, needle)

        for address, row_id, types, values in searcher.find_records(
                address_space):
            sql = values[4]
            try:
                table_name, table_schema = sqlitetools.TableSchema.from_sql(
                    sql, use_heuristics)
            except sqlitetools.SqlParsingError as e:
                continue
            if table_name != values[2]:
                continue

            needle_size = sqlitetools.RowSearch(table_schema).needle.size

            if self._config.RAW_SQL:
                yield table_name, needle_size, sql
            else:
                yield table_name, needle_size, str(table_schema)
Exemple #46
0
    def calculate(self):
        addr_space = utils.load_as(self._config)
        addr_space.profile.add_types(evt_log_types)
        if addr_space.profile.metadata.get('major', 0) != 5:
            print "This plugin only works on XP and 2K3"
            return

        if self._config.VERBOSE:
            self.reset_current()
            self.set_current("SYSTEM")
            ssids = getservicesids.GetServiceSids.calculate(self)
            for sid, service in ssids:
                self.extrasids[sid] = " (Service: " + service + ")"
        else:
            for sid in self.extrasids:
                self.extrasids[sid] = " (Service: " + self.extrasids[sid] + ")"

        self.reset_current()
        self.set_current("SOFTWARE")
        for k1 in self.reg_enum_key(
                'SOFTWARE',
                'Microsoft\\Windows NT\\CurrentVersion\\ProfileList'):
            val = self.reg_get_value('SOFTWARE', k1, 'ProfileImagePath')
            sid = k1.split("\\")[-1]
            if val != None:
                self.extrasids[sid] = " (User: "******"\\")[-1] + ")"

        for proc in tasks.pslist(addr_space):
            if str(proc.ImageFileName).lower() == "services.exe":
                map = self.list_mapped_files(proc,
                                             pe_only=False,
                                             get_data=True)
                for key, (name, buf) in map.items():
                    if name and buf:
                        name = str(name).lower()
                        if name.endswith(".evt"):
                            yield name, buf
    def calculate(self):
        addr_space = utils.load_as(self._config)
        regapi = registryapi.RegistryApi(self._config)

        user_hive = "ntuser.dat"
        trustrecords = {"Software\\Microsoft\\Office\\14.0\\Word\\Security\\Trusted Documents\\TrustRecords",
                        "Software\\Microsoft\\Office\\14.0\\Excel\\Security\\Trusted Documents\\TrustRecords",
                        "Software\\Microsoft\\Office\\14.0\\PowerPoint\\Security\\Trusted Documents\\TrustRecords",
                        "Software\\Microsoft\\Office\\14.0\\Access\\Security\\Trusted Documents\\TrustRecords",
                       }

        hive_offsets = {}
        if not self._config.HIVE_OFFSET:
            for h in hivelist.HiveList.calculate(self):
                hive_name = self.hive_name(h)
                if user_hive in hive_name.lower():
                    hive_offsets[h.obj_offset] = hive_name
        else:
            hive_offsets = [("User Specified", self._config.HIVE_OFFSET)]

        found = False
        for hoff, name in hive_offsets.iteritems():
            h = hivemod.HiveAddressSpace(addr_space, self._config, hoff)
            root = rawreg.get_root(h)
            if not root:
                if self._config.HIVE_OFFSET:
                    debug.error("Unable to find root key. Is the hive offset correct?")
            else:
                for r in trustrecords:
                    trustrecord_key = rawreg.open_key(root, r.split('\\'))
                    if trustrecord_key:
                        yield name, r, trustrecord_key
                        found = True

        if not found:
            debug.error("The requested key could not be found in the hive(s) searched\n")
Exemple #48
0
    def collect_pe_info(self):

        addr_space = utils.load_as(self._config)

        if self._config.PID != None:
            for prc in tasks.pslist(addr_space):
                if prc.UniqueProcessId == self._config.PID:
                    addr_space = prc.get_process_address_space()
                    break

        dos_header = obj.Object("_IMAGE_DOS_HEADER",
                                offset=self._config.BASE,
                                vm=addr_space)
        nt_headers = dos_header.get_nt_header()
        sections = list(nt_headers.get_sections())
        sections_data = []

        for i in range(0, len(sections)):
            data = addr_space.zread(
                sections[i].VirtualAddress + self._config.BASE,
                sections[i].Misc.VirtualSize)
            sections_data.append(data)

        return dos_header, nt_headers, sections, sections_data
Exemple #49
0
    def calculate(self):
        image_name = os.path.basename(self._config.LOCATION)
        self.log(image_name)

        self.kernel_address_space = utils.load_as(self._config)
        available_pages = self.kernel_address_space.get_available_pages()

        #self.log('Get continuous pages')
        #dict_page_addr_to_size = self.get_continuous_pages(available_pages)
        dict_page_addr_to_size = {}
        for addr, size in available_pages:
            if addr > 0x80000000:
                dict_page_addr_to_size[addr] = size

        with open(PAGES_OUTPUT_PATH + 'pages.' + image_name, 'w') as output:
            list_addr = dict_page_addr_to_size.keys()
            list_addr.sort()
            for addr in list_addr:
                size = dict_page_addr_to_size[addr]
                physical_addr = self.kernel_address_space.vtop(addr)
                output.write(
                    str(addr) + '\t' + str(physical_addr) + '\t' + str(size) +
                    '\n')
        self.log('Finish')
Exemple #50
0
    def calculate(self):
        addr_space = utils.load_as(self._config)

        all_tasks = list(tasks.pslist(addr_space))

        ps_sources = {}
        # The keys are names of process sources. The values
        # are dictionaries whose keys are physical process
        # offsets and the values are _EPROCESS objects.
        ps_sources['pslist'] = self.check_pslist(all_tasks)
        ps_sources['psscan'] = self.check_psscan()
        ps_sources['thrdproc'] = self.check_thrdproc(addr_space)
        ps_sources['csrss'] = self.check_csrss_handles(all_tasks)
        ps_sources['pspcid'] = self.check_pspcid(addr_space)
        ps_sources['session'] = self.check_sessions(addr_space)
        ps_sources['deskthrd'] = self.check_desktop_thread(addr_space)

        # Build a list of offsets from all sources
        seen_offsets = []
        for source in ps_sources.values():
            for offset in source.keys():
                if offset not in seen_offsets:
                    seen_offsets.append(offset)
                    yield offset, source[offset], ps_sources
Exemple #51
0
    def calculate(self):
        addr_space = utils.load_as(self._config)
        regapi = registryapi.RegistryApi(self._config)
        hiveset = set()

        if not self._config.HIVE_OFFSET:
            hive_offsets = [
                h.obj_offset for h in hivelist.HiveList.calculate(self)
            ]
        else:
            hive_offsets = [self._config.HIVE_OFFSET]

        for hoff in set(hive_offsets):
            h = hivemod.HiveAddressSpace(addr_space, self._config, hoff)
            name = obj.Object("_CMHIVE", vm=addr_space, offset=hoff).get_name()
            print "[debug]", name
            root = rawreg.get_root(h)
            hive = name.split("\\")[-1]
            hiveset.add(hive)

        print hiveset
        for hive in hiveset:
            print "\n========================", hive

            for regtime, keyname in regapi.reg_get_last_modified(hive,
                                                                 count=5):
                print "\n", regtime, keyname
                regapi.set_current(hive_name=hive)
                k = keyname.split('\\')[1:]
                k = '\\'.join(k)
                print k + "\n"
                for value, tp, data in self.reg_yield_values_type(
                        regapi, hive_name=hive, key=k):
                    yield value, tp, data

            regapi.reset_current()
Exemple #52
0
    def generator(self, data):
        profile = utils.load_as(self._config).profile

        # Get the OS version being analyzed
        version = (profile.metadata.get('major',
                                        0), profile.metadata.get('minor', 0))

        # Choose which USER handle enum to use
        if version >= (6, 1):
            handle_types = consts.HANDLE_TYPE_ENUM_SEVEN
        else:
            handle_types = consts.HANDLE_TYPE_ENUM

        for session in data:
            gahti = session.find_gahti()
            if gahti:
                for i, h in handle_types.items():
                    yield (0, [
                        str(session.SessionId),
                        str(h),
                        str(gahti.types[i].dwAllocTag),
                        Address(gahti.types[i].fnDestroy),
                        str(gahti.types[i].bObjectCreateFlags)
                    ])
Exemple #53
0
    def calculate(self):
        """Determines the address space"""
        profilelist = [ p.__name__ for p in registry.get_plugin_classes(obj.Profile).values() ]

        proflens = {}
        maxlen = 0
        origprofile = self._config.PROFILE
        for p in profilelist:
            self._config.update('PROFILE', p)
            buf = addrspace.BufferAddressSpace(self._config)
            proflens[p] = str(obj.VolMagic(buf).KDBGHeader)
            maxlen = max(maxlen, len(proflens[p]))
        self._config.update('PROFILE', origprofile)

        scanner = KDBGScanner(needles = proflens.values())

        aspace = utils.load_as(self._config, astype = 'any')

        for offset in scanner.scan(aspace):
            val = aspace.read(offset, maxlen + 0x10)
            for l in proflens:
                if val.find(proflens[l]) >= 0:
                    kdbg = obj.Object("_KDDEBUGGER_DATA64", offset = offset, vm = aspace)
                    yield l, kdbg
Exemple #54
0
    def calculate(self):
        addr_space = utils.load_as(self._config)
        regapi = registryapi.RegistryApi(self._config)
        regapi.reset_current()
        currentcs = regapi.reg_get_currentcontrolset()
        if currentcs == None:
            currentcs = "ControlSet001"

        version = (addr_space.profile.metadata.get('major', 0),
                   addr_space.profile.metadata.get('minor', 0))
        xp = False

        if version <= (5, 1):
            key = currentcs + '\\' + "Control\\Session Manager\\AppCompatibility"
            xp = True
        else:
            key = currentcs + '\\' + "Control\\Session Manager\\AppCompatCache"

        data_raw = regapi.reg_get_value('system', key, "AppCompatCache")
        if data_raw == None or len(data_raw) < 0x1c:
            debug.warning("No ShimCache data found")
            return

        bufferas = addrspace.BufferAddressSpace(self._config, data=data_raw)
        shimdata = obj.Object("ShimRecords", offset=0, vm=bufferas)
        if shimdata == None:
            debug.warning("No ShimCache data found")
            return

        for e in shimdata.Entries:
            if xp:
                yield e.Path, e.LastModified, e.LastUpdate
            else:
                yield self.remove_unprintable(
                    bufferas.read(int(e.PathOffset),
                                  int(e.Length))), e.LastModified, None
Exemple #55
0
    def calculate(self):
        addr_space = utils.load_as(self._config)
        win7 = addr_space.profile.metadata.get(
            'major',
            0) == 6 and addr_space.profile.metadata.get('minor', 0) >= 1
        skey = "software\\microsoft\\windows\\currentversion\\explorer\\userassist"

        if not self._config.HIVE_OFFSET:
            self.regapi.set_current("ntuser.dat")
        else:
            name = obj.Object("_CMHIVE",
                              vm=addr_space,
                              offset=self._config.HIVE_OFFSET).get_name()
            self.regapi.all_offsets[self._config.HIVE_OFFSET] = name
            self.regapi.current_offsets[self._config.HIVE_OFFSET] = name

        for key, name in self.regapi.reg_yield_key(None, skey):
            for guidkey in self.regapi.reg_get_all_subkeys(None,
                                                           None,
                                                           given_root=key):
                for count in self.regapi.reg_get_all_subkeys(
                        None, None, given_root=guidkey):
                    if count.Name == "Count":
                        yield win7, name, count
    def calculate(self):
        self.get_dll_list()
        self.regapi = registryapi.RegistryApi(self._config)
        self.currentcs = self.regapi.reg_get_currentcontrolset() or "ControlSet001"
        asep_list = ['autoruns', 'services', 'appinit', 'winlogon', 'tasks', 'activesetup', 'sdb']
        os_major = utils.load_as(self._config).profile.metadata.get('major', 0)

        # If all_offsets is empty then regapi was unable to find
        # hive offsets and we exit with an error message
        if not self.regapi.all_offsets:
            debug.error('Unable to find registry hives.')

        if self._config.ASEP_TYPE:
            debug.debug('Config: {}'.format(self._config.ASEP_TYPE))
            asep_list = [s for s in self._config.ASEP_TYPE.replace(' ', '').split(',')]

        # Scan for ASEPs and populate the lists
        if 'autoruns' in asep_list:
            self.autoruns = self.get_autoruns()
        if 'services' in asep_list:
            self.services = self.get_services()
        if 'appinit' in asep_list:
            self.appinit_dlls = self.get_appinit_dlls()
        if 'winlogon' in asep_list:
            self.winlogon = self.get_winlogon()
            if os_major == 5:
                self.winlogon_registrations = self.get_winlogon_registrations()
        if 'tasks' in asep_list:
            self.tasks = self.get_tasks()
        if 'activesetup' in asep_list:
            self.activesetup = self.get_activesetup()
        if 'sdb' in asep_list:
            self.sdb = self.get_sdb()

        #Returns a generator to generator() that generates the unified output data
        return self.get_unified_output_data()
    def calculate(self):
        if not has_yara:
            debug.error("Yara must be installed for this plugin")

        addr_space = utils.load_as(self._config)
        rules = yara.compile(sources=sigs)

        for task in self.filter_tasks(tasks.pslist(addr_space)):
            scanner = malfind.VadYaraScanner(task=task, rules=rules)
            config = False
            start_add = False
            stop_add = False
            for hit, address in scanner.scan():
                if str(hit) == 'darkcomet_config':
                    config = hit
                    start_add = address
                if str(hit) == 'darkcomet_config_stop':
                    stop_add = address + 0x20  #Add 0x20 to address to get all of EOF statement

            #if we have a hit on all three sigs lets yield
            if config and start_add and stop_add:
                yield task, config, start_add, stop_add
            else:
                pass
Exemple #58
0
    def calculate(self):
        addr_space = utils.load_as(self._config)

        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")

        if self._config.OFFSET != None:
            data = [
                self.virtual_process_from_physical_offset(
                    addr_space, self._config.OFFSET)
            ]
        else:
            data = self.filter_tasks(tasks.pslist(addr_space))

        if self._config.REGEX:
            try:
                if self._config.IGNORE_CASE:
                    mod_re = re.compile(self._config.REGEX, re.I)
                else:
                    mod_re = re.compile(self._config.REGEX)
            except re.error, e:
                debug.error('Error parsing regular expression: %s' % e)
    def calculate(self):
        if not has_yara:
            debug.error("Yara must be installed for this plugin")

        addr_space = utils.load_as(self._config)

        if not self.is_valid_profile(addr_space.profile):
            debug.error("This command does not support the selected profile.")
# For each process in the list
        for task in self.filter_tasks(tasks.pslist(addr_space)):
            # print task.ImageFileName
            for vad, address_space in task.get_vads(
                    vad_filter=task._injection_filter):
                # Injected code detected if there's values returned
                rules = yara.compile(sources=signatures)
                scanner = malfind.VadYaraScanner(task=task, rules=rules)
                # print 'before'
                for hit, address in scanner.scan():
                    vad_base_addr = self.get_vad_base(task, address)

                    # Get a chuck of memory of size 2048 next to where the string was detected
                    content = address_space.zread(address, 2048)
                    yield task, address, vad_base_addr, content
                    break
Exemple #60
0
 def __guessProfile(self):
     self.__steps += 1
     bestguess = None
     profiles = [
         p.__name__
         for p in registry.get_plugin_classes(obj.Profile).values()
     ]
     scan_kdbg = kdbgscan.KDBGScan(self._config)
     suglist = []
     suglist = [s for s, _ in scan_kdbg.calculate()]
     if suglist:
         bestguess = suglist[0]
     if bestguess in profiles:
         profiles = [bestguess] + profiles
     chosen = 'none'
     profcount = len(profiles)
     count = 1
     for profile in profiles:
         self.stateinfo = "Step {:<2d} / {:<2d} -- Guessing profile: trying profile {:<20s} ({:<2d} / {:<2d})".format(
             self.__step, self.__steps, profile, count, profcount)
         self._config.updateCtx('profile', profile)
         addr_space = utils.load_as(self._config, astype='any')
         if hasattr(addr_space, 'dtb'):
             chosen = profile
             break
         count += 1
     if debug and bestguess != chosen:
         print bestguess, chosen
     volmagic = obj.VolMagic(addr_space)
     kdbgoffset = volmagic.KDBG.v()
     self._kdbg = obj.Object("_KDDEBUGGER_DATA64",
                             offset=kdbgoffset,
                             vm=addr_space)
     self._config.updateCtx('kdbg', self._kdbg.obj_offset)
     self._aspace = addr_space
     self.__step += 1