The Powershell Diaries 2 - Software Inventory

Published: 2015-06-29
Last Updated: 2015-06-29 12:17:47 UTC
by Rob VandenBrink (Version: 1)
5 comment(s)

After last week's story, hopefully you've got your "problem" users accounts identified.  With that worked out, let's see about finding problem applications.

We all need a handle on what applications are installed on workstations for a number of reasons

  • to make sure that when upgrade time comes, that nobody gets left behind
  • that older apps that have security vulnerabilities or have limited function get taken care of - old versions of putty or Java for instance
  • that users don't install applications that the organization hasn't paid for
  • and finally, it's a decent shot at finding installed malware that your AV product might have missed.

First, let's look at the powershell command to list installed software.  This is a rough equivalent of control panel / programs, or "wmic product list"

Get-WmiObject -Class Win32_Product -computername

If you run this, you'll see that this is *really* verbose (I won't show the output), and the list view is not so useful.  Let's trim it down to Vendor, Product Name and Version:

Get-WmiObject -Class Win32_Product -computername . | select vendor, name, version | format-table

or, to make the display more useful, replace "format-table" with "out-gridview" or "output-csv" as we discussed last week:

But that just gives us programs that use the Microsoft installer process to install (msi's and similar packages).  How about single exe type apps, things like putty.exe, sed.exe and so on?  We can address those file by file:

get-childitem sed.exe | fl

Name           : sed.exe
Length         : 186880
CreationTime   : 9/4/2012 1:33:52 PM
LastWriteTime  : 3/31/2009 3:32:34 PM
LastAccessTime : 9/4/2012 1:33:52 PM
VersionInfo    : File:             C:\sed.exe
                 InternalName:     sed
                 OriginalFilename: sed
                 FileVersion:      10.0.7063.0
                 FileDescription:  SUA Utility
                 Product:          Microsoftr Windowsr Oper
                 ProductVersion:   10.0.7063.0
                 Debug:            False
                 Patched:          False
                 PreRelease:       False
                 PrivateBuild:     True
                 SpecialBuild:     False
                 Language:         English (United States)

 

But we want a table view, and again just a few of those fields.  The name, the original name (to account for users renaming EXE files), the file and application versions, and maybe the publisher.  Some of these are a bit tricky to get, as they're lower down in the heirarchy of the object, but it's very do-able:

get-childitem ssh.exe | format-list name,creationtime,lastwritetime,@{label="ProductVersion";expression={$_.versioninfo.productversion}},@{label="FileVersion";expression={$_.versioninfo.fileversion}},@{label="Original FileName";expression={$_.versioninfo.originalfilename}}

Name              : ssh.exe
CreationTime      : 5/30/2011 4:50:57 PM
LastWriteTime     : 8/6/2013 6:12:44 PM
ProductVersion    : Release 0.63
FileVersion       : Release 0.63
Original FileName : PuTTY

 

OOOPS - looks like I'm a rev back on putty!  - note that I renamed putty to ssh, but the file metadata remembers the original name for me

This also works for more legitimate apps (excel is shown here):

get-childitem excel.exe | format-list

    Directory: C:\Program Files (x86)\Microsoft Office\Office14

 

Name           : excel.exe
Length         : 20400288
CreationTime   : 5/22/2015 7:11:54 PM
LastWriteTime  : 5/22/2015 7:11:54 PM
LastAccessTime : 6/11/2015 3:58:19 PM
VersionInfo    : File:             C:\Program Files (x86)\Microsoft
                 Office\Office14\excel.exe
                 InternalName:     Excel
                 OriginalFilename: Excel.exe
                 FileVersion:      14.0.7151.5001
                 FileDescription:  Microsoft Excel
                 Product:          Microsoft Office 2010
                 ProductVersion:   14.0.7151.5001
                 Debug:            False
                 Patched:          False
                 PreRelease:       False
                 PrivateBuild:     False
                 SpecialBuild:     False
                 Language:         Language Neutral

Great, you say, how is inventorying things one file at a time useful?  Let's use get-childitem recursively and pull all the EXE's in one shot.  This is a reasonable way to grab everything.  With that in a spreadsheet or database, you'll likely want to delete duplicates entries (multiples for MS Office for instance), then after a closer look, store that as a baseline to track for changes at a later date.

get-childitem c:\*.exe -recurse | format-table name,creationtime,lastwritetime,@{label="ProductVersion";expression={$_.versioninfo.productversion}},@{label="FileVersion";expression={$_.versioninfo.fileversion}},@{label="Original FileName";expression={$_.versioninfo.originalfilename}},@{label="Product";expression={$_.versioninfo.product}}

Or, better yet, using a slightly different script and outputting to CSV - so you can more easily read it in excel or dump it to a database:

Get-ChildItem -Path c:\utils\*.exe -Recurse |`
foreach{
$Item = $_
$Filename = $_.Name
$Ver = $_.versioninfo.productversion
$filever = $_.versioninfo.fileversion
$Age = $_.CreationTime
$originalname = $_.versioninfo.originalfilename
$product=$_.versioninfo.product

$Path | Select-Object `
    @{n="Name";e={$Filename}},`
    @{n="FilePath";e={$Item}},`
    @{n="Original Name";e={$originalname}},`
    @{n="Created";e={$Age}},`
    @{n="Product Ver";e={$product}},`
    @{n="File Ver";e={$filever}}`
}| Export-Csv d:\sans\Results.csv -NoTypeInformation

 

 

Note that not all values are populated in the metadata for every file - that's just the way it is when you're processing standalone files like this.

Using this approach, you can see that with maybe an afternoon of scripting effort, you can set up a system that you might otherwise pay thousands or tens of thousands of dollars for - assuming that you're OK running your software inventory system from the CLI.  For me, running my inventory from the CLI would be prefered, but I guess you figured that out !

Have you found a trick to process information like this more efficiently?  Got a better script to collect this info more simply?  Please, share using our comment form!

===============
Rob VandenBrink
Metafore

5 comment(s)
ISC StormCast for Monday, June 29th 2015 http://isc.sans.edu/podcastdetail.html?id=4547

Comments

What's this all about ..?
password reveal .
<a hreaf="https://technolytical.com/">the social network</a> is described as follows because they respect your privacy and keep your data secure:

<a hreaf="https://technolytical.com/">the social network</a> is described as follows because they respect your privacy and keep your data secure. The social networks are not interested in collecting data about you. They don't care about what you're doing, or what you like. They don't want to know who you talk to, or where you go.

<a hreaf="https://technolytical.com/">the social network</a> is not interested in collecting data about you. They don't care about what you're doing, or what you like. They don't want to know who you talk to, or where you go. The social networks only collect the minimum amount of information required for the service that they provide. Your personal information is kept private, and is never shared with other companies without your permission
https://thehomestore.com.pk/
<a hreaf="https://defineprogramming.com/the-public-bathroom-near-me-find-nearest-public-toilet/"> public bathroom near me</a>
<a hreaf="https://defineprogramming.com/the-public-bathroom-near-me-find-nearest-public-toilet/"> nearest public toilet to me</a>
<a hreaf="https://defineprogramming.com/the-public-bathroom-near-me-find-nearest-public-toilet/"> public bathroom near me</a>
<a hreaf="https://defineprogramming.com/the-public-bathroom-near-me-find-nearest-public-toilet/"> public bathroom near me</a>
<a hreaf="https://defineprogramming.com/the-public-bathroom-near-me-find-nearest-public-toilet/"> nearest public toilet to me</a>
<a hreaf="https://defineprogramming.com/the-public-bathroom-near-me-find-nearest-public-toilet/"> public bathroom near me</a>
https://defineprogramming.com/
https://defineprogramming.com/
Enter comment here... a fake TeamViewer page, and that page led to a different type of malware. This week's infection involved a downloaded JavaScript (.js) file that led to Microsoft Installer packages (.msi files) containing other script that used free or open source programs.
distribute malware. Even if the URL listed on the ad shows a legitimate website, subsequent ad traffic can easily lead to a fake page. Different types of malware are distributed in this manner. I've seen IcedID (Bokbot), Gozi/ISFB, and various information stealers distributed through fake software websites that were provided through Google ad traffic. I submitted malicious files from this example to VirusTotal and found a low rate of detection, with some files not showing as malware at all. Additionally, domains associated with this infection frequently change. That might make it hard to detect.
https://clickercounter.org/
Enter corthrthmment here...

Diary Archives