A collection of scripts built for reading windows event log files.
This document serves as an overview to using the GrokEVT suite of tools. Please see the man pages for each tool for specific command-line options.
Using GrokEVT on a set of windows partitions is a three stage process. One must first mount the partitions and configure the system's profile. Next, grokevt-builddb(1) must be run to extract the necessary information from these partitions. Finally, grokevt-parselog(1) may be run to use this information to convert the logs to something useful.
Mounting and configuration:
This is the most labor-intensive step of the process. There are several technical reasons why this cannot be simpler, and it is unlikely many will be resolved anytime soon. (Sorry, blame the vendor who produced these logs that you wish to convert.)
First mount the partitions used by your windows system. Specifically, mount any partition that has software installed on it. (You can probably get away with not mounting ones with no software, or no software that produces events in the event log.) This includes windows shares, if you have any with software installed on them.
The key point when mounting partitions or shares, is that you must mount them with case-insensitive filenames. To do this in Linux, you should be able to use the NTFS option 'posix=0', or with type vfat this appears to be the default. On FreeBSD, one can use the -i option with NTFS and mount_ntfs, but this hasn't been tested. (More research is necessary in this area. Please let me know if case-insensitivity is available on other *NIXes and what the options are.) All of this, of course, depends on your version of mount and related software. See mount(8) for more information.
Once you have all necessary filesystems mounted for your windows image, you need to configure GrokEVT so it knows where everything is. If you look in the main configuration directory, (by default at '/usr/local/etc/grokevt') you'll find a sub-directory called 'systems'. In there is a set of system configuration profiles. Each directory under 'systems' represents the configuration for a single windows host. You may create directories here of any name. It is suggested you use the host name of the system you wish to extract logs from.
By default, there will be one system configuration there already, named 'example'. I suggest you make a full copy of this, and edit it from there to create your own configuration:
\*(T< # cd /usr/local/etc/grokevt/systems # cp -r example mysystem \*(T>
Now that you have your own configuration, take a look at the files under this directory:
\*(T< path-vars/%SystemRoot% system-registry drives/c: drives/d: \*(T>
Each file represents a single configuration setting. The first line of every file is the setting, all others are ignored. You should start by configuring your drive letters. These drive letters need to map to the *NIX path of the drives. So, if you mounted your C: partition under '/mnt/win/c', then you should do the following:
\*(T< echo /mnt/win/c > drives/c: \*(T>
This will of course, overwrite that file with your actual mount point for the C: drive. Do this for all drives mounted on your windows system.
Next, you need to configure your %SystemRoot% path variable. Since the registry often references files in relation to this variable, we need to know where it is on your system. Typically, on W2K this should be 'C:\WINNT'. On other windows systems it is often 'C:\Windows'. This path may be referenced as a full windows path (with drive letters) or as a *NIX path.
Finally, you need to set the path of the system registry. This path must be a *NIX path, and not a windows path. It should be located under your %SystemRoot%. For instance, if you mount a W2K machine's C: on '/mnt/win/c', this path will probably be: /mnt/win/c/WINNT/system32/config/system
This will vary from system to system, but if you have ever done any forensics, you should be able to find the correct path pretty quickly.
Once you get past the mounting and configuration step, you're in good shape. To extract the necessary information from the system you just mounted, you just need to decide where you want to store the output database. Based on the example paths above, one could run grokevt-builddb(1) like so:
\*(T< grokevt-builddb mysystem /var/db/grokevt/mysystem \*(T>
Or something similar. This step will take some time, as a lot of files need to be parsed. You will likely get some warnings about missing DLLs and possibly service removals. This is normal if software on the windows system failed to clean up the registry correctly when it was un-installed. You might want to record this information though, if later you find you are missing a lot of message templates in your log output.
Now that you have finished this step, you have fully extracted all information needed to interpret the event logs.
\*(T< grokevt-parselog -l /var/db/grokevt/mysystem \*(T>
This will print out all available event log types, based on information found previously in the system's registry. Then you may view one of those logs simply by dropping the -l option, and adding it's name as the second parameter. For instance, to view the 'System' log:
\*(T< grokevt-parselog /var/db/grokevt/mysystem System \*(T>
See the grokevt-parselog(1) man page for further options.
Finding and Parsing Log Fragments:
One may find it useful to parse deleted log files or fragments of log files found in a system's RAM dump. A special-purpose tool, grokevt-findlogs(1) is included in this distribution which makes finding log fragments easy. It can find even a single log record by itself with a relatively low rate of false positives.
Suppose one has a file, dump.img, which contains an image of a system's RAM, or perhaps the unallocated blocks of a filesystem (as might be produced by The SleuthKit's dls(1)). One could search this dump by running:
\*(T< grokevt-findlogs dump.img \*(T>
This will produce a listing of all hits in the file, which may include header records, cursor records, or log records, offsets and contiguity information to help one eliminate any false positives.
Supposing we found a log fragment in this dump that we're interested in, we could simply use dd(1) or some other tool to carve out the relevant data in to a file named fragment.evt. We'd then need to find a way to associate this log with a set of message templates. This is what grokevt-addlog(1) is for. Let's take a guess that the fragment.evt was originally a part of System log. We would add the log into our previously built message database by running:
\*(T< grokevt-addlog /var/db/grokevt/mysystem fragment.evt System-fragment System \*(T>
Finally, we can parse the log by simply specifying the newly imported name with grokevt-parselog(1):
\*(T< grokevt-parselog /var/db/grokevt/mysystem System-fragment \*(T>
If we found that most of the log entries didn't have associated message templates (which would result in lots of warnings to stderr), we would be pretty that fragment.evt really wasn't based on a System log. Simply re-importing it as another log type (and a different name) would let us parse it again as if it were of another type.
This man page written by Timothy D. Morgan
Please see the file "LICENSE" included with this software distribution.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License version 2 for more details.