FSEvent is a short for File System Events, FSEvents is a macOS-specific API allows applications to register for notifications of changes such as file creation, deletion, modification, and renaming to a given directory tree which helps applications to keep track of file system changes in real-time without continuously scanning the disk, which would be inefficient and resource-intensive. Whenever the filesystem is changed, the kernel passes notifications via the special device file /dev/fsevents to a userspace process called fseventsd. This process combines multiple changes to a single directory tree that occur within a short period of time, then notifies applications that have registered for changes to the affected directory.
They are introduced in 10.5 (only directory events up to 10.6), then file events are added with 10.7. They are stored in FSEvent log files (gzip).
They can be found on iOS, OS X devices and external devices plugged into a Mac.
FSEvents captures detailed information about modifications occurring within the file system such as file creation, deletion, modification, renaming and mounting. offering a timeline of changes that can help identify patterns or anomalies, and can uncover critical artifacts that play a key role in cross-referencing and validating other digital evidence during investigations.
Based on "Mac Forensics_ Looking into the Past with FSEvents - SANS DFIR Summit 2017" introduced by Nicole Ibrahim, this is the structure of the FSEvents after unzipping the log file.
4-bytes
: In macOS versions prior to 10.13, the magic header within a decompressed FSEvents log was 1SLD
. Beginning with 10.13, the magic header 2SLD
, now the magic header is 3SLD
0x0c
(not a standard but, you will always notice it in the structure), and length is variable.00 null byte
after end of Full Path and it is 8-bytes
size.4-bytes
To make sure that our analysis is good, we will try FSEvent-parser to check it's results.
Based on David Cown's repo, FSEvent records the following categories :
Tools : macOS v10.13 machine, FSEventparser_v4.0
I created 2 files one using TextEdit and the other one using nano commandline, then I parsed the .fseventsd/ directory.
python2.7 FSEParser_V4.0.py -s ./fsevent/ -t folder -o output -q report_queries.json
tes.no1.rtf
has many records within the log file. You can trace this when ordering Event-IDs.Renamed;ExtendedAttrModified;ExtendedAttrRemoved;
flag.test1.txt
has few events, maybe there are more, but i assumed this based on event's sequence.Modified;Created;
flag.I removed event log files, then I will wait few minutes to rename test1.txt
to test2.txt
, then renaming output
directory to output2, then shutdown the machine to force the content within memory to be written to the disk.
output
directory to output2
. the 2 events are Consecutive, and the flags will be Renamed
mv test1.txt test2.txt
, lets check if the node_id is the same. Yes they have the same node_id .Finding .DS_Store in fsevents after any renaming or modification or deletion, indicating that that action happened through Finder app.
I copied test2.txt from root directory to Users/m4shl3/Desktop through cp
command, then I copied it from Desktop to Documents through Finder GUI Window.
When I run the parser, I found the 2 events under Desktop and Documents.
cp
was found with Modified;ItemCloned;Created;PermissionChange;
flag.ItemCloned;Created;PermissionChange;
flag.I will back and copy the file again from root directory to Music Directory with cp command.
It appears as a record with Modified;Created;PermissionChange
flag without ItemCloned
I will do copy the file from Music/ to Library/ using cp
command then to Applications/ using Finder and see what flags will hit.
Hypothesis :
Modified;Created;PermissionChange;
flag.ItemCloned;Created;PermissionChange;
or Modified;ItemCloned;Created;PermissionChange;
flag. And log file will show 2 files before and after copying.I made same process again just to be sure about Hypothesis. And same results.
I have test2.txt on Desktop, I will move it to Documents directroy.
It will generate Renamed flag.
I will unzip sample-2 file and see what recoreds we will get.
InodeMetaMod;FolderCreated;
InodeMetaMod;PermissionChange;FolderCreated;
Modified;Renamed;Created;ExtendedAttrModified;
, and creates an entry into .Trash directoryAs seen you can know the content of each file in the zip file. This is so important from forensics perspective.
Moving the file to Trash means the file is still exist but in the Trash itself.
There will be Renamed
flag within .Trash record.
Removing file from the Trash means file will no longer exist.
There will be Renamed;Removed
flag.
when you need to install dmg app on mac, you just can double click the dmg file, that will mount the dmg file on disk.
There will be some checks before mounting and the record will have flag Mount
Browser events will not tell you the urls or even what you typed in safari search, it is just will tell you that there was a browser activity by the user.
Here is an example of downloading a zip file using safari, you can notice that there are events (modification of files) related to safari cache/ directory, indicating of downloading something.
Action | Flag |
---|---|
Creating text file with nano command | Modified;Created; |
Creating file with TextEdit | Renamed;ExtendedAttrModified;ExtendedAttrRemoved |
Renaming a File | Renamed |
Renaming a Directory | Renamed |
Copying file through command line | Modified;Created;PermissionChange |
Copying file through Finder GUI Window | ItemCloned;Created;PermissionChange; or Modified;ItemCloned;Created;PermissionChange; |
Moving file to a directory | Renamed |
Unzpping a file with default command | InodeMetaMod;FolderCreated; |
Unzipping to new directory | InodeMetaMod;PermissionChange;FolderCreated; |
Moving file to the Trash | Renamed |
Removing file from the Trash (Empty Trash) | Renamed;Removed |
Mounting dmg file | Mount |
This is what I got during my tests, The events may change based on macOS versions or the way the examiner doing the test, you will never know till you try.
FSEvents are stored in memory so, they are lost due to either :
There is no timestamp within each record, so we can't determine from those events when exactly if something changed. All what we can got the nearly day the event was added to the logs.
The FSEvents API coalesces multiple changes into a single record, This file may have been created 3 times and removed twice, but we will never know.