opexxx

virustotal.py

Feb 23rd, 2014
232
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 5.86 KB | None | 0 0
  1. #!/usr/bin/python
  2. import httplib, mimetypes, simplejson, urllib, urllib2
  3. import hashlib, time
  4. import sys, getopt
  5.  
  6. apikey = ""
  7.  
  8. class bcolors:
  9.     GREEN = '\033[92m'
  10.     RED = '\033[91m'
  11.     ENDC = '\033[0m'
  12.  
  13.     def disable(self):
  14.         self.GREEN = ''
  15.         self.RED = ''
  16.         self.ENDC = ''
  17.  
  18. # From VirusTotal API example https://www.virustotal.com/documentation/public-api/
  19. # Upload file support
  20. def post_multipart(host, selector, fields, files):
  21.     """
  22.    Post fields and files to an http host as multipart/form-data.
  23.    fields is a sequence of (name, value) elements for regular form fields.
  24.    files is a sequence of (name, filename, value) elements for data to be uploaded as files
  25.    Return the server's response page.
  26.    """
  27.     content_type, body = encode_multipart_formdata(fields, files)
  28.     h = httplib.HTTP(host)
  29.     h.putrequest('POST', selector)
  30.     h.putheader('content-type', content_type)
  31.     h.putheader('content-length', str(len(body)))
  32.     h.endheaders()
  33.     h.send(body)
  34.     errcode, errmsg, headers = h.getreply()
  35.     return h.file.read()
  36.  
  37. def encode_multipart_formdata(fields, files):
  38.     """
  39.    fields is a sequence of (name, value) elements for regular form fields.
  40.    files is a sequence of (name, filename, value) elements for data to be uploaded as files
  41.    Return (content_type, body) ready for httplib.HTTP instance
  42.    """
  43.     BOUNDARY = '----------ThIs_Is_tHe_bouNdaRY_$'
  44.     CRLF = '\r\n'
  45.     L = []
  46.     for (key, value) in fields:
  47.         L.append('--' + BOUNDARY)
  48.         L.append('Content-Disposition: form-data; name="%s"' % key)
  49.         L.append('')
  50.         L.append(value)
  51.     for (key, filename, value) in files:
  52.         L.append('--' + BOUNDARY)
  53.         L.append('Content-Disposition: form-data; name="%s"; filename="%s"' % (key, filename))
  54.         L.append('Content-Type: %s' % get_content_type(filename))
  55.         L.append('')
  56.         L.append(value)
  57.     L.append('--' + BOUNDARY + '--')
  58.     L.append('')
  59.     body = CRLF.join(L)
  60.     content_type = 'multipart/form-data; boundary=%s' % BOUNDARY
  61.     return content_type, body
  62.  
  63. def get_content_type(filename):
  64.     return mimetypes.guess_type(filename)[0] or 'application/octet-stream'
  65.  
  66. # Return sha256 of a file
  67. def filetohash(filename):
  68.     file_content = open(filename, "rb").read()
  69.     sha = hashlib.sha256(file_content).hexdigest()
  70.     return sha
  71.  
  72. # Upload on VirusTotal
  73. def upload(filename):
  74.     host = "www.virustotal.com"
  75.     selector = "https://www.virustotal.com/vtapi/v2/file/scan"
  76.     fields = [("apikey", apikey)]
  77.     file_to_send = open(filename, "rb").read()
  78.     files = [("file", filename, file_to_send)]
  79.     json = post_multipart(host, selector, fields, files)
  80.     result = simplejson.loads(json)
  81.     return result
  82.  
  83. # Get report from a hash (md5, sha1, sha256, sha256+timestamp)
  84. def report(resource):
  85.     url = "https://www.virustotal.com/vtapi/v2/file/report"
  86.     parameters = {"resource": resource,
  87.         "apikey": apikey}
  88.     data = urllib.urlencode(parameters)
  89.     req = urllib2.Request(url, data)
  90.     response = urllib2.urlopen(req)
  91.     json = response.read()
  92.     #print json
  93.     result = simplejson.loads(json)
  94.     return result
  95.  
  96. # Print a VirusTotal report
  97. def format_report(result):
  98.     scans = result.get("scans")
  99.     for k, v in scans.items():
  100.         if v['detected'] == True:
  101.             print ("%s: %s%s%s") % (k, bcolors.RED, v['result'], bcolors.ENDC)
  102.         else:
  103.             print ("%s: %s-%s") % (k, bcolors.GREEN, bcolors.ENDC )
  104.  
  105.     print "-"*72
  106.     print "SHA256: %s" % result['sha256']
  107.     print "MD5: %s" % result['md5']
  108.     print ("Detection ratio: %s%s/%s%s") % \
  109.         (bcolors.RED, result['positives'], result['total'], bcolors.ENDC)
  110.     print ("Analysis date: %s%s%s") % (bcolors.GREEN, result['scan_date'],  
  111.         bcolors.ENDC)
  112.     print "-"*72
  113.     print "URL: %s" % result['permalink']
  114.  
  115. def usage():
  116.     print "%s <file>" % sys.argv[0]
  117.     print "%s --no-upload <file>" % sys.argv[0]
  118.     print "%s -n <file>" % sys.argv[0]
  119.     print "%s --hash <hash>" % sys.argv[0]
  120.     print "%s -h <hash>" % sys.argv[0]
  121.     print "%s --force <file>" % sys.argv[0]
  122.     print "%s -f <file>" % sys.argv[0]
  123.     print " -n don't upload the file if report not available"
  124.     print " -h check if report exist for a hash"
  125.     print " -f force a new scan for the file"
  126.  
  127. def main():
  128.     if len(apikey) != 64:
  129.         print "Please set your VirusTotal API key"
  130.         sys.exit(2)
  131.  
  132.     try:
  133.         opts, args = getopt.getopt(sys.argv[1:],
  134.             "fhn", ["force", "hash", "no-upload"])
  135.     except getopt.GetoptError, err:
  136.         print str(err)
  137.         usage()
  138.         sys.exit(2)
  139.  
  140.     if len(args) == 0:
  141.         usage()
  142.         sys.exit(2)
  143.  
  144.     file_hash = None
  145.     file_upload = True
  146.     force = False
  147.     check_hash = False
  148.     for o, a in opts:
  149.         if o in ("-n", "--no-upload"):
  150.             file_upload = False
  151.         elif o in ("-h", "--hash"):
  152.             check_hash = True
  153.         elif o in ("-f", "--force"):
  154.             force = True
  155.         else:
  156.             assert False, "unhandled option"
  157.  
  158.     if check_hash == False:
  159.         file_hash = filetohash(args[0])
  160.     else:
  161.         file_hash = args[0]
  162.    
  163.     if force == False:
  164.         r = report(file_hash)
  165.         if r['response_code'] == 1:
  166.             format_report(r)
  167.             sys.exit(0)
  168.         else:
  169.             print "File %s not in VirusTotal or in queue" % file_hash
  170.             if file_upload == False or check_hash == True:
  171.                 sys.exit(0)
  172.  
  173.     print "Upload in progress..."
  174.     ru = upload(args[0])
  175.     print ru['permalink']
  176.     print ru['verbose_msg']
  177.  
  178.     print "Wait for report..."
  179.     r = report(ru['resource'])
  180.     while r['response_code'] == 0:
  181.         time.sleep(15)
  182.         r = report(ru['resource'])
  183.    
  184.     format_report(r)
  185.  
  186. if __name__ == '__main__':
  187.     main()
Add Comment
Please, Sign In to add comment