Verifying Running Processes against VirusTotal - Domain-Wide
Over the last few days we've:
- Collected all of the running processes in the Domain, and computed the hashes for the executable files
- Looked for "outliers" in file hashes
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: https://www.powershellgallery.com/packages/Posh-VirusTotal/1.3)
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 https://developers.virustotal.com/reference#file-report, the request (using curl) would look like:
curl --request GET --url 'https://www.virustotal.com/vtapi/v2/file/report?apikey=<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 |
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 https://www.virustotal.com/gui/user/YourUseridGoesHere/apikey.
Private API keys can be requested here: https://www.virustotal.com/gui/contact-us/premium-services
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 |
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
Comments