-
Notifications
You must be signed in to change notification settings - Fork 24
Development
pytsk3 (as of February 17, 2014) comes with 2 different version numbers:
- the SleuthKit version it was built against;
- the version of the pytsk3 code.
To obtain the SleuthKit version:
import pytsk3
print pytsk3.TSK_VERSION_STR
To obtain the pytsk3 version:
import pytsk3
print pytsk3.get_version()
This is an example of how to replicate the mmls functionality.
import pytsk3
img = pytsk3.Img_Info(url="/path/to/image/file")
volume = pytsk3.Volume_Info(img)
for part in volume:
print part.addr, part.desc.decode('utf-8'), part.start, part.len
Note: at the moment the volume object is an iterator object that will change state if accessed
To retain the state e.g. in a nested construction use:
list(volume)
Note: that part.desc contains an UTF-8 encoded byte stream.
To access a file system via pytsk3 run:
import pytsk3
img = pytsk3.Img_Info(url="/path/to/image/file")
fs = pytsk3.FS_Info(img)
When you try to access a file system make sure that the image object (img) contains a file system. If not you can pass pytsk3.FS_Info a byte offset of where the volume containing the file system starts, e.g.
fs_offset = 2048 * 512
fs = pytsk3.FS_Info(img, offset=fs_offset)
The term "file entry" is used to indicates any "entry" the file system can define e.g. a file, a directory, a symbolic link, etc.
To access a specific file entry within a file system by path:
file_entry = fs.open("/Windows/MyFile.txt")
A file entry can also be accessed based on its "inode":
file_entry = fs.open_meta(inode=15)
Note: that the term inode applied to the abstraction the SleuthKit provides, which can also apply to file systems that do not define inodes e.g. NTFS.
Note that there is a difference between open and open_meta, from: http://www.sleuthkit.org/sleuthkit/docs/api-docs/fspage.html
The tsk_fs_file_open_meta() function takes a metadata address as an argument and returns a TSK_FS_FILE structure. The TSK_FS_FILE::name pointer will be NULL because the file name was not used to open the file and, for efficiency, TSK does not search the directory tree to locate the file name that points to the metadata address.
The file entry type is stored in the attribute:
file_entry.info.meta.type
Note that not every file entry necessarily has the .info or .info.meta property.
This attribute contains a value of pytsk3.TSK_FS_META_TYPE_ENUM, e.g. to determine if a file entry is a "regular" file.
if file_entry.info.meta.type == pytsk3.TSK_FS_META_TYPE_REG:
print "A file :)"
else:
print "Not a file :("
The file entry address is stored in the attribute:
file_entry.info.meta.addr
Note that not every file entry necessarily has the .info or .info.meta property.
The address is also referred to as the inode by the SleuthKit.
The timestamp values contain the number of seconds since January 1, 1970 00:00:00, which often are normalized to UTC but not guaranteed. TODO check if the SleuthKit has an option to pass a timezone.
The file entry access time is stored in the attribute:
file_entry.info.meta.atime
The file entry change time (or entry modification time) is stored in the attribute:
file_entry.info.meta.ctime
The file entry modification time is stored in the attribute:
file_entry.info.meta.mtime
The file entry creation time (or birth time) is stored in the attribute:
file_entry.info.meta.crtime
For file systems that provide a larger granularity there is a nano-attribute available e.g. for the atime:
file_entry.info.meta.atime_nano
Note that the SleuthKit can has conversions issues with timestamps outside the range 1970 - 2038 for NTFS.
Also see: https://github.com/sleuthkit/sleuthkit/pull/323
for directory_entry in fs.open_dir(path="/Windows"):
directory_entry = directory_entry.info.name.name
try:
print directory_entry.decode("utf8")
except UnicodeError:
pass
Note that not every directory entry necessarily has the .info or .info.name property.
Note that (at the moment January 19, 2014) directory_entry.info.name.name contains a UTF-8 formatted binary string.
Note that this will include the directory entries "." (self), ".." (parent) and entries recovered by the SleuthKit.
Note that the SleuthKit will also expose virtual directories like "/$OrphanFiles"
ads_attribute = None
for attribute in file_entry:
if attribute.info.name == name_ads:
ads_attribute = attribute
break
if ads_attribute:
file_entry.read_random(
offset, size, ads_attribute.info.type, ads_attribute.info.id)
The underlying behavior of the SleuthKit for file_entry.read_random() seems to be to read the first available $DATA NTFS attribute in case no default (nameless) $DATA NTFS attribute is available e.g. $Extend$UsnJrnl.
import pytsk3
help(pytsk3)
help(pytsk3.Img_Info)
help(pytsk3.Volume_Info)
help(pytsk3.FS_Info)