Didier Stevens

VirusTotal Tools

virustotal-search.py is a Python program to search VirusTotal for hashes.

virustotal-submit.py is a Python program to submit files to VirusTotal.

To get these tools to work, you need to get a VirusTotal API key and add it to these program. You need a VirusTotal account to get your API key.

virustotal-search

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:

virustotal-search.py supports proxies (Python variables HTTP_PROXY and HTTPS_PROXY or environment variables http_proxy and https_proxy).

And my program respects VirusTotal’s rate limitation (4 requests per minute), I don’t want it to DoS VirusTotal.
virustotal-search_V0_1_2.zip (https)
MD5: 62C8031738E6E20FEC38337010496DF6
SHA256: 317AF862A62CF78FC58604EDB77AA3C00EC1543D2337EC634749C25CC5E4908C

virustotal-submit

I created this tool because I needed to submit a sample stored in a password protected ZIP-file (not the ZIP-file), without extracting the sample to disk.

To submit a file to VirusTotal, you just run virustotal-submit.py sample.exe.

If you submit a ZIP file, virustotal-submit.py will extract the first file to memory and submit that to VirusTotal. The ZIP file can be password protected with password “infected”. To submit the ZIP file itself, use option -z.

To submit a batch of samples, create a textfile with the name of the files to submit and use option -f.

virustotal-submit.py supports proxies (Python variables HTTP_PROXY and HTTPS_PROXY or environment variables http_proxy and https_proxy).

Python module poster is required for this tool.

virustotal-submit_V0_0_3.zip (https)
MD5: 3F9F5421F711E2930AB6F80D87DF9E2B
SHA256: 37CCE3E8469DE097912CB23BAC6B909C9C7F5A5CEE09C9279D32BDB9D6E23BCC

25 Comments »

  1. […] virustotal-search and virustotal-submit have their own page now: VirusTotal Tools. […]

    Pingback by Update: virustotal-submit.py V0.0.3 | Didier Stevens — Saturday 14 December 2013 @ 22:22

  2. Great tool !

    Just encountered a python exception when searching for hash ‘0164dc11b05124166f83da841b2cefbf91a8a1ee105820b416d9493263ebd222’ : one AV result has a ‘None’ version…

    Comment by Thierry — Monday 13 January 2014 @ 11:12

  3. @Thierry What version of the virustotal-search did you use?

    Comment by Didier Stevens — Tuesday 14 January 2014 @ 1:53

  4. I am having an issue with the v3 of the virus search – I am getting the error “;Error jsonalias.loads;No JSON object could be decoded;’Traceback (most recent call last):\n File “virustotal-search.py”, line 200, in GetReports\n oResults = jsonalias.loads(jsonResponse)\n File “/usr/lib64/python2.7/json/__init__.py”, line 338, in loads\n return _default_decoder.decode(s)\n File “/usr/lib64/python2.7/json/decoder.py”, line 365, in decode\n obj, end = self.raw_decode(s, idx=_w(s, 0).end())\n File “/usr/lib64/python2.7/json/decoder.py”, line 383, in raw_decode\n raise ValueError(“No JSON object could be decoded”)\nValueError: No JSON object could be decoded\n'” Any ideas?

    Comment by Anonymous — Tuesday 28 January 2014 @ 13:19

  5. Version0.0.3 is an old version, use the last version: 0.1.0.

    Comment by Didier Stevens — Wednesday 29 January 2014 @ 7:36

  6. Running version 0.1.0 – It runs fine for a few hours (at default rate), and then I get an “Error jsonalias.loads;No JSON object could be decoded;’Traceback (most recent call last):\n File “virustotal-search.py”, line 200, in GetReports…” error. It appears to be the same error as ‘Anonymous’ posted. The script won’t run again until I reboot my workstation (Windows 7).

    Comment by Jon — Tuesday 14 April 2015 @ 19:32

  7. @Jon Look in file virustotal-search-*.csv for the last successful request. Then search in your file for that searchterm. What is the next searchterm?

    Comment by Didier Stevens — Tuesday 14 April 2015 @ 19:45

  8. It looks like I somehow hit my API limit. I thought I was running this script at home under a different API key, but I think I was running them both under the same API key. I think the rfox on eboot was just by chance, since I didn’t reboot until the next day.

    Comment by Jon — Wednesday 15 April 2015 @ 13:35

  9. @jon I have a new version that I’ll release soon. When you hit your daily quota, you can instruct this new version to wait and resume when your daily quota is reset.

    Comment by Didier Stevens — Wednesday 15 April 2015 @ 19:02

  10. […] new version op virustotal-search adds a bunch of options to manage the local database, and 2 features I want to highlight […]

    Pingback by Update: virustotal-search Version 0.1.2 Daily Quota Handling and CVEs | Didier Stevens — Monday 27 April 2015 @ 0:01

  11. Didier – great tool! Ran it once and perfect results. When I ran it the second time, and all subsequent times, I’m getting this: “Traceback (most recent call last):
    File “virustotal-search.py”, line 510, in
    Main()
    File “virustotal-search.py”, line 507, in Main
    VirusTotalSearch(args[0], options)
    File “virustotal-search.py”, line 454, in VirusTotalSearch
    statuscode = GetReports(searchTermsToRequest[0:4], reports, options.comment, dNotFound)
    File “virustotal-search.py”, line 280, in GetReports
    LogResult(searchTermComments[iIter][0], searchTermComments[iIter][1], oResults[iIter], True, withComment)
    File “virustotal-search.py”, line 241, in LogResult
    oLogger.PrintAndLog(formats, parameters)
    File “virustotal-search.py”, line 171, in PrintAndLog
    line = self.separator.join(formats) % parameters
    UnicodeDecodeError: ‘ascii’ codec can’t decode byte 0xff in position 0: ordinal not in range(128)”

    Running version: 0.1.2

    Any suggestions?

    Thanks!

    Steve Bunting

    Comment by Steve Bunting — Friday 5 June 2015 @ 17:25

  12. Didier – forget above post! 2nd run hash list was using Unicode and not ASCII. My bad… thanks anyway! – Steve

    Comment by Steve Bunting — Friday 5 June 2015 @ 17:37

  13. Above text shows:
    virustotal-search_V0_1_2.zip (https)
    MD5: 62C8031738E6E20FEC38337010496DF6
    SHA256: 317AF862A62CF78FC58604EDB77AA3C00EC1543D2337EC634749C25CC5E4908C

    Downloaded file shows:
    md5sum *
    2e7dbaeb1a2d6054ae9db9a323bbf4ea virustotal-search.py
    62c8031738e6e20fec38337010496df6 virustotal-search_V0_1_2.zip

    sha256sum *
    d4a3069929fe84beb9189e0488117c8707a9805e56d4a34fd7c0f23a8c7a8291 virustotal-search.py
    317af862a62cf78fc58604edb77aa3c00ec1543d2337ec634749c25cc5e4908c virustotal-search_V0_1_2.zip

    Could you confirm if the file above is valid? Thanks!!

    Comment by Anonymous — Tuesday 11 August 2015 @ 17:58

  14. I don’t see the problem, can you give more info? I see that the hashes you calculated are the same than the ones I posted.

    Comment by Didier Stevens — Tuesday 11 August 2015 @ 19:29

  15. […] virustotal-tools: Interact with the VirusTotal database from the command-line […]

    Pingback by REMnux: Distribución de Linux especializada en en el análisis de malware | Skydeep — Thursday 20 August 2015 @ 1:49

  16. How do we create a list of hashes to scan?

    Comment by Anonymous — Wednesday 26 August 2015 @ 14:29

  17. Nevermind. Figured out you just needed to use a simple text file. This works great! Thanks so much for making it!

    Comment by Anonymous — Wednesday 26 August 2015 @ 15:50

  18. VirusTotal Public API support “shared” public key in a way of tuple(key, IP), so probably don’t need each user to create an account. On their FAQ:
    ==================
    I integrated the public API in free software, the default request rate is too low to attend all my users

    The public API request can be fixed by the tuple (api key, IP address). Whenever this is done it is this tuple the one having the 4 requests/minute limitation and not the key on its own. This means that you can include a unique key in the software you have developed and each one of your users (provided they are not sharing their IP address) will experience a different 4 requests/minute limitation. Contact us in order to make your key a shared key, this is a free setting.
    ==================

    Comment by Tyler — Wednesday 17 February 2016 @ 0:41

  19. This tool is great! Keep up the great work.

    Have you considered adding a progress bar, using something like tqdm? Here’s a link for reference: https://pypi.python.org/pypi/tqdm

    Comment by Brian — Wednesday 16 March 2016 @ 17:26

  20. No, I try to develop Python tools with as little external modules as possible.

    Comment by Didier Stevens — Wednesday 23 March 2016 @ 19:55

  21. i need a tool, which can read API secuences from a csv file ( second columns) and download json, executable file,pcap file and etc from virustotal

    Comment by botmaster — Sunday 29 May 2016 @ 11:19

  22. Can you use this tool in its current format to scan a list of IP addresses using VT? Or can I make a feature request to have a cmdline argument that says the contents of the text file is IP addresses to scan through?

    Comment by randomaccess — Monday 13 June 2016 @ 23:31

  23. I’ll put it on my todo list.

    Comment by Didier Stevens — Wednesday 15 June 2016 @ 8:25

  24. Anyway the output can include the other hashes? i.e. I feed the script a list with sha-1 and the script pull sha256 and md5 along with the other information

    Comment by Anonymous — Wednesday 15 June 2016 @ 18:37

  25. […] the dumped processes against Virus Total to see if there are any hits. Didier Stevens has a great set of scripts to do this, so mad props to him! You can get a lot of false positives doing this, but it can also […]

    Pingback by Fun stuff with Volatility | 31ric — Wednesday 27 July 2016 @ 18:51


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 )

Twitter picture

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

Facebook photo

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

Google+ photo

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

Connecting to %s

The Rubric Theme. Blog at WordPress.com.

Follow

Get every new post delivered to your Inbox.

Join 449 other followers

%d bloggers like this: