def calculate(self): address_space = utils.load_as(self._config, astype='physical') scanner = INDXScanner(needles=['INDX\(']) # Carve INDX Headers for offset in scanner.scan(address_space): indx_entries = [] indx_header_buff = address_space.zread(offset, 0x40) bufferas = addrspace.BufferAddressSpace(self._config, data=indx_header_buff) indx_header = obj.Object('INDX_HEADER', vm=bufferas, offset=0) # Check the headers if indx_header.isValid: indx_buff = address_space.zread(offset + 40, 4096) indx_bufferas = addrspace.BufferAddressSpace(self._config, data=indx_buff) o = 0 # Iterate through the entries while o < indx_header.AllocatedSizeOfEntries: indx_entry_header = obj.Object('INDX_ENTRY_HEADER', vm=indx_bufferas, offset=o) # Check the entry headers if indx_entry_header.isValid: if len(indx_bufferas. data[o + 16:o + 16 + indx_entry_header.StreamLength] ) == indx_entry_header.StreamLength: indx_entry = obj.Object('FILE_NAME', vm=indx_bufferas, offset=o + 16) if indx_entry.is_valid(): null_date = datetime.datetime( 1990, 1, 1, 0, 0, 0).replace(tzinfo=timefmt.UTC()) future_date = datetime.datetime( 2025, 1, 1, 0, 0, 0).replace(tzinfo=timefmt.UTC()) if null_date <= indx_entry.FileAccessedTime.as_datetime() <= future_date and \ null_date <= indx_entry.ModifiedTime.as_datetime() <= future_date and \ null_date <= indx_entry.MFTAlteredTime.as_datetime() <= future_date and \ null_date <= indx_entry.CreationTime.as_datetime() <= future_date: indx_entries.append( [indx_entry_header, indx_entry]) o = o + indx_entry_header.EntryLength else: o += 1 yield offset, indx_header, indx_entries
def as_datetime(self): try: dt = datetime.datetime.utcfromtimestamp(self.v()) if self.is_utc: # Only do dt.replace when dealing with UTC dt = dt.replace(tzinfo=timefmt.UTC()) except ValueError, e: return obj.NoneObject("Datetime conversion failure: " + str(e))
def body(self, record_bufferas, record_data): if self.RedoOP == 0x02 or self.UndoOP == 0x02: # MFT file record mft_entry = obj.Object('MFT_FILE_RECORD', vm=record_bufferas, offset=0) if mft_entry.is_valid(): attributes = mft_entry.parse_attributes(record_data, entrysize=1024) # find the win32 filename for this record # if not found get the dos name # if not found there should be a posix name filesize = 0 filename = "" posix = "" win32 = "" dos = "" for a, i in attributes: if a.startswith("FILE_NAME"): filesize = i.RealFileSize if i.Namespace == 1 or i.Namespace == 3: win32 = i.get_name() if i.Namespace == 2 or i.Namespace == 3: dos = i.get_name() if i.Namespace == 0: posix = i.get_name() if win32 != "": filename = win32 elif dos != "": filename = dos elif posix != "": filename = posix else: filename = "[NO FILENAME FOUND]" out = "" for a, i in attributes: if a.startswith("STANDARD_INFORMATION"): if out != "": out = out + "\n" out = out + "0|{0}|{6}|0|0|0|{1}|{2}|{3}|{4}|{5}".format( filename + " (SI)", str(filesize), i.FileAccessedTime.v(), i.ModifiedTime.v(), i.MFTAlteredTime.v(), i.CreationTime.v(), str(mft_entry.RecordNumber)) elif a.startswith("FILE_NAME"): if out != "": out = out + "\n" out = out + "0|{0}|{6}|0|0|0|{1}|{2}|{3}|{4}|{5}".format( filename + " (FN)", i.RealFileSize, i.FileAccessedTime.v(), i.ModifiedTime.v(), i.MFTAlteredTime.v(), i.CreationTime.v(), str(mft_entry.RecordNumber)) return out else: return "" elif self.RedoOP == 0x0e or self.UndoOP == 0x0e: # INDX entry indx_entry_header = obj.Object('INDX_ENTRY_HEADER', vm=record_bufferas, offset=0) if indx_entry_header.isValid: indx_entry = obj.Object('FILE_NAME', vm=record_bufferas, offset=16) if indx_entry.is_valid(): null_date = datetime.datetime( 1970, 1, 1, 0, 0, 0).replace(tzinfo=timefmt.UTC()) future_date = datetime.datetime( 2025, 1, 1, 0, 0, 0).replace(tzinfo=timefmt.UTC()) if indx_entry.FileAccessedTime.as_datetime() <= future_date and indx_entry.FileAccessedTime.as_datetime() >= null_date and \ indx_entry.ModifiedTime.as_datetime() <= future_date and indx_entry.ModifiedTime.as_datetime() >= null_date and \ indx_entry.MFTAlteredTime.as_datetime() <= future_date and indx_entry.MFTAlteredTime.as_datetime() >= null_date and \ indx_entry.CreationTime.as_datetime() <= future_date and indx_entry.CreationTime.as_datetime() >= null_date: return "0|{0}|{6}|0|0|0|{1}|{2}|{3}|{4}|{5}".format( indx_entry.get_name() + " (INDX)", indx_entry.RealFileSize, indx_entry.FileAccessedTime.v(), indx_entry.ModifiedTime.v(), indx_entry.MFTAlteredTime.v(), indx_entry.CreationTime.v(), indx_entry_header.MFT.RecordNumber) else: return "" else: return "" else: return "" elif self.RedoOP == 0x14 or self.UndoOP == 0x14: # FILENAME Allocation fna = obj.Object('FILE_NAME', vm=record_bufferas, offset=0) filename = "[NO FILENAME FOUND] (FNA, VCN: %d, Offset into the file: %d)" % ( self.TargetLCN, self.AttributeOffset) return "0|{0}|0|0|0|0|{1}|{2}|{3}|{4}|{5}".format( filename, fna.RealFileSize, fna.FileAccessedTime.v(), fna.ModifiedTime.v(), fna.MFTAlteredTime.v(), fna.CreationTime.v()) else: return ""