How it works...

We import a number of libraries to assist with argument parsing, date parsing, writing CSVs, processing volume shadow copies, and the custom pytskutil module.

from __future__ import print_function
import argparse
from datetime import datetime, timedelta
import os
import pytsk3
import pyewf
import pyvshadow
import sys
import unicodecsv as csv
from utility import vss
from utility.pytskutil import TSKUtil
from utility import pytskutil

This recipe's command-line handler takes two positional arguments: EVIDENCE_FILE and OUTPUT_CSV. These represent the path to the evidence file and the file path for the output spreadsheet, respectively. Notice the conspicuous absence of the evidence type argument. This script only supports raw image files and does not work with E01s. To prepare an EWF image for use with the script you may either convert it to a raw image or mount it with ewfmount, a tool associated with libewf, and provide the mount point as the input.

if __name__ == "__main__":
parser = argparse.ArgumentParser(
description=__description__,
epilog="Developed by {} on {}".format(
", ".join(__authors__), __date__)
)
parser.add_argument("EVIDENCE_FILE", help="Evidence file path")
parser.add_argument("OUTPUT_CSV",
help="Output CSV with VSS file listing")
args = parser.parse_args()

After parsing the input arguments, we separate the directory from the OUTPUT_CSV input and confirm that it exists or create it if it is not present. We also validate the input file path's existence before passing the two positional arguments to the main() function.

    directory = os.path.dirname(args.OUTPUT_CSV)
if not os.path.exists(directory) and directory != "":
os.makedirs(directory)

if os.path.exists(args.EVIDENCE_FILE) and
os.path.isfile(args.EVIDENCE_FILE):
main(args.EVIDENCE_FILE, args.OUTPUT_CSV)
else:
print("[-] Supplied input file {} does not exist or is not a "
"file".format(args.EVIDENCE_FILE))
sys.exit(1)

The main() function calls a few new functions within the TSKUtil object that we have not explored yet. After we create our TSKUtil object, we extract its volume using the return_vol() method. Interacting with an evidence file's volume, as we have seen in previous recipes, is one of the requisite steps before we can interact with the filesystem. However, this process has been previously performed in the background when necessary. This time, however, we need access to the pytsk3 volume object to iterate through each partition to identify NTFS filesystems. The detect_ntfs() method returns a Boolean value if the specific partition has an NTFS filesystem.

For each NTFS filesystem we encounter, we pass the evidence file, the offset of the discovered NTFS partition, and the output CSV file to the explore_vss() function. If the volume object is None, we print a status message to the console to remind users that the evidence file must be a physical device image as opposed to only a logical image of a specific partition.

def main(evidence, output):
# Create TSK object and query path for prefetch files
tsk_util = TSKUtil(evidence, "raw")
img_vol = tsk_util.return_vol()
if img_vol is not None:
for part in img_vol:
if tsk_util.detect_ntfs(img_vol, part):
print("Exploring NTFS Partition for VSS")
explore_vss(evidence, part.start * img_vol.info.block_size,
output)
else:
print("[-] Must be a physical preservation to be compatible "
"with this script")
sys.exit(2)

The explore_vss() method starts by creating a pyvshadow.volume() object. We use this volume to open the vss_handle object created from the vss.VShadowVolume() method. The vss.VShadowVolume() method takes the evidence file and the partition offset value and exposes a volume-like object that is compatible with the pyvshadow library, which does not natively support physical disk images. The GetVssStoreCount() function returns the number of volume shadow copies found in the evidence.

If there are volume shadows, we open our vss_handle object with the pyvshadow vss_volume and instantiate a list to hold our data. We create a for loop to iterate through each volume shadow copy present and perform the same series of steps. First, we use the pyvshadow get_store() method to access the particular volume shadow copy of interest. Then, we use the vss helper library VShadowImgInfo to create a pytsk3 image handle. Lastly, we pass the image handle to the openVSSFS() method and append the returned data to our list. The openVSSFS() method uses similar methods as discussed before to create a pytsk3 filesystem object and then recurse through the directories present to return an active file listing. After we have performed these steps on all of the volume shadow copies, we pass the data and the output CSV file path to our csvWriter() method.

def explore_vss(evidence, part_offset, output):
vss_volume = pyvshadow.volume()
vss_handle = vss.VShadowVolume(evidence, part_offset)
vss_count = vss.GetVssStoreCount(evidence, part_offset)
if vss_count > 0:
vss_volume.open_file_object(vss_handle)
vss_data = []
for x in range(vss_count):
print("Gathering data for VSC {} of {}".format(x, vss_count))
vss_store = vss_volume.get_store(x)
image = vss.VShadowImgInfo(vss_store)
vss_data.append(pytskutil.openVSSFS(image, x))

write_csv(vss_data, output)

The write_csv() method functions as you would expect it to. It first checks if there is any data to write. If there isn't, it prints a status message to the console before exiting the script. Alternatively, it creates a CSV file using the user-provided input, writes the spreadsheet headers, and iterates through each list, calling writerows() for each volume shadow copy. To prevent the headers from ending up several times in the CSV output, we will check to see if the CSV already exists and add new data in for review. This allows us to dump information after each volume is processed for volume shadow copies.

def write_csv(data, output):
if data == []:
print("[-] No output results to write")
sys.exit(3)

print("[+] Writing output to {}".format(output))
if os.path.exists(output):
append = True
with open(output, "ab") as csvfile:
csv_writer = csv.writer(csvfile)
headers = ["VSS", "File", "File Ext", "File Type", "Create Date",
"Modify Date", "Change Date", "Size", "File Path"]
if not append:
csv_writer.writerow(headers)
for result_list in data:
csv_writer.writerows(result_list)

After running this script, we can review the files found within each volume shadow copy and learn about the metadata of each item:

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.191.5.239