Monday, January 31, 2005

File Version Information

Now and again, you'll find a file on your system that you don't recognize, or know nothing about. It may be sitting in the system32 directory, or anyplace else in the file system. You may find references to the file as a running process, or in one of the many autostart locations within the Registry or file system. So, how do you figure out what the file is?

There are a bunch of ways to figure these things out. While Google is a useful tool, I don't recommend starting there necessarily. Why? Well, everyone knows that files can be named anything. Well, okay...not everyone...bad guys and people who think like bad guys (security weenies) know this, but for the most part, many admins don't seem to understand this. I say this from personal experience, as well as from monitoring the various SecurityFocus lists I follow.

One of my favorite exercises in my incident response course is to copy netcat (ie, nc.exe) over to a system, and rename it to "inetinfo.exe". I then run a command line to launch the renamed netcat, bound to port 80. From the basic netstat.exe and TaskManager outputs, this looks like the IIS web server to most people.

I'm going to blog in more detail later about basic IR activities, but I wanted to take a second to present some information on looking into (literally) binary executable files (ie, file signature of 'MZ', or extensions of .exe, .dll, .sys, etc). These files will, in many cases, have file version information compiled into them, especially if they are products of commercial organizations, such as Microsoft, Symantec, etc. This information can help you narrow down "suspicious" files pretty quickly.

Below is a Perl script written using the Win32::File::VersionInfo module. This module provides convenient access to the file verison information. The script takes a file name (with complete path) as it's only argument, and attempts to retrieve the file version information. This is a basic script with limited functionality, but it is sufficient as an example.

#! c:\perl\bin\perl.exe
use strict;
use Win32::File::VersionInfo;

my $file = shift die "You must enter a filename.\n";

if (-e $file) {
if (my $ver = GetFileVersionInfo ($file)) {
print "File Version : ".$ver->{FileVersion}."\n";
print "Product Version : ".$ver->{ProductVersion}."\n";
print "OS : ".$ver->{OS}."\n";
print "Type : ".$ver->{Type}."\n";
if (my $lang = (keys %{$ver->{Lang}})[0]) {
print "CompanyName : ".$ver->{Lang}{$lang}{CompanyName}, "\n";
print "FileDescription : ".$ver->{Lang}{$lang}{FileDescription}, "\n";
print "FileVersion : ".$ver->{Lang}{$lang}{FileVersion}, "\n";
print "InternalName : ".$ver->{Lang}{$lang}{InternalName}, "\n";
print "Copyright : ".$ver->{Lang}{$lang}{Copyright}, "\n";
print "Trademarks : ".$ver->{Lang}{$lang}{Trademarks}, "\n";
print "OrigFileName : ".$ver->{Lang}{$lang}{OriginalFilename}, "\n";
print "ProductName : ".$ver->{Lang}{$lang}{ProductName}, "\n";
print "ProductVersion : ".$ver->{Lang}{$lang}{ProductVersion}, "\n";
print "PrivateBuild : ".$ver->{Lang}{$lang}{PrivateBuild}, "\n";
print "SpecialBuild : ".$ver->{Lang}{$lang}{SpecialBuild}, "\n";
}
}
}
else {
die "$file not found.\n";
}

Again, this is just a basic script, but it provides the basis for a much more extensive search utility. I ran the script on several files on my system, and here's an example output (from svchost.exe):

C:\Perl>ver.pl c:\windows\system32\svchost.exe
File Version : 5.1.2600.2180
Product Version : 5.1.2600.2180
OS : NT/Win32
Type : Application
CompanyName : Microsoft Corporation
FileDescription : Generic Host Process for Win32 Services
FileVersion : 5.1.2600.2180 (xpsp_sp2_rtm.040803-2158)
InternalName : svchost.exe
Copyright : ⌐ Microsoft Corporation. All rights reserved.
Trademarks :
OrigFileName : svchost.exe
ProductName : Microsoft« Windows« Operating System
ProductVersion : 5.1.2600.2180
PrivateBuild :
SpecialBuild :

Pretty revealing, eh? Suffice to say, another file with the same name wouldn't include the same information. Microsoft used to have a tool available called "showbinarymfr.exe" that pulled some of this information from a file, but for some reason, that tool doesn't seem to be available any longer. However, who needs showbinarymfr.exe when you can use your own tools?

4 comments:

dragon said...

Hi Harlan:

This program is great. I can't find showbinarymfr.exe and I found your blog....

Here is a tiny bug, when
my $file = shift die "You must enter a filename.\n";

I guess you'd like to write
my $file = shift or die "You must enter a filename.\n";

Have a nice day!

Keydet89 said...

Dragon,

Thanks for the comment!

Yeah, I know what you mean...I had an "||" in their, but it doesn't show up in the blog.

Thanks again, and check out some of my more recent programs...

Anonymous said...

Hi Guys,
I am trying to get the file version of an file as part of some data collection work I am doing and this module (Win32::File::VersionInfo) would be perfect - I am having problems however installing it on Windows XP + Perl 5.6.1 - does anyone have a PPD for it?
Thanks Pete

Keydet89 said...

PPM isn't working for you? I have no trouble with it at all, but I'm using Perl v 5.8...