1
2
3
4
5 import logging
6 import time
7 import urlparse
8
9 try:
10 import requests
11 HAVE_REQUESTS = True
12
13
14 logging.getLogger("requests").setLevel(logging.WARNING)
15 logging.getLogger("urllib3").setLevel(logging.WARNING)
16 except ImportError:
17 HAVE_REQUESTS = False
18
19 from lib.cuckoo.common.abstracts import Processing
20 from lib.cuckoo.common.exceptions import CuckooOperationalError
21 from lib.cuckoo.common.utils import sha256_file
22
23 log = logging.getLogger(__name__)
24
25 -class Irma(Processing):
26 """Gets antivirus signatures from IRMA for various results.
27
28 Currently obtains IRMA results for the target sample or URL and the
29 dropped files.
30 """
31
32 IRMA_FINISHED_STATUS = 50
33
35 """Wrapper around doing a request and parsing its JSON output."""
36 try:
37 r = requests.get(url, timeout=self.timeout, **kwargs)
38 return r.json() if r.status_code == 200 else {}
39 except (requests.ConnectionError, ValueError) as e:
40 raise CuckooOperationalError(
41 "Unable to fetch IRMA results: %r" % e.message
42 )
43
44 - def _post_json(self, url, **kwargs):
45 """Wrapper around doing a post and parsing its JSON output."""
46 try:
47 r = requests.post(url, timeout=self.timeout, **kwargs)
48 return r.json() if r.status_code == 200 else {}
49 except (requests.ConnectionError, ValueError) as e:
50 raise CuckooOperationalError(
51 "Unable to fetch IRMA results: %r" % e.message
52 )
53
55
56 init = self._post_json(urlparse.urljoin(self.url, "/api/v1.1/scans"))
57
58 log.debug("Scanning file: %s", filepath)
59
60
61 files = {
62 "files": open(filepath, "rb"),
63 }
64 url = urlparse.urljoin(
65 self.url, "/api/v1.1/scans/%s/files" % init.get("id")
66 )
67 self._post_json(url, files=files,)
68
69
70 params = {
71 "force": force,
72 }
73 url = urlparse.urljoin(
74 self.url, "/api/v1.1/scans/%s/launch" % init.get("id")
75 )
76 requests.post(url, json=params)
77
78 result = None
79
80 while result is None or result.get("status") != self.IRMA_FINISHED_STATUS:
81 log.debug("Polling for results for ID %s", init.get("id"))
82 url = urlparse.urljoin(
83 self.url, "/api/v1.1/scans/%s" % init.get("id")
84 )
85 result = self._request_json(url)
86 time.sleep(1)
87
88 return
89
91
92 results = self._request_json(
93 urlparse.urljoin(self.url, "/api/v1.1/files/%s" % sha256)
94 )
95
96 if not results.get("items"):
97 log.info("File %s hasn't been scanned before", sha256)
98 return
99
100 result_id = results["items"][-1]["result_id"]
101 return self._request_json(
102 urlparse.urljoin(self.url, "/api/v1.1/results/%s" % result_id)
103 )
104
132