Forensic Relevance of Vim Artifacts

In this post, I am going to be taking a closer look at the artifacts associated with the popular text-editor software known as ‘Vim’ to see if they have any forensic relevance when conducting a forensic investigation on a machine it has been installed on.

.

Introduction to Vim

Vim is available on most modern Operating Systems in different flavours, for example; MacVim for OS X and gVim for Windows. However, I would argue that Vim is much more prevalent and widely known on Unix Operating Systems and thus this post will focus primarily on the latest Linux command-line version of Vim. However, I will briefly touch upon two Windows-specific implementations of Vim.

For those who have never heard of Vim; it is simply a text-editor that can be used either from the command-line (traditional Vim) or with a graphical user interface (gVim). Vim derives its name from the older ‘vi’ editor, of which it is considered to be an improvement on, hence: “Vi IMproved”.

As a side note; this post is not intended to be a tutorial on how to use the Vim text-editor and its powerful command-set, however if you would like to learn more about Vim; I will leave some resources I personally found helpful at the end of this post.

.

Files associated with Vim

On a Unix system, Vim is generally very easy to install as it should be included in most distributions base repositories. Simply run your desired package managers install command as a privileged user, which could be something like:

  • apt-get install vim
  • dnf/yum install vim
  • pacman -S vim
  • zypper install vim

To demonstrate, I created a fresh KVM virtual machine for a minimal installation of Fedora 26 and ran the following commands:

  • dnf update
  • dnf install vim

This installed the latest vim-enhanced package (Version 8.0.1171 at time of writing) along with several other dependencies. One of the first things you may notice is that this will generate a hidden file (a file prepended with the ‘.’ character) in the users home directory (in my case this was the root user at /root/) called ‘.viminfo’. Interestingly, this file was created and populated with data before running any command with Vim, although it should be noted that the data was informational only and nothing of forensic value as of yet:

Figure 1 – .viminfo on Fedora Virtual Machine

The .viminfo file, according to the official documentation is a special file used to remember information that would otherwise be lost when exiting vim. It essentially operates like a cache file in which vim persistently stores buffer information. From the documentation (and Figure 1) we can also learn exactly what is supposed to populate this file:

  • The command line history
  • The search string history
  • The input-line history
  • Contents of non-empty registers
  • Marks for several files
  • File marks, pointing to locations in files
  • Last search/substitute pattern
  • The buffer list
  • Global variables

A couple of these entries peaked my interest when I first saw this, particularly the search string history and the file marks because at face value, I would consider those to be of higher forensic value then the others.

The command line history is one of the five history tables and consists of a list of the most recently used ‘:’ commands within Vim. On Linux systems, this information includes the full command itself and an epoch timestamp of when the command was run. The two most likely Vim commands you will find in this history table are ‘:q’ and ‘:wq’, which exit and save+exit respectively. According to the official documentation; by default .viminfo stores the last 20 commands and repeated commands replace old ones.

The search string history is another of the five history tables and consists of a list of the most recent search terms that were queried in Vim. Searching for a string in a file opened with Vim is invoked by typing the ‘/’ character when in command mode, followed by your search term. Like the command-line history table, on Linux systems; this history table will show the string that was searched for in the file as well as an epoch timestamp.

The input-line history is another history table, this time consisting of input lines, typed for the input() function. This history table is populated when a user calls a function made executable in a script within the Vim file. On Linux systems; the history table will display the string that was input into the function as well as its associated epoch timestamp.

Contents of non-empty registers is a list of special registers that Vim dynamically fills with text within a file that has been deleted with the ‘d’, ‘c’, ‘s’, ‘x’ commands, or copied with the yank (‘y’) command. Vim uses the contents of the unnamed register for any put (‘p’ or ’P’ aka paste) command. On Linux systems, this section consists of the text that the registers were filled with, along with an epoch timestamp.

File marks are among the last items in most .viminfo files and essentially consist of a list of files that have been opened with Vim. A ‘mark’ allows a user to record their location in a file they were editing, like a bookmark of sorts, which they can jump back to. On Linux systems, the “History of marks within files” section of .viminfo records the last 20 files that were opened using the Vim editor, along with their file path (relative to the user) and epoch timestamp.

If you are an avid user of Vim, another hidden file you may have encountered in a users home directory is called ‘.vimrc’. This file is not created upon installation or even usage of traditional Vim, it has to be manually created and populated by a user. The .vimrc file is used to configure runtime settings to initialize when Vim starts. For example; if you use Vim to edit source code, you probably want line numbers enabled, so you could write the string ‘:set nu’ to the .vimrc file to save you having to run the command every-time you open a file in Vim.

I would not consider the contents of a .vimrc file to be of particular interest as they should simply be a list of Vim commands to be executed at runtime. However, because each user on a Unix system receives their own unique .viminfo file, a .vimrc file for a particular user could indicate that they are quite proficient with Vim and potentially use it a lot more than other text editors. Thus increasing the possible forensic value of their individual .viminfo file.

.

Forensic Relevance of these files

As you may have gathered, the contents of a users .viminfo file do contain some forensic value. On Linux systems, we can gather the following information:

  • The path names for files that have been recently opened with Vim, which remain in the .viminfo file even if the original file is deleted or wiped from the system.
  • The search string history can provide some interesting insight into the users activity on the system and may contain information such as passwords, names, places, etc.
  • A timeline of activity can be formed using the epoch timestamps provided from each section described above.

Obviously, this information is not going to bust a case wide open, but can be used as a supplement to other data of evidentiary value, akin to finding remnants of past files and applications in Windows using LNK/prefetch files. Additionally, the .viminfo file will persist on the system even if the Vim package is removed.

Ultimately, I would say for any examiner performing an investigation on a Linux system that the existence of the .viminfo file should not be ignored and analysed for any relevant forensic data.

.

Windows Implementations of Vim

Originally, I was going to limit this post to only covering artifacts of Vim for the traditional Unix version of the program, however I happened upon a Windows machine and was able to test two implementations of Vim for Windows 10, which are:

  • gVim
  • Vim for the Bash subsystem

Starting with the GUI version of Vim for Windows; gVim, during the installation phase, the program presents you with the option to create the ‘_vimrc’ file if it does not exist. I left all the options as their default value and the program was installed to the following file path:

        C:\Program Files (x86)\Vim\

Figure 2 – gVim installation directory contents

The _vimrc file is stored in this directory. However, the viminfo file (called ‘_viminfo’ in gVim) is not installed to this directory and instead can be found in:

        C:\Users\<username>\

Unlike the Unix version, the viminfo file was not created when gVim was installed, instead, _viminfo was only generated after being run for the first time:

Figure 3 – gVim first run on Windows 10

This also interestingly runs Vim version 8.0. After running gVim for the first time and subsequently exiting the program, my _viminfo file was generated in the aforementioned directory path and looked like this:

Figure 4 – Contents of _viminfo after first run

As you can see, the information contained within _viminfo is exactly the same as the Vim package on Unix, including all of the information that we determined to be of forensic value in .viminfo. This includes the epoch timestamps and the relative file paths.

It should also be noted that all files created with gVim are stored in the following directory by default:

         C:\Program Files (x86)\Vim\vim80\

Finally, I took a look at the Bash subsystem for Windows 10 (specifically the Ubuntu variant), which I downloaded and launched from the Microsoft store. I was prompted to create a user I called ‘test’, after which it logged me into the subsystem. The first thing I noticed from querying the package information was that a legacy version of Vim (7.0) was installed by default and the ‘.viminfo’ file was NOT present in either the test user or root users home directories.

Upon running Vim against a file, the .viminfo file was subsequently created and populated for the user I was currently logged in as, which was root at the time.

Figure 5 – Existence of .viminfo on subsystem after first use
Figure 6 – Contents of .viminfo on subsystem after first use

Figure 6 shows the contents of the .viminfo file on the Ubuntu subsystem, which contains the same information as seen previously, with one major caveat. You may have noticed that there are no epoch timestamps present in the .viminfo file and this is because the subsystem is not using the latest version of Vim (8.0 is the latest at the time of writing).

However, this does not make the file completely irrelevant from a forensic perspective, as it still contains pathnames for files opened by Vim as well as the search string history.

As mentioned at the start of this post: here are some useful resources I found invaluable when I first started learning the vast functionality and usage of the Vim command-set:

Vim Tips Wiki
Vim Cheat Sheet
Vim Tricks

Thank you for reading and I hope this information has taught you something new!

If you have any questions about this post, please email me using the form in the ‘Contact’ section at the top of the page.