Skip to content

Artifact Analysis: Linux Text Editors (.viminfo, nano, less)

Vim is the ubiquitous standard editor on Unix-like systems. Its history file, .viminfo, is incredibly verbose and acts as a detailed ledger of the user’s interaction with the file system.

  • Artifact Locations: /home/<user>/.viminfo and /root/.viminfo
  • Format: A plain-text file, neatly divided into specific operational sections.

When analyzing a mounted forensic image (e.g., at /mnt/analysis/), DFIR analysts must hunt for the following specific sections within the .viminfo file:

# Command Line History (:)

Records commands typed in Vim’s command mode. Analysts will see routine commands like :wq (save and quit) or :set paste. Red Flag: Look for shell escapes like :!/bin/bash or :!curl. Attackers frequently use Vim to spawn interactive root shells (a classic GTFOBins technique) to bypass restricted environments.

# Search String History (/)

Records terms the user searched for within documents. Red Flag: Finding terms like /password, /DB_HOST, or /PRIVATE_KEY proves the attacker’s immediate intent was credential harvesting within configuration files.

# File Marks

A list of files that were opened with Vim, logging the exact absolute path and the line number where the cursor was last placed. Forensic Value: Even if the attacker cleared their .bash_history, the presence of '/etc/ssh/sshd_config here definitively proves they accessed the SSH configuration.

# Registers (Clipboard)

Vim stores deleted (x or d) or yanked/copied (y) text in registers. Forensic Value: If an attacker deletes a password from a configuration file to hide their tracks, or pastes a malicious reverse shell payload into a script, the raw text may be perfectly preserved here.

While Vim is the standard, threat actors (especially less experienced ones) may rely on simpler tools that maintain their own hidden histories.

Nano is a straightforward text editor. While it does not log file paths like Vim, it does maintain a search history.

  • Location: ~/.nano_history (or sometimes in ~/.local/share/nano/).
  • Forensic Value: Primarily records search terms. It proves the editor was used and reveals the attacker’s target keywords.

less is the standard pager command used to read files (e.g., reading logs or large configurations).

  • Location: ~/.lesshst
  • Forensic Value: Like Vim, less supports search history and, more dangerously, shell escapes. If an attacker reads /var/www/html/config.php and then types !sh inside less to spawn a shell, both the search terms ("db_password") and the shell escape command are logged here.

When a file is opened in Vim, the editor creates a hidden temporary swap file in the same directory as the target file. If Vim crashes, or if the attacker’s SSH session drops abruptly (a common occurrence with unstable C2 infrastructure), the swap file is left behind.

  • The Indicator: While listing a directory (ls -la), you observe a file named .sshd_config.swp.
  • The Implication: Someone was editing sshd_config and the session terminated uncleanly.
  • DFIR Action: The swap file contains the uncommitted, unsaved keystrokes and modifications made by the attacker. Analysts can recover these drafts using the recovery command: vim -r .sshd_config.swp.
  1. Target Web Accounts: Do not limit the search to root. Accounts like www-data or apache are highly likely to be used for modifying web pages or dropping webshells.
  2. Correlate with MAC Times: If /etc/ssh/sshd_config was modified at 14:00, and the root user’s .viminfo file was updated at 14:01 containing a file mark for that exact configuration file, you have positively attributed the file modification to that specific user session.
  3. Automate the Hunt: Use bash scripting to quickly parse these artifacts across the entire offline forensic image.
audit_editor_artifacts.sh
#!/bin/bash
TARGET_DIR="/mnt/analysis"
echo "[+] Hunting for .viminfo files across all users..."
find $TARGET_DIR/home $TARGET_DIR/root -type f -name ".viminfo" -exec echo -e "\n=== {} ===" \; -exec cat {} \;
echo "[+] Hunting for .lesshst and shell escapes..."
find $TARGET_DIR/home $TARGET_DIR/root -type f -name ".lesshst" -exec echo -e "\n=== {} ===" \; -exec cat {} \;
echo "[+] Searching for orphaned Vim swap files (.swp) in critical directories..."
find $TARGET_DIR/etc $TARGET_DIR/var/www -type f -name ".*.swp" -ls