Skip to content

File accessAnti-forensics

ext4 Timestamps, crtime and Deleted Files

ext4 inode timestamps (atime, mtime, ctime, crtime, dtime) with nanoseconds, relatime, the jbd2 journal and what deleted-file recovery can still do.

Location
/dev/<ext4-partition>
Distributions
Proves
When a file was created, modified, changed and possibly read or deleted, and sometimes what it contained
Timestamps
Unix epoch seconds UTC plus nanoseconds in *_extra fields (256-byte inodes); i_dtime in seconds
Access
Any user for stat on accessible files; root or raw device access for debugfs and deleted inodes
Retention
Timestamps until overwritten; deleted inodes and blocks until reused; journal is a small circular log
Collection
dd, ewfacquire, UAC, Velociraptor

What it is

ext4 is the default filesystem of Debian and Ubuntu and a common choice elsewhere. Every file and directory is an inode holding its metadata, including up to five timestamps. These timestamps are the backbone of any Linux file-system timeline, and the way ext4 handles deletion decides what can still be recovered after an attacker cleans up.

Where it lives

StructureLocationNotes
InodesInode tables in each block groupDefault inode size 256 bytes, which holds the extra timestamp fields
Directory entriesDirectory data blocks (hashed htree for large directories)Name to inode mapping; deleted names may linger
Journal (jbd2)Normally inode 8, internalDefault data=ordered: metadata blocks are journaled, file data is not
SuperblockOffset 1024 of the volumeMount times, last write, last fsck, UUID, features

On live systems check the options with findmnt -o TARGET,SOURCE,FSTYPE,OPTIONS and features with dumpe2fs -h /dev/<dev> (read-only).

What it proves

  • crtime (birth): when the inode was created on this filesystem. Copies and extractions get a new crtime; touch cannot change it.
  • mtime: last change of the file content. Settable from userspace (touch -d), so it can be forged.
  • ctime: last change of the inode (content, permissions, owner, rename, link count). Not settable directly; it moves to "now" whenever an attacker runs touch, which exposes timestomping.
  • atime: last read, subject to the relatime rules below.
  • dtime: set when the inode was deleted (also used for orphan handling).
  • Not proven: who performed the action (combine with auditd, shell history or logs).

Key fields

Inode fieldMeaning
i_atime, i_mtime, i_ctimeSeconds since the Unix epoch
i_crtimeBirth time, stored in the extended inode area
i_atime_extra, i_mtime_extra, i_ctime_extra, i_crtime_extraNanoseconds plus two epoch bits that push the range past 2038
i_dtimeDeletion time in seconds
i_links_count0 for deleted inodes
i_mode, i_uid, i_gid, i_sizeType, permissions, owner, size

Timestamps

All values are UTC. stat shows the birth time when coreutils, glibc and the kernel support statx (coreutils 8.31 or later on kernel 4.11 or later); debugfs always shows it.

stat --format='%n birth=%w modify=%y change=%z access=%x' /etc/passwd
debugfs -R 'stat /etc/passwd' /dev/sda1        # crtime, dtime and nanoseconds, read-only

relatime has been the default mount behaviour since Linux 2.6.30: atime is updated only when it is older than mtime or ctime, or more than 24 hours old. noatime disables atime updates entirely. Treat atime as "read at least once since roughly this time", not a precise access log. Nanosecond fields ending in all zeros on a file whose neighbours have full precision are a classic sign of timestamps set by a tool.

Retention

  • Timestamps change with normal activity; an image taken promptly preserves them.
  • On deletion ext4 sets i_dtime, drops the link count to zero and clears the inode's block or extent mapping, so the inode alone usually no longer points at the data. Directory entries may keep the name for a while.
  • Older copies of the inode can survive in the journal until it wraps, which is what journal-based recovery relies on.
  • Data blocks stay in unallocated space until reused; fstrim or discard on SSDs can erase them quickly.

Collection

Image the device read-only (dd, dc3dd or ewfacquire behind a write blocker, or a cloud/VM snapshot) and work on the copy. For live triage, UAC's bodyfile output records paths, sizes and timestamps (birth time only where its collection method can read it), and Velociraptor offers the same through its timeline artifacts. Mount images with -o ro,noload so the journal is not replayed.

Parsing

fls -r -m / -o <offset> image.raw > body.txt      # The Sleuth Kit, includes deleted names
mactime -b body.txt -d -z UTC > timeline.csv
istat -o <offset> image.raw <inode>               # full inode, times, dtime
icat -o <offset> image.raw <inode> > recovered    # content if blocks are still mapped
debugfs -c -R 'ls -d /tmp' image.raw              # deleted entries shown in <angle brackets>
ext4magic image.raw -a <epoch> -f /home/user -r -d /cases/out   # journal-based recovery

Plaso (log2timeline.py) parses the filesystem timestamps together with logs into a super timeline. ext4magic (last release 2014) and extundelete (last release 2013) are unmaintained; results vary on modern ext4 features, so validate recovered files.

Investigator tips

  • Compare crtime with mtime: a file "modified" years before it was born on this disk was copied, extracted from an archive or timestomped.
  • ctime later than every other time with a round mtime is the typical footprint of touch -d or touch -r.
  • Package-installed files get the mtime from the package, not the install time; use crtime and package manager logs for install time.
  • Deleted names in /tmp and /var/tmp are prime targets: fls -d lists only deleted entries.
  • A large number of inodes sharing one dtime indicates a scripted mass deletion; line it up with shell history and auditd.
  • Record the image's timezone assumptions: ext4 is UTC, but log files around it may be local time.

See also