Пример #1
0
 def _get_raw_registry_data2(self, regvalue):
     tp, dat = rawreg.value_data(regvalue)
     if tp == 'REG_BINARY' or tp == 'REG_NONE':
         dat = "\n" + "\n".join([
             "{0:#010x}  {1:<48}  {2}".format(o, h, ''.join(c))
             for o, h, c in volutils.Hexdump(dat)
         ])
     if tp in ['REG_SZ', 'REG_EXPAND_SZ', 'REG_LINK']:
         dat = dat.encode("ascii", 'backslashreplace')
     if tp == 'REG_MULTI_SZ':
         for i in range(len(dat)):
             dat[i] = dat[i].encode("ascii", 'backslashreplace')
     return dat
Пример #2
0
    def render_text(self, outfd, data):
        for task, address, hit, buf in data:
            if task:
                outfd.write("Task: {0} pid {1} rule {2} addr {3:#x}\n".format(
                    task.p_comm, task.p_pid, hit.rule, address))
            else:
                outfd.write("[kernel] rule {0} addr {1:#x}\n".format(
                    hit.rule, address))

            outfd.write("".join([
                "{0:#018x}  {1:<48}  {2}\n".format(address + o, h, ''.join(c))
                for o, h, c in utils.Hexdump(buf)
            ]))
Пример #3
0
    def render_extra(self, outfd, task, vad, params):
        """Show any Zeus specific fields"""

        rc4_offset = task.obj_vm.profile.get_obj_offset(
            self.magic_struct, 'rc4key')
        creds_key = params['decoded_magic'][rc4_offset:rc4_offset +
                                            RC4_KEYSIZE]

        outfd.write("{0:<30} : \n{1}\n".format(
            "Credential RC4 key", "\n".join([
                "{0:#010x}  {1:<48}  {2}".format(vad.Start + o, h, ''.join(c))
                for o, h, c in utils.Hexdump(creds_key)
            ])))
Пример #4
0
 def render_text(self, outfd, data):
     self.table_header(outfd, [
         ("Address", "#018x"),
         ("Cipher", "32"),
         ("FVEK", "64"),
         ("TWEAK Key", "64"),
     ])
     for (pool, BLMode, tweak, fvek_raw) in data:
         fvek = []
         for o, h, c in utils.Hexdump(fvek_raw):
             fvek.append(h)
         self.table_row(outfd, pool, BLMode, ''.join(fvek).replace(" ", ""),
                        ''.join(tweak).replace(" ", ""))
Пример #5
0
    def render_text(self, outfd, data):

        if not has_distorm3:
            debug.warning("For best results please install distorm3")

        if self._config.DUMP_DIR and not os.path.isdir(self._config.DUMP_DIR):
            debug.error(self._config.DUMP_DIR + " is not a directory")

        for task in data:
            for vad, address_space in task.get_vads(
                    vad_filter=task._injection_filter):

                if self._is_vad_empty(vad, address_space):
                    continue

                content = address_space.zread(vad.Start, 64)

                outfd.write("Process: {0} Pid: {1} Address: {2:#x}\n".format(
                    task.ImageFileName, task.UniqueProcessId, vad.Start))

                outfd.write("Vad Tag: {0} Protection: {1}\n".format(
                    vad.Tag,
                    vadinfo.PROTECT_FLAGS.get(vad.u.VadFlags.Protection.v(),
                                              "")))

                outfd.write("Flags: {0}\n".format(str(vad.u.VadFlags)))
                outfd.write("\n")

                outfd.write("{0}\n".format("\n".join([
                    "{0:#010x}  {1:<48}  {2}".format(vad.Start + o, h,
                                                     ''.join(c))
                    for o, h, c in utils.Hexdump(content)
                ])))

                outfd.write("\n")
                outfd.write("\n".join([
                    "{0:#x} {1:<16} {2}".format(o, h, i)
                    for o, i, h in Disassemble(content, vad.Start)
                ]))

                # Dump the data if --dump-dir was supplied
                if self._config.DUMP_DIR:

                    filename = os.path.join(
                        self._config.DUMP_DIR,
                        "process.{0:#x}.{1:#x}.dmp".format(
                            task.obj_offset, vad.Start))

                    self.dump_vad(filename, vad, address_space)

                outfd.write("\n\n")
Пример #6
0
    def generate_output(self, outfd, vad, task, file_object_name,
                        peb_image_path_name):
        # this function will output data for a given VAD passed to it

        content = None

        outfd.write("Process: {0} Pid: {1} Ppid: {2}\n".format(
            task.ImageFileName, task.UniqueProcessId,
            task.InheritedFromUniqueProcessId))

        outfd.write("Address: {0:#x} Protection: {1}\n".format(
            vad.Start,
            vadinfo.PROTECT_FLAGS.get(vad.VadFlags.Protection.v(), "")))

        if peb_image_path_name != None:
            outfd.write("Initially mapped file object: {0}\n".format(
                peb_image_path_name))
        else:
            outfd.write("Initially mapped file object: {0}\n".format("None"))

        if file_object_name != None:
            outfd.write(
                "Currently mapped file object: {0}\n".format(file_object_name))
        else:
            outfd.write("Currently mapped file object: {0}\n".format("None"))

        address_space = task.get_process_address_space()
        content = address_space.zread(vad.Start, 64)

        if content:
            outfd.write("{0}\n".format("\n".join([
                "{0:#010x}  {1:<48}  {2}".format(vad.Start + o, h, ''.join(c))
                for o, h, c in utils.Hexdump(content)
            ])))

            outfd.write("\n")
            outfd.write("\n".join([
                "{0:#010x} {1:<16} {2}".format(o, h, i)
                for o, i, h in malfind.Disassemble(content, vad.Start)
            ]))

        outfd.write("\n\n")

        # dump vad incase -D was specified
        if self._config.DUMP_DIR:
            filename = os.path.join(
                self._config.DUMP_DIR,
                "process.{0:#x}.{1:#x}.dmp".format(task.obj_offset, vad.Start))
            self.dump_vad(filename, vad, address_space)
Пример #7
0
    def render_text(self, outfd, data):

        for v, tp, dat in data:
            if tp == 'REG_BINARY' or tp == 'REG_NONE':
                dat = "\n" + "\n".join([
                    "{0:#010x}  {1:<48}  {2}".format(o, h, ''.join(c))
                    for o, h, c in utils.Hexdump(dat)
                ])
            if tp in ['REG_SZ', 'REG_EXPAND_SZ', 'REG_LINK']:
                dat = dat.encode("ascii", 'backslashreplace')
            if tp == 'REG_MULTI_SZ':
                for i in range(len(dat)):
                    dat[i] = dat[i].encode("ascii", 'backslashreplace')
            outfd.write("{0:13} {1:15} : {2} \n".format(tp, v, dat))
        """
Пример #8
0
 def render_text(self, outfd, data):
     keyfound = False
     for win7, reg, key in data:
         if key:
             keyfound = True
             outfd.write("----------------------------\n")
             outfd.write("Registry: {0}\n".format(reg))
             outfd.write("Path: {0}\n".format(
                 self.regapi.reg_get_key_path(key)))
             outfd.write("Last updated: {0}\n".format(key.LastWriteTime))
             outfd.write("\n")
             outfd.write("Subkeys:\n")
             for s in self.regapi.reg_get_all_subkeys(None,
                                                      None,
                                                      given_root=key):
                 if s.Name == None:
                     outfd.write("  Unknown subkey: " + s.Name.reason +
                                 "\n")
                 else:
                     outfd.write("  {0}\n".format(s.Name))
             outfd.write("\n")
             outfd.write("Values:\n")
             for subname, dat in self.regapi.reg_yield_values(
                     None, None, given_root=key, thetype="REG_BINARY"):
                 dat_raw = dat
                 dat = "\n".join([
                     "{0:#010x}  {1:<48}  {2}".format(o, h, ''.join(c))
                     for o, h, c in utils.Hexdump(dat)
                 ])
                 try:
                     subname = subname.encode('rot_13')
                 except UnicodeDecodeError:
                     pass
                 if win7:
                     guid = subname.split("\\")[0]
                     if guid in folder_guids:
                         subname = subname.replace(guid, folder_guids[guid])
                 d = self.parse_data(dat_raw)
                 if d != None:
                     dat = "{0}Raw Data:\n{1}".format(d, dat)
                 else:
                     dat = "Raw Data:\n{0}".format(dat)
                 outfd.write("\n{0:13} {1:15} : {2}\n".format(
                     "REG_BINARY", subname, dat))
     if not keyfound:
         outfd.write(
             "The requested key could not be found in the hive(s) searched\n"
         )
Пример #9
0
    def disassemble(self, address_space, entry_point):
        """
        :param address_space: process's address space object
        :param entry_point: Start address
        :return: A string of the disassembled code
        Disassemble the 64 bytes of code by giving the process's
        address space and the start address
        """
        entry_point = int(entry_point)
        content = address_space.read(entry_point, 64)

        # Check if we could have read from memory, might be paged
        if content:
            disassemble_code = "\t"
            disassemble_code += ("{0}\n\n".format("\n\t".join([
                "{0:#010x}  {1:<48}  {2}".format(entry_point + o, h,
                                                 ''.join(c))
                for o, h, c in utils.Hexdump(content)
            ])))
            disassemble_code += "\t"

            # Rather disassemble with distrom3 than malfind
            if has_distorm:
                # Get OS profile
                mode = address_space.profile.metadata.get('memory_model')

                if mode == '64bit':
                    mode = distorm3.Decode64Bits

                else:
                    mode = distorm3.Decode32Bits

                disassemble_code += "\n\t".join(["{0:<#010x} {1:<16} {2}".format(o, h, i) \
                                              for o, _size, i, h in \
                                              distorm3.DecodeGenerator(entry_point, content, mode)])

            else:
                disassemble_code += "\n\t".join([
                    "{0:#010x} {1:<16} {2}".format(o, h, i)
                    for o, i, h in malfind.Disassemble(content, entry_point)
                ])

            disassemble_code += "\n"

        else:
            disassemble_code = "\t** Couldn't read memory\n"

        return disassemble_code
Пример #10
0
    def render_text(self, outfd, data):
        """Render the plugin's default text output"""
        
        for task, vad, params in data:

            # Get a magic object from the buffer
            buffer_space = addrspace.BufferAddressSpace(
                                config = self._config, 
                                data = params['decoded_magic'])

            magic_obj = obj.Object(self.magic_struct, 
                                offset = 0, vm = buffer_space)

            outfd.write("*" * 50 + "\n")
            outfd.write("{0:<30} : {1}\n".format("Process", task.ImageFileName))
            outfd.write("{0:<30} : {1}\n".format("Pid", task.UniqueProcessId))
            outfd.write("{0:<30} : {1}\n".format("Address", vad.Start))

            # grab the URLs from the decoded buffer
            decoded_config = params['decoded_config']
            urls = []
            while "http" in decoded_config:
                url = decoded_config[decoded_config.find("http"):]
                urls.append(url[:url.find('\x00')])
                decoded_config = url[url.find('\x00'):]
            for i, url in enumerate(urls):
                outfd.write("{0:<30} : {1}\n".format("URL {0}".format(i), url))

            outfd.write("{0:<30} : {1}\n".format("Identifier", 
                ''.join([chr(c) for c in magic_obj.guid if c != 0])))
            outfd.write("{0:<30} : {1}\n".format("Mutant key", magic_obj.guid_xor_key))
            outfd.write("{0:<30} : {1}\n".format("XOR key", magic_obj.xorkey))
            outfd.write("{0:<30} : {1}\n".format("Registry", 
                "HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\{0}".format(magic_obj.keyname)))
            outfd.write("{0:<30} : {1}\n".format(" Value 1", magic_obj.value1))
            outfd.write("{0:<30} : {1}\n".format(" Value 2", magic_obj.value2))
            outfd.write("{0:<30} : {1}\n".format(" Value 3", magic_obj.value3))
            outfd.write("{0:<30} : {1}\n".format("Executable", magic_obj.exefile))
            outfd.write("{0:<30} : {1}\n".format("Data file", magic_obj.datfile))

            outfd.write("{0:<30} : \n{1}\n".format("Config RC4 key", 
                    "\n".join(
                    ["{0:#010x}  {1:<48}  {2}".format(vad.Start + o, h, ''.join(c))
                    for o, h, c in utils.Hexdump(params['config_key'])
                    ])))

            self.render_extra(outfd, task, vad, params)
Пример #11
0
    def render_text(self, outfd, data):
        linux_common.set_plugin_members(self)

        if self.addr_space.profile.metadata.get('memory_model',
                                                '32bit') == '32bit':
            bits = '32bit'
        else:
            bits = '64bit'

        for task in data:
            proc_as = task.get_process_address_space()

            for vma in task.get_proc_maps():

                if vma.is_suspicious():
                    fname = vma.vm_name(task)
                    if fname == "[vdso]":
                        continue

                    prots = vma.protection()
                    flags = vma.flags()

                    content = proc_as.zread(vma.vm_start, 64)

                    outfd.write(
                        "Process: {0} Pid: {1} Address: {2:#x} File: {3}\n".
                        format(task.comm, task.pid, vma.vm_start, fname))

                    outfd.write("Protection: {0}\n".format(prots))

                    outfd.write("Flags: {0}\n".format(str(flags)))
                    outfd.write("\n")

                    outfd.write("{0}\n".format("\n".join([
                        "{0:#016x}  {1:<48}  {2}".format(
                            vma.vm_start + o, h, ''.join(c))
                        for o, h, c in utils.Hexdump(content)
                    ])))

                    outfd.write("\n")
                    outfd.write("\n".join([
                        "{0:#x} {1:<16} {2}".format(o, h, i) for o, i, h in
                        malfind.Disassemble(content, vma.vm_start, bits=bits)
                    ]))

                    outfd.write("\n\n")
Пример #12
0
 def render_text(self, outfd, data):
     keyfound = False
     for win7, reg, key in data:
         if key:
             keyfound = True
             outfd.write("----------------------------\n")
             outfd.write(f"Registry: {reg}\n")
             outfd.write(f"Path: {self.regapi.reg_get_key_path(key)}\n")
             outfd.write(f"Last updated: {key.LastWriteTime}\n")
             outfd.write("\n")
             outfd.write("Subkeys:\n")
             for s in self.regapi.reg_get_all_subkeys(None,
                                                      None,
                                                      given_root=key):
                 if s.Name == None:
                     outfd.write(f"  Unknown subkey: {s.Name.reason}\n")
                 else:
                     outfd.write(f"  {s.Name}\n")
             outfd.write("\n")
             outfd.write("Values:\n")
             for subname, dat in self.regapi.reg_yield_values(
                     None, None, given_root=key, thetype="REG_BINARY"):
                 dat_raw = dat
                 dat = "\n".join([
                     f"{o:#010x}  {h:<48}  {''.join(c)}"
                     for o, h, c in utils.Hexdump(dat)
                 ])
                 try:
                     subname = codecs.encode(str(subname), 'rot_13')
                 except UnicodeDecodeError:
                     pass
                 if win7:
                     guid = subname.split("\\")[0]
                     if guid in folder_guids:
                         subname = subname.replace(guid, folder_guids[guid])
                 d = self.parse_data(dat_raw)
                 if d != None:
                     dat = f"{d}Raw Data:\n{dat}"
                 else:
                     dat = f"Raw Data:\n{dat}"
                 outfd.write(f"\n{'REG_BINARY':13} {subname:15} : {dat}\n")
     if not keyfound:
         outfd.write(
             "The requested key could not be found in the hive(s) searched\n"
         )
Пример #13
0
    def get_alloc(self, addr_space):
        '''
        Mimics the Volatility malfind plugin
        '''
        import volatility.plugins.malware.malfind as malfind
        import volatility.utils as utils

        mfind = malfind.Malfind(self.vol.config)
        for task in mfind.calculate():  
            for vad, address_space in task.get_vads(vad_filter=task._injection_filter):
                if mfind._is_vad_empty(vad, address_space):
                    continue
                content = address_space.zread(vad.Start, 16)    
                content = "{0}".format("\n".join(
                    ["{0:<48}  {1}".format(h, ''.join(c))
                    for o, h, c in utils.Hexdump(content)
                    ]))
                offset = "{0:#x}".format(vad.Start)
                yield Injection(task, vad, offset, content)
    def dict_for_key(self, key):
        # Inspired from the Volatility printkey plugin
        valdict = {}
        for v in rawreg.values(key):
            tp, data = rawreg.value_data(v)

            if tp == 'REG_BINARY' or tp == 'REG_NONE':
                data = "\n" + "\n".join([
                    "{0:#010x}  {1:<48}  {2}".format(o, h, ''.join(c))
                    for o, h, c in utils.Hexdump(data)
                ])
            if tp in ['REG_SZ', 'REG_EXPAND_SZ', 'REG_LINK']:
                data = data.encode("ascii", 'backslashreplace')
            if tp == 'REG_MULTI_SZ':
                for i in range(len(data)):
                    data[i] = data[i].encode("ascii", 'backslashreplace')

            valdict[str(v.Name)] = str(data)
        return valdict
Пример #15
0
    def calculate(self):
        self.regapi = registryapi.RegistryApi(self._config)

        builds_with_old_location = ['16299', '17134']

        # Get Windows build version
        addr_space = utils.load_as(self._config)
        build = addr_space.profile.metadata.get('build', 0)

        # Choose which location of bam to use in the registry. Builds 16299 and 17134
        # use another path.
        bam_path = ""
        controlset = self.regapi.reg_get_currentcontrolset() or "ControlSet001"

        if build in builds_with_old_location:
            bam_path = controlset + "\\Services\\bam\\UserSettings"
        else:
            bam_path = controlset + "\\Services\\bam\\State\\UserSettings"

        bam_key = self.regapi.reg_get_key('system', bam_path)

        # Get all subkeys in UserSettings
        bam_sub_keys = self.regapi.reg_get_all_subkeys('system',
                                                       bam_path,
                                                       given_root=bam_key)

        # Get all key values, processing the binary content of the values
        self.data = {}
        for sidkey in bam_sub_keys:
            sidkey_values = []
            for key, value in self.regapi.reg_yield_values(
                    'system', sidkey, thetype='REG_BINARY', given_root=sidkey):
                dat = "\n".join(
                    ["{0:<48}".format(h) for o, h, c in utils.Hexdump(value)])
                sidkey_values.append({
                    'key': key,
                    'time': self.reg_bin_to_file_time(dat)
                })
                #print sidkey.Name, key, self.reg_bin_to_file_time(dat)
            self.data[sidkey.Name] = sidkey_values

        return self.data
Пример #16
0
    def yarascan(self):
        """Volatility yarascan plugin.
        @see volatility/plugins/malware/malfind.py
        """
        log.debug("Executing Volatility yarascan plugin on "
                  "{0}".format(self.memdump))

        self.__config()
        results = []

        ypath = os.path.join(CUCKOO_ROOT, "data", "yara", "index_memory.yar")
        if not os.path.exists(ypath):
            return dict(config={}, data=[])

        self.config.update("YARA_FILE", ypath)

        command = self.plugins["yarascan"](self.config)
        for o, addr, hit, content in command.calculate():
            # Comment: this code is pretty much ripped from render_text in volatility.
            # Find out if the hit is from user or kernel mode
            if o == None:
                owner = "Unknown Kernel Memory"
            elif o.obj_name == "_EPROCESS":
                owner = "Process {0} Pid {1}".format(o.ImageFileName,
                                                     o.UniqueProcessId)
            else:
                owner = "{0}".format(o.BaseDllName)

            hexdump = "".join([
                "{0:#010x}  {1:<48}  {2}\n".format(addr + o, h, ''.join(c))
                for o, h, c in utils.Hexdump(content[0:64])
            ])

            new = {
                "rule": hit.rule,
                "owner": owner,
                "hexdump": hexdump,
            }
            results.append(new)

        return dict(config={}, data=results)
Пример #17
0
 def render_text(self, outfd, data):
     outfd.write("Legend: (S) = Stable   (V) = Volatile\n\n")
     keyfound = False
     for reg, key in data:
         if key:
             keyfound = True
             outfd.write("----------------------------\n")
             outfd.write("Registry: {0}\n".format(reg))
             outfd.write("Key name: {0} {1:3s}\n".format(
                 key.Name, self.voltext(key)))
             outfd.write("Last updated: {0}\n".format(key.LastWriteTime))
             outfd.write("\n")
             outfd.write("Subkeys:\n")
             for s in rawreg.subkeys(key):
                 if s.Name == None:
                     outfd.write("  Unknown subkey: " + s.Name.reason +
                                 "\n")
                 else:
                     outfd.write("  {1:3s} {0}\n".format(
                         s.Name, self.voltext(s)))
             outfd.write("\n")
             outfd.write("Values:\n")
             for v in rawreg.values(key):
                 tp, dat = rawreg.value_data(v)
                 if tp == 'REG_BINARY' or tp == 'REG_NONE':
                     dat = "\n" + "\n".join([
                         "{0:#010x}  {1:<48}  {2}".format(o, h, ''.join(c))
                         for o, h, c in utils.Hexdump(dat)
                     ])
                 if tp in ['REG_SZ', 'REG_EXPAND_SZ', 'REG_LINK']:
                     dat = dat.encode("ascii", 'backslashreplace')
                 if tp == 'REG_MULTI_SZ':
                     for i in range(len(dat)):
                         dat[i] = dat[i].encode("ascii", 'backslashreplace')
                 outfd.write("{0:13} {1:15} : {3:3s} {2}\n".format(
                     tp, v.Name, dat, self.voltext(v)))
     if not keyfound:
         outfd.write(
             "The requested key could not be found in the hive(s) searched\n"
         )
Пример #18
0
    def render_text(self, outfd, data):
        for task in data:
            proc_as = task.get_process_address_space()

            for vma in task.get_proc_maps():

                if vma.is_suspicious():
                    fname = vma.vm_name(task)
                    if fname == "[vdso]":
                        continue

                    prots = vma.protection()
                    flags = vma.flags()

                    content = proc_as.zread(vma.vm_start, 64)

                    outfd.write(
                        "Process: {0} Pid: {1} Address: {2:#x} File: {3}\n".
                        format(task.comm, task.pid, vma.vm_start, fname))

                    outfd.write("Protection: {0}\n".format(prots))

                    outfd.write("Flags: {0}\n".format(str(flags)))
                    outfd.write("\n")

                    outfd.write("{0}\n".format("\n".join([
                        "{0:#010x}  {1:<48}  {2}".format(
                            vma.vm_start + o, h, ''.join(c))
                        for o, h, c in utils.Hexdump(content)
                    ])))

                    outfd.write("\n")
                    outfd.write("\n".join([
                        "{0:#x} {1:<16} {2}".format(o, h, i)
                        for o, i, h in malfind.Disassemble(
                            content, vma.vm_start)
                    ]))

                    outfd.write("\n\n")
Пример #19
0
    def render_text(self, outfd, data):
        for task in data:
            proc_as = task.get_process_address_space()

            bit_string = str(task.task.map.pmap.pm_task_map or '')[9:]

            if bit_string == "64BIT":
                bits = '64bit'
            else:
                bits = '32bit'

            for map in task.get_proc_maps():
                if map.is_suspicious():
                    fname = map.get_path()
                    prots = map.get_perms()

                    content = proc_as.zread(map.start, 64)

                    outfd.write(
                        "Process: {0} Pid: {1} Address: {2:#x} File: {3}\n".
                        format(task.p_comm, task.p_pid, map.start, fname))

                    outfd.write("Protection: {0}\n".format(prots))

                    outfd.write("\n")

                    outfd.write("{0}\n".format("\n".join([
                        "{0:#010x}  {1:<48}  {2}".format(
                            map.start + o, h, ''.join(c))
                        for o, h, c in utils.Hexdump(content)
                    ])))

                    outfd.write("\n")
                    outfd.write("\n".join([
                        "{0:#x} {1:<16} {2}".format(o, h, i) for o, i, h in
                        malfind.Disassemble(content, map.start, bits=bits)
                    ]))

                    outfd.write("\n\n")
Пример #20
0
        def db(address, length = 0x80, space = None):
            """Print bytes as canonical hexdump.
            
            This function prints bytes at the given virtual address as a canonical
            hexdump. The address will be translated in the current process context
            (see help on cc for information on how to change contexts).
            
            The length parameter (default: 0x80) specifies how many bytes to print,
            the width parameter (default: 16) allows you to change how many bytes per
            line should be displayed, and the space parameter allows you to
            optionally specify the address space to read the data from.
            """
            if not space:
                space = self._proc.get_process_address_space()
            #if length % 4 != 0:
            #    length = (length+4) - (length%4)
            data = space.read(address, length)
            if not data:
                print "Memory unreadable at {0:08x}".format(address)
                return

            for offset, hexchars, chars in utils.Hexdump(data):
                print "{0:#010x}  {1:<48}  {2}".format(address + offset, hexchars, ''.join(chars))
Пример #21
0
 def render_text(self, outfd, data):
     outfd.write("Legend: (S) = Stable   (V) = Volatile\n\n")
     keyfound = False
     for reg, key in data:
         if key:
             keyfound = True
             outfd.write("----------------------------\n")
             outfd.write(f"Registry: {reg}\n")
             outfd.write(f"Key name: {key.Name} {self.voltext(key):3s}\n")
             outfd.write(f"Last updated: {key.LastWriteTime}\n")
             outfd.write("\n")
             outfd.write("Subkeys:\n")
             for s in rawreg.subkeys(key):
                 if s.Name == None:
                     outfd.write(f"  Unknown subkey at {s.obj_offset:#x}\n")
                 else:
                     outfd.write(f"  {self.voltext(s):3s} {s.Name}\n")
             outfd.write("\n")
             outfd.write("Values:\n")
             for v in rawreg.values(key):
                 tp, dat = rawreg.value_data(v)
                 if tp == 'REG_BINARY' or tp == 'REG_NONE':
                     dat = "\n" + "\n".join([
                         f"{o:#010x}  {h:<48}  {''.join(c)}"
                         for o, h, c in utils.Hexdump(dat)
                     ])
                 if tp in ['REG_SZ', 'REG_EXPAND_SZ', 'REG_LINK']:
                     dat = dat.encode("ascii", 'backslashreplace')
                 if tp == 'REG_MULTI_SZ':
                     for i in range(len(dat)):
                         dat[i] = dat[i].encode("ascii", 'backslashreplace')
                 outfd.write(
                     f"{tp:13} {v.Name:15} : {self.voltext(v):3s} {dat}\n")
     if not keyfound:
         outfd.write(
             "The requested key could not be found in the hive(s) searched\n"
         )
Пример #22
0
def parse_malfind_data(data, out, output="text"):
    import volatility.plugins.malware.malfind as malfind
    import volatility.utils as utils
    datas = getinfos(data, plugin_cols["malfind"]["cols"])
    if output == "json":
        out.write("{}\n\n".format(datas))
        return
    elif output == "text":
        mode = "32bit"
        if platform.machine() == "AMD64":
            mode = "64bit"
        for proc, pid, address, vadtag, protection, flags, data in datas:
            out.write("Process: {}, Pid: {}\n".format(proc, pid))
            out.write("VadTag: {}, Protection: {}, Flags: {}\n\n".format(
                vadtag, protection, flags))
            out.write("Raw data at address {0:#x}: {1}\n\n".format(
                address, data))
            out.write("Disassembly:\n")
            out.write("\n".join([
                "{0:#x} {1:<16} {2}".format(o, h, i)
                for o, i, h in malfind.Disassemble(data.decode("hex"),
                                                   int(address), mode)
            ]))
            out.write("\n\nHexdump:\n")
            out.write("{0}\n".format("\n".join([
                "{0:#010x}  {1:<48}  {2}".format(
                    int(address) + o, h, ''.join(c))
                for o, h, c in utils.Hexdump(data.decode("hex"))
            ])))
            out.write("\n\n")
    else:
        for proc, pid, address, vadtag, protection, flags, data in datas:
            out.write("{},{},{},{},{},{},{}\n".format(proc, pid, address,
                                                      vadtag, protection,
                                                      flags, data))
        out.write("\n\n")
    out.write("\n\n")
Пример #23
0
 def render_text(self, outfd, data):
     for device in data:
         ext = device.DeviceExtension.dereference_as("EXTENSION")
         if not ext.is_valid():
             continue
         outfd.write("Container: {0}\n".format(ext.wszVolume))
         outfd.write("Hidden Volume: {0}\n".format(
             "Yes" if ext.cryptoInfo.hiddenVolume == 1 else "No"))
         outfd.write("Removable: {0}\n".format("Yes" if ext.bRemovable ==
                                               1 else "No"))
         outfd.write("Read Only: {0}\n".format("Yes" if ext.bReadOnly ==
                                               1 else "No"))
         outfd.write("Disk Length: {0} (bytes)\n".format(ext.DiskLength))
         outfd.write("Host Length: {0} (bytes)\n".format(ext.HostLength))
         outfd.write("Encryption Algorithm: {0}\n".format(
             ext.cryptoInfo.ea))
         outfd.write("Mode: {0}\n".format(ext.cryptoInfo.mode))
         outfd.write("Master Key\n")
         key = device.obj_vm.read(ext.cryptoInfo.master_keydata.obj_offset,
                                  64)
         addr = ext.cryptoInfo.master_keydata.obj_offset
         outfd.write("{0}\n".format("\n".join([
             "{0:#010x}  {1:<48}  {2}".format(addr + o, h, ''.join(c))
             for o, h, c in utils.Hexdump(key)
         ])))
         if self._config.DUMP_DIR:
             if not os.path.isdir(self._config.DUMP_DIR):
                 debug.error("The path {0} is not a valid directory".format(
                     self._config.DUMP_DIR))
             name = "{0:#x}_master.key".format(addr)
             keyfile = os.path.join(self._config.DUMP_DIR, name)
             with open(keyfile, "wb") as handle:
                 handle.write(key)
             outfd.write("Dumped {0} bytes to {1}\n".format(
                 len(key), keyfile))
         outfd.write("\n")
Пример #24
0
    def render_text(self, outfd, data):

        header = data.get_header()

        ## First some of the version meta-data
        outfd.write("Magic: {0:#x} (Version {1})\n".format(
            header.Magic, header.Version))
        outfd.write("Group count: {0:#x}\n".format(header.GroupCount))

        ## Now let's print the runs
        self.table_header(outfd, [("File Offset", "[addrpad]"),
                                  ("PhysMem Offset", "[addrpad]"),
                                  ("Size", "[addrpad]")])

        for memory_offset, file_offset, length in data.get_runs():
            self.table_row(outfd, file_offset, memory_offset, length)

        outfd.write("\n")

        ## Go through and print the groups and tags
        self.table_header(outfd, [("DataOffset", "[addrpad]"),
                                  ("DataSize", "[addr]"), ("Name", "50"),
                                  ("Value", "")])

        for group in header.Groups:
            for tag in group.Tags:

                ## The indices should look like [0][1]
                indices = ""
                for i in tag.TagIndices:
                    indices += "[{0}]".format(i)

                ## Attempt to format standard values
                if tag.DataMemSize == 0:
                    value = ""
                elif tag.DataMemSize == 1:
                    value = "{0}".format(tag.cast_as("unsigned char"))
                elif tag.DataMemSize == 2:
                    value = "{0}".format(tag.cast_as("unsigned short"))
                elif tag.DataMemSize == 4:
                    value = "{0:#x}".format(tag.cast_as("unsigned int"))
                elif tag.DataMemSize == 8:
                    value = "{0:#x}".format(tag.cast_as("unsigned long long"))
                else:
                    value = ""

                self.table_row(
                    outfd, tag.RealDataOffset, tag.DataMemSize,
                    "{0}/{1}{2}".format(group.Name, tag.Name, indices), value)

                ## In verbose mode, when we're *not* dealing with memory segments,
                ## print a hexdump of
                if (self._config.VERBOSE and tag.DataMemSize > 0
                        and str(group.Name) != "memory" and value == ""):

                    ## When we read, it must be done via the AS base (FileAddressSpace)
                    addr = tag.RealDataOffset
                    ## FIXME: FileAddressSpace.read doesn't handle NativeType so we have to case.
                    ## Remove the cast after Issue #350 is fixed.
                    data = tag.obj_vm.read(addr, int(tag.DataMemSize))

                    outfd.write("".join([
                        "{0:#010x}  {1:<48}  {2}\n".format(
                            addr + o, h, ''.join(c))
                        for o, h, c in utils.Hexdump(data)
                    ]))
Пример #25
0
 def generator(self, data):
     for (pool, BLMode, tweak, fvek_raw) in data:
         fvek = []
         for o, h, c in utils.Hexdump(fvek_raw):
             fvek.append(h)
         yield(0, [Address(pool),BLMode, str(''.join(fvek).replace(" ","")),str(''.join(tweak).replace(" ","")),])
Пример #26
0
    def calculate(self):
        PoolSize = {
        'Fvec128' : 527,
        'Fvec256' : 1008,
        'Cngb128' : 672,
        'Cngb256' : 672,
        }
        BLMode = {
        '00' : 'AES 128-bit with Diffuser',
        '01' : 'AES 256-bit with Diffuser',
        '02' : 'AES 128-bit',
        '03' : 'AES 256-bit',
        '10' : 'AES 128-bit (Win 8+)',
        '20' : 'AES 256-bit (Win 8+)'
     }

        length = 16

        address_space = utils.load_as(self._config)
        winver = (address_space.profile.metadata.get("major", 0), address_space.profile.metadata.get("minor", 0))
        if winver < (6,2):
            poolsize = lambda x : x >= PoolSize['Fvec128'] and x <= PoolSize['Fvec256']


            scanner = KeyPoolScan()
            scanner.checks = [
                ('PoolTagCheck', dict(tag = "FVEc")),
                ('CheckPoolSize', dict(condition = poolsize)),
                ('CheckPoolType', dict(paged = False, non_paged = True)),
                     ]
            for offset in scanner.scan(address_space):
                pool = obj.Object("_POOL_HEADER", offset = offset, vm = address_space)
                mode = address_space.zread(offset+0x2C,1)
	        for o, h, c in utils.Hexdump(mode):
                    mode =h

                if mode == '01' or mode == '03':
                    length = 32
                fvek_raw = address_space.zread(offset+0x30,length)
                tweak = []
                if mode == '01' or mode == '00':
                    for o, h ,c in utils.Hexdump(address_space.zread(offset+0x210,length)):
                        tweak.append(h)
                yield pool, BLMode[mode], tweak, fvek_raw
        if winver >= (6,2):
            tweak = "Not Applicable"
            poolsize = lambda x : x >= PoolSize['Cngb128'] and x <= PoolSize['Cngb256']
            scanner = KeyPoolScan()
            scanner.checks = [
                ('PoolTagCheck', dict(tag = "Cngb")),
                ('CheckPoolSize', dict(condition = poolsize)),
                ('CheckPoolType', dict(paged = False, non_paged = True)),
                     ]
            for offset in scanner.scan(address_space):
                pool = obj.Object("_POOL_HEADER", offset = offset, vm = address_space)
                mode = address_space.zread(offset+0x68,1)
                for o, h, c in utils.Hexdump(mode):
                    mode =h

                if mode == '20':
                    length = 32
                f1 = address_space.zread(offset+0x6C,length)
                f2 = address_space.zread(offset+0x90,length)
                if f1 == f2:
                    yield pool, BLMode[mode], tweak, f2
    def render_text(self, outfd, data):
        for (proc_peb_info, proc_vad_info, parent_proc_info,
             similar_procs) in data:
            (proc, pid, proc_name, ppid, create_time, proc_cmd_line,
             proc_image_baseaddr, mod_baseaddr, mod_size, mod_basename,
             mod_fullname) = proc_peb_info
            (vad_filename, vad_baseaddr, vad_size, vad_protection,
             vad_tag) = proc_vad_info
            (parent_name, parent_id) = parent_proc_info

            outfd.write("Process Information:\n")
            outfd.write("\tProcess: {0} PID: {1}\n".format(proc_name, pid))
            outfd.write("\tParent Process: {0} PPID: {1}\n".format(
                parent_name,
                ppid,
            ))
            outfd.write("\tCreation Time: {0}\n".format(create_time))
            outfd.write("\tProcess Base Name(PEB): {0}\n".format(mod_basename))
            outfd.write("\tCommand Line(PEB): {0}\n".format(proc_cmd_line))
            outfd.write("\n")
            outfd.write("VAD and PEB Comparison:\n")
            outfd.write("\tBase Address(VAD): {0:#x}\n".format(vad_baseaddr))
            outfd.write("\tProcess Path(VAD): {0}\n".format(vad_filename))
            outfd.write("\tVad Protection: {0}\n".format(vad_protection))
            outfd.write("\tVad Tag: {0}\n".format(vad_tag))
            outfd.write("\n")
            outfd.write(
                "\tBase Address(PEB): {0:#x}\n".format(proc_image_baseaddr))
            outfd.write("\tProcess Path(PEB): {0}\n".format(mod_fullname))
            if vad_baseaddr != proc_image_baseaddr:
                for vad, addr_space in proc.get_vads():
                    if vad.Start == proc_image_baseaddr:
                        content = addr_space.read(vad.Start, 64)
                        outfd.write("\tMemory Protection: {0}\n".format(
                            str(
                                vadinfo.PROTECT_FLAGS.get(
                                    vad.VadFlags.Protection.v()) or "")))
                        outfd.write("\tMemory Tag: {0}\n".format(
                            str(vad.Tag or "")))
                        outfd.write("\n")
                        if content != None:
                            outfd.write("".join([
                                "{0:#010x}  {1:<48}  {2}\n".format(
                                    vad.Start + o, h, ''.join(c))
                                for o, h, c in utils.Hexdump(content)
                            ]))
                        else:
                            outfd.write(
                                "\tNo Hexdump: Memory Unreadable at {0:#010x}\n"
                                .format(vad.Start))
                        outfd.write("\n")
            else:
                outfd.write(
                    "\tMemory Protection: {0}\n".format(vad_protection))
                outfd.write("\tMemory Tag: {0}\n".format(vad_tag))

            outfd.write("\n")

            outfd.write("Similar Processes:\n")
            for similar_proc in similar_procs:
                (process_name, process_id, parent_name, parent_id,
                 creation_time, full_path) = similar_proc
                outfd.write("{0}\n".format(full_path))
                outfd.write("\t{0}({1}) Parent:{2}({3}) Start:{4}\n".format(
                    process_name, process_id, parent_name, parent_id,
                    creation_time))
            outfd.write("\n")

            outfd.write("Suspicious Memory Regions:\n")
            for vad, addr_space in proc.get_vads():
                content = addr_space.read(vad.Start, 64)
                if content == None:
                    continue
                vad_prot = str(
                    vadinfo.PROTECT_FLAGS.get(vad.VadFlags.Protection.v()))
                if obj.Object("_IMAGE_DOS_HEADER",
                              offset=vad.Start,
                              vm=addr_space).e_magic != 0x5A4D:
                    flag = "No PE/Possibly Code"
                    if (vad_prot == "PAGE_EXECUTE_READWRITE"):
                        sus_addr = vad.Start
                        outfd.write(
                            "\t{0:#x}({1})  Protection: {2}  Tag: {3}\n".
                            format(vad.Start, flag, vad_prot, str(vad.Tag
                                                                  or "")))
                        if self._config.DUMP_DIR:
                            filename = os.path.join(
                                self._config.DUMP_DIR,
                                "process.{0}.{1:#x}.dmp".format(pid, sus_addr))
                            self.dump_vad(filename, vad, addr_space)

                    elif (vad_prot == "PAGE_EXECUTE_WRITECOPY"):
                        sus_addr = vad.Start
                        outfd.write(
                            "\t{0:#x}({1})  Protection: {2}  Tag: {3}\n".
                            format(sus_addr, flag, vad_prot, str(vad.Tag
                                                                 or "")))
                        if self._config.DUMP_DIR:
                            filename = os.path.join(
                                self._config.DUMP_DIR,
                                "process.{0}.{1:#x}.dmp".format(pid, sus_addr))
                            self.dump_vad(filename, vad, addr_space)

                else:
                    if vad_prot == "PAGE_EXECUTE_READWRITE":
                        flag = "PE Found"
                        sus_addr = vad.Start
                        outfd.write(
                            "\t{0:#x}({1})  Protection: {2}  Tag: {3}\n".
                            format(sus_addr, flag, vad_prot, str(vad.Tag
                                                                 or "")))
                        if self._config.DUMP_DIR:
                            filename = os.path.join(
                                self._config.DUMP_DIR,
                                "process.{0}.{1:#x}.dmp".format(pid, sus_addr))
                            self.dump_vad(filename, vad, addr_space)

                    elif (vad_prot == "PAGE_EXECUTE_WRITECOPY") and (not bool(
                            vad.FileObject)):
                        flag = "PE - No Mapped File"
                        sus_addr = vad.Start
                        outfd.write(
                            "\t{0:#x}({1})  Protection: {2}  Tag: {3}\n".
                            format(sus_addr, flag, vad_prot, str(vad.Tag
                                                                 or "")))
                        if self._config.DUMP_DIR:
                            filename = os.path.join(
                                self._config.DUMP_DIR,
                                "process.{0}.{1:#x}.dmp".format(pid, sus_addr))
                            self.dump_vad(filename, vad, addr_space)

            outfd.write(
                "---------------------------------------------------\n\n")
Пример #28
0
 def render_text(self, outfd, data):
     if self._config.DUMP_DIR != None and not os.path.isdir(self._config.DUMP_DIR):
         debug.error(self._config.DUMP_DIR + " is not a directory")
     border = "*" * 75
     for offset, mft_entry, attributes in data:
         if len(attributes) == 0:
             continue
         outfd.write("{0}\n".format(border))
         outfd.write("MFT entry found at offset 0x{0:x}\n".format(offset))
         outfd.write("Attribute: {0}\n".format(mft_entry.get_mft_type())) 
         outfd.write("Record Number: {0}\n".format(mft_entry.RecordNumber))
         outfd.write("Link count: {0}\n".format(mft_entry.LinkCount))
         outfd.write("\n")
         # there can be more than one resident $DATA attribute
         # e.g. ADS.  Therfore we need to differentiate somehow
         # to avoid clobbering.  For now we'll use a counter (datanum)
         datanum = 0
         for a, i in attributes:
             if i == None:
                 outfd.write("${0}: malformed entry\n".format(a))
                 continue
             if a.startswith("STANDARD_INFORMATION"):
                 outfd.write("\n${0}\n".format(a))
                 self.table_header(outfd, i.get_header())
                 outfd.write("{0}\n".format(str(i)))
             elif a.startswith("FILE_NAME"):
                 outfd.write("\n${0}\n".format(a))
                 if hasattr(i, "ParentDirectory"):
                     full = mft_entry.get_full_path(i)
                     self.table_header(outfd, i.get_header())
                     output = i.get_full(full)
                     if output == None:
                         continue
                     outfd.write("{0}\n".format(output))
                 else:
                     outfd.write("{0}\n".format(str(i)))
             elif a.startswith("DATA"):
                 outfd.write("\n${0}\n".format(a))
                 contents = "\n".join(["{0:010x}: {1:<48}  {2}".format(o, h, ''.join(c)) for o, h, c in utils.Hexdump(i)])
                 outfd.write("{0}\n".format(str(contents)))
                 if len(str(i)) > 0:
                     file_string = ".".join(["file", "0x{0:x}".format(offset), "data{0}".format(datanum), "dmp"])
                     datanum += 1
                     if self._config.DUMP_DIR != None:
                         of_path = os.path.join(self._config.DUMP_DIR, file_string)
                         of = open(of_path, 'wb')
                         of.write(i)
                         of.close()
             elif a == "OBJECT_ID":
                 outfd.write("\n$OBJECT_ID\n")
                 outfd.write(str(i))
         outfd.write("\n{0}\n".format(border))
Пример #29
0
 def render_text(self, outfd, data):
     keyfound = False
     for win7, reg, key in data:
         if key:
             keyfound = True
             outfd.write("----------------------------\n")
             outfd.write("Registry: {0}\n".format(reg))
             outfd.write("Key name: {0}\n".format(key.Name))
             outfd.write("Last updated: {0}\n".format(key.LastWriteTime))
             outfd.write("\n")
             outfd.write("Subkeys:\n")
             for s in rawreg.subkeys(key):
                 if s.Name == None:
                     outfd.write("  Unknown subkey: " + s.Name.reason + "\n")
                 else:
                     outfd.write("  {0}\n".format(s.Name))
             outfd.write("\n")
             outfd.write("Values:\n")
             for v in rawreg.values(key):
                 tp, dat = rawreg.value_data(v)
                 subname = v.Name
                 if tp == 'REG_BINARY':
                     dat_raw = dat
                     dat = "\n".join(["{0:#010x}  {1:<48}  {2}".format(o, h, ''.join(c)) for o, h, c in utils.Hexdump(dat)])
                     try:
                         subname = subname.encode('rot_13')
                     except UnicodeDecodeError:
                         pass
                     if win7:
                         guid = subname.split("\\")[0]
                         if guid in folder_guids:
                             subname = subname.replace(guid, folder_guids[guid])
                     d = self.parse_data(dat_raw)
                     if d != None:
                         dat = d + dat
                     else:
                         dat = "\n" + dat
                 #these types shouldn't be encountered, but are just left here in case:
                 if tp in ['REG_SZ', 'REG_EXPAND_SZ', 'REG_LINK']:
                     dat = dat.encode("ascii", 'backslashreplace')
                 if tp == 'REG_MULTI_SZ':
                     for i in range(len(dat)):
                         dat[i] = dat[i].encode("ascii", 'backslashreplace')
                 outfd.write("\n{0:13} {1:15} : {2}\n".format(tp, subname, dat))
     if not keyfound:
         outfd.write("The requested key could not be found in the hive(s) searched\n")
Пример #30
0
    def render_text(self, outfd, data):

        if not has_distorm3:
            debug.warning("For best results please install distorm3")

        if self._config.DUMP_DIR and not os.path.isdir(self._config.DUMP_DIR):
            debug.error(self._config.DUMP_DIR + " is not a directory")

        refined_criteria = ["MZ", "\x55\x8B"]

        for task in data:
            for vad, address_space in task.get_vads(
                    vad_filter=task._injection_filter):

                if self._is_vad_empty(vad, address_space):
                    continue

                content = address_space.zread(vad.Start, 64)

                if self._config.REFINED and content[
                        0:2] not in refined_criteria:
                    continue

                outfd.write("Process: {0} Pid: {1} Address: {2:#x}\n".format(
                    task.ImageFileName, task.UniqueProcessId, vad.Start))

                outfd.write("Vad Tag: {0} Protection: {1}\n".format(
                    vad.Tag,
                    vadinfo.PROTECT_FLAGS.get(vad.VadFlags.Protection.v(),
                                              "")))

                outfd.write("Flags: {0}\n".format(str(vad.VadFlags)))
                outfd.write("\n")

                # this is for address reporting in the output
                data_start = vad.Start

                # all zeros in the first page followed by 558B at the base of
                # the second page is an indicator of wiped PE headers
                if content.count(chr(0)) == len(content):
                    if address_space.zread(vad.Start,
                                           0x1000).count(chr(0)) == 0x1000:
                        next_page = address_space.zread(vad.Start + 0x1000, 64)
                        if next_page[0:2] == "\x55\x8B":
                            outfd.write(
                                "**** POSSIBLE WIPED PE HEADER AT BASE *****\n\n"
                            )
                            content = next_page
                            data_start = vad.Start + 0x1000

                outfd.write("{0}\n".format("\n".join([
                    "{0:#010x}  {1:<48}  {2}".format(data_start + o, h,
                                                     ''.join(c))
                    for o, h, c in utils.Hexdump(content)
                ])))

                outfd.write("\n")
                outfd.write("\n".join([
                    "{0:#010x} {1:<16} {2}".format(o, h, i)
                    for o, i, h in Disassemble(content, data_start)
                ]))

                # Dump the data if --dump-dir was supplied
                if self._config.DUMP_DIR:

                    filename = os.path.join(
                        self._config.DUMP_DIR,
                        "process.{0:#x}.{1:#x}.dmp".format(
                            task.obj_offset, vad.Start))

                    self.dump_vad(filename, vad, address_space)

                outfd.write("\n\n")