Verifying Running Processes against VirusTotal - Domain-Wide

Published: 2019-06-28
Last Updated: 2019-06-28 17:51:16 UTC
by Rob VandenBrink (Version: 1)
1 comment(s)

Over the last few days we've:

What to do next?  Well, with a pool of suspect file hashes, a logical next step would be to compare them against what's in VirusTotal.  Let's see how we can automate this process.

Let's use the Posh-SSH module from the Powershell Gallery -thanks to Carlos Perez for writing this one (docs are here:

To install:
install-module -name Posh-VirusTotal

Now, we can take that next step and check all of the hashes we collected in yesterday's story (or maybe just the "most interesting" ones - the ones-ies and two-sies) against VirusTotal, to see if we're harboring any known malwer.  We'll use the Get-VTFileReport commandlet, which can take an MD5, SHA1 or a SHA256 Checksum, or a ScanID as input.  We'll use the SHA1 checksums that we've generated in the last two stories to check.

Really you could do this as a simple web request, as documented at, the request (using curl) would look like:
curl --request GET --url '<apikey>&resource=<resource>'

So before you can do anything, create a VT account and get an API key if you don't already have one (of each).

Looking at one hash, we'll run an assessment using get-VTFileReport:

The value that we're looking for is "positives".  There are a large number of AV vendors that participate on VirusTotal (66 as of today), so a score of zero indicates that they all agree that the file is benign, a score of 66 indicates that they all agree that it's malicious.  For our purposes, we'll agree that any score of 1 or greater means that we should do some research on that file and make a determination.

So let's add a member to our "InterestingHashes" object, then Loop through all of our collected "hashes of interest":

# add the VTScore member to the object, pre-populate it as an empty string
$InterestingHashes | add-member -membertype noteproperty -name VTScore -value ""
# Look through all of the hashes of interest, and see how they score on VT
ForEach-Object ($InterestingHashes) {
    $VTReport = Get-VTFileReport -APIKey <your key goes here> -Resource _$.filehash
    $_.VTScore = $VTReport.positives

Note that a public API key with VT is rate-limited to:
Request rate: 4 requests/minute
Daily quota: 5760 requests/day
Monthly quota: 172800 requests/month

Private keys don't have these limits (though I'm sure you can still exceed a counter with those as well).  So if you don't have a private API Key, add a "sleep(16)" in that loop to ensure that your rate of queries stays below 4, and keep track of your total queries.  Microsoft keeps count for you at
Private API keys can be requested here:

So when all is said and done, $InterestingHashes should have a new field called "VTScore", and the results should look like this (one listing chosen at random).

$InterestingHashes[12] | Select-Object FileHash, VTScore

FileHash                                 VTScore
--------                                 -------
BEFA5CF53D4C698FEFBB707F23D9C17D742BF0C6       0


You can of course sort these, let's do a reverse sort so any suspect files will go to the top:
$InterestingHashes | Select FileHash, VTScore | sort-Object -Property VTScore -descending

If you've gone through this exercise, did you find anything that VT flagged as possibly malicious?  If so, did that turn out to be a real piece of evil, or was it a false positive?  Please share any details that you can in our comment form.

Have a good weekend all, thanks for supporting the Internet Storm Center!

Rob VandenBrink
Coherent Security

1 comment(s)


Great article.

Just a note that Microsoft does not own VirusTotal. Google did when they acquired Hispasec Sistemas in 2012. Now it is owned by Chronicle, which is subsidiary of Google's parent Alphabet.

Diary Archives