Today I Learned - Zsh Sessions (even more Timestamps)

Table of Contents

Zsh Sessions

In a previous blog post (Today I Learned - Zsh History Timestamps), we discussed how Zsh records commands entered in the shell along with a timestamp, provided that the session remains open. This is useful for live response scenarios if we still have access to the session and can run commands like fc -lf or fc -li 100. However, Zsh also utilizes the .zsh_sessions directory, located at the root level of the user’s home directory. Here’s an excerpt from my .zsh_sessions directory:

52B May 15 21:50 8300FB5D-3D4F-4805-9F30-CE7A1A3685D8.session
31K May 15 21:50 8300FB5D-3D4F-4805-9F30-CE7A1A3685D8.history
52B May 16 09:11 03955FF6-41A0-437D-B4E9-93A0BBB29F20.session
31K May 16 09:11 03955FF6-41A0-437D-B4E9-93A0BBB29F20.history
52B May 16 11:47 53517CEE-640B-4445-98BD-1A4BEE3FB463.session
31K May 16 11:47 53517CEE-640B-4445-98BD-1A4BEE3FB463.history

Each .history file corresponds to a .session file with the same timestamp. The most current file within that folder has the extension .historynew, and no associated .session file.

0B May 16 20:21 9C83F55C-D97C-430E-A4AE-030AC62F7E14.historynew

The environment variable $HISTFILE tracks the most recent file:

% echo $HISTFILE
/Users/malmoeb/.zsh_sessions/9C83F55C-D97C-430E-A4AE-030AC62F7E14.historynew

The identifier (filename) is known as TERM_SESSION_ID, which is generated when a session starts and remains constant throughout the session’s lifetime:

% echo $TERM_SESSION_ID
TERM_SESSION_ID=9C83F55C-D97C-430E-A4AE-030AC62F7E14

Forensic values

Beyond the .zsh_history file, we have additional sources to view executed commands. This is beneficial if an attacker manually deletes the .zsh_history file.

% head 53517CEE-640B-4445-98BD-1A4BEE3FB463.history
cat * | cut -d"," -f1-10 | head
[...]

As described above, each .history file has a corresponding .session file with the same TERM_SESSION_ID. The .session file contains a timestamp indicating when the terminal was reopened:

% cat 53517CEE-640B-4445-98BD-1A4BEE3FB463.session
echo Restored session: "$(/bin/date -r 1715852825)"

And we have a timestamp (Thu May 16 2024 09:47:05 UTC). 🥳 While it may not offer the detailed granularity of timestamps from a live terminal session (fc -lf), it still helps to narrow down the timeframe better (when the commands were executed) than the history file alone.


What I learned today: Short blog posts about novel information for me.