1
2
3
4
5
6 import logging
7 import os
8
9 from lib.cuckoo.common.abstracts import Processing
10 from lib.cuckoo.common.exceptions import CuckooOperationalError
11 from lib.cuckoo.common.exceptions import CuckooProcessingError
12 from lib.cuckoo.common.virustotal import VirusTotalAPI
13 from lib.cuckoo.common.virustotal import VirusTotalResourceNotScanned
14
15 log = logging.getLogger(__name__)
16
18 """Gets antivirus signatures from VirusTotal.com for various results.
19
20 Currently obtains VirusTotal results for the target sample or URL and the
21 dropped files.
22 """
23 order = 2
24
26 """Runs VirusTotal processing
27 @return: full VirusTotal report.
28 """
29 self.key = "virustotal"
30
31 apikey = self.options.get("key")
32 timeout = int(self.options.get("timeout", 60))
33 scan = int(self.options.get("scan", 0))
34
35 if not apikey:
36 raise CuckooProcessingError("VirusTotal API key not "
37 "configured, skipping VirusTotal "
38 "processing module.")
39
40 self.vt = VirusTotalAPI(apikey, timeout, scan)
41
42
43 if self.task["category"] == "file":
44 results = self.scan_file(self.file_path)
45 elif self.task["category"] == "url":
46 results = self.scan_url(self.task["target"])
47 elif self.task["category"] == "baseline":
48 return
49 elif self.task["category"] == "service":
50 return
51 else:
52 raise CuckooProcessingError("Unsupported task category: %s" %
53 self.task["category"])
54
55
56 for row in self.results.get("dropped", []):
57 if not self.should_scan_file(row["type"]):
58 continue
59
60 row["virustotal"] = self.scan_file(row["path"], summary=True)
61
62 return results
63
64 - def scan_file(self, filepath, summary=False):
65 """Retrieve VirusTotal results for a file.
66 @param filepath: file path
67 @param summary: if you want a summary report
68 """
69 if not os.path.exists(filepath):
70 log.warning("Path \"%s\" could not be found for VirusTotal "
71 "lookup, skipping it", os.path.basename(filepath))
72 return
73
74 try:
75 return self.vt.file_report(filepath, summary=summary)
76 except VirusTotalResourceNotScanned:
77 return self.vt.file_scan(filepath)
78 except CuckooOperationalError as e:
79 log.warning("Error fetching results from VirusTotal for "
80 "\"%s\": %s", os.path.basename(filepath), e.message)
81
94
96 """Determines whether a certain filetype should be scanned on
97 VirusTotal. For example, we're not interested in scanning text
98 files.
99 @param filetype: file type
100 """
101 return "PE32" in filetype or "MS-DOS" in filetype
102