1
2
3
4
5
6 import logging
7 import os.path
8 import subprocess
9 import threading
10
11 from lib.cuckoo.common.abstracts import Auxiliary
12 from lib.cuckoo.common.constants import CUCKOO_ROOT
13
14 log = logging.getLogger(__name__)
15 PORTS = []
16 PORT_LOCK = threading.Lock()
17
18 -class MITM(Auxiliary):
22
24 mitmdump = self.options.get("mitmdump", "/usr/local/bin/mitmdump")
25 port_base = int(self.options.get("port_base", 50000))
26 script = self.options.get("script", "data/mitm.py")
27 certificate = self.options.get("certificate", "bin/cert.p12")
28
29 outpath = os.path.join(CUCKOO_ROOT, "storage", "analyses",
30 "%d" % self.task.id, "dump.mitm")
31
32 if not os.path.exists(mitmdump):
33 log.error("Mitmdump does not exist at path \"%s\", man in the "
34 "middle interception aborted.", mitmdump)
35 return
36
37 if not os.path.exists(script):
38 log.error("Mitmdump script file does not exist at path \"%s\", "
39 "man in the middle interception aborted.", script)
40 return
41
42 cert_path = os.path.join("analyzer", "windows", certificate)
43 if not os.path.exists(cert_path):
44 log.error("Mitmdump root certificate not found at path \"%s\" "
45 "(real path \"%s\"), man in the middle interception "
46 "aborted.", certificate, cert_path)
47 return
48
49 PORT_LOCK.acquire()
50
51 for port in xrange(port_base, port_base + 512):
52 if port not in PORTS:
53 self.port = port
54 break
55
56 PORTS.append(self.port)
57
58 PORT_LOCK.release()
59
60 args = [
61 mitmdump, "-q",
62 "-s", "\"%s\" %s" % (script, self.task.options.get("mitm", "")),
63 "-p", "%d" % self.port,
64 "-w", outpath
65 ]
66
67 mitmlog = os.path.join(CUCKOO_ROOT, "storage", "analyses",
68 "%d" % self.task.id, "mitm.log")
69
70 mitmerr = os.path.join(CUCKOO_ROOT, "storage", "analyses",
71 "%d" % self.task.id, "mitm.err")
72
73 self.proc = subprocess.Popen(args,
74 stdout=open(mitmlog, "wb"),
75 stderr=open(mitmerr, "wb"))
76
77 if "cert" in self.task.options:
78 log.warning("A root certificate has been provided for this task, "
79 "however, this is overridden by the mitm auxiliary "
80 "module.")
81
82 self.task.options["cert"] = certificate
83
84 if "proxy" in self.task.options:
85 log.warning("A proxy has been provided for this task, however, "
86 "this is overridden by the mitm auxiliary module.")
87
88
89
90 self.task.options["proxy"] = \
91 "%s:%d" % (self.machine.resultserver_ip, port)
92
93 log.info("Started mitm interception with PID %d (ip=%s, port=%d).",
94 self.proc.pid, self.machine.resultserver_ip, self.port)
95
97 if self.proc and not self.proc.poll():
98 try:
99 self.proc.terminate()
100 PORTS.remove(self.port)
101 except:
102 try:
103 if not self.proc.poll():
104 log.debug("Killing mitmdump")
105 self.proc.kill()
106 PORTS.remove(self.port)
107 except OSError as e:
108 log.debug("Error killing mitmdump: %s. Continue", e)
109 except Exception as e:
110 log.exception("Unable to stop mitmdump with pid %d: %s",
111 self.proc.pid, e)
112