Didier Stevens

Monday 21 May 2012

Searching With VirusTotal

Filed under: Malware,My Software — Didier Stevens @ 5:04

Did you know that you can search VirusTotal? You don’t have to submit a file, but you can search for the report of a file has been submitted before. You use a cryptographic hash (MD5, SHA1, SHA256) to identify the file.

There are several tools to submit a batch of files to VirusTotal, but I didn’t find any that just searches VirusTotal for a list of search terms via VirusTotal’s API.

Thus I wrote my own Python program. It accepts a file with a list of hashes, and produces a CSV file with the result. Here is an example displayed with InteractiveSieve:

To get this program working, you need to get a VirusTotal API key and add it to this program. You need a VirusTotal account to get your API key.

And my program respects VirusTotal’s rate limitation (4 requests per minute), I don’t want it to DoS VirusTotal.

virustotal-search_V0_0_2.zip (https)
MD5: 0d3c70213dd59cc935ed999a038237d6
SHA256: BD213BBC55A9048DBB7B890209E2831EF81049B45ABE9091E01F0692F4F23283


  1. Don’t we need the virustotal-search.pkl file to run your script ?

    Comment by kqkq — Monday 21 May 2012 @ 9:17

  2. No, that file is created by the script and persists the query results.

    Comment by Didier Stevens — Monday 21 May 2012 @ 14:51

  3. File “C:\virustotal-search.py”, line 191, in VirusTotalSearch
    reports = DeSerialize()[‘reports’]
    TypeError: ‘NoneType’ object is unsubscriptable

    Any ideas on the following error?

    Comment by exo — Tuesday 22 May 2012 @ 7:22

  4. Is the name of the hash for Virus Total, based on the name of the uploaded file, its size, or the physical content(s) within? It would be great to be able to file hash incoming data to a network and block it before reaching the internal networks, but wouldn’t you have to hash the files in the same manner as Virus Total to get properly matching results?

    Comment by DigiP — Tuesday 22 May 2012 @ 13:46

  5. Hello, I got this error when I tried running the script. Could you please help? Thank you very much. I’m a newbie in python 😦

    Traceback (most recent call last):
    File “virustotal-search.py”, line 217, in
    File “virustotal-search.py”, line 214, in Main
    VirusTotalSearch(args[0], options)
    File “virustotal-search.py”, line 190, in VirusTotalSearch
    reports = DeSerialize()[‘reports’]
    TypeError: ‘NoneType’ object is unsubscriptable

    Comment by Anonymous — Wednesday 23 May 2012 @ 0:33

  6. I can’t create virustotal-search.pkl.
    To run this script. What I need to create .pkl-file?
    sorry. I’m not english native speaker.

    Comment by Anonymous — Wednesday 23 May 2012 @ 7:53

  7. Sorry all, I posted a wrong version. Will try to fix in coming days.

    Comment by Didier Stevens — Wednesday 23 May 2012 @ 10:27

  8. Hello,
    I’m not sure if my understanding with the code is right but it seems that the pickle file needs to be created first by calling Serialize function and the reports identifier needs to be declared as well.

    I managed to run the script successfully by inserting this two lines before “reports = DeSerialize()[‘reports’] is called, i guess before line 191

    reports = {} # declaring it as a dict
    Serialize({‘reports’: reports}) # creating/initializing the pickle pile

    Hope this helps.

    However, the produced csv file does not seemed to be in the right format, minor issue perhaps

    Thanks for sharing the code.

    Comment by MountFranklin — Wednesday 23 May 2012 @ 23:25

  9. @MountFranklin Thanks, but I just released a fix: version 0.0.2

    Comment by Didier Stevens — Thursday 24 May 2012 @ 15:17

  10. @DigiP VirusTotal hashes the content of the file and uses that as a key. md5, sha-256

    Comment by Didier Stevens — Thursday 24 May 2012 @ 15:18

  11. No issues. Apparently in my test, the csv report is breaking on this malware md5hash ‘4912c0ce8c03c2b28a70e6a8a67355aa’. Next to the ‘.AO#’ char.

    Comment by MountFranklin — Friday 25 May 2012 @ 4:50

  12. @MountFranklin Can you be more specific on this breaking? I’ve searched the MD5 you mentioned, and I can open the produced CSV report in Excel 2010 without problems.

    Comment by Didier Stevens — Friday 25 May 2012 @ 23:00

  13. […] didn’t expect my virustotal-search program to be that popular, so here is a new version with new features and a few fixes (version 0.0.1 […]

    Pingback by Update: virustotal-search « Didier Stevens — Wednesday 30 May 2012 @ 9:04

  14. Hi Didier,

    Great code, my python skill are not up to your standards!
    I find it very usefull to find reports related to hashes. Though I was missing one feature. That is to be able to find a report for a binary without having t manually create one Therefor I’ve added a ‘-f –file’ flag. This makes the program expect to hash the file before using it as a searchTerm. Works great. Check it out: http://pastebin.com/aEpr5i6q

    Comment by TecToDo — Monday 4 June 2012 @ 1:36

  15. @TecToDo Thanks for the new feature, but there’s a small issue, I’ve released an update last week with option -f (–force) to force queries to be send to VirusTotal.
    So I can’t use -f for file.

    Comment by Didier Stevens — Monday 4 June 2012 @ 17:35

  16. […] Searching With VirusTotal VirusTotal API를 이용해 질의하고 결과를 얻는 도구다. […]

    Pingback by [May 2012] FI Newsletter | FORENSIC INSIGHT — Friday 8 June 2012 @ 5:29

  17. […] to Didier Stevens for his tool to upload a batch of files on Virustotal.com and get the results in a proper format. […]

    Pingback by Honeypot results May 2012 — Sunday 10 June 2012 @ 10:22

  18. […] to Didier Stevens for his tool to upload a batch of files on Virustotal.com and get the results in a proper format. […]

    Pingback by Honeypot results June 2012 | SimonGaniere.ch — Sunday 8 July 2012 @ 2:24

  19. Hi Didier Stevens,

    Thanks for sharing this awesome script. Im a newbie in python scripts.

    I keyed in my API key in your script and executed it with sample MD5 hashes.

    Somehow I get this message:

    Any idea what can I do to fix this?

    Comment by Anand Aherkar — Thursday 3 July 2014 @ 8:00

  20. Which version do you use? Is it the latest?

    Comment by Didier Stevens — Thursday 3 July 2014 @ 15:12

  21. Cheers tried this just now, working a treat. Thanks for supplying it.

    Comment by Johnny J — Thursday 12 May 2016 @ 14:39

RSS feed for comments on this post. TrackBack URI

Leave a Reply (comments are moderated)

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Blog at WordPress.com.