[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[or-cvs] [torbrowser/master 1/4] Example code for submitting samples to VirusTotal



Author: Steven Murdoch <Steven.Murdoch@xxxxxxxxxxxx>
Date: Sun, 24 Oct 2010 22:12:06 +0100
Subject: Example code for submitting samples to VirusTotal
Commit: fc7b945481fb20f8e78ea9a4a9eed4a651aace82

Written by Bryce Boe
Downloaded from http://www.bryceboe.com/2010/09/01/submitting-binaries-to-virustotal/
---
 build-scripts/virus-scan.py |   93 +++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 93 insertions(+), 0 deletions(-)
 create mode 100644 build-scripts/virus-scan.py

diff --git a/build-scripts/virus-scan.py b/build-scripts/virus-scan.py
new file mode 100644
index 0000000..3b14fcb
--- /dev/null
+++ b/build-scripts/virus-scan.py
@@ -0,0 +1,93 @@
+import hashlib, httplib, mimetypes, os, pprint, simplejson, sys, urlparse
+
+DEFAULT_TYPE = 'application/octet-stream'
+
+REPORT_URL = 'https://www.virustotal.com/api/get_file_report.json'
+SCAN_URL = 'https://www.virustotal.com/api/scan_file.json'
+
+API_KEY = 'YOUR KEY HERE'
+
+# The following function is modified from the snippet at:
+# http://code.activestate.com/recipes/146306/
+def encode_multipart_formdata(fields, files=()):
+    """
+    fields is a dictionary of name to value for regular form fields.
+    files is a sequence of (name, filename, value) elements for data to be
+    uploaded as files.
+    Return (content_type, body) ready for httplib.HTTP instance
+    """
+    BOUNDARY = '----------ThIs_Is_tHe_bouNdaRY_$'
+    CRLF = '\r\n'
+    L = []
+    for key, value in fields.items():
+        L.append('--' + BOUNDARY)
+        L.append('Content-Disposition: form-data; name="%s"' % key)
+        L.append('')
+        L.append(value)
+    for (key, filename, value) in files:
+        L.append('--' + BOUNDARY)
+        L.append('Content-Disposition: form-data; name="%s"; filename="%s"' %
+                 (key, filename))
+        content_type = mimetypes.guess_type(filename)[0] or DEFAULT_TYPE
+        L.append('Content-Type: %s' % content_type)
+        L.append('')
+        L.append(value)
+    L.append('--' + BOUNDARY + '--')
+    L.append('')
+    body = CRLF.join(L)
+    content_type = 'multipart/form-data; boundary=%s' % BOUNDARY
+    return content_type, body
+
+def post_multipart(url, fields, files=()):
+    """
+    url is the full to send the post request to.
+    fields is a dictionary of name to value for regular form fields.
+    files is a sequence of (name, filename, value) elements for data to be
+    uploaded as files.
+    Return body of http response.
+    """
+    content_type, data = encode_multipart_formdata(fields, files)
+    url_parts = urlparse.urlparse(url)
+    if url_parts.scheme == 'http':
+        h = httplib.HTTPConnection(url_parts.netloc)
+    elif url_parts.scheme == 'https':
+        h = httplib.HTTPSConnection(url_parts.netloc)
+    else:
+        raise Exception('Unsupported URL scheme')
+    path = urlparse.urlunparse(('', '') + url_parts[2:])
+    h.request('POST', path, data, {'content-type':content_type})
+    return h.getresponse().read()
+
+def scan_file(filename):
+    files = [('file', filename, open(filename, 'rb').read())]
+    json = post_multipart(SCAN_URL, {'key':API_KEY}, files)
+    return simplejson.loads(json)
+
+def get_report(filename):
+    md5sum = hashlib.md5(open(filename, 'rb').read()).hexdigest()
+    json = post_multipart(REPORT_URL, {'resource':md5sum, 'key':API_KEY})
+    data = simplejson.loads(json)
+    if data['result'] != 1:
+        print 'Result not found, submitting file.'
+        data = scan_file(filename)
+        if data['result'] == 1:
+            print 'Submit successful.'
+            print 'Please wait a few minutes and try again to receive report.'
+        else:
+            print 'Submit failed.'
+            pprint.pprint(data)
+    else:
+        pprint.pprint(data['report'])
+
+
+if __name__ == '__main__':
+    if len(sys.argv) != 2:
+        print 'Usage: %s filename' % sys.argv[0]
+        sys.exit(1)
+
+    filename = sys.argv[1]
+    if not os.path.isfile(filename):
+        print '%s is not a valid file' % filename
+        sys.exit(1)
+
+    get_report(filename)
-- 
1.7.1