Threat Level: green Handler on Duty: Rob VandenBrink

SANS ISC: Internet Storm Center - SANS Internet Storm Center Internet Storm Center

Sign Up for Free!   Forgot Password?
Log In or Sign Up for Free!

Latest Diaries

The Other Side of CIS Critical Control 2 - Inventorying *Unwanted* Software

Published: 2019-06-26
Last Updated: 2019-06-26 18:41:00 UTC
by Rob VandenBrink (Version: 1)
2 comment(s)

When I work with clients and we discuss CIS Critical Control 2, their focus is often on inventorying their installed software.  Today we'll talk about inventorying software that you didn't install.  Malware is typically the primary target in that “we didn’t install that software” list.

The method we're looking at today will inventory the running processes across the enterprise, and we'll look at how to "sift" that information to find outliers - applications that are running only one or two (or 5 or 10%, whatever your cutoff is) of hosts.  Note that this is hunting for *running* software, not software that was installed with a traditional MSI file, so this does a good job of finding malware, especially malware that hasn't spread too far past its initial infection hosts yet.

OK, let's look at the base code.  We're basically running get-process, getting the path on disk for that process, then hashing that file on disk.  If the hash operation errors out (which it will for file-less malware for instance), that file is saved to an error log.  The hash is the key item, it uniquely identifies each file, even if malware has replaced a known filename the hash will be different on that station.  You can then use this hash to reference back to malware IOCs if that's helpful.  Note that the hash in this case is SHA1 - you can change this to meet whatever your hashing requirements are, or add a few different hashing algorithms if that works better for you.

# collect the process list, then loop through the list
$proc = @()
Foreach ($proc in get-process)
        # hash the executable file on disk
        $hash = Get-FileHash $proc.path -Algorithm SHA1 -ErrorAction stop
         # error handling.  If the file can't be hashed - either it's not there or we don't have rights to it
        $, $proc.path | out-file c:\temp\proc_hash_error.log -Append

We'll then run our script across the entire organization, and save both the process data and the errors in one set of files. Because we're hashing the files, its likely better (and certainly much faster) to run this operation on the remote systems rather than opening all the files over the network to hash them.

Note that when we do this we’ll be logging the error information out to a remote share.

function RemoteTaskList {
# collect the process list, then loop through the list

$proc = @()
$wsproclist = @()
Foreach ($proc in get-process)
        # hash the executable file on disk
        $hash = Get-FileHash $proc.path -Algorithm SHA1 -ErrorAction stop
        $p = $proc
        $p | add-member -membertype noteproperty -name FileHash -value $hash.hash
        $p | add-member -membertype noteproperty -name HashAlgo -value $hash.Algorithm
        $wsproclist += $p
         # error handling.  If the file can't be hashed - either it's not there or we don't have rights to it
         # note that you will need to edit the host and share for your environment
        $env:ComputerName,$,$proc.path | out-file \\loghost\logshare\hash_error.log -Append

$targets =get-adcomputer -filter * -Property DNSHostName
$DomainTaskList = @()
$i = 1
$count = $targets.count

foreach ($targethost in $targets) {
   write-host $i of $count -  $targethost.DNSHostName
   if (Test-Connection -ComputerName $targethost.DNSHostName -count 2 -Quiet) {
       $DomainTaskList += invoke-command -ComputerName $targethost ${function:RemoteTaskList}

$DomainTaskList | select-object PSComputerName,Id,ProcessName,Path,FileHash,FileVersion,Product,ProductVersion, HashAlgo | export-csv domain-wide-tasks.csv

With that CSV file exported, you can now look at the domain-wide list in Excel or any tool of your choice that will read a CSV file.

Rob VandenBrink
Coherent Security

2 comment(s)

If you have more information or corrections regarding our diary, please share.

Recent Diaries

Rig Exploit Kit sends Pitou.B Trojan
Jun 25th 2019
2 days ago by Brad (0 comments)

Extensive BGP Issues Affecting Cloudflare and possibly others
Jun 24th 2019
2 days ago by Johannes (0 comments)

Netstat Local and Remote -new and improved, now with more PowerShell!
Jun 21st 2019
6 days ago by Rob VandenBrink (0 comments)

Using a Travel Packing App for Infosec Purpose
Jun 20th 2019
6 days ago by Xme (0 comments)

View All Diaries →

Latest Discussions

Entrust resolving to CNAME that is an invalid CDN host
created Jun 10th 2019
2 weeks ago by jauntysankey (0 replies)

Outlook Forms (
created May 31st 2019
3 weeks ago by MasterYoshi (0 replies)

McAfee - Trenmicro - Symantec Breached by Fxmsp hackers
created May 14th 2019
1 month ago by DrGreen (0 replies)

Domain registration date plugin for email?
created Mar 30th 2019
2 months ago by Anonymous (1 reply)

Run Extracted binaries from mirror traffic on cuckoo
created Feb 6th 2019
4 months ago by ching (1 reply)

View All Forums →

Latest News

View All News →

Top Diaries

Wide-scale Petya variant ransomware attack noted
Jun 27th 2017
1 year ago by Brad (0 comments)

Using a Raspberry Pi honeypot to contribute data to DShield/ISC
Aug 3rd 2017
1 year ago by Johannes (0 comments)

Second Google Chrome Extension Banker Malware in Two Weeks
Aug 29th 2017
1 year ago by Renato (0 comments)

Detection Lab: Visibility & Introspection for Defenders
Dec 15th 2017
1 year ago by Russ McRee (0 comments)

Maldoc with auto-updated link
Aug 17th 2017
1 year ago by Xme (0 comments)