How it works...

We import a number of libraries to assist with argument parsing, handling evidence containers and filesystems, and creating tabular console data.

from __future__ import print_function
import argparse
import os
import pytsk3
import pyewf
import sys
from tabulate import tabulate

This recipe's command-line handler takes two positional arguments, EVIDENCE_FILE and TYPE, which represent the path to the evidence file and the type of evidence file (that is, raw or ewf). Note that for segmented E01 files, you only need to supply the path to the first E01 (with the assumption that the other splits are in the same directory). After performing some input validation on the evidence file, we supply the main() function with the two provided inputs and begin executing the script.

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("TYPE",
help="Type of evidence: raw (dd) or EWF (E01)",
choices=("raw", "ewf"))
parser.add_argument("-o", "--offset",
help="Partition byte offset", type=int)
args = parser.parse_args()

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

In the main() function, we first check what type of evidence file we are working with. If it is an E01 container, we need to first use pyewf to create a handle before we can access its contents with pytsk3. With a raw image, we can directly access its contents with pytsk3 without needing to perform this intermediate step first.

The pyewf.glob() method is used here to combine all segments of the E01 container, if there are any, and store the segment names in a list. Once we have the list of filenames, we can create the E01 handle object. We can then use this object to open the filenames.

def main(image, img_type, offset):
print("[+] Opening {}".format(image))
if img_type == "ewf":
try:
filenames = pyewf.glob(image)
except IOError:
_, e, _ = sys.exc_info()
print("[-] Invalid EWF format: {}".format(e))
sys.exit(2)
ewf_handle = pyewf.handle()
ewf_handle.open(filenames)

Next, we must pass the ewf_handle to the EWFImgInfo class, which will create the pytsk3 object. The else statement here is for raw images that can use the pytsk3.Img_Info function to achieve the same task. Let's now look at the EWFImgInfo class to understand how EWF files are processed slightly differently.

        # Open PYTSK3 handle on EWF Image
img_info = EWFImgInfo(ewf_handle)
else:
img_info = pytsk3.Img_Info(image)

The code for this component of the script is from the Combining pyewf with pytsk3 section of the Python development page for pyewf.

Learn more about pyewf functions, visit https://github.com/libyal/libewf/wiki/Development.

This EWFImgInfo class inherits from the pytsk3.Img_Info base class and is of the type TSK_IMG_TYPE_EXTERNAL. It is important to note that the three functions defined next, close(), read(), and get_size(), are all required by pytsk3 to interact with the evidence container appropriately. With this simple class created, we can now use pytsk3 with any supplied E01 file.

class EWFImgInfo(pytsk3.Img_Info):
def __init__(self, ewf_handle):
self._ewf_handle = ewf_handle
super(EWFImgInfo, self).__init__(url="",
type=pytsk3.TSK_IMG_TYPE_EXTERNAL)

def close(self):
self._ewf_handle.close()

def read(self, offset, size):
self._ewf_handle.seek(offset)
return self._ewf_handle.read(size)

def get_size(self):
return self._ewf_handle.get_media_size()

Back in the main() function, we have successfully created our pytsk3 handler for either raw or E01 images. We can now begin accessing the filesystem. As mentioned, this script is designed to work with logical images and not physical images. We will introduce support for physical images in the next recipe. Accessing the filesystem is really simple; we do so by calling the FS_Info() function on the pytsk3 handle.

    # Get Filesystem Handle
try:
fs = pytsk3.FS_Info(img_info, offset)
except IOError:
_, e, _ = sys.exc_info()
print("[-] Unable to open FS: {}".format(e))
exit()

With access to the filesystem, we can iterate through the folders and files in the root directory. First, we access the root using the open_dir() method on the filesystem and specifying the root directory, /, as the input. Next, we create a nested list structure that will hold the table content, which we will later print to the console using tabulate. The first element of this list is the headers of that table.

Following that, we'll begin to iterate through the image as we would with any Python iterable object. There are a variety of attributes and functions for each object, and we begin to use them here. First, we extract the name of the object using the f.info.name.name attribute. We then check if we are dealing with a directory or a file using the f.info.meta.type attribute. If this is equal to the built-in TSK_FS_META_TYPE_DIR object, then we set the f_type variable to DIR; otherwise, to FILE.

Lastly, we use a few more attributes to extract the directory or file size and create and modify timestamps. Be aware that object timestamps are stored in Unix time and must be converted if you would like to display them in a human-readable format. With these attributes extracted, we append the data to the table list and continue on to the next object. Once we have finished processing all objects in the root folder, we use tabulate to print the data to the console. This is accomplished in one line by supplying the tabulate() method with the list and setting the headers keyword argument to firstrow to indicate that the first element in the list should be used as the table header.

    root_dir = fs.open_dir(path="/")
table = [["Name", "Type", "Size", "Create Date", "Modify Date"]]
for f in root_dir:
name = f.info.name.name
if f.info.meta.type == pytsk3.TSK_FS_META_TYPE_DIR:
f_type = "DIR"
else:
f_type = "FILE"
size = f.info.meta.size
create = f.info.meta.crtime
modify = f.info.meta.mtime
table.append([name, f_type, size, create, modify])
print(tabulate(table, headers="firstrow"))

When we run the script, we can learn about the files and folders at the root of the evidence container as seen in the following screenshot:

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

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