diff --git a/volatility3/framework/plugins/windows/mbrscan.py b/volatility3/framework/plugins/windows/mbrscan.py index beda342fb..fcc9dabb1 100644 --- a/volatility3/framework/plugins/windows/mbrscan.py +++ b/volatility3/framework/plugins/windows/mbrscan.py @@ -3,6 +3,7 @@ # import logging +import hashlib from volatility3.framework import constants, interfaces, renderers, symbols from volatility3.framework.configuration import requirements @@ -52,22 +53,30 @@ class MBRScan(interfaces.plugins.PluginInterface): mbr_start_offset = offset - (mbr_length - len(mbr_signature)) partition_table = self.context.object(partition_table_object, offset = mbr_start_offset, layer_name = layer.name) - boot_code = layer.read(mbr_start_offset, boot_code_length, pad = True) + full_mbr = layer.read(mbr_start_offset, mbr_length, pad = True) + boot_code = full_mbr[:boot_code_length] if boot_code: all_zeros = boot_code.count(b"\x00") == len(boot_code) if not all_zeros: - - first_entry = partition_table.FirstEntry - second_entry = partition_table.SecondEntry - third_entry = partition_table.ThirdEntry - fourth_entry = partition_table.FourthEntry + bootcode_hash = hashlib.md5(boot_code).hexdigest() + full_bootcode_hash = hashlib.md5(full_mbr).hexdigest() + partition_entries = [ partition_table.FirstEntry, partition_table.SecondEntry, + partition_table.ThirdEntry, partition_table.FourthEntry ] + partition_info = "" + + for index, partition_entry_object in enumerate(partition_entries): + partition_entry_object.set_index(index) + partition_info += str(partition_entry_object) + yield 0, ( format_hints.Hex(offset), partition_table.get_disk_signature(), - str(partition_table.FirstEntry), + bootcode_hash, + full_bootcode_hash, + partition_info, interfaces.renderers.Disassembly(boot_code, 0, architecture), format_hints.HexBytes(boot_code) ) @@ -76,9 +85,11 @@ class MBRScan(interfaces.plugins.PluginInterface): def run(self): return renderers.TreeGrid([ - ("Offset", format_hints.Hex), + ("Potential MBR at Physical Offset", format_hints.Hex), ("Disk Signature", str), - ("First Entry", str), + ("Bootcode md5", str), + ("Bootcode (FULL) md5", str), + ("Partition Entries Info", str), ("Disasm", interfaces.renderers.Disassembly), ("Hexdump", format_hints.HexBytes) ], self._generator()) diff --git a/volatility3/framework/symbols/windows/extensions/mbr.py b/volatility3/framework/symbols/windows/extensions/mbr.py index e4aaefad1..8e02db822 100644 --- a/volatility3/framework/symbols/windows/extensions/mbr.py +++ b/volatility3/framework/symbols/windows/extensions/mbr.py @@ -7,6 +7,7 @@ from volatility3.framework import objects class PARTITION_TABLE(objects.StructType): def get_disk_signature(self) -> str: + """Get Disk Signature (GUID).""" return "{0:02x}-{1:02x}-{2:02x}-{3:02x}".format( self.DiskSignature[0], self.DiskSignature[1], @@ -15,42 +16,57 @@ class PARTITION_TABLE(objects.StructType): ) class PARTITION_ENTRY(objects.StructType): + + def set_index(self, index:int): + self.index = index def get_bootable_flag(self) -> int: + """Get Bootable Flag.""" return self.BootableFlag def is_bootable(self) -> bool: + """Check Bootable Partition.""" return False if not (self.BootableFlag == 0x80) else True def get_partition_type(self) -> str: + """Get Partition Type.""" return self.PartitionType.lookup() if self.PartitionType.is_valid_choice else "Not Defined PartitionType" def get_starting_chs(self): + """Get Starting CHS (Cylinder Header Sector) Address.""" return self.StartingCHS[0] def get_ending_chs(self): + """Get Ending CHS (Cylinder Header Sector) Address.""" return self.EndingCHS[0] def get_starting_sector(self): + """Get Starting Sector.""" return self.StartingCHS[1] % 64 - def get_starting_cylinder(self): - return (self.StartingCHS[1] - self.get_starting_sector()) * 4 + self.StartingCHS[2] - def get_ending_sector(self): + """Get Ending Sector.""" return self.EndingCHS[1] % 64 + def get_starting_cylinder(self): + """Get Starting Cylinder.""" + return (self.StartingCHS[1] - self.get_starting_sector()) * 4 + self.StartingCHS[2] + def get_ending_cylinder(self): + """Get Ending Cylinder.""" return (self.EndingCHS[1] - self.get_ending_sector()) * 4 + self.EndingCHS[2] def get_starting_lba(self): + """Get Starting LBA (Logical Block Addressing).""" return self.StartingLBA def get_size_in_sectors(self): + """Get Size in Sectors.""" return self.SizeInSectors def __str__(self): - processed_entry = "========= Partition Info =========\n" + """Get overall of Partition Entry Info""" + processed_entry = "\n===== Partition Table #{0} =====\n".format(self.index+1) processed_entry += "Boot Flag: {0:#x} {1}\n".format( self.is_bootable(), "(Bootable)" if self.is_bootable() else '' @@ -70,5 +86,5 @@ class PARTITION_ENTRY(objects.StructType): self.get_ending_chs(), self.get_ending_sector() ) - processed_entry += "Size in sectors: {0:#x} ({0})\n\n".format(self.get_size_in_sectors()) + processed_entry += "Size in Sectors: {0:#x} ({0})\n".format(self.get_size_in_sectors()) return processed_entry