iTerm2
iTerm2
Overview
iTerm2 is the dominant third-party terminal emulator on macOS and is nearly ubiquitous on developer and system-administrator workstations. Because those workstations are frequently the focus of insider-threat, data-exfiltration, and intrusion investigations, iTerm2's artifacts are routinely relevant to macOS forensics.
iTerm2's most forensically significant feature is Shell Integration. When enabled, iTerm2 records the commands a user runs, the directories they visit, and the remote hosts they connect to, writing them to plaintext JSON files under ~/.iterm2/. Because these files live outside the standard shell-history locations, they frequently survive anti-forensic clearing of ~/.zsh_history or ~/.bash_history — an investigator may recover a command from iTerm2's history that the user believed they had deleted.
Beyond Shell Integration, iTerm2 stores a rich configuration in its preferences plist: named profiles that often embed SSH hostnames, ports, usernames, and key paths; trigger rules that fire actions on matching terminal output; saved session state that can retain terminal buffer contents after a session ends; and Python automation scripts that reveal user workflows. The macfor plugin identifier is devtools.iterm2.
Forensic Significance
| Evidence Type | Forensic Value |
|---|---|
| Shell Integration command history | Commands executed in iTerm2, often surviving shell-history clearing |
| Directory history | Working directories the user navigated to, with timestamps |
| Remote hosts | Hostnames and usernames of systems connected to via the terminal |
| Profiles & SSH configuration | Mapped remote infrastructure: hosts, ports, usernames, key paths |
| Triggers | Automated actions — password sends, coprocesses, scripts — configured by the user |
| Saved state | Terminal buffer content (including command output) that may persist after a session ends |
| Automation scripts | Python workflows, scheduled tasks, and potentially exfiltration tooling |
| Preferences | Secure Keyboard Entry state, granted integrations, window arrangements |
Why iTerm2 Matters Forensically
macOS shell-history collection (bash, zsh, fish) captures commands the shell recorded. iTerm2 Shell Integration captures commands the terminal recorded, from a different subsystem and to different files. The two are complementary:
- A user who runs
rm ~/.zsh_historyorhistory -cclears the shell's record but not~/.iterm2/CommandHistory.json. - iTerm2 associates each command with the remote host it ran on, so commands executed over SSH inside an iTerm2 session are attributed to the correct machine — context that a bare
.bash_historyon the local disk does not provide. - iTerm2 records a use count and a last-used timestamp per command and per directory, supporting frequency analysis.
Artifact Locations
| Artifact | Path | Format |
|---|---|---|
| Command history | ~/.iterm2/CommandHistory.json | JSON array |
| Directory history | ~/.iterm2/DirectoryHistory.json | JSON array |
| Remote hosts | ~/.iterm2/RemoteHosts.json | JSON array |
| Shell integration loader | ~/.iterm2_shell_integration.{zsh,bash,fish,tcsh} | Shell script |
| Profiles, SSH config & triggers | ~/Library/Preferences/com.googlecode.iterm2.plist | Binary/XML plist (New Bookmarks array) |
| Dynamic profiles | ~/Library/Application Support/iTerm2/DynamicProfiles/*.json | JSON |
| Saved session state | ~/Library/Application Support/iTerm2/SavedState/ | Opaque binary |
| Automation scripts | ~/Library/Application Support/iTerm2/Scripts/ | Python (.py), directories |
| Application bundle | /Applications/iTerm.app or ~/Applications/iTerm.app | App bundle (version in Info.plist) |
All per-user paths are relative to each user's home directory. macfor enumerates every local user account and checks each location for each user, so a multi-user system yields per-user artifact sets.
Categories
- Command History — Shell Integration command, directory, and remote-host histories from
~/.iterm2/ - Profiles & SSH Configuration — Named profiles, embedded SSH connection details, dynamic profiles, and trigger rules from the preferences plist
- Saved State — Window and session restoration files that may retain terminal buffer content
- Automation Scripts — Python API scripts under
Scripts/that reveal user workflows
Detection
iTerm2 is present if any of the following exist:
- The application bundle at
/Applications/iTerm.appor~/Applications/iTerm.app(version read fromCFBundleShortVersionStringin the bundleInfo.plist). - The preferences plist
~/Library/Preferences/com.googlecode.iterm2.plist. - The Shell Integration directory
~/.iterm2/or a~/.iterm2_shell_integration.*loader script (indicates Shell Integration is enabled). - The Application Support directory
~/Library/Application Support/iTerm2/.
The presence of ~/.iterm2/ or a loader script is the signal that command/directory/host histories should be available. Their absence means Shell Integration was never enabled — all other artifact groups are still collected.
Timestamps
Shell Integration history files store timestamps as Unix epoch values (seconds since 1970-01-01 00:00:00 UTC), stored as floating-point numbers that may carry a fractional component. macfor converts them to RFC 3339 UTC strings in its output. File-system metadata timestamps (saved-state and script modification and creation times) come from the on-disk stat/birth-time values.
Tool Support
| Tool | Support |
|---|---|
| macfor | Full collection of Shell Integration histories, profiles/SSH/triggers, saved state, scripts, and preferences (devtools.iterm2) |
| plutil / defaults (macOS built-in) | Read the preferences plist and profiles |
| python3 / jq | Parse the ~/.iterm2/*.json history files |
| strings | Best-effort text recovery from saved-state binaries |