1
2
3
4
5
6 import os
7 import codecs
8 import base64
9
10 from lib.cuckoo.common.abstracts import Report
11 from lib.cuckoo.common.constants import CUCKOO_ROOT
12 from lib.cuckoo.common.exceptions import CuckooReportError
13 from lib.cuckoo.common.objects import File
14
15 try:
16 from jinja2.environment import Environment
17 from jinja2.loaders import FileSystemLoader
18 HAVE_JINJA2 = True
19 except ImportError:
20 HAVE_JINJA2 = False
21
23 """Stores report in HTML format."""
24
25 - def run(self, results):
26 """Writes report.
27 @param results: Cuckoo results dict.
28 @raise CuckooReportError: if fails to write report.
29 """
30 if not HAVE_JINJA2:
31 raise CuckooReportError(
32 "Failed to generate HTML report: Jinja2 library is not "
33 "installed (install `pip install jinja2`)")
34
35 shots_path = os.path.join(self.analysis_path, "shots")
36 if os.path.exists(shots_path):
37 shots = []
38 counter = 1
39 for shot_name in os.listdir(shots_path):
40 if not shot_name.endswith(".jpg"):
41 continue
42
43 shot_path = os.path.join(shots_path, shot_name)
44 if not os.path.getsize(shot_path):
45 continue
46
47 shot = {}
48 shot["id"] = os.path.splitext(File(shot_path).get_name())[0]
49 shot["data"] = base64.b64encode(open(shot_path, "rb").read())
50 shots.append(shot)
51
52 counter += 1
53
54 shots.sort(key=lambda shot: shot["id"])
55 results["screenshots"] = shots
56 else:
57 results["screenshots"] = []
58
59 env = Environment(autoescape=True)
60 env.loader = FileSystemLoader(os.path.join(CUCKOO_ROOT,
61 "data", "html"))
62
63 processed = None
64 mapping = [
65 ("file_read", "File", "Read"),
66 ("file_written", "File", "Written"),
67 ("file_deleted", "File", "Deleted"),
68 ("file_opened", "File", "Opened"),
69 ("file_copied", "File", "Copied"),
70 ("file_moved", "File", "Moved"),
71 ("connects_ip", "Network", "Connects IP"),
72 ("resolves_url", "Network", "Resolves URL"),
73 ("fetches_url", "Network", "Fetches URL"),
74 ("connects_host", "Network", "Connects Host"),
75 ("downloads_file_url", "Network", "Downloads File URL"),
76 ("directory_created", "Directory", "Created"),
77 ("directory_removed", "Directory", "Removed"),
78 ("directory_enumerated", "Directory", "Enumerated"),
79 ("regkey_opened", "Registry Key", "Opened"),
80 ("regkey_deleted", "Registry Key", "Deleted"),
81 ("regkey_read", "Registry Key", "Read"),
82 ("regkey_written", "Registry Key", "Written"),
83 ("mutex", "Mutex", "Accessed"),
84 ]
85
86 processed = {}
87 for proc in results.get("behavior", {}).get("generic", []):
88 for orig, cat, subcat in mapping:
89 if cat not in processed:
90 processed[cat] = {}
91
92 if subcat not in processed[cat]:
93 processed[cat][subcat] = []
94
95
96 if orig == "file_moved" or orig == "file_copied":
97 for src, dst in proc.get("summary", {}).get(orig, []):
98 entry = "%s -> %s" % (src, dst)
99 processed[cat][subcat].append(entry)
100 continue
101
102 if "summary" in proc and orig in proc["summary"]:
103 for content in proc["summary"][orig]:
104 processed[cat][subcat].append(content)
105
106 try:
107 tpl = env.get_template("report.html")
108 html = tpl.render({"results": results,
109 "processed": processed,
110 "mapping": mapping})
111 except Exception as e:
112 raise CuckooReportError("Failed to generate HTML report: %s" % e)
113
114 try:
115 report_path = os.path.join(self.reports_path, "report.html")
116 with codecs.open(report_path, "w", encoding="utf-8") as report:
117 report.write(html)
118 except (TypeError, IOError) as e:
119 raise CuckooReportError("Failed to write HTML report: %s" % e)
120
121 return True
122